jbzoo / cli
The framework helps create CLI tools and provides new tools for symfony/console, symfony/process.
Installs: 260 800
Dependents: 4
Suggesters: 0
Security: 0
Stars: 2
Watchers: 1
Forks: 0
Open Issues: 2
Requires
- php: >=7.4
- bluepsyduck/symfony-process-manager: >=1.3.3
- jbzoo/event: ^3.2|^4.0
- jbzoo/utils: ^4.4|^5.0
- symfony/console: ^4.4|^5.4|^6.0
- symfony/lock: ^4.4|^5.4|^6.0
- symfony/process: ^4.4|^5.4|^6.0
Requires (Dev)
- jbzoo/toolbox-dev: ^4.0.1
This package is auto-updated.
Last update: 2023-03-12 23:16:30 UTC
README
The library greatly extends the functionality of Symfony/Console and helps make creating new console utilities in PHP quicker and easier.
- Improved progress bar with a new template and additional information. See ExamplesProgressBar.php.
- Convert option values to a strict variable type. See ExamplesOptionsStrictTypes.php.
- New built-in styles and colors for text output. See ExamplesStyles.php.
- A powerful alias
$this->_($messages, $level)
instead ofoutput->wrileln()
. See ExamplesOutput.php. - Display timing and memory usage information with
--profile
option. - Show timestamp at the beginning of each message with
--timestamp
option. - Mute any sort of errors. So exit code will be always
0
(if it's possible) with--mute-errors
. - None-zero exit code on any StdErr message with
--non-zero-on-error
option. - For any errors messages application will use StdOut instead of StdErr
--stdout-only
option (It's on your own risk!). - Disable progress bar animation for logs with
--no-progress
option. - Shortcut for crontab
--cron
. It's basically focused on logs output. It's combination of--timestamp --profile --stdout-only --no-progress -vv
.
Live Demo
Installing
composer require jbzoo/cli
Usage Example
The simplest CLI application has the following file structure. See the Demo App for more details.
/path/to/app/
my-app # Binrary file (See below)
composer.json # Composer file
/Commands/ # Commands directory
Simple.php # One of the commands (See below)
/vendor/
autoload.php # Composer autoload
See Details
{ "name" : "vendor/my-app", "type" : "project", "description" : "Example of CLI App based on JBZoo/CLI", "license" : "MIT", "keywords" : ["cli", "application", "example"], "require" : { "php" : ">=7.4", "jbzoo/cli" : "^2.0.0" }, "require-dev" : { "roave/security-advisories" : "dev-latest" }, "autoload" : { "psr-4" : {"DemoApp\\" : ""} }, "bin" : ["my-app"] }
Binary file: demo/my-app
See Details
#!/usr/bin/env php <?php declare(strict_types=1); namespace DemoApp; use JBZoo\Cli\CliApplication; // Init composer autoloader if (file_exists(__DIR__ . '/vendor/autoload.php')) { require_once __DIR__ . '/vendor/autoload.php'; } else { require_once dirname(__DIR__) . '/vendor/autoload.php'; } // Set your application name and version. $application = new CliApplication('My Console Application', 'v1.0.0'); // Looks at the online generator of ASCII logos // https://patorjk.com/software/taag/#p=testall&f=Epic&t=My%20Console%20App $application->setLogo(implode(PHP_EOL, [ " __ __ _____ _ ", " | \/ | / ____| | | /\ ", " | \ / |_ _ | | ___ _ __ ___ ___ | | ___ / \ _ __ _ __ ", " | |\/| | | | | | | / _ \| '_ \/ __|/ _ \| |/ _ \ / /\ \ | '_ \| '_ \ ", " | | | | |_| | | |___| (_) | | | \__ \ (_) | | __/ / ____ \| |_) | |_) |", " |_| |_|\__, | \_____\___/|_| |_|___/\___/|_|\___| /_/ \_\ .__/| .__/ ", " __/ | | | | | ", " |___/ |_| |_| ", ])); // Scan directory to find commands. // * It doesn't work recursively! // * They must be inherited from the class \JBZoo\Cli\CliCommand $application->registerCommandsByPath(__DIR__ . '/Commands', __NAMESPACE__); // Action name by default (if there is no arguments) $application->setDefaultCommand('list'); // Run application $application->run();
The simplest CLI action: ./demo/Commands/Simple.php
See Details
<?php declare(strict_types=1); namespace DemoApp\Commands; use JBZoo\Cli\CliCommand; use JBZoo\Cli\Codes; class Simple extends CliCommand { protected function configure(): void { // Action name. It will be used in command line. // Example: `./my-app simple` $this->setName('simple'); // Defined inhereted CLI options. See ./src/CliCommand.php for details. parent::configure(); } protected function executeAction(): int { // Your code here $this->_('Hello world!'); // Exit code. 0 - success, 1 - error. return self::SUCCESS; } }
Built-in Functionality
Sanitize input variables
As live-demo take a look at demo application - ./demo/Commands/ExamplesOptionsStrictTypes.php.
Try to launch ./my-app examples:options-strict-types
.
// If the option has `InputOption::VALUE_NONE` it returns true/false. // --flag-name $value = $this->getOpt('flag-name'); // `$value === true` // --flag-name=" 123.6 " $value = $this->getOpt('flag-name'); // Returns the value AS-IS. `$value === " 123.6 "` // --flag-name=" 123.6 " $value = $this->getOptBool('flag-name'); // Converts an input variable to boolean. `$value === true` // --flag-name=" 123.6 " $value = $this->getOptInt('flag-name'); // Converts an input variable to integer. `$value === 123` // --flag-name=" 123.6 " $value = $this->getOptFloat('flag-name'); // Converts an input variable to float. `$value === 123.6` // --flag-name=" 123.6 " $value = $this->getOptString('flag-name'); // Converts an input variable to trimmed string. `$value === "123.6"` // --flag-name=123.6 $value = $this->getOptArray('flag-name'); // Converts an input variable to trimmed string. `$value === ["123.6"]` // --flag-name="15 July 2021 13:48:00" $value = $this->getOptDatetime('flag-name'); // Converts an input variable to \DateTimeImmutable object. // Use standard input as input variable. // Example. `echo " Qwerty 123 " | php ./my-app examples:agruments` $value = self::getStdIn(); // Reads StdIn as string value. `$value === " Qwerty 123 \n"`
Rendering text in different colors and styles
There are list of predefined colors
<black> Text in Black color </black> <red> Text in Red Color </red> <green> Text in Green Color </green> <yellow> Text in Yellow Color </yellow> <blue> Text in Blue Color </blue> <magenta>Text in Magenta Color</magenta> <cyan> Text in Cyan Color </cyan> <white> Text in White Color </white> <!-- Usually default color is white. It depends on terminal settings. --> <!-- You should use it only to overwrite nested tags. --> <default>Text in Default Color</default>
There are list of predefined styles
<bl>Blinked Text</bl> <b>Bold Text</b> <u>Underlined Text</u> <r>Reverse Color/Backgroud</r> <bg>Change Background Only</bg>
Also, you can combine colors ans styles.
<magenta-bl>Blinked text in magenta color</magenta-bl> <magenta-b>Bold text in magenta color</magenta-b> <magenta-u>Underlined text in magenta color</magenta-u> <magenta-r>Reverse text in magenta color</magenta-r> <magenta-bg>Reverse only background of text in magenta color</magenta-bg>
And predefined shortcuts for standard styles of Symfony Console
<i> alias for <info> <c> alias for <commnet> <q> alias for <question> <e> alias for <error>
Verbosity Levels
Console commands have different verbosity levels, which determine the messages displayed in their output.
As live-demo take a look at demo application - ./demo/Commands/ExamplesOutput.php. You can see Demo video.
Example of usage of verbosity levels
// There two strictly recommended output ways: $this->_($messages, $verboseLevel); // Prints a message to the output in the command class which inherits from the class \JBZoo\Cli\CliCommand cli($messages, $verboseLevel); // This is global alias function of `$this->_(...)`. It's nice to have it if you want to display a text from not CliCommand class. // * `$messages` can be an array of strings or a string. Array of strings will be imploded with new line. // * `$verboseLevel` is one of value form the class \JBZoo\Cli\OutLvl::*
# Do not output any message ./my-app examples:output -q ./my-app examples:output --quiet # Normal behavior, no option required. Only the most useful messages. ./my-app examples:output # Increase verbosity of messages ./my-app examples:output -v # Display also the informative non essential messages ./my-app examples:output -vv # Display all messages (useful to debug errors) ./my-app examples:output -vvv
As result, you will see
Memory and time profiling
As live-demo take a look at demo application - ./demo/Commands/ExamplesProfile.php.
Try to launch ./my-app examples:profile --profile
.
Easy logging
No need to bother with the logging setup as Symfony/Console suggests. Just add the --timestamp
flag and save the output to a file. Especially, this is very handy for saving cron logs.
./my-app examples:profile --timestamp >> /path/to/crontab/logs/`date +\%Y-\%m-\%d`.log
Helper Functions
As live-demo take a look at demo application - ./demo/Commands/ExamplesHelpers.php.
Try to launch ./my-app examples:helpers
.
JBZoo/Cli uses Symfony Question Helper as base for aliases.
Regualar question
Ask any custom question and wait for a user's input. There is an option to set a default value.
$yourName = $this->ask("What's your name?", 'Default Noname'); $this->_("Your name is \"{$yourName}\"");
Ask user's password
Ask a question and hide the response. This is particularly convenient for passwords. There is an option to set a random value as default value.
$yourSecret = $this->askPassword("New password?", true); $this->_("Your secret is \"{$yourSecret}\"");
Ask user to select the option
If you have a predefined set of answers the user can choose from, you could use a method askOption
which makes sure
that the user can only enter a valid string from a predefined list.
There is an option to set a default option (index or string).
$selectedColor = $this->askOption("What's your favorite color?", ['Red', 'Blue', 'Yellow'], 'Blue'); $this->_("Selected color is {$selectedColor}");
Represent a yes/no question
Suppose you want to confirm an action before actually executing it. Add the following to your command.
$isConfirmed = $this->confirmation('Are you ready to execute the script?'); $this->_("Is confirmed: " . ($isConfirmed ? 'Yes' : 'No'));
Rendering key=>value list
If you need to show an aligned list, use the following code.
use JBZoo\Cli\CliRender; $this->_(CliRender::list([ "It's like a title", 'Option Name' => 'Option Value', 'Key' => 'Value', 'Another Key #2' => 'Qwerty', ], '*')); // It's bullet character
* It's like a title
* Option Name : Option Value
* Key : Value
* Another Key #2: Qwerty
Useful projects and links
- Symfony/Console Docs
- kevinlebrun/colors.php - New colors for the terminal
- php-school/cli-menu - Interactive menu with nested items
- nunomaduro/collision - Beautiful error reporting
- splitbrain/php-cli - Lightweight and no dependencies CLI framework
- thephpleague/climate - Allows you to easily output colored text, special formats
- Exit Codes With Special Meanings
License
MIT
See Also
- CI-Report-Converter - Converting different error reports for deep compatibility with popular CI systems.
- Composer-Diff - See what packages have changed after
composer update
. - Composer-Graph - Dependency graph visualization of composer.json based on mermaid-js.
- Mermaid-PHP - Generate diagrams and flowcharts with the help of the mermaid script language.
- Utils - Collection of useful PHP functions, mini-classes, and snippets for every day.
- Image - Package provides object-oriented way to manipulate with images as simple as possible.
- Data - Extended implementation of ArrayObject. Use files as config/array.
- Retry - Tiny PHP library providing retry/backoff functionality with multiple backoff strategies and jitter support.
- SimpleTypes - Converting any values and measures - money, weight, exchange rates, length, ...