<?php
namespace App\Commands;
use App\Commands\Concerns\InteractsWithPijul;
use LaravelZero\Framework\Commands\Command;
class PijulCreditWithMessagesCommand extends Command
{
use InteractsWithPijul;
/**
* @var string
*/
protected $signature = 'pijul:credit-with-messages
{file : The file to annotate}
{--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 = 'Show pijul credit output with change messages inline';
/**
* @var array<int, string>
*/
protected $aliases = ['pijul-credit-with-messages'];
/**
* @var array<string, string>
*/
private array $changeMessages = [];
public function handle(): int
{
$output = $this->runPijul($this->creditArguments())->output();
foreach (preg_split("/\r\n|\n|\r/", rtrim($output, "\r\n")) ?: [] as $line) {
$this->line($this->isHashLine($line) ? $this->formatHashLine($line) : $line);
}
if (str_ends_with($output, "\n\n")) {
$this->newLine();
}
return self::SUCCESS;
}
/**
* @return array<int, string>
*/
private function creditArguments(): array
{
$arguments = ['credit'];
if (($repository = $this->option('repository')) !== null) {
$arguments[] = '--repository';
$arguments[] = $repository;
}
if (($channel = $this->option('channel')) !== null) {
$arguments[] = '--channel';
$arguments[] = $channel;
}
if ($this->option('no-prompt')) {
$arguments[] = '--no-prompt';
}
$arguments[] = (string) $this->argument('file');
return $arguments;
}
private function isHashLine(string $line): bool
{
return preg_match('/^[A-Z0-9]+(?:\s*,\s*[A-Z0-9]+)*$/', $line) === 1;
}
private function formatHashLine(string $line): string
{
$hashes = preg_split('/\s*,\s*/', trim($line)) ?: [];
$formatted = [];
foreach ($hashes as $hash) {
$formatted[] = sprintf('%s (%s)', $hash, $this->resolveMessage($hash));
}
return implode(', ', $formatted);
}
private function resolveMessage(string $hash): string
{
if (array_key_exists($hash, $this->changeMessages)) {
return $this->changeMessages[$hash];
}
$changeArguments = ['change'];
if (($repository = $this->option('repository')) !== null) {
$changeArguments[] = '--repository';
$changeArguments[] = $repository;
}
if ($this->option('no-prompt')) {
$changeArguments[] = '--no-prompt';
}
$changeArguments[] = $hash;
$rawOutput = $this->runPijul($changeArguments)->output();
if (preg_match('/^message = "(.*)"$/m', $rawOutput, $matches) !== 1) {
return $this->changeMessages[$hash] = '<message unavailable>';
}
return $this->changeMessages[$hash] = str_replace('\"', '"', $matches[1]);
}
}