Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor facade generator, allow facades to implement given interfaces, related changes #365

Merged
merged 15 commits into from
Feb 21, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
68 changes: 36 additions & 32 deletions docs/Console.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
## Terminal output and logging

With a similar API to the `console` object provided by web browsers, the
[Console][Console] class[^1] provides:
[Console][] class[^1] provides:

- Familiar methods like `Console::log()` and `Console::error()`
- Variants like `Console::logOnce()` and `Console::errorOnce()` to output
Expand All @@ -13,16 +13,16 @@ With a similar API to the `console` object provided by web browsers, the

### Default targets

By default, [Console][Console] output is appended to a file in the default
temporary directory, created with mode `0600` if it doesn't already exist:
By default, [Console][] output is appended to a file in the default temporary
directory, created with mode `0600` if it doesn't already exist:

```php
<?php
sys_get_temp_dir() . '/<script_basename>-<realpath_hash>-<user_id>.log'
```

If the value of environment variable `console_target` is `stderr` or `stdout`,
[Console][Console] output is also written to `STDERR` or `STDOUT` respectively.
[Console][] output is also written to `STDERR` or `STDOUT` respectively.

If `console_target` is not set and the script is running on the command line:

Expand All @@ -34,38 +34,40 @@ If `console_target` is not set and the script is running on the command line:
Debug messages are written to the output log but are not written to `STDOUT` or
`STDERR` if environment variable `DEBUG` is empty or not set.

To override these defaults, register at least one [Console][Console] output
target, e.g. by calling [registerTarget()][registerTarget], before any other
`Console` methods are called, preferably while bootstrapping your application.
To override these defaults, register at least one [Console][] output target,
e.g. by calling [registerTarget()][], before any other `Console` methods are
called, preferably while bootstrapping your application.

> [Application][Application] and [CliApplication][CliApplication] always call
> [registerStdioTargets()][registerStdioTargets], which registers the default
> `STDOUT` and `STDERR` targets and prevents creation of the default output log.
> To create a log file that persists between reboots (in your project's
> `var/log` directory by default), call the app container's
> [logOutput()][logOutput] method.
> [Application][] and [CliApplication][] always call [registerStdioTargets()][],
> which registers the default `STDOUT` and `STDERR` targets and prevents
> creation of the default output log. To create a log file that persists between
> reboots (in your project's `var/log` directory by default), call the app
> container's [logOutput()][] method.

### Output methods

<!-- prettier-ignore -->
| `Console` method | `ConsoleLevel` | Message prefix | Default output target |
| ---------------- | --------------- | -------------- | ------------------------- |
| `error[Once]()` | `ERROR` = `3` | ` ! ` | `STDERR` |
| `warn[Once]()` | `WARNING` = `4` | ` ^ ` | `STDERR` |
| `info[Once]()` | `NOTICE` = `5` | ` ➤ ` | `STDOUT` |
| `log[Once]()` | `INFO` = `6` | ` - ` | `STDOUT` |
| `debug[Once]()` | `DEBUG` = `7` | ` : ` | `STDOUT` (if `DEBUG` set) |
| `group()`[^2] | `NOTICE` = `5` | ` » ` | `STDOUT` |
| `logProgress()` | `INFO` = `6` | ` ⠿ ` | `STDOUT` |

[^1]: Actually a facade for [ConsoleWriter][ConsoleWriter].
| Method | Message level | Default prefix | Default output target |
| --------------- | --------------------- | -------------- | ------------------------- |
| `error[Once]()` | `LEVEL_ERROR` = `3` | ` ! ` | `STDERR` |
| `warn[Once]()` | `LEVEL_WARNING` = `4` | ` ^ ` | `STDERR` |
| `info[Once]()` | `LEVEL_NOTICE` = `5` | ` ➤ ` | `STDOUT` |
| `log[Once]()` | `LEVEL_INFO` = `6` | ` - ` | `STDOUT` |
| `debug[Once]()` | `LEVEL_DEBUG` = `7` | ` : ` | `STDOUT` (if `DEBUG` set) |
| `group()`[^2] | `LEVEL_NOTICE` = `5` | ` » ` | `STDOUT` |
| `logProgress()` | `LEVEL_INFO` = `6` | ` ⠿ ` | `STDOUT` |

[^1]:
Actually a facade for [ConsoleInterface][], which is backed by a shared
instance of [Console][ConsoleService] by default.

[^2]:
`Console::group()` adds a level of indentation to all `Console` output until
`Console::groupEnd()` is called.

### Formatting

The following Markdown-like syntax is supported in [Console][Console] messages:
The following Markdown-like syntax is supported in [Console][] messages:

| Style | Tag | Typical appearance | Example |
| ------------ | ------------------------------------------------------ | ------------------------------------- | ------------------------------------------------------------------------- |
Expand All @@ -83,11 +85,13 @@ The following Markdown-like syntax is supported in [Console][Console] messages:
https://salient-labs.github.io/toolkit/Salient.Cli.CliApplication.html
[Console]:
https://salient-labs.github.io/toolkit/Salient.Core.Facade.Console.html
[ConsoleWriter]:
https://salient-labs.github.io/toolkit/Salient.Console.ConsoleWriter.html
[logOutput]:
[ConsoleInterface]:
https://salient-labs.github.io/toolkit/Salient.Contract.Console.ConsoleInterface.html
[ConsoleService]:
https://salient-labs.github.io/toolkit/Salient.Console.Console.html
[logOutput()]:
https://salient-labs.github.io/toolkit/Salient.Container.Application.html#_logOutput
[registerStdioTargets]:
https://salient-labs.github.io/toolkit/Salient.Console.ConsoleWriter.html#_registerStdioTargets
[registerTarget]:
https://salient-labs.github.io/toolkit/Salient.Console.ConsoleWriter.html#_registerTarget
[registerStdioTargets()]:
https://salient-labs.github.io/toolkit/Salient.Console.Console.html#_registerStdioTargets
[registerTarget()]:
https://salient-labs.github.io/toolkit/Salient.Console.Console.html#_registerTarget
6 changes: 0 additions & 6 deletions phpstan-baseline-7.4.neon

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 0 additions & 6 deletions phpstan-baseline-8.3.neon

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 2 additions & 3 deletions scripts/delete-covers.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
<?php declare(strict_types=1);

use Salient\Cli\CliApplication;
use Salient\Contract\Catalog\MessageLevel as Level;
use Salient\Core\Facade\Console;
use Salient\Utility\Exception\FilesystemErrorException;
use Salient\Utility\File;
Expand Down Expand Up @@ -54,7 +53,7 @@
$replaced++;

if ($check) {
Console::count(Level::ERROR);
Console::count(Console::LEVEL_ERROR);
$status |= 1;
if (!class_exists(Differ::class)) {
Console::log('Install sebastian/diff to show changes');
Expand All @@ -76,7 +75,7 @@
}

if ($replaced) {
Console::printOut('', Level::INFO);
Console::printOut('', Console::LEVEL_INFO);
}

Console::summary(Inflect::format(
Expand Down
13 changes: 7 additions & 6 deletions scripts/generate.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,15 @@
use Salient\Cli\CliApplication;
use Salient\Cli\CliOption;
use Salient\Cli\CliOptionBuilder;
use Salient\Console\ConsoleWriter;
use Salient\Console\Console as ConsoleService;
use Salient\Container\Container;
use Salient\Contract\Cache\CacheInterface;
use Salient\Contract\Catalog\MessageLevel as Level;
use Salient\Contract\Console\ConsoleWriterInterface;
use Salient\Contract\Console\ConsoleInterface;
use Salient\Contract\Container\ContainerInterface;
use Salient\Contract\Core\Event\EventDispatcherInterface;
use Salient\Contract\Sync\SyncStoreInterface;
use Salient\Contract\HasMessageLevel;
use Salient\Contract\HasMessageLevels;
use Salient\Core\Event\EventDispatcher;
use Salient\Core\Facade\App;
use Salient\Core\Facade\Cache;
Expand Down Expand Up @@ -78,7 +79,7 @@
App::class => [ContainerInterface::class, [Container::class], '--desc', 'A facade for the global service container', '--api'],
Cache::class => [CacheInterface::class, [CacheStore::class], '--desc', 'A facade for the global cache', '--api'],
Config::class => [ConfigurationManager::class, '--api'],
Console::class => [ConsoleWriterInterface::class, [ConsoleWriter::class], '--desc', 'A facade for the global console writer', '--api'],
Console::class => [ConsoleInterface::class, [ConsoleService::class], '--implement', HasMessageLevel::class . ',' . HasMessageLevels::class, '--desc', 'A facade for the global console service', '--api'],
Err::class => [ErrorHandler::class, '--skip', 'handleShutdown,handleError,handleException', '--api'],
Event::class => [EventDispatcherInterface::class, [EventDispatcher::class], '--desc', 'A facade for the global event dispatcher', '--api'],
Sync::class => [SyncStoreInterface::class, [SyncStore::class], '--desc', 'A facade for the global sync entity store'],
Expand Down Expand Up @@ -234,7 +235,7 @@ function generated($commandOrFile): void
Console::log('Skipping', $file);
} elseif (!$exists && in_array('--check', $args)) {
Console::info('Would create', $file);
Console::count(Level::ERROR);
Console::count(Console::LEVEL_ERROR);
$status |= 1;
continue;
} elseif (!in_array('--check', $args)) {
Expand Down Expand Up @@ -327,7 +328,7 @@ function generated($commandOrFile): void
if (File::getContents($file) !== $attributes) {
if (in_array('--check', $args)) {
Console::info('Would replace', $file);
Console::count(Level::ERROR);
Console::count(Console::LEVEL_ERROR);
$status |= 1;
} else {
Console::info('Replacing', $file);
Expand Down
5 changes: 2 additions & 3 deletions src/Toolkit/Cli/CliApplication.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
use Salient\Console\Support\ConsoleMarkdownFormat;
use Salient\Console\ConsoleFormatter as Formatter;
use Salient\Container\Application;
use Salient\Contract\Catalog\MessageLevel as Level;
use Salient\Contract\Cli\CliApplicationInterface;
use Salient\Contract\Cli\CliCommandInterface;
use Salient\Contract\Cli\CliHelpSectionName;
Expand Down Expand Up @@ -324,7 +323,7 @@

// or version info if it's "--version"
if ($arg === '--version' && !$args) {
return $this->reportVersion(Level::INFO, true);
return $this->reportVersion(Console::LEVEL_INFO, true);

Check warning on line 326 in src/Toolkit/Cli/CliApplication.php

View check run for this annotation

Codecov / codecov/patch

src/Toolkit/Cli/CliApplication.php#L326

Added line #L326 was not covered by tests
}

// - If $args was empty before this iteration, print terse usage
Expand Down Expand Up @@ -455,7 +454,7 @@
/**
* @inheritDoc
*/
public function reportVersion(int $level = Level::INFO, bool $stdout = false)
public function reportVersion(int $level = Console::LEVEL_INFO, bool $stdout = false)
{
$version = $this->getVersionString();

Expand Down
3 changes: 1 addition & 2 deletions src/Toolkit/Cli/CliCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
use Salient\Cli\Exception\CliInvalidArgumentsException;
use Salient\Cli\Exception\CliUnknownValueException;
use Salient\Console\ConsoleFormatter as Formatter;
use Salient\Contract\Catalog\MessageLevel as Level;
use Salient\Contract\Cli\CliApplicationInterface;
use Salient\Contract\Cli\CliCommandInterface;
use Salient\Contract\Cli\CliHelpSectionName;
Expand Down Expand Up @@ -190,7 +189,7 @@ final public function __invoke(string ...$args): int
}

if ($this->HasVersionArgument) {
$this->App->reportVersion(Level::INFO, true);
$this->App->reportVersion(Console::LEVEL_INFO, true);
return 0;
}

Expand Down
3 changes: 1 addition & 2 deletions src/Toolkit/Cli/CliOption.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@

use Salient\Cli\Exception\CliInvalidArgumentsException;
use Salient\Cli\Exception\CliUnknownValueException;
use Salient\Contract\Catalog\MessageLevel as Level;
use Salient\Contract\Cli\CliOptionType;
use Salient\Contract\Cli\CliOptionValueType;
use Salient\Contract\Cli\CliOptionValueUnknownPolicy;
Expand Down Expand Up @@ -981,7 +980,7 @@
throw new CliUnknownValueException($message);
}

Console::message('__Warning:__', $message, Level::WARNING, MessageType::UNFORMATTED);
Console::message('__Warning:__', $message, Console::LEVEL_WARNING, MessageType::UNFORMATTED);

Check warning on line 983 in src/Toolkit/Cli/CliOption.php

View check run for this annotation

Codecov / codecov/patch

src/Toolkit/Cli/CliOption.php#L983

Added line #L983 was not covered by tests
$value = array_intersect($value, $this->AllowedValues);
}
}
Expand Down
8 changes: 4 additions & 4 deletions src/Toolkit/Console/Concept/ConsolePrefixTarget.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

namespace Salient\Console\Concept;

use Salient\Contract\Catalog\MessageLevel as Level;
use Salient\Contract\Console\ConsoleInterface as Console;
use Salient\Contract\Console\ConsoleTag as Tag;
use Salient\Contract\Console\ConsoleTargetPrefixInterface;

Expand All @@ -16,15 +16,15 @@ abstract class ConsolePrefixTarget extends ConsoleTarget implements ConsoleTarge
private int $PrefixLength = 0;

/**
* @param Level::* $level
* @param Console::LEVEL_* $level
* @param array<string,mixed> $context
*/
abstract protected function writeToTarget($level, string $message, array $context): void;
abstract protected function writeToTarget(int $level, string $message, array $context): void;

/**
* @inheritDoc
*/
final public function write($level, string $message, array $context = []): void
final public function write(int $level, string $message, array $context = []): void
{
$this->assertIsValid();

Expand Down
55 changes: 27 additions & 28 deletions src/Toolkit/Console/Concept/ConsoleStreamTarget.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,19 @@
use Salient\Console\Support\ConsoleMessageFormat as MessageFormat;
use Salient\Console\Support\ConsoleMessageFormats as MessageFormats;
use Salient\Console\Support\ConsoleTagFormats as TagFormats;
use Salient\Contract\Catalog\HasAnsiEscapeSequence;
use Salient\Contract\Catalog\MessageLevel as Level;
use Salient\Contract\Catalog\MessageLevelGroup as LevelGroup;
use Salient\Contract\Console\ConsoleInterface as Console;
use Salient\Contract\Console\ConsoleMessageType as MessageType;
use Salient\Contract\Console\ConsoleMessageTypeGroup as MessageTypeGroup;
use Salient\Contract\Console\ConsoleTag as Tag;
use Salient\Contract\Console\ConsoleTargetStreamInterface;
use Salient\Contract\HasEscapeSequence;

/**
* Base class for console output targets with an underlying PHP stream
*/
abstract class ConsoleStreamTarget extends ConsolePrefixTarget implements
ConsoleTargetStreamInterface,
HasAnsiEscapeSequence
HasEscapeSequence
{
/**
* @inheritDoc
Expand Down Expand Up @@ -61,12 +60,12 @@

$bold = Format::ttyBold();
$dim = Format::ttyDim();
$boldCyan = Format::ttyBold(self::CYAN);
$red = Format::ttyColour(self::RED);
$green = Format::ttyColour(self::GREEN);
$yellow = Format::ttyColour(self::YELLOW);
$cyan = Format::ttyColour(self::CYAN);
$yellowUnderline = Format::ttyUnderline(self::YELLOW);
$boldCyan = Format::ttyBold(self::CYAN_FG);
$red = Format::ttyColour(self::RED_FG);
$green = Format::ttyColour(self::GREEN_FG);
$yellow = Format::ttyColour(self::YELLOW_FG);
$cyan = Format::ttyColour(self::CYAN_FG);
$yellowUnderline = Format::ttyUnderline(self::YELLOW_FG);

Check warning on line 68 in src/Toolkit/Console/Concept/ConsoleStreamTarget.php

View check run for this annotation

Codecov / codecov/patch

src/Toolkit/Console/Concept/ConsoleStreamTarget.php#L63-L68

Added lines #L63 - L68 were not covered by tests

return (new TagFormats())
->withFormat(Tag::HEADING, $boldCyan)
Expand All @@ -90,25 +89,25 @@
$default = Format::getDefaultFormat();
$bold = Format::ttyBold();
$dim = Format::ttyDim();
$boldRed = Format::ttyBold(self::RED);
$boldGreen = Format::ttyBold(self::GREEN);
$boldYellow = Format::ttyBold(self::YELLOW);
$boldMagenta = Format::ttyBold(self::MAGENTA);
$boldCyan = Format::ttyBold(self::CYAN);
$green = Format::ttyColour(self::GREEN);
$yellow = Format::ttyColour(self::YELLOW);
$cyan = Format::ttyColour(self::CYAN);
$boldRed = Format::ttyBold(self::RED_FG);
$boldGreen = Format::ttyBold(self::GREEN_FG);
$boldYellow = Format::ttyBold(self::YELLOW_FG);
$boldMagenta = Format::ttyBold(self::MAGENTA_FG);
$boldCyan = Format::ttyBold(self::CYAN_FG);
$green = Format::ttyColour(self::GREEN_FG);
$yellow = Format::ttyColour(self::YELLOW_FG);
$cyan = Format::ttyColour(self::CYAN_FG);

Check warning on line 99 in src/Toolkit/Console/Concept/ConsoleStreamTarget.php

View check run for this annotation

Codecov / codecov/patch

src/Toolkit/Console/Concept/ConsoleStreamTarget.php#L92-L99

Added lines #L92 - L99 were not covered by tests

return (new MessageFormats())
->set(LevelGroup::ERRORS, MessageTypeGroup::ALL, new MessageFormat($boldRed, $default, $boldRed))
->set(Level::WARNING, MessageTypeGroup::ALL, new MessageFormat($yellow, $default, $boldYellow))
->set(Level::NOTICE, MessageTypeGroup::ALL, new MessageFormat($bold, $cyan, $boldCyan))
->set(Level::INFO, MessageTypeGroup::ALL, new MessageFormat($default, $yellow, $yellow))
->set(Level::DEBUG, MessageTypeGroup::ALL, new MessageFormat($dim, $dim, $dim))
->set(LevelGroup::INFO, MessageType::PROGRESS, new MessageFormat($default, $yellow, $yellow))
->set(LevelGroup::INFO, MessageTypeGroup::GROUP, new MessageFormat($boldMagenta, $default, $boldMagenta))
->set(LevelGroup::INFO, MessageType::SUMMARY, new MessageFormat($default, $default, $bold))
->set(LevelGroup::INFO, MessageType::SUCCESS, new MessageFormat($green, $default, $boldGreen))
->set(LevelGroup::ERRORS_AND_WARNINGS, MessageType::FAILURE, new MessageFormat($yellow, $default, $boldYellow));
->set(Console::LEVELS_ERRORS, MessageTypeGroup::ALL, new MessageFormat($boldRed, $default, $boldRed))
->set(Console::LEVEL_WARNING, MessageTypeGroup::ALL, new MessageFormat($yellow, $default, $boldYellow))
->set(Console::LEVEL_NOTICE, MessageTypeGroup::ALL, new MessageFormat($bold, $cyan, $boldCyan))
->set(Console::LEVEL_INFO, MessageTypeGroup::ALL, new MessageFormat($default, $yellow, $yellow))
->set(Console::LEVEL_DEBUG, MessageTypeGroup::ALL, new MessageFormat($dim, $dim, $dim))
->set(Console::LEVELS_INFO, MessageType::PROGRESS, new MessageFormat($default, $yellow, $yellow))
->set(Console::LEVELS_INFO, MessageTypeGroup::GROUP, new MessageFormat($boldMagenta, $default, $boldMagenta))
->set(Console::LEVELS_INFO, MessageType::SUMMARY, new MessageFormat($default, $default, $bold))
->set(Console::LEVELS_INFO, MessageType::SUCCESS, new MessageFormat($green, $default, $boldGreen))
->set(Console::LEVELS_ERRORS_AND_WARNINGS, MessageType::FAILURE, new MessageFormat($yellow, $default, $boldYellow));
}

Check warning on line 112 in src/Toolkit/Console/Concept/ConsoleStreamTarget.php

View check run for this annotation

Codecov / codecov/patch

src/Toolkit/Console/Concept/ConsoleStreamTarget.php#L102-L112

Added lines #L102 - L112 were not covered by tests
}
Loading