СLI или интерфейс командной строки — гибкий инструмент для автоматизации рутинных операций. Рассказываем, как использовать его преимущества на примере простого приложения на Node.js.
Это адаптированный перевод статьи Command-line interface to the rescue with commander.js! из блога разработчика Виктора Кезадо. Повествование ведется от лица автора оригинала.
Пятьдесят лет назад у программ не было удобных пользовательских интерфейсов: единственным средством ввода была клавиатура, приложения вызывались путем написания их имен, а вывод был текстовым.
Разработчикам приходилось проявлять изобретательность, чтобы сделать программы более гибкими. Так появился интерфейс командной строки (или пользовательский интерфейс командной строки — CLI). Его определение звучит как «параметрическая компьютерная программа, которая получает входные данные (параметры и опции) через консольный интерфейс или скрипт».
Следующим шагом было появление графического пользовательского интерфейса (GUI), который вытеснил CLI в узкую область системного администрирования, разработки и поклонников Unix.
Хотя CLI далек от былой популярности, среди разработчиков он переживает период возрождения. Многие приложения (например, VS Code и Spotify) интегрировали CLI в свои пользовательские интерфейсы, а языки программирования (например, Node.js и Golang) используют его для упрощения процесса разработки.
Интерфейс командной строки полезен, когда нужно передавать сценарии или команды с одинаковым набором параметров, а также для автоматизации определенных последовательностей действий.
Инструменты интерфейса командной строки можно рассматривать как набор сценариев автоматизации, объединенных удобным API. Речь идет обо всех преимуществах автоматизации рутинных действий (повышение производительности, снижение количества ошибок и других) в купе с гибкостью.
Вероятно, вы подумали, что графический интерфейс лучше подходит для этих целей и выглядит удобнее. Однако он потребляет больше ресурсов при запуске и его сложно масштабировать. Кроме того, разработка графического интерфейса занимает больше времени и стоит дороже, чем CLI.
Преимущества CLI для бизнеса можно описать так:
Подробно эти пункты раскрыты в исследовании IBM и Forbes, а также в отчете McKinsey.
Можно создать собственный интерфейс командной строки с нуля, но гораздо удобнее использовать фреймворки: они существуют для Python, Javascript, Golang и многих других языков программирования.
Для этой статьи я использовал JS-фреймворк с открытым исходным кодом commander.js, который работает на Node.js.
Прежде чем перейти к коду, рассмотрим некоторые особенности commander.js:
-h
) или длинной (—help
) формах.Перейдем к коду. Начнем с простого примера, который можно использовать в каждом проекте: вывода «Hello, World!». Создадим файл с именем my.js и добавим в него следующий код:
#!/usr/bin/env node
// file: my.js
import { program } from 'commander';
const command = () => {
console.log('Hello, World!');
};
program
.version('0.0.1')
.action(command)
.parse(process.argv);
Эта программа вызывается так:
$ node ./my.js
Hello, World!
Теперь сделаем так, чтобы программа могла учитывать некоторые параметры (аргументы). Например, приветствовать людей по именам:
#!/usr/bin/env node
// file: my.js
import { program } from 'commander';
const command = (names) => {
for (const name of names) {
console.log(`Hello, ${name}!`);
}
};
program
.version('0.0.1')
.arguments('<names...>')
.action(command)
.parse(process.argv);
Из примера выше видно, что программа принимает количество имен, отличное от нуля, в качестве аргументов. Для этого используется метод arguments(args)
, а в методе action(Function)
имена можно обрабатывать так, как мы хотим. Аргументы передаются вместе с командой вызова и указываются через пробелы:
$ node ./my.js Alpha Bravo Charlie
Hello, Alpha!
Hello, Bravo!
Hello, Charlie!
В таком виде программа уже выглядит интереснее. Теперь реализуем одно из главных преимуществ CLI — возможность работать с несколькими командами одновременно:
#!/usr/bin/env node
// file: my.js
import { program } from 'commander';
program
.version('0.0.1')
.command('hello <names...>', 'says hello to people')
.parse(process.argv);
Теперь создадим другой файл, следуя правилу имен: файл точки входа и имя команды через дефис. В этом примере файл точки входа my.js, значит чтобы вызвать команду hello
, мне понадобится файл my-hello.js.
#!/usr/bin/env node
// file: my-hello.js
import { program } from 'commander';
const command = (names) => {
for (const name of names) {
console.log(`Hello, ${name}!`);
}
};
program.parse(process.argv);
const { args } = program;
command(args);
Попробуем вызвать команду hello
передав её вместе с именами:
$ node ./my.js hello Alpha Bravo Charlie
Hello, Alpha!
Hello, Bravo!
Hello, Charlie!
Теперь проверим, как CLI может менять функциональность, передавая параметры. Чтобы сделать это, просто вызовем метод option(opts, description)
:
#!/usr/bin/env node
// file: my.js
import { program } from 'commander';
const hello = (name) => {
return `Hello, ${name}!`;
};
const command = (names, lower, upper) => {
for (const name of names) {
const msg = hello(name);
if (lower) {
console.log(msg.toLowerCase());
} else if (upper) {
console.log(msg.toUpperCase());
} else {
console.log(msg);
}
}
};
program
.option('-l, --lower', 'only use lowercase letters')
.option('-u, --upper', 'only use uppercase letters')
.parse(process.argv);
const { args } = program;
const options = program.opts();
const { lower, upper } = options;
command(args, lower, upper);
В результате получаем следующее:
$ node ./my.js --lower Alpha Bravo Charlie
hello, alpha!
hello, bravo!
hello, charlie!
$ node ./my.js -u Alpha Bravo Charlie
HELLO, ALPHA!
HELLO, BRAVO!
HELLO, CHARLIE!
Мы только что создали очень упрощенный, но рабочий инструмент, используя возможности интерфейса командной строки. Посмотреть результат можно здесь. Чтобы развернуть его, можно отправить код в npm, локально связать с npm-пакетами или создать имя для команды оболочки.
Хотя именно этот инструмент бесполезен в практических целях, в документации commander.js есть описание инструментов, которые принесут реальную пользу.
Никогда не останавливайтесь: В программировании говорят, что нужно постоянно учиться даже для того, чтобы просто находиться на месте. Развивайтесь с нами — на Хекслете есть сотни курсов по разработке на разных языках и технологиях