league/climate
League CLImate makes PHP CLI output nicer with easy colored text, formatting, and styled messages. Install via Composer and use simple methods like red() or blue() to print readable, attention-grabbing console output for scripts and command-line tools.
Installation:
composer require league/climate
Add to composer.json under require-dev if only for local scripts.
First Use:
use League\CLImate\CLImate;
$climate = new CLImate();
$climate->out('Hello, Laravel!')->bold()->green();
Run via CLI:
php script.php
Key Entry Points:
$climate->out(), $climate->error(), $climate->success()$climate->confirm(), $climate->input(), $climate->checkboxes()$climate->table(), $climate->progress(), $climate->columns()Replace a basic echo in a Laravel command:
// Before
echo "User created: " . $user->name;
// After
$this->climate->success("User created: {$user->name}")->bold();
$climate->out('Warning: ')->yellow()->bold()
->out('Disk space low!')->reset();
trait UsesCLImate {
protected function climate() {
return new CLImate();
}
}
$name = $climate->input('Enter your name', ['required' => true]);
$confirm = $climate->confirm('Proceed?', false);
readline() in custom commands with CLImate’s prompts.$progress = $climate->progress()->start('Processing...');
foreach ($items as $item) {
$progress->advance();
// Simulate work
usleep(100000);
}
$progress->finish();
Artisan::call() with progress bars for batch jobs.$climate->table([
'ID', 'Name', 'Status'
], [
[1, 'John', 'Active'],
[2, 'Jane', 'Inactive'],
]);
dd() or var_dump() in debug commands with formatted tables.if ($climate->supportsAnsi()) {
$climate->out('ANSI colors enabled!')->green();
}
Service Container Binding: Bind CLImate to Laravel’s container for dependency injection:
$app->singleton(CLImate::class, function () {
return new CLImate();
});
Inject into commands:
public function __construct(protected CLImate $climate) {}
Custom Extensions: Extend CLImate for domain-specific methods:
$climate->extend('userCreated', function ($user) {
return $this->success("User {$user->name} created!")->bold();
});
Use in commands:
$this->climate->userCreated($user);
Logging Integration: Use CLImate’s PSR-3 logger for structured CLI logs:
$logger = new League\CLImate\Logger\Logger($climate);
$logger->debug('Debug message');
Artisan Command Helpers: Create a base command class:
abstract class ClimateCommand extends Command {
protected function climate() {
return new CLImate();
}
}
ANSI Escape Sequences:
$climate->supportsAnsi() to check before applying styles:
if ($climate->supportsAnsi()) {
$climate->out('Colored text')->red();
} else {
$climate->out('Colored text (fallback)');
}
Terminal Width Detection:
$climate->setTerminalWidth(120);
Input Validation:
input().accept() with regex or callbacks:
$email = $climate->input('Email', [
'accept' => '/^[^\s@]+@[^\s@]+\.[^\s@]+$/'
]);
Progress Bar Redraws:
forceRedraw(false) to optimize:
$progress->forceRedraw(false);
Windows-Specific Quirks:
ext-mbstring is installed or use the seld/cli-prompt polyfill.Disable ANSI for Debugging: Force non-ANSI output to test rendering:
$climate->forceAnsiOff();
Log Raw Output:
Use buffer() to capture output for debugging:
$output = $climate->buffer(function () {
$climate->out('Debug me')->red();
});
$climate->out($output);
Check for Deprecations: Monitor the changelog for breaking changes (e.g., PHP 8.2+ type juggling fixes).
Custom Output Writers: Override default output behavior by setting a custom writer:
$climate->output = new CustomWriter();
Argument Parsing: Extend argument handling for custom CLI tools:
$climate->arguments->addOption('verbose', 'v', 'Enable verbose mode');
$verbose = $climate->arguments->has('verbose');
PSR-3 Logger Integration: Use CLImate’s logger with Monolog or other PSR-3 loggers:
$logger = new League\CLImate\Logger\Logger($climate);
$logger->addHandler(new StreamHandler('php://stderr', Logger::ERROR));
Custom Terminal Objects:
Create reusable components (e.g., GitStatus):
$climate->extend('gitStatus', function () {
return $this->out('Git: ')->yellow()->out(shell_exec('git status --porcelain'));
});
Artisan Command Styling:
Use CLImate in handle() for consistent output:
public function handle() {
$this->climate->info('Starting migration...');
// ...
$this->climate->success('Migration completed!');
}
Exception Handling:
Replace throw new \Exception() with styled errors:
$this->climate->error('Failed to connect to database!')->bold();
Testing CLI Output: Mock CLImate in tests:
$climate = Mockery::mock(CLImate::class);
$climate->shouldReceive('out')->with('Expected output');
$this->app->instance(CLImate::class, $climate);
Configuration:
Store CLImate settings in config/cli.php:
'ansi_enabled' => env('CLI_ANSI_ENABLED', true),
'default_width' => 120,
How can I help you explore Laravel packages today?