tereta/console

Building console (CLI) applications on PHP 8.2+ with PSR-3 output and a PSR-11 dependency container.

Maintainers

Package info

gitlab.com/tereta/library/console

Homepage

Issues

pkg:composer/tereta/console

Transparency log

Statistics

Installs: 3

Dependents: 1

Suggesters: 0

Stars: 0

0.0.4 2026-08-16 23:46 UTC

This package is not auto-updated.

Last update: 2026-08-16 20:48:23 UTC


README

🌐 English | Русский | Π£ΠΊΡ€Π°Ρ—Π½ΡΡŒΠΊΠ°

Building console (CLI) applications on PHP 8.2+ with PSR-3 output and a PSR-11 dependency container.

Requirements

PHP 8.2+, psr/container ^2.0, psr/log ^3.0.

Installation

composer require tereta/console

Quick start

The entry point is the Tereta\Console\Runtime class - it registers commands and passes $argv for execution:

#!/usr/bin/env php
<?php

declare(strict_types=1);

require_once __DIR__ . '/../vendor/autoload.php';

use Tereta\Console\Runtime;
use Tereta\Console\Commands\Listing;

(new Runtime())
    ->register(Listing::class)
    ->execute($argv);

The first argument is the command identifier, the rest is passed to the command. With no arguments the built-in commands:listing runs - a table of the registered commands:

php bin/console
php bin/console commands:listing

Runtime::register, Runtime::registerList - register commands, Runtime::execute - runs a command processing the $argv attributes.

Command

Commands are built on the Tereta\Console\Interfaces\Command interface: the constructor takes the context, execute() takes the arguments and the PSR-3 output. The identifier and the description are declared with class attributes:

use Psr\Log\LoggerInterface;
use Tereta\Console\Attributes\Description as DescriptionAttribute;
use Tereta\Console\Attributes\Identifier as IdentifierAttribute;
use Tereta\Console\Contexts\Runtime as RuntimeContext;
use Tereta\Console\Interfaces\Command;

#[IdentifierAttribute('cache:clean')]
#[DescriptionAttribute('Clears the application cache')]
class Clean implements Command
{
    public function __construct(private RuntimeContext $context)
    {
    }

    public function execute(array $argv, LoggerInterface $output): void
    {
        $output->info('Cache is cleaned.');
    }
}

Without the Tereta\Console\Attributes\Identifier attribute the identifier is built from the last two namespace segments of the class implementing the Tereta\Console\Interfaces\Command interface: The Tereta\Console\Attributes\Description attribute declares the command description, when it is omitted the command listing shows No description available.

Context and dependencies

Tereta\Console\Contexts\Runtime - the context holds:

  • the command container Tereta\Console\Containers\Command, constructor attribute ($commands).
  • the factory Tereta\Console\Factories\Command, constructor attribute ($factory),
  • the output service Tereta\Console\Services\Output, constructor attribute ($output), and the formatting service Tereta\Console\Services\Format, constructor attribute ($format)
  • the pool Tereta\Console\Containers\Pool, constructor attribute $pool - a PSR-11 container for non-standardised configurations, such as databases or anything else that can be described at the environment initialisation level.

For example, a configured ORM or PDO can be put into the pool during bootstrap like this:

$runtime = new Runtime();
$runtime->context->pool->set('orm', $orm);

And taken out inside a command:

$orm = $this->context->pool->get('orm');

Output and formatting

Tereta\Console\Services\Output - a PSR-3 logger implementation: the emergency, critical, error, warning, alert levels are logged to stderr, while the regular notice, info, debug messages go to stdout.

Tereta\Console\Services\Format - the output formatting service, a tool for formatting tables, boxes and colours; the width is configured from the terminal when the instance is created, or can be set manually:

$format = $this->context->format;

$format->setWidth($format::getTerminalWidth());

$output->info($format->table($rows));
$output->info($format::box('Done', $format::FONT_GREEN));

The Tereta\Console\Services\Format functions that depend on the output width:

$format->setWidth(int $width): static
$format->getWidth(): int
$format->decoration(string $message, string $color = self::FONT_GREEN): string
$format->table(array $rows, array $titles = [], string $font = ''): string
  • setWidth - sets the output width in characters, getWidth - returns the current one, Format::DEFAULT_WIDTH (80) by default.
  • decoration - a banner with the logo, the message is split into at most three lines of 52 characters; below a width of 95 characters it returns just the coloured message.
  • table - a table in a pseudographic frame, $titles overrides the column headers by the array keys, $font styles the whole table; when the table does not fit the width, simpleTable is called; the frame is drawn with unicode only when LANG/LC_ALL contains utf, otherwise +, -, |.

Static functions, not affected by the output width:

Format::getTerminalWidth(): int
Format::simpleTable(array $rows, array $titles, string $font = ''): string
Format::box(string $text, ?string $font = null): string
Format::info(string $message, bool $bold = false): string
Format::warning(string $message, bool $bold = false): string
Format::error(string $message, bool $bold = false): string
Format::bold(string $message): string
Format::splitLines(string $string, int $length): array
  • getTerminalWidth - the terminal width via tput cols, 0 when there is no TERM or no tput utility.
  • simpleTable - the same table without a frame, columns separated by two spaces, the last column is not padded.
  • box - text in a frame, multiline text is aligned to the longest line.
  • info, warning, error - a coloured message (green, yellow, red) with a line break, $bold additionally makes it bold.
  • bold - makes the text bold without a line break.
  • splitLines - splits the text into lines of the given length at word boundaries.

Constants: Format::DEFAULT_WIDTH - the default width, Format::FONT_* - ANSI sequences for colour (FONT_RED, FONT_BRIGHT_GREEN), background (FONT_BACKGROUND_BLUE), style (FONT_BOLD, FONT_UNDERLINE) and reset (FONT_RESET, FONT_RESET_ALL, FONT_RESET_COLOR, FONT_RESET_BOLD).

License and author

Tereta Alexander tereta.alexander@gmail.com Web: https://tereta.dev Copyright Β©2008-2026 Tereta Alexander License https://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0

 www.β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—
     β•šβ•β•β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•”β•β•β•β•β•β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•—β–ˆβ–ˆβ•”β•β•β•β•β•β•šβ•β•β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•—
        β–ˆβ–ˆβ•‘   β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—  β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—     β–ˆβ–ˆβ•‘   β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•‘
        β–ˆβ–ˆβ•‘   β–ˆβ–ˆβ•”β•β•β•  β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•—β–ˆβ–ˆβ•”β•β•β•     β–ˆβ–ˆβ•‘   β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•‘
        β–ˆβ–ˆβ•‘   β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•‘  β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—   β–ˆβ–ˆβ•‘   β–ˆβ–ˆβ•‘  β–ˆβ–ˆβ•‘
        β•šβ•β•   β•šβ•β•β•β•β•β•β•β•šβ•β•  β•šβ•β•β•šβ•β•β•β•β•β•β•   β•šβ•β•   β•šβ•β•  β•šβ•β•
                                                    .dev