Changes output to JSON serialization.
This commit is contained in:
parent
2a8d603f98
commit
e6f0059e5e
@ -20,12 +20,12 @@ public function __construct(RemoteProcessArgs $remoteProcessArgs)
|
||||
->withProperties($properties)
|
||||
->performedOn($remoteProcessArgs->model)
|
||||
->event($remoteProcessArgs->type)
|
||||
->log("");
|
||||
->log("[]");
|
||||
} else {
|
||||
$this->activity = activity()
|
||||
->withProperties($remoteProcessArgs->toArray())
|
||||
->event($remoteProcessArgs->type)
|
||||
->log("");
|
||||
->log("[]");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -27,11 +27,6 @@ class RunRemoteProcess
|
||||
|
||||
protected int $counter = 1;
|
||||
|
||||
public const MARK_START = "|--";
|
||||
public const MARK_END = "--|";
|
||||
public const SEPARATOR = '|';
|
||||
public const MARK_REGEX = "/(\|--\d+\|\d+\|(?:out|err)--\|)/";
|
||||
|
||||
/**
|
||||
* Create a new job instance.
|
||||
*/
|
||||
@ -93,7 +88,7 @@ protected function handleOutput(string $type, string $output)
|
||||
|
||||
$this->currentTime = $this->elapsedTime();
|
||||
|
||||
$this->activity->description .= $this->encodeOutput($type, $output);
|
||||
$this->activity->description = $this->encodeOutput($type, $output);
|
||||
|
||||
if ($this->isAfterLastThrottle()) {
|
||||
// Let's write to database.
|
||||
@ -106,12 +101,37 @@ protected function handleOutput(string $type, string $output)
|
||||
|
||||
public function encodeOutput($type, $output)
|
||||
{
|
||||
return
|
||||
static::MARK_START . $this->counter++ .
|
||||
static::SEPARATOR . $this->elapsedTime() .
|
||||
static::SEPARATOR . $type .
|
||||
static::MARK_END .
|
||||
$output;
|
||||
$outputStack = json_decode($this->activity->description, associative: true, flags: JSON_THROW_ON_ERROR);
|
||||
|
||||
$outputStack[] = [
|
||||
'type' => $type,
|
||||
'output' => $output,
|
||||
'elapsed_tim' => $this->elapsedTime(),
|
||||
'order' => $this->counter++,
|
||||
];
|
||||
|
||||
return json_encode($outputStack, flags: JSON_THROW_ON_ERROR);
|
||||
}
|
||||
|
||||
public static function decodeOutput(?Activity $activity = null): string
|
||||
{
|
||||
if(is_null($activity)) {
|
||||
return '';
|
||||
}
|
||||
|
||||
try {
|
||||
$decoded = json_decode(data_get($activity, 'description'),
|
||||
associative: true,
|
||||
flags: JSON_THROW_ON_ERROR
|
||||
);
|
||||
} catch (\JsonException $exception) {
|
||||
return '';
|
||||
}
|
||||
|
||||
return collect($decoded)
|
||||
->sortBy(fn($i) => $i['order'])
|
||||
->map(fn($i) => $i['output'])
|
||||
->implode("\n");
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1,90 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Actions\RemoteProcess;
|
||||
|
||||
use Illuminate\Support\Collection;
|
||||
use Spatie\Activitylog\Models\Activity;
|
||||
|
||||
class TidyOutput
|
||||
{
|
||||
protected $output;
|
||||
|
||||
public function __construct(
|
||||
protected Activity $activity
|
||||
)
|
||||
{
|
||||
}
|
||||
|
||||
public function __invoke()
|
||||
{
|
||||
$chunks = preg_split(
|
||||
RunRemoteProcess::MARK_REGEX,
|
||||
$this->activity->description,
|
||||
flags: PREG_SPLIT_DELIM_CAPTURE
|
||||
);
|
||||
|
||||
$tidyRows = $this
|
||||
->joinMarksWithFollowingItem($chunks)
|
||||
->reject(fn($i) => $i === '')
|
||||
->map(function ($i) {
|
||||
if (!preg_match('/\|--(\d+)\|(\d+)\|(out|err)--\|(.*)/', $i, $matches)) {
|
||||
return $i;
|
||||
}
|
||||
[$wholeLine, $sequence, $elapsedTime, $type, $output] = $matches;
|
||||
return [
|
||||
'sequence' => $sequence,
|
||||
'time' => $elapsedTime,
|
||||
'type' => $type,
|
||||
'output' => $output,
|
||||
];
|
||||
});
|
||||
|
||||
return $tidyRows
|
||||
->sortBy(fn($i) => $i['sequence'])
|
||||
->map(fn($i) => $i['output'])
|
||||
->implode("\n");
|
||||
}
|
||||
|
||||
/**
|
||||
* Function to join the defined mark, with the output
|
||||
* that is the following element in the array.
|
||||
*
|
||||
* Turns this:
|
||||
* [
|
||||
* "|--1|149|out--|",
|
||||
* "/root\n",
|
||||
* "|--2|251|out--|",
|
||||
* "Welcome 1 times 1\n",
|
||||
* "|--3|366|out--|",
|
||||
* "Welcome 2 times 2\n",
|
||||
* "|--4|466|out--|",
|
||||
* "Welcome 3 times 3\n",
|
||||
* ]
|
||||
*
|
||||
* into this:
|
||||
*
|
||||
* [
|
||||
* "|--1|149|out--|/root\n",
|
||||
* "|--2|251|out--|Welcome 1 times 1\n",
|
||||
* "|--3|366|out--|Welcome 2 times 2\n",
|
||||
* "|--4|466|out--|Welcome 3 times 3\n",
|
||||
* ]
|
||||
*/
|
||||
public function joinMarksWithFollowingItem($chunks): Collection
|
||||
{
|
||||
return collect($chunks)->reduce(function ($carry, $item) {
|
||||
$last = $carry->last();
|
||||
if (preg_match(RunRemoteProcess::MARK_REGEX, $last) && !preg_match(RunRemoteProcess::MARK_REGEX, $item)) {
|
||||
// If the last element is a delimiter and the current element is not,
|
||||
// join them together and replace the last element with the joined string
|
||||
$carry->pop();
|
||||
$joined = $last . $item;
|
||||
$carry->push($joined);
|
||||
} else {
|
||||
// Otherwise, just add the current element to the result array
|
||||
$carry->push($item);
|
||||
}
|
||||
return $carry;
|
||||
}, collect());
|
||||
}
|
||||
}
|
@ -2,21 +2,10 @@
|
||||
|
||||
namespace App\Http\Livewire;
|
||||
|
||||
use App\Jobs\ContainerStatusJob;
|
||||
use App\Jobs\DeployApplicationJob;
|
||||
use App\Models\Application;
|
||||
use App\Models\CoolifyInstanceSettings;
|
||||
use DateTimeImmutable;
|
||||
use Illuminate\Support\Facades\Http;
|
||||
use Illuminate\Support\Facades\Process;
|
||||
use Livewire\Component;
|
||||
use Symfony\Component\Yaml\Yaml;
|
||||
use Visus\Cuid2\Cuid2;
|
||||
use Lcobucci\JWT\Encoding\ChainedFormatter;
|
||||
use Lcobucci\JWT\Encoding\JoseEncoder;
|
||||
use Lcobucci\JWT\Signer\Key\InMemory;
|
||||
use Lcobucci\JWT\Signer\Rsa\Sha256;
|
||||
use Lcobucci\JWT\Token\Builder;
|
||||
|
||||
class DeployApplication extends Component
|
||||
{
|
||||
|
@ -24,6 +24,7 @@ public function polling()
|
||||
$this->isKeepAliveOn = false;
|
||||
}
|
||||
}
|
||||
|
||||
public function render()
|
||||
{
|
||||
return view('livewire.poll-activity');
|
||||
|
@ -64,7 +64,7 @@ public function __construct(
|
||||
->performedOn($this->application)
|
||||
->withProperties($remoteProcessArgs->toArray())
|
||||
->event(ActivityTypes::DEPLOYMENT->value)
|
||||
->log("");
|
||||
->log("[]");
|
||||
}
|
||||
|
||||
/**
|
||||
@ -139,7 +139,7 @@ public function handle(): void
|
||||
], setStatus: true);
|
||||
$this->executeNow([
|
||||
"docker stop -t 0 {$this->deployment_uuid} >/dev/null"
|
||||
]);
|
||||
], setStatus: true);
|
||||
}
|
||||
|
||||
private function execute_in_builder(string $command)
|
||||
|
@ -1,3 +1,5 @@
|
||||
<div>
|
||||
<pre style="width: 100%;overflow-y: scroll;" @if ($isKeepAliveOn) wire:poll.750ms="polling" @endif>{{ data_get($activity, 'description') }}</pre>
|
||||
<pre style="width: 100%;overflow-y: scroll;" @if ($isKeepAliveOn) wire:poll.3750ms="polling" @endif>
|
||||
{{ \App\Actions\RemoteProcess\RunRemoteProcess::decodeOutput($activity) }}
|
||||
</pre>
|
||||
</div>
|
||||
|
@ -15,5 +15,18 @@
|
||||
*/
|
||||
|
||||
Artisan::command('inspire', function () {
|
||||
$this->comment(Inspiring::quote());
|
||||
|
||||
$activity = Spatie\Activitylog\Models\Activity::latest()->first();
|
||||
|
||||
$this->info(
|
||||
collect(
|
||||
json_decode(data_get($activity, 'description'), associative: true, flags: JSON_THROW_ON_ERROR)
|
||||
)
|
||||
->sortBy('order')
|
||||
->map(fn($i) => $i['output'])
|
||||
->implode("\n")
|
||||
);
|
||||
|
||||
|
||||
|
||||
})->purpose('Display an inspiring quote');
|
||||
|
@ -1,5 +1,6 @@
|
||||
<?php
|
||||
|
||||
use App\Actions\RemoteProcess\RunRemoteProcess;
|
||||
use App\Actions\RemoteProcess\TidyOutput;
|
||||
use App\Models\User;
|
||||
use App\Models\Server;
|
||||
@ -38,7 +39,7 @@
|
||||
|
||||
// Assert there's no containers start with coolify_test_*
|
||||
$activity = remoteProcess([$areThereCoolifyTestContainers], $host);
|
||||
$tidyOutput = (new TidyOutput($activity))();
|
||||
$tidyOutput = RunRemoteProcess::decodeOutput($activity);
|
||||
$containers = formatDockerCmdOutputToJson($tidyOutput);
|
||||
expect($containers)->toBeEmpty();
|
||||
|
||||
@ -48,7 +49,7 @@
|
||||
|
||||
// docker ps name = $container
|
||||
$activity = remoteProcess([$areThereCoolifyTestContainers], $host);
|
||||
$tidyOutput = (new TidyOutput($activity))();
|
||||
$tidyOutput = RunRemoteProcess::decodeOutput($activity);
|
||||
$containers = formatDockerCmdOutputToJson($tidyOutput);
|
||||
expect($containers->where('Names', $containerName)->count())->toBe(1);
|
||||
|
||||
|
@ -1,7 +1,6 @@
|
||||
<?php
|
||||
|
||||
use App\Actions\RemoteProcess\RunRemoteProcess;
|
||||
use App\Actions\RemoteProcess\TidyOutput;
|
||||
use App\Models\Server;
|
||||
use Database\Seeders\DatabaseSeeder;
|
||||
use Illuminate\Foundation\Testing\DatabaseMigrations;
|
||||
@ -24,13 +23,10 @@
|
||||
], $host);
|
||||
|
||||
|
||||
preg_match(RunRemoteProcess::MARK_REGEX, $activity->description, $matchesInRawContent);
|
||||
$out = (new TidyOutput($activity))();
|
||||
preg_match(RunRemoteProcess::MARK_REGEX, $out, $matchesInTidyOutput);
|
||||
|
||||
expect($matchesInRawContent)
|
||||
->not()->toBeEmpty()
|
||||
->and($matchesInTidyOutput)
|
||||
->toBeEmpty();
|
||||
$tidyOutput = RunRemoteProcess::decodeOutput($activity);
|
||||
|
||||
expect($tidyOutput)
|
||||
->toContain('Welcome 1 times')
|
||||
->toContain('Welcome 3 times')
|
||||
->not()->toBeJson();
|
||||
});
|
||||
|
Loading…
Reference in New Issue
Block a user