mirror of
https://github.com/crazywhalecc/static-php-cli.git
synced 2026-07-07 08:45:40 +08:00
feat: add --installed flag to check-update, improve CLI and InteractiveTerm
- Add --installed option to check-update command to compare against on-disk version (tool packages) - Support use_installed parameter in ArtifactDownloader::checkUpdate/checkUpdates - Add -y shorthand for --auto-fix in doctor command - Hook InteractiveTerm::init() in ConsoleApplication::doRun() to properly inject Symfony input/output
This commit is contained in:
@@ -4,7 +4,6 @@ declare(strict_types=1);
|
||||
|
||||
namespace StaticPHP\Util;
|
||||
|
||||
use StaticPHP\DI\ApplicationContext;
|
||||
use Symfony\Component\Console\Helper\ProgressIndicator;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Output\ConsoleOutput;
|
||||
@@ -15,10 +14,31 @@ class InteractiveTerm
|
||||
{
|
||||
private static ?ProgressIndicator $indicator = null;
|
||||
|
||||
private static ?OutputInterface $output = null;
|
||||
|
||||
private static ?bool $noAnsi = null;
|
||||
|
||||
/**
|
||||
* Initialize with a real Symfony Console input/output (called from ConsoleApplication::doRun()).
|
||||
* After this call, all output goes through the configured Console, and noAnsi reflects
|
||||
* the user's --no-ansi flag.
|
||||
*/
|
||||
public static function init(InputInterface $input, OutputInterface $output): void
|
||||
{
|
||||
self::$output = $output;
|
||||
try {
|
||||
self::$noAnsi = (bool) $input->getOption('no-ansi');
|
||||
} catch (\InvalidArgumentException) {
|
||||
// Symfony hasn't bound the application-level input definition yet
|
||||
// (e.g. ArgvInput passed directly to doRun() on some versions).
|
||||
self::$noAnsi = false;
|
||||
}
|
||||
}
|
||||
|
||||
public static function notice(string $message, bool $indent = false): void
|
||||
{
|
||||
$no_ansi = (bool) ApplicationContext::get(InputInterface::class)->getOption('no-ansi');
|
||||
$output = ApplicationContext::get(OutputInterface::class);
|
||||
$no_ansi = self::noAnsi();
|
||||
$output = self::output();
|
||||
if ($output->isVerbose()) {
|
||||
logger()->notice(strip_ansi_colors($message));
|
||||
} else {
|
||||
@@ -29,8 +49,8 @@ class InteractiveTerm
|
||||
|
||||
public static function success(string $message, bool $indent = false): void
|
||||
{
|
||||
$no_ansi = (bool) ApplicationContext::get(InputInterface::class)->getOption('no-ansi');
|
||||
$output = ApplicationContext::get(OutputInterface::class);
|
||||
$no_ansi = self::noAnsi();
|
||||
$output = self::output();
|
||||
if ($output->isVerbose()) {
|
||||
logger()->info(strip_ansi_colors($message));
|
||||
} else {
|
||||
@@ -41,8 +61,8 @@ class InteractiveTerm
|
||||
|
||||
public static function plain(string $message, string $level = 'info'): void
|
||||
{
|
||||
$no_ansi = (bool) ApplicationContext::get(InputInterface::class)->getOption('no-ansi');
|
||||
$output = ApplicationContext::get(OutputInterface::class);
|
||||
$no_ansi = self::noAnsi();
|
||||
$output = self::output();
|
||||
if ($output->isVerbose()) {
|
||||
match ($level) {
|
||||
'debug' => logger()->debug(strip_ansi_colors($message)),
|
||||
@@ -59,8 +79,8 @@ class InteractiveTerm
|
||||
|
||||
public static function info(string $message): void
|
||||
{
|
||||
$no_ansi = (bool) ApplicationContext::get(InputInterface::class)->getOption('no-ansi');
|
||||
$output = ApplicationContext::get(OutputInterface::class);
|
||||
$no_ansi = self::noAnsi();
|
||||
$output = self::output();
|
||||
if (!$output->isVerbose()) {
|
||||
$output->writeln(($no_ansi ? 'strip_ansi_colors' : 'strval')(ConsoleColor::green('▶ ') . $message));
|
||||
}
|
||||
@@ -69,8 +89,8 @@ class InteractiveTerm
|
||||
|
||||
public static function error(string $message, bool $indent = true): void
|
||||
{
|
||||
$no_ansi = (bool) ApplicationContext::get(InputInterface::class)->getOption('no-ansi');
|
||||
$output = ApplicationContext::get(OutputInterface::class);
|
||||
$no_ansi = self::noAnsi();
|
||||
$output = self::output();
|
||||
if ($output->isVerbose()) {
|
||||
logger()->error(strip_ansi_colors($message));
|
||||
} else {
|
||||
@@ -86,16 +106,16 @@ class InteractiveTerm
|
||||
|
||||
public static function setMessage(string $message): void
|
||||
{
|
||||
$no_ansi = (bool) ApplicationContext::get(InputInterface::class)->getOption('no-ansi');
|
||||
$no_ansi = self::noAnsi();
|
||||
self::$indicator?->setMessage(($no_ansi ? 'strip_ansi_colors' : 'strval')($message));
|
||||
logger()->debug(strip_ansi_colors($message));
|
||||
}
|
||||
|
||||
public static function finish(string $message, bool $status = true): void
|
||||
{
|
||||
$no_ansi = (bool) ApplicationContext::get(InputInterface::class)->getOption('no-ansi');
|
||||
$no_ansi = self::noAnsi();
|
||||
$message = $no_ansi ? strip_ansi_colors($message) : $message;
|
||||
$output = ApplicationContext::get(OutputInterface::class);
|
||||
$output = self::output();
|
||||
if ($output->isVerbose()) {
|
||||
if ($status) {
|
||||
logger()->info($message);
|
||||
@@ -116,8 +136,8 @@ class InteractiveTerm
|
||||
|
||||
public static function indicateProgress(string $message): void
|
||||
{
|
||||
$no_ansi = (bool) ApplicationContext::get(InputInterface::class)->getOption('no-ansi');
|
||||
$output = ApplicationContext::get(OutputInterface::class);
|
||||
$no_ansi = self::noAnsi();
|
||||
$output = self::output();
|
||||
if ($output->isVerbose()) {
|
||||
logger()->info(strip_ansi_colors($message));
|
||||
return;
|
||||
@@ -131,11 +151,41 @@ class InteractiveTerm
|
||||
logger()->debug(strip_ansi_colors($message));
|
||||
// if no ansi, use a dot instead of spinner
|
||||
if ($no_ansi) {
|
||||
self::$indicator = new ProgressIndicator(ApplicationContext::get(OutputInterface::class), 'verbose', 100, [' •', ' •']);
|
||||
self::$indicator = new ProgressIndicator(self::output(), 'verbose', 100, [' •', ' •']);
|
||||
self::$indicator->start(strip_ansi_colors($message));
|
||||
return;
|
||||
}
|
||||
self::$indicator = new ProgressIndicator(ApplicationContext::get(OutputInterface::class), 'verbose', 100, [' ⠏', ' ⠛', ' ⠹', ' ⢸', ' ⣰', ' ⣤', ' ⣆', ' ⡇']);
|
||||
self::$indicator = new ProgressIndicator(self::output(), 'verbose', 100, [' ⠏', ' ⠛', ' ⠹', ' ⢸', ' ⣰', ' ⣤', ' ⣆', ' ⡇']);
|
||||
self::$indicator->start($message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Lazy default initialization used when init() was never called (early-boot errors,
|
||||
* tests, programmatic usage). Creates a plain STDERR output so error messages are
|
||||
* visible without depending on the Symfony Console lifecycle.
|
||||
*/
|
||||
private static function initDefault(): void
|
||||
{
|
||||
if (self::$output !== null) {
|
||||
return;
|
||||
}
|
||||
self::$output = new ConsoleOutput(ConsoleOutput::VERBOSITY_NORMAL, false);
|
||||
self::$noAnsi = false;
|
||||
}
|
||||
|
||||
private static function noAnsi(): bool
|
||||
{
|
||||
if (self::$output === null) {
|
||||
self::initDefault();
|
||||
}
|
||||
return self::$noAnsi ?? false;
|
||||
}
|
||||
|
||||
private static function output(): OutputInterface
|
||||
{
|
||||
if (self::$output === null) {
|
||||
self::initDefault();
|
||||
}
|
||||
return self::$output;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user