<?php
namespace App\Commands;
use App\Commands\Concerns\InteractsWithPijul;
use JsonException;
use LaravelZero\Framework\Commands\Command;
class PijulListIntentTagsCommand extends Command
{
use InteractsWithPijul;
/**
* @var string
*/
protected $signature = 'pijul:list-intent-tags
{--limit= : Number of recent log entries to scan}
{--repository= : Work with the repository at PATH}
{--channel= : Work with CHANNEL instead of the current channel}
{--no-prompt : Abort rather than prompt for input}';
/**
* @var string
*/
protected $description = 'List unique intent tags from pijul log messages';
/**
* @var array<int, string>
*/
protected $aliases = ['pijul-list-intent-tags'];
/**
* @throws JsonException
*/
public function handle(): int
{
foreach ($this->resolveTags(
limit: $this->option('limit'),
repository: $this->option('repository'),
channel: $this->option('channel'),
noPrompt: (bool) $this->option('no-prompt'),
) as $tag) {
$this->line($tag);
}
return self::SUCCESS;
}
/**
* @return list<string>
*
* @throws JsonException
*/
public function resolveTags(
?string $limit = null,
?string $repository = null,
?string $channel = null,
bool $noPrompt = false,
): array {
$arguments = ['log', '--output-format', 'json'];
if ($limit !== null && $limit !== '') {
$arguments[] = '--limit';
$arguments[] = $limit;
}
if ($repository !== null && $repository !== '') {
$arguments[] = '--repository';
$arguments[] = $repository;
}
if ($channel !== null && $channel !== '') {
$arguments[] = '--channel';
$arguments[] = $channel;
}
if ($noPrompt) {
$arguments[] = '--no-prompt';
}
$changes = json_decode(
$this->runPijul($arguments)->output(),
true,
512,
JSON_THROW_ON_ERROR,
);
$tags = [];
foreach ($changes as $change) {
$message = $change['message'] ?? null;
if (! is_string($message) || preg_match('/^([A-Za-z0-9_-]+\([^)]*\))/', $message, $matches) !== 1) {
continue;
}
$tags[$matches[1]] = true;
}
return array_keys($tags);
}
}