Сколько раз вы сталкивались с проблемой, которая никак не могла решиться сама собой? Сколько раз вы задавались вопросом, если бы только эта утилита могла делать «это» или «это», моя жизнь была бы такой легкой? У меня это происходит минимум 3 раза в день.

В моей компании мы настоятельно рекомендуем автоматизацию. Все, что может работать без участия человека, должно работать без участия человека. Черт, если бы можно было принести мне пепси без необходимости вставать, я бы, наверное, спал за своим столом.

Проблема

Недавно, работая с системами сборки CI, я столкнулся с похожей проблемой (не совсем так). Если бы мне пришлось подытожить проблему тремя словами: «Частные репозитории NPM». Если вы когда-либо работали с ними, вы знаете, что вам необходимо пройти аутентификацию, чтобы загружать и устанавливать любые приватные модули. В NPM есть небольшая изящная утилита командной строки, которая позволяет вам войти в любой частный реестр, но есть одна загвоздка. Предполагается, что у вас есть стандартный поток ввода/вывода. В системах CI рекомендуется не использовать эти потоки. Как же тогда система сборки получит доступ к частным репозиториям? Это мыслитель.

Решение

Вы, вероятно, могли бы взломать скрипт, который позволил бы вам сделать это в пару строк (я сделал!), но это не чисто. Это не метод OSS. Кроме того, хаки — это плохо, они имеют тенденцию ломаться, когда среда перестает быть идеальной, что происходит в большинстве случаев (по иронии судьбы). В такие моменты к вам подходит коллега и говорит, почему бы вам просто не создать модуль NPM, который сделает это за вас? Блестящий. Я никогда раньше не работал над модулем NPM, так что самое время начать. Но проблема осталась, как отправить данные в CLI, который принимает только стандартные входные потоки? Вы делаете шаг назад и переоцениваете. «Как здорово было бы, если бы он принимал аргументы командной строки?». Джекпот. Так что все, что мне было нужно, — это способ предоставить аргументы в CLI.

Взломы — это плохо, они имеют тенденцию ломаться, когда среда перестает быть идеальной, что происходит в большинстве случаев (по иронии судьбы).

Было несколько целей, которые я и мой коллега поставили перед попыткой построить это:

  • Требуется возможность получения сведений о пользователе с помощью аргументов командной строки.
  • Он должен изящно отступить, если отсутствует аргумент командной строки.
  • Он также должен обеспечивать программный способ делать все

Вопрос. Как подделать стандартный стандартный ввод?

Ответ: нет. ты вообще пропускаешь.

Вот "как"

Давайте пройдемся по тому, что я сделал. Команда NPM adduser обеспечивает аккуратный программный способ входа в любой реестр NPM. Итак, если вы можете создать оболочку для этого программного API и преобразовать его в интерфейс командной строки, наша работа выполнена, и мы все можем идти домой. Вопрос только в том, как нам получить ввод от пользователя?

Моим ответом на это были переменные среды (сначала). Таким образом, вы устанавливаете переменные среды для имени пользователя, пароля, электронной почты и реестра NPM. Если у вас есть пакеты с ограниченной областью действия, вы также устанавливаете это в переменной среды. Затем вы читаете их в своем скрипте Node, передаете его API adduser и покончили с этим. Довольно просто, верно? Это действительно так.

С переменными среды все в порядке, но на самом деле мы разрабатываем интерфейс командной строки, поэтому давайте посмотрим, как мы можем считывать аргументы для нашего интерфейса командной строки. Я не эксперт во всем этом, поэтому я использую единственный ресурс в моем распоряжении, мой мозг. Как работают аргументы командной строки? Вы предоставляете специальный «маркер», за которым следует значение, верно? (Что-то вроде my-cli -u yo). Итак, чтобы прочитать «значение» «-u», все, что нам нужно сделать, это некоторые манипуляции со строками, которые JS делает для нас невероятно простыми. Так вот что я действительно сделал, я ищу свой специальный «маркер» и читаю слово, которое следует за ним. Если этого маркера нет, я просто возвращаюсь к переменной среды. Если этого нет, то у нас действительно есть проблема, не так ли? Так что справиться с этим на самом деле не проблема разработчика.

После этого мы используем NPM adduser API, перенаправляя наши переменные для имени пользователя, пароля, электронной почты (области действия) и реестра, и возвращаем токен. Запишите это в свой файл NPMRC, и все готово! Очевидно, мне нужно было посмотреть на обычный вход в систему, чтобы увидеть, как структурирован файл NPMRC, чтобы я мог его воспроизвести. Нам также нужно убедиться, что мы не мешаем входам в другие реестры, поэтому мы всегда добавляем в файл (или, в моем случае, считываем все и записываем обратно).

Было несколько крайних случаев, о которых мне нужно было позаботиться, чтобы убедиться, что все работает идеально.

  1. Что делать, если пользователь уже вошел в реестр? В этом случае вам нужно только заменить токен и больше не заниматься ерундой.
  2. Что произойдет, если нет области? В этом случае вам нужно опустить строку, описывающую область действия, в NPMRC.
  3. Это немного сложно. Существует множество видов токенов доступа, которые вы можете иметь. Тот, который мы используем (кодированный base64), содержит специальные символы, такие как «=». Эти символы имеют особое значение в контексте программирования, поэтому такие токены аутентификации необходимо заключать в кавычки. Как разработчик библиотеки, вы не можете знать, какой токен аутентификации вы собираетесь получить, а проверить ответ и определить кодировку очень сложно. Что вы делаете в такой ситуации? Легко, пусть пользователь решает. Это именно то, что я сделал, и именно поэтому существует маркер — кавычки.

Как только вы решите все эти проблемы, у вас будет хороший программный API, который вы сможете использовать. Но как сделать это CLI? Ответ до безобразия прост. Все, что вам нужно сделать, это добавить ключ «bin» в ваш package.json и указать его на ваш скрипт Node. Убедитесь, что вы добавили

#!/usr/bin/env node

в качестве первой строки вашего скрипта, чтобы Bash знал, как запустить ваш скрипт.

Та Да! Мы только что создали интерфейс командной строки с помощью Node, и это было так просто! Посмотрите на код, он есть на GitHub (https://github.com/postmanlabs/npm-cli-login), и он действительно прост.

Вывод из клише

Сообщество JavaScript или, в более общем смысле, сообщество Open Source зависит от вас, разработчика, в своем росте и изменении. В следующий раз, когда вы столкнетесь с проблемой, которая просто так не исчезнет, ​​и вы будете тосковать по инструменту, который мог бы ее решить, создайте его! Я собираюсь построить своего бота для доставки пепси!