Какая аннотация используется для классов, все поля которых должны быть final?
Anonymous Quiz
5%
2%
88%
4%
❤4
Для чего используется аннотация @visibleForTesting?
Anonymous Quiz
6%
Для генерации тестов автоматически
91%
Для обозначения элементов, предназначенных только для тестов
1%
Для скрытия кода от тестирования
3%
Для запуска тестов в production
❤4
Какая аннотация запрещает наследование класса за пределами его библиотеки?
Final Results
38%
5%
54%
3%
❤4
This media is not supported in your browser
VIEW IN TELEGRAM
Пока я готовлю пост про шейдеры, давайте обсудим, как можно создать свой CLI-пакет на Dart. Мы сталкиваемся с CLI каждый день, зачастую даже не задумываясь об этом. Когда вы вводите flutter doctor, чтобы проверить окружение, или запускаете firebase init, чтобы создать проект Firebase, вы взаимодействуете именно с CLI.
CLI (Command Line Interface) — это интерфейс взаимодействия с приложением через консоль: вы передаете команды и аргументы, а приложение что-то выполняет. Если сильно упростить, CLI — это возможность ввести в консоли:
mytool login
И программа выполнит какое-то действие, не открывая UI.
Создать свой CLI на Dart довольно просто. Для этого нужно выполнить команду:
dart create -t console-full my_cli_tool
cd my_cli_tool
После генерации у вас появится базовая структура проекта:
/bin
my_cli_tool.dart <-- точка входа
/lib
...
Все, что находится в папке bin/, является входной точкой нашего CLI.
Когда структура готова, можно добавить команды. Для обработки аргументов и команд идеально подходит пакет args. Кстати, про эту библиотеку вы можете подробнее прочитать в этом посте.
Представим, что у нас есть приложение, и мы хотим добавить CLI-команду для авторизации пользователя. Создадим команду LoginCommand:
class LoginCommand extends Command {
@override
final name = 'login'; // название команды
@override
final description = 'Login to service'; // описание, показывается при -h
@override
Future<void> run() async {
// ... логика авторизации
}
}Для взаимодействия с терминалом используем потоки: stdout, stderr и stdin.
✔️ stdout — вывод обычной информации в терминал (сообщения, результаты)
✔️ stderr — поток ошибок (то, что пользователю важно видеть, если что-то пошло не так)
✔️ stdin — ввод данных пользователем. Например, stdin.readLineSync() просто ждет, пока пользователь нажмет Enter, и возвращает введенный текст
stdout.write('📧 Enter your email: ');
final email = stdin.readLineSync();Для более удобной работы с интерактивным вводом (например, чтобы скрыть ввод пароля или добавить выбор стрелками) можно использовать библиотеку dcli.
mixin CliMixin {
String askStringField(
String prompt, {
String? defaultValue,
bool required = true,
bool hidden = false,
}) {
final result = ask(
prompt,
hidden: hidden,
defaultValue: defaultValue,
required: required,
validator: const NotEmptyValidator(),
);
return result;
}
String askSelectField(
String prompt,
List<String> options, {
String? defaultValue,
}) {
final selected = menu(
prompt,
options: options,
defaultOption: defaultValue,
);
return selected;
}
}После успешного логина данные можно сохранить на диск (например, в ~/.my_cli/config.json). В следующих командах CLI автоматически поймет, что пользователь уже авторизован.
И вот наступает самый приятный момент: CLI готов, его можно сделать глобальной системной командой. Для этого в файле pubspec.yaml нужно добавить секцию executables:
executables:
mytool: my_cli_tool
После этого выполняем:
dart pub global activate --source path
Теперь в любой директории можно набрать:
mytool login
и команда запустится, будто это встроенная системная утилита.
Если вы хотите пойти дальше, можно собрать бинарник под macOS, Linux или Windows:
dart compile exe bin/my_cli_tool.dart -o mytool
Таким образом, CLI становится полноценным инструментом, который можно использовать на любых платформах и с приложениями на разных языках программирования: его можно публиковать на pub.dev, подключить через Homebrew или распространять внутри команды.
❤️ — если нужно продолжение про публикацию CLI в Homebrew и сборку бинарников
Please open Telegram to view this post
VIEW IN TELEGRAM
❤8