diff --git a/front/js/svelte/build/Report.svelte b/front/js/svelte/build/Report.svelte index 32d8c44..e1de88b 100644 --- a/front/js/svelte/build/Report.svelte +++ b/front/js/svelte/build/Report.svelte @@ -1,22 +1,23 @@
Members - {#if channel.generateCommand} - Build website + {#if channel.commands} + +
Actions
+ {#each channel.commands as command} + {command.name} + {/each} +
+ {/if} @@ -19,8 +27,8 @@ - - - + + +
diff --git a/src/Channel/Channel.php b/src/Channel/Channel.php index 05da1af..b269be0 100644 --- a/src/Channel/Channel.php +++ b/src/Channel/Channel.php @@ -2,6 +2,7 @@ namespace Lucent\Channel; +use Lucent\Channel\Data\UserCommand; use Lucent\Primitive\Collection; use Lucent\Schema\Schema; @@ -13,12 +14,13 @@ final class Channel /** * @param Collection $schemas + * @param Collection $commands */ function __construct( public string $name, public string $url, public string $previewTarget, - public string $generateCommand, + public Collection $commands, public Collection $schemas, public array $imageFilters, public array $roles, diff --git a/src/Channel/ChannelService.php b/src/Channel/ChannelService.php index 1460195..e514be7 100644 --- a/src/Channel/ChannelService.php +++ b/src/Channel/ChannelService.php @@ -3,7 +3,7 @@ namespace Lucent\Channel; -use Lucent\File\FileService; +use Lucent\Channel\Data\UserCommand; use Lucent\Primitive\Collection; use Lucent\Schema\Schema; use Lucent\Schema\SchemaService; @@ -30,11 +30,16 @@ final class ChannelService $schemaService = new SchemaService(); $schemasCollection = (new Collection($schemasArray["schemas"] ?? []))->map([$schemaService, 'fromArray']); + $userCommands = []; + foreach (config("lucent.commands") as $signature => $desc) { + $userCommands[] = new UserCommand($desc, $signature); + } + $channel = new Channel( name: config("lucent.name") ?? "", url: rtrim(config("lucent.url") ?? "", "/"), previewTarget: rtrim(config("lucent.previewTarget") ?? "", "/"), - generateCommand: config("lucent.generateCommand") ?? "", + commands: Collection::make($userCommands), schemas: $schemasCollection, imageFilters: config("lucent.imageFilters") ?? [], roles: $schemasArray["roles"] ?? [] @@ -64,7 +69,7 @@ final class ChannelService */ public function schemasReadableByRoles(array $roles): array { - $schemasAllRead = $this->channel->schemas->filter(fn(Schema $schema) => empty($schema->read))->values()->pluck("name"); + $schemasAllRead = $this->channel->schemas->filter(fn(Schema $schema) => empty($schema->read))->values()->pluck("name"); $schemasCanRead = $this->channel->schemas->filter(fn(Schema $schema) => count(array_intersect($schema->read ?? [], $roles)) > 0)->values()->pluck("name"); $schemasCanWrite = $this->channel->schemas->filter(fn(Schema $schema) => count(array_intersect($schema->write ?? [], $roles)) > 0)->values()->pluck("name"); return $schemasAllRead->merge($schemasCanRead)->merge($schemasCanWrite)->unique()->values()->toArray(); @@ -77,8 +82,8 @@ final class ChannelService */ public function schemasWritableByRoles(array $roles): array { - $schemasAllRead = $this->channel->schemas->filter(fn(Schema $schema) => empty($schema->write ?? []))->values()->pluck("name"); - $schemasCanWrite = $this->channel->schemas->filter(fn(Schema $schema) => count(array_intersect($schema->write ?? [], $roles)) > 0)->values()->pluck("name"); + $schemasAllRead = $this->channel->schemas->filter(fn(Schema $schema) => empty($schema->write ?? []))->values()->pluck("name"); + $schemasCanWrite = $this->channel->schemas->filter(fn(Schema $schema) => count(array_intersect($schema->write ?? [], $roles)) > 0)->values()->pluck("name"); return $schemasAllRead->merge($schemasCanWrite)->unique()->values()->toArray(); } diff --git a/src/Channel/Data/UserCommand.php b/src/Channel/Data/UserCommand.php new file mode 100644 index 0000000..a66e81c --- /dev/null +++ b/src/Channel/Data/UserCommand.php @@ -0,0 +1,15 @@ + env("LUCENT_ENV", "production"), - "schemas_path" => env("LUCENT_SCHEMAS_PATH", "app/Lucent"), - "database" => env('LUCENT_DB_CONNECTION', env('DB_CONNECTION',"sqlite")), - "name" => env("LUCENT_NAME", "Lucent"), + "env" => env("LUCENT_ENV", "production"), + "schemas_path" => env("LUCENT_SCHEMAS_PATH", "app/Lucent"), + "database" => env('LUCENT_DB_CONNECTION', env('DB_CONNECTION', "sqlite")), + "name" => env("LUCENT_NAME", "Lucent"), "url" => env("LUCENT_URL", env('APP_URL')), - "previewTarget" => env("LUCENT_PREVIEW_TARGET", "previewTarget"), - "generateCommand" => env("LUCENT_GENERATE_COMMAND", "generate:static"), + "previewTarget" => env("LUCENT_PREVIEW_TARGET", "previewTarget"), + "commands" => [], "imageFilters" => [], "canInvite" => ["admin"], "canBuild" => ["admin"], diff --git a/src/Http/Controller/BuildController.php b/src/Http/Controller/BuildController.php index 7373ba8..b17e2f7 100644 --- a/src/Http/Controller/BuildController.php +++ b/src/Http/Controller/BuildController.php @@ -5,11 +5,8 @@ namespace Lucent\Http\Controller; use App\Http\Controllers\Controller; use Illuminate\Contracts\View\View; use Illuminate\Http\Request; -use Illuminate\Http\Response; -use Illuminate\Support\Facades\Artisan; use Lucent\Channel\ChannelService; use Lucent\Svelte\Svelte; -use function Lucent\Response\ok; class BuildController extends Controller { @@ -20,49 +17,66 @@ class BuildController extends Controller { } - public function build() + public function build(Request $request) { - - $buildLogFile = storage_path("lucent/build.log"); - if(file_exists($buildLogFile)){ + $commandSignature = $request->route("signature"); + $buildLogFile = $this->getLogFile($commandSignature); + $pidFile = $this->getPidFile($commandSignature); + if (file_exists($buildLogFile)) { unlink($buildLogFile); } + if (file_exists($pidFile)) { + unlink($pidFile); + } - exec("cd " . base_path() . " && php8.3 artisan {$this->channelService->channel->generateCommand} > " . $buildLogFile . " 2>&1 & echo $!", $op); + exec("cd " . base_path() . " && php8.3 artisan {$commandSignature} > " . $buildLogFile . " 2>&1 & echo $!", $op); $pid = (int)$op[0]; - return redirect($this->channelService->channel->lucentUrl . "/build-report"); + file_put_contents($pidFile, $pid); + return redirect($this->channelService->channel->lucentUrl . "/command-report/" . $commandSignature); } - public function report(): View + public function report(Request $request): View { + $commandSignature = $request->route("signature"); + $command = $this->channelService->channel->commands->firstWhere("signature", $commandSignature); return $this->svelte->render( layout: "channel", view: "buildReport", - title: "Build Report", + title: $command->name, + data: [ + "command" => $command, + ] ); } - public function reportSource() + public function reportSource(Request $request) { - return response()->stream(function () { + $commandSignature = $request->route("signature"); + return response()->stream(function () use ($commandSignature) { while (true) { -// sleep(1); // 50ms $data["date"] = date("Y-m-d H:i:s"); - $data["logs"] = file_get_contents(storage_path("lucent/build.log")); + $data["logs"] = file_get_contents($this->getLogFile($commandSignature)); // $lines = explode("\n",$data["logs"]); - echo 'data: ' .json_encode($data); + echo 'data: ' . json_encode($data); echo "\n\n"; ob_flush(); flush(); - if(str_contains($data["logs"],"Finito")){ + $pidFile = $this->getPidFile($commandSignature); + if (file_exists($pidFile)) { + $pid = file_get_contents($pidFile); + } else { break; } - if(str_contains($data["logs"],"Exception")){ + if (empty($pid)) { + break; + } + + if (!file_exists("/proc/$pid")) { break; } @@ -79,5 +93,13 @@ class BuildController extends Controller ]); } + private function getLogFile(string $signature): string + { + return storage_path("lucent/$signature.log"); + } + private function getPidFile(string $signature): string + { + return storage_path("lucent/$signature.pid.log"); + } } diff --git a/src/Http/web.php b/src/Http/web.php index c5adb59..ca9be22 100644 --- a/src/Http/web.php +++ b/src/Http/web.php @@ -33,9 +33,9 @@ Route::group([ Route::get('/profile', [AccountController::class, 'profile']); Route::post('/account/update-name', [AccountController::class, 'updateName']); Route::post('/account/update-email', [AccountController::class, 'updateEmail']); - Route::get('/build-report', [BuildController::class, 'report']); - Route::get('/build-report-source', [BuildController::class, 'reportSource']); - Route::post('/build', [BuildController::class, 'build']); + Route::get('/command-report/{signature}', [BuildController::class, 'report']); + Route::get('/command-report-source/{signature}', [BuildController::class, 'reportSource']); + Route::post('/command/{signature}', [BuildController::class, 'build']); }); diff --git a/src/StaticGenerator/StaticGenerator.php b/src/StaticGenerator/StaticGenerator.php index e8413c6..33fb73a 100644 --- a/src/StaticGenerator/StaticGenerator.php +++ b/src/StaticGenerator/StaticGenerator.php @@ -27,11 +27,11 @@ class StaticGenerator try { $callback($this->writer); }catch (Throwable $th){ - echo "Finito with errors".Carbon::now()->format("Y-m-d H:i:s")." ".$th->getMessage().PHP_EOL; + echo "Finished with errors".Carbon::now()->format("Y-m-d H:i:s")." ".$th->getMessage().PHP_EOL; } $this->copyBuildDirectory(); - echo "Finito ".Carbon::now()->format("Y-m-d H:i:s").PHP_EOL; + echo "Finished ".Carbon::now()->format("Y-m-d H:i:s").PHP_EOL; } private function removeBuildDirectory() :void{