diff --git a/app/Actions/RemoteProcess/DispatchRemoteProcess.php b/app/Actions/RemoteProcess/DispatchRemoteProcess.php index c1f0e8036..2d23513ea 100644 --- a/app/Actions/RemoteProcess/DispatchRemoteProcess.php +++ b/app/Actions/RemoteProcess/DispatchRemoteProcess.php @@ -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("[]"); } } diff --git a/app/Actions/RemoteProcess/RunRemoteProcess.php b/app/Actions/RemoteProcess/RunRemoteProcess.php index 53e0beb10..322fa5bed 100644 --- a/app/Actions/RemoteProcess/RunRemoteProcess.php +++ b/app/Actions/RemoteProcess/RunRemoteProcess.php @@ -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"); } /** diff --git a/app/Actions/RemoteProcess/TidyOutput.php b/app/Actions/RemoteProcess/TidyOutput.php deleted file mode 100644 index e2bd02f69..000000000 --- a/app/Actions/RemoteProcess/TidyOutput.php +++ /dev/null @@ -1,90 +0,0 @@ -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()); - } -} diff --git a/app/Http/Livewire/DeployApplication.php b/app/Http/Livewire/DeployApplication.php index 5ad4e7f00..dfaa9a725 100644 --- a/app/Http/Livewire/DeployApplication.php +++ b/app/Http/Livewire/DeployApplication.php @@ -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 { diff --git a/app/Http/Livewire/PollActivity.php b/app/Http/Livewire/PollActivity.php index ae3be1324..da8ed5252 100644 --- a/app/Http/Livewire/PollActivity.php +++ b/app/Http/Livewire/PollActivity.php @@ -24,6 +24,7 @@ public function polling() $this->isKeepAliveOn = false; } } + public function render() { return view('livewire.poll-activity'); diff --git a/app/Jobs/DeployApplicationJob.php b/app/Jobs/DeployApplicationJob.php index 2e1ee1aac..b77c5aeed 100644 --- a/app/Jobs/DeployApplicationJob.php +++ b/app/Jobs/DeployApplicationJob.php @@ -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) diff --git a/resources/views/livewire/poll-activity.blade.php b/resources/views/livewire/poll-activity.blade.php index 4a91ba622..46a7f9371 100644 --- a/resources/views/livewire/poll-activity.blade.php +++ b/resources/views/livewire/poll-activity.blade.php @@ -1,3 +1,5 @@
-
{{ data_get($activity, 'description') }}
+
+        {{ \App\Actions\RemoteProcess\RunRemoteProcess::decodeOutput($activity) }}
+    
diff --git a/routes/console.php b/routes/console.php index e05f4c9a1..0f43c3b31 100644 --- a/routes/console.php +++ b/routes/console.php @@ -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'); diff --git a/tests/Feature/DockerCommandsTest.php b/tests/Feature/DockerCommandsTest.php index 5e40fe85d..cc6f76444 100644 --- a/tests/Feature/DockerCommandsTest.php +++ b/tests/Feature/DockerCommandsTest.php @@ -1,5 +1,6 @@ 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); diff --git a/tests/Feature/RemoteProcessTest.php b/tests/Feature/RemoteProcessTest.php index aeca27edc..1db036ebf 100644 --- a/tests/Feature/RemoteProcessTest.php +++ b/tests/Feature/RemoteProcessTest.php @@ -1,7 +1,6 @@ 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(); });