В этом второй часть(статья из двух частей), мы рассмотрим еще четыре новых функции, добавленные Symfony 3.2 к компоненту Console, чтобы улучшить его DX (опыт разработчика).
Введен новый класс Terminal
Консольный класс Application определяет несколько методов, чтобы получить размеры (высота и ширина) окна терминала:
use Symfony\Component\Console\Application; $application = new Application(); $dimensions = $application->getTerminalDimensions(); // [$width, $height] $height = $application->getTerminalHeight(); $width = $application->getTerminalWidth();
С технической точки зрения получать эту информацию для всех видов терминалов и операционных систем является сложным, запутанным, медленным и подверженым ошибкам процессом. В Symfony 3.2 мы решили перенести всю эту логику в новый класс Terminal
:
use Symfony\Component\Console\Terminal; $height = (new Terminal())->getHeight(); $width = (new Terminal())->getWidth();
Кроме того, мы улучшили логику, чтобы получить/установить размеры, чтобы установить приоритет использования переменных окружения. Если переменные окружения COLUMNS
и LINES
определены, Terminal
использует их значения, чтобы получить размеры. При установке размеров, терминал создает или обновляет значения этих переменных.
Этот новый класс Terminal
будет использоваться в дальнейшем, чтобы получать/устанавливать более подробную информацию о терминале, а не только его размеры. На данный момент, эти изменения позволили нам исправить некоторые крайние случаи в помощнике Progress Bar, когда окно терминала было небольшим.
Введен новый интерфейс StreamableInputInterface
В Symfony 2.8 мы ввели новый стиль для консоли, который упрощает создание последовательных команд. Тем не менее, эти команды было трудно проверить, особенно при использовании помощника ask()
, при получении ввода пользователя.
В Symfony 3.2 мы ввели новый StreamableInputInterface и сделали абстрактную его реализацию Symfony\Component\Console\Input\Input
. Это изменение позволяет централизовать управление входным потоком в одном классе, и облегчит для тестирования код, связанный с QuestionHelper.
Добавлен метод hasErrors() в ConsoleLogger
В Symfony 3.2, класс ConsoleLogger включает в себя метод с hasErrored(), которая возвращает true
, как только одно сообщение уровня ERROR было зарегистрировано. Таким образом, вам не нужно добавлять какие-либо пользовательскую логику, чтобы решить, следует ли вашей команде возвращать код завершения (exit(1)
) или нет.
Добавлен «Lockable» trait
В Symfony 2.6 мы ввели lock handler, для обеспечения простой абстракции, чтобы залочить что-либо с помощью блокировки файла. Этот обработчик блокировки в основном используется, для избежания проблем параллелизма, предотвращая множественное выполнение одной и той же команды:
use Symfony\Component\Filesystem\LockHandler; class UpdateContentsCommand extends Command { protected function execute(InputInterface $input, OutputInterface $output) { $lock = new LockHandler('update:contents'); if (!$lock->lock()) { // manage lock errors } // ... } }
В Symfony 3.2 мы сделали обработчик блокировки немного проще в использовании благодаря новому LockableTrait
. Эта особенность содержит метод lock()
, который создает не-блокируемую блокировки имени текущей команды:
use Symfony\Component\Console\Command\LockableTrait; class UpdateContentsCommand extends Command { use LockableTrait; protected function execute(InputInterface $input, OutputInterface $output) { if (!$this->lock()) { // manage lock errors } // ... } }
Вы также можете создавать блокировки с пользовательскими именами и даже блокировки блокировок, которые ждут, пока какая нибудь из существующих блокировок не будет снята:
if (!$this->lock('custom_lock_name')) { ... } // the second boolean argument tells whether the lock is blocking or not if (!$this->lock('custom_lock_name', true)) { ... }