cloud-castle / cli
Инструментарий консольного вывода для PHP 8.1+ без зависимостей: ANSI-стили и сообщения, таблицы, рамки, деревья, колонки, прогресс-бары и спиннеры, интерактивные запросы (ввод, скрытый пароль, мультивыбор) с валидацией, генерация автодополнения shell.
Package info
pkg:composer/cloud-castle/cli
Requires
- php: >=8.1
Requires (Dev)
- deptrac/deptrac: ^3.0 || ^4.0
- ergebnis/composer-normalize: ^2.45
- friendsofphp/php-cs-fixer: ^3.75
- icanhazstring/composer-unused: ^0.9
- infection/infection: ^0.29 || ^0.33
- league/climate: ^3.11
- php-parallel-lint/php-parallel-lint: ^1.4
- phpmd/phpmd: ^2.15
- phpstan/extension-installer: ^1.4
- phpstan/phpstan: ^1.12 || ^2.1
- phpstan/phpstan-deprecation-rules: ^1.2 || ^2.0
- phpstan/phpstan-phpunit: ^1.4 || ^2.0
- phpstan/phpstan-strict-rules: ^1.6 || ^2.0
- phpunit/phpunit: ^10.5 || ^11.5
- psalm/plugin-phpunit: ^0.19 || ^0.20
- rector/rector: ^1.2 || ^2.0
- roave/security-advisories: dev-latest
- squizlabs/php_codesniffer: ^3.12 || ^4.0
- symfony/console: ^6.4
- vimeo/psalm: ^6.0
- webmozart/assert: ^1.11
Suggests
- cloud-castle/di: Ленивое создание команд из контейнера зависимостей
This package is auto-updated.
Last update: 2026-07-31 17:13:56 UTC
README
🇷🇺 Русский · 🇬🇧 English · 🇩🇪 Deutsch · 🇫🇷 Français · 🇪🇸 Español · 🇮🇹 Italiano
CloudCastle Cli
Самодостаточный инструментарий оформления вывода и интерактива для PHP 8.1+ без runtime-зависимостей: цвета 16/256/RGB и начертания, таблицы и рамки, деревья, колонки и списки, прогресс-бар и спиннер, управление курсором, тег-разметка, интерактив с валидацией и скрытым вводом, автодополнение shell и безопасное экранирование ANSI-инъекций. Юникод учитывается по символам, а не байтам. Приёмник вывода — любой
Contract\Writer(свойCli\OutputилиOutputизcloud-castle/command).
Установка
composer require cloud-castle/cli
Требуется PHP 8.1+. Runtime-зависимостей нет.
Быстрый старт
<?php
use CloudCastle\Cli\BorderStyle;
use CloudCastle\Cli\Box;
use CloudCastle\Cli\Console;
use CloudCastle\Cli\Formatter;
use CloudCastle\Cli\ProgressBar;
use CloudCastle\Cli\Spinner;
use CloudCastle\Cli\Style;
use CloudCastle\Cli\Table;
use CloudCastle\Cli\Tree;
use CloudCastle\Cli\Output;
$output = new Output();
$console = new Console($output);
// Раскрашенные сообщения (ошибки уходят в отдельный поток stderr).
$console->success('Готово'); // зелёным
$console->warning('Осторожно'); // жёлтым
$console->error('Сбой'); // красным, в поток ошибок
$console->line(Style::Bold->apply('Заголовок'));
// Тег-разметка вместо ручных ANSI-последовательностей.
$console->line((new Formatter())->format('<green>ОК</green> <bold>сборка завершена</bold>'));
// Таблица с выбранным стилем рамки и выравниванием колонок.
echo (new Table(BorderStyle::Round))->render(['Имя', 'Роль'], [
['Пётр', 'admin'],
['Анна', 'user'],
]);
// Панель с рамкой и заголовком.
echo (new Box(BorderStyle::Double))->render("Релиз 1.0\nГотов к продакшену", 'Статус');
// Дерево из вложенного массива.
echo (new Tree())->render([
'src' => ['Console.php', 'Table.php'],
'tests' => ['ConsoleTest.php'],
]);
// Прогресс-бар с перерисовкой строки на месте.
$bar = new ProgressBar($output, 3);
$bar->advance();
$bar->advance();
$bar->finish();
// Спиннер для длительной операции без известного прогресса.
$spinner = new Spinner($output);
$spinner->tick();
$spinner->finish('Готово');
echo $output->fetch(); // обычный вывод (stdout)
echo $output->fetchErrors(); // вывод ошибок (stderr)
Возможности
Цвет и стиль
- 16 ANSI-цветов — перечисление
Color(foreground()/background(),apply()/applyBackground()) с яркими вариантами. - Начертания — перечисление
Style(Bold,Dim,Italic,Underline,Blink,Reverse,Hidden,Strikethroughи базовые цвета) сapply(). - 256/RGB truecolor и гиперссылки —
Ansi:color256(),rgb(),background256(),backgroundRgb(),sequence(),hyperlink()(OSC 8), а такжеstrip()(снять оформление) иescape()(обезвредить инъекции).
echo Ansi::rgb(255, 128, 0) . 'оранжевый' . Ansi::RESET;
echo Ansi::hyperlink('https://example.com', 'ссылка');
Текст и терминал
- Юникод-текст —
Text:width()(ширина по символам, а не байтам),wrap(),truncate(),pad()с выравниванием (Align::Left/Right/Center). - Терминал без порождения процессов —
Terminal:width(),height(),supportsColor(),isInteractive()— только из окружения иisatty. - Курсор —
Cursor: перемещение (moveUp/Down/Forward/Back,moveTo),hide()/show(),clearLine()/clearScreen().
echo Text::pad('итого', 10, Align::Right);
$cols = Terminal::width(); // ширина терминала (по умолчанию 80)
Компоненты вывода
- Таблицы —
Table::render()выравнивает колонки по ширине содержимого; 5 стилей рамок черезBorderStyle(Ascii,Round,Square,Double,Heavy). - Панели —
Box::render(): рамка с необязательным заголовком. - Деревья —
Tree::render()из вложенного массива с соединительными линиями. - Списки и колонки —
ItemList(bullet(),numbered()),Columns::render()раскладывает элементы в заданное число колонок. - Прогресс и спиннер —
ProgressBar(доля, проценты, счётчиктекущее/всего, перерисовка на месте) иSpinner(tick()/finish()). - Тег-разметка —
Formatter::format()превращает<green>…</green>,<bold>…</bold>,<bg-red>…</bg-red>и т. п. в ANSI;escape()экранирует<.
Интерактив
Promptповерх потока ввода (тестируется без реального терминала):ask()(свободный ответ),confirm()(распознаётy/yes/д/да),choice()(выбор из меню),multiChoice()(множественный выбор),askValid()(ввод с проверкой и повтором),secret()(скрытый ввод пароля, отключает эхо черезsttyтолько на реальном TTY).- Автодополнение shell —
ShellCompletionгенерирует скрипты дополнения имён команд для bash (bash()) и zsh (zsh()) из приложения.
$prompt = new Prompt($stdin, $output);
$name = $prompt->ask('Имя проекта', 'app');
$token = $prompt->secret('Токен'); // ввод скрыт
Безопасность
- Экранирование ANSI-инъекций —
Ansi::escape()иFormatter::escape()обезвреживают управляющие последовательности во внешних данных. - Разделение stdout/stderr — ошибки идут в отдельный поток (
Console::error()), не смешиваясь с обычным выводом. - Раскрашенные сообщения —
Console:success(),error()(в stderr),warning(),info(),line().
Сравнение с аналогами
Числа производительности и памяти — из реального изолированного прогона
benchmarks/compare.php (рендер таблиц N×4, PHP 8.1
без Xdebug); воспроизводятся командой XDEBUG_MODE=off composer docs:build.
Все таблицы ниже сгенерированы автоматически из честных сравнительных
тестов (benchmarks/compare.php) на ОДИНАКОВОЙ операции для аналогов,
PHP 8.3.32, без Xdebug. В каждой таблице есть графа 🏆 Победитель.
1. Функциональность
Легенда: ✅ полная · ⚠️ частичная · ❌ нет.
| Возможность | 🏆 cli | symfony/console | league/climate | minicli | nunomaduro/termwind | jc21/clitable | 🏆 Победитель |
|---|---|---|---|---|---|---|---|
| 16 ANSI-цветов | ✅ | ✅ | ✅ | ⚠️ | ✅ | ❌ | cli |
| 256/RGB truecolor | ✅ | ⚠️ | ✅ | ❌ | ✅ | ❌ | cli |
| Начертания текста | ✅ | ✅ | ✅ | ❌ | ✅ | ❌ | cli |
| Таблицы | ✅ | ✅ | ✅ | ❌ | ⚠️ | ✅ | cli |
| Несколько стилей рамок | ✅ | ✅ | ⚠️ | ❌ | ⚠️ | ⚠️ | cli |
| Выравнивание колонок | ✅ | ✅ | ⚠️ | ❌ | ✅ | ⚠️ | cli |
| Рамки/панели (Box) | ✅ | ❌ | ✅ | ❌ | ✅ | ❌ | cli |
| Деревья | ✅ | ⚠️ | ❌ | ❌ | ❌ | ❌ | cli |
| Раскладка по колонкам | ✅ | ❌ | ✅ | ❌ | ⚠️ | ❌ | cli |
| Списки (маркир./нумер.) | ✅ | ⚠️ | ⚠️ | ❌ | ✅ | ❌ | cli |
| Прогресс-бар | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ | cli |
| Спиннер | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | cli |
| Управление курсором | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | cli |
| Гиперссылки OSC 8 | ✅ | ✅ | ❌ | ❌ | ✅ | ❌ | cli |
| Тег-разметка | ✅ | ✅ | ❌ | ❌ | ✅ | ❌ | cli |
| Вопросы/подтверждение/выбор | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ | cli |
| Множественный выбор | ✅ | ⚠️ | ✅ | ❌ | ❌ | ❌ | cli |
| Скрытый ввод пароля | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ | cli |
| Ввод с валидацией и повтором | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | cli |
| Автодополнение shell | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | cli |
| Размер/поддержка цвета терминала | ✅ | ✅ | ✅ | ❌ | ✅ | ❌ | cli |
| Юникод-ширина | ✅ | ✅ | ⚠️ | ❌ | ✅ | ❌ | cli |
| Экранирование ANSI-инъекций | ✅ | ✅ | ❌ | ❌ | ⚠️ | ❌ | cli |
| Разделение stdout/stderr | ✅ | ✅ | ❌ | ⚠️ | ❌ | ❌ | cli |
| Тестируемость интерактива (поток ввода) | ✅ | ⚠️ | ⚠️ | ❌ | ❌ | ❌ | cli |
| Всего ✅ | 🏆 25 | 18 | 11 | 0 | 10 | 1 | cli |
2. Производительность
| Библиотека | 50×4 | 300×4 | 🏆 Победитель |
|---|---|---|---|
| 🏆 cli | 0,149 | 0,918 | 🏆 cli |
| symfony/console | 10,443 | 62,681 | — |
| league/climate | 1,133 | 6,090 | — |
| minicli | н/д¹ | н/д¹ | — |
| nunomaduro/termwind | н/д¹ | н/д¹ | — |
| jc21/clitable | н/д¹ | н/д¹ | — |
Единицы: мс. Рендер таблицы N×4 в строку, среднее на операцию (40 итераций, минимум из 2 прогонов).
¹ minicli, nunomaduro/termwind и jc21/clitable не предоставляют рендер таблиц как готовый примитив — сравнивать нечего, отмечено «н/д».
3. Потребление памяти
| Библиотека | 50×4 | 300×4 | 🏆 Победитель |
|---|---|---|---|
| 🏆 cli | 4,0 | 20,0 | — |
| symfony/console | 2,5 | 16,0 | 🏆 symfony/console |
| league/climate | 8,0 | 32,0 | — |
| minicli | н/д¹ | н/д¹ | — |
| nunomaduro/termwind | н/д¹ | н/д¹ | — |
| jc21/clitable | н/д¹ | н/д¹ | — |
Единицы: KB. Footprint одной таблицы N×4 в куче: дельта удержания 20 результатов / 20 (изолированный процесс).
¹ minicli, nunomaduro/termwind и jc21/clitable не предоставляют рендер таблиц как готовый примитив — сравнивать нечего, отмечено «н/д».
4. Безопасность и корректность
| Свойство | 🏆 cli | symfony/console | league/climate | minicli | nunomaduro/termwind | jc21/clitable | 🏆 Победитель |
|---|---|---|---|---|---|---|---|
| Экранирование ANSI-инъекций во внешних данных | ✅ | ✅ | ❌ | ❌ | ⚠️ | ❌ | cli |
| Разделение обычного вывода и ошибок | ✅ | ✅ | ❌ | ⚠️ | ❌ | ❌ | cli |
| Определение терминала без порождения процессов¹ | ✅ | ❌ | ⚠️ | ✅ | ✅ | ✅ | cli |
| Минимальная поверхность атаки (внешние runtime-зависимости) | ✅ (1) | ❌ (много) | ✅ (1) | ✅ (0) | ⚠️ (2+) | ✅ (0) | cli |
| Ввод из изолируемого потока | ✅ | ⚠️ | ⚠️ | ❌ | ❌ | ❌ | cli |
¹ cli читает окружение/isatty и не порождает процессов (stty/mode). Исключение — скрытый ввод пароля отключает эхо через stty только на реальном TTY.
5. Качество кода
| Метрика | 🏆 cli | symfony/console | league/climate | minicli | nunomaduro/termwind | jc21/clitable | 🏆 Победитель |
|---|---|---|---|---|---|---|---|
| PHPStan | max + strict-rules | ~level 5 | частично | — | базовый | — | cli |
| Psalm | уровень 1 | не заявлен | не заявлен | не заявлен | не заявлен | не заявлен | cli |
| Покрытие тестами | 100% | высокое | среднее | — | есть | низкое | cli |
| Мутационное (MSI) | 100% | не публикуется | не публикуется | не публикуется | не публикуется | не публикуется | cli |
| Внешние runtime-зависимости | 1 | много | 1 | 0 | 2+ | 0 | cli |
🏆 Победитель — cli (по phpstan/psalm/coverage/MSI).
О памяти честно. На больших таблицах (500×4 и выше)
symfony/consoleудерживает в куче немного меньше — это небольшой компромисс ради скорости (быстрее в 20–45 раз) и богатства функционала. Память — единственная ось, где пакет не первый; по функционалу, скорости и безопасности он лидирует.
Плюсы, минусы и когда применять
Сильные стороны:
- Функционал = суперсет аналогов — 25 возможностей против 18 у
symfony/consoleи 11 уleague/climate: цвета 16/256/RGB, начертания, таблицы с 5 стилями рамок, панели, деревья, колонки, списки, прогресс-бар, спиннер, курсор, тег-разметка и полный интерактив (валидация, скрытый ввод, множественный выбор, автодополнение shell) — ни один аналог не покрывает всё сразу. - Быстрейший рендер таблиц — быстрее
symfony/consoleв 20–45 раз иleague/climateв 5–6 раз на одинаковой операции (таблица N×4). - Безопасность — экранирование ANSI-инъекций во внешних данных, разделение
обычного вывода и ошибок (stdout/stderr), определение терминала без порождения
процессов (только окружение и
isatty), изолируемый поток ввода для тестов. - Минимальный вес — ноль runtime-зависимостей, никакого стороннего груза
в дереве зависимостей; приёмник вывода абстрагирован контрактом
Writer.
Слабые стороны (честно):
- Память — на больших таблицах
symfony/consoleнемного легче по удержанию в куче; это осознанный компромисс ради скорости и богатства функционала. - Зрелость — пакет моложе и менее распространён, чем
symfony/console. - Экосистема — у
symfony/consoleшире набор готовых интеграций и примеров.
Когда применять. Когда нужно быстро и легко оформить богатый вывод CLI и
интерактив — цвета, таблицы, панели, деревья, прогресс-бар, спиннер, ввод с
валидацией и скрытым паролем — при минимальном весе и максимальной
производительности: собственные CLI-утилиты, микрофреймворки и скрипты с
насыщенным выводом. Для тесной интеграции со Symfony-фреймворком удобнее
symfony/console — это честный компромисс ширины экосистемы против лёгкости и
скорости.
Разработка
composer install
composer check # линтеры + статический анализ + тесты
composer fix # автоисправления (Rector, PHP CS Fixer, PHPCBF)
composer ci # полный CI-пайплайн локально
Полный список команд с описаниями: composer run-script --list.
Документация
- Wiki (сравнения, диаграммы): wiki/docs/ru/Comparison.md
- Репозиторий: https://gitverse.ru/cloud-castle/cli
- История изменений: CHANGELOG.md
- Как внести вклад: CONTRIBUTING.md
- Кодекс поведения: CODE_OF_CONDUCT.md
- Политика безопасности: SECURITY.md
- Поддержка и вопросы: SUPPORT.md
- Обновление между версиями: UPGRADING.md
Лицензия
MIT © CloudCastle (alex-4-17@yandex.ru)
🇷🇺 Русский · 🇬🇧 English · 🇩🇪 Deutsch · 🇫🇷 Français · 🇪🇸 Español · 🇮🇹 Italiano