multiple commands
This commit is contained in:
@@ -1,22 +1,23 @@
|
|||||||
<script>
|
<script>
|
||||||
import {getContext, onMount} from "svelte";
|
import {getContext, onMount} from "svelte";
|
||||||
|
import axios from "axios";
|
||||||
|
|
||||||
const channel = getContext("channel");
|
const channel = getContext("channel");
|
||||||
export let title;
|
export let title;
|
||||||
|
export let command;
|
||||||
$: date = "";
|
$: date = "";
|
||||||
$: logs = "";
|
$: logs = "";
|
||||||
|
|
||||||
let inProgress = false;
|
let inProgress = false;
|
||||||
|
|
||||||
function connect() {
|
function connect() {
|
||||||
const eventSource = new EventSource(channel.lucentUrl + "/build-report-source");
|
const eventSource = new EventSource(channel.lucentUrl + "/command-report-source/" + command.signature );
|
||||||
|
|
||||||
eventSource.onmessage = function (event) {
|
eventSource.onmessage = function (event) {
|
||||||
inProgress = true;
|
inProgress = true;
|
||||||
const data = JSON.parse(event.data);
|
const data = JSON.parse(event.data);
|
||||||
date = data.date;
|
date = data.date;
|
||||||
logs = data.logs;
|
logs = data.logs;
|
||||||
|
|
||||||
}
|
}
|
||||||
eventSource.onerror = (e) => {
|
eventSource.onerror = (e) => {
|
||||||
console.log(e)
|
console.log(e)
|
||||||
@@ -28,8 +29,7 @@
|
|||||||
function buildWebsite(e) {
|
function buildWebsite(e) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
inProgress = true;
|
inProgress = true;
|
||||||
|
axios.post(channel.lucentUrl + "/command/" + command.signature).then(response => {
|
||||||
axios.post(channel.lucentUrl + "/build").then(response => {
|
|
||||||
connect()
|
connect()
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -46,20 +46,19 @@
|
|||||||
|
|
||||||
<h3 class="header-small mb-5">{title}</h3>
|
<h3 class="header-small mb-5">{title}</h3>
|
||||||
|
|
||||||
<button on:click={buildWebsite} class="button primary mb-3" disabled={inProgress}>Start Build
|
<button on:click={buildWebsite} class="button primary mb-3" disabled={inProgress}>Start
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<div class="mb-3">
|
<div class="mb-3">
|
||||||
{#if inProgress}
|
{#if inProgress}
|
||||||
<span class="badge text-bg-warning">
|
<span class="badge text-bg-warning">
|
||||||
Build in progress
|
Action in progress
|
||||||
</span>
|
</span>
|
||||||
{/if}
|
{/if}
|
||||||
{#if !inProgress && logs}
|
{#if !inProgress && logs}
|
||||||
<span class="badge text-bg-info">
|
<span class="badge text-bg-info">
|
||||||
Build completed
|
Action completed
|
||||||
</span>
|
</span>
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
|
|||||||
@@ -61,7 +61,6 @@
|
|||||||
if (!filter.isReference) {
|
if (!filter.isReference) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
console.log(graph)
|
|
||||||
return graph.records.find(r => r.id === value);
|
return graph.records.find(r => r.id === value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,17 +1,25 @@
|
|||||||
<script>
|
<script>
|
||||||
import Avatar from "../account/Avatar.svelte";
|
import Avatar from "../account/Avatar.svelte";
|
||||||
import {getContext} from "svelte";
|
import {getContext} from "svelte";
|
||||||
|
import Dropdown from "../common/Dropdown.svelte";
|
||||||
|
|
||||||
const channel = getContext("channel");
|
const channel = getContext("channel");
|
||||||
const user = getContext("user");
|
const user = getContext("user");
|
||||||
|
console.log( channel.commands)
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
||||||
<div class="top-nav ">
|
<div class="top-nav ">
|
||||||
<a class="top-nav-item" href="{channel.lucentUrl}/members">Members</a>
|
<a class="top-nav-item" href="{channel.lucentUrl}/members">Members</a>
|
||||||
|
|
||||||
{#if channel.generateCommand}
|
{#if channel.commands}
|
||||||
<a href="{channel.lucentUrl}/build-report" class="top-nav-item">Build website</a>
|
<Dropdown>
|
||||||
|
<div slot="button">Actions</div>
|
||||||
|
{#each channel.commands as command}
|
||||||
|
<a href="{channel.lucentUrl}/command-report/{command.signature}" class="top-nav-item">{command.name}</a>
|
||||||
|
{/each}
|
||||||
|
</Dropdown>
|
||||||
|
|
||||||
{/if}
|
{/if}
|
||||||
<!-- <div>-->
|
<!-- <div>-->
|
||||||
<!-- <form method="GET">-->
|
<!-- <form method="GET">-->
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
namespace Lucent\Channel;
|
namespace Lucent\Channel;
|
||||||
|
|
||||||
|
use Lucent\Channel\Data\UserCommand;
|
||||||
use Lucent\Primitive\Collection;
|
use Lucent\Primitive\Collection;
|
||||||
use Lucent\Schema\Schema;
|
use Lucent\Schema\Schema;
|
||||||
|
|
||||||
@@ -13,12 +14,13 @@ final class Channel
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @param Collection<Schema> $schemas
|
* @param Collection<Schema> $schemas
|
||||||
|
* @param Collection<UserCommand> $commands
|
||||||
*/
|
*/
|
||||||
function __construct(
|
function __construct(
|
||||||
public string $name,
|
public string $name,
|
||||||
public string $url,
|
public string $url,
|
||||||
public string $previewTarget,
|
public string $previewTarget,
|
||||||
public string $generateCommand,
|
public Collection $commands,
|
||||||
public Collection $schemas,
|
public Collection $schemas,
|
||||||
public array $imageFilters,
|
public array $imageFilters,
|
||||||
public array $roles,
|
public array $roles,
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
namespace Lucent\Channel;
|
namespace Lucent\Channel;
|
||||||
|
|
||||||
|
|
||||||
use Lucent\File\FileService;
|
use Lucent\Channel\Data\UserCommand;
|
||||||
use Lucent\Primitive\Collection;
|
use Lucent\Primitive\Collection;
|
||||||
use Lucent\Schema\Schema;
|
use Lucent\Schema\Schema;
|
||||||
use Lucent\Schema\SchemaService;
|
use Lucent\Schema\SchemaService;
|
||||||
@@ -30,11 +30,16 @@ final class ChannelService
|
|||||||
$schemaService = new SchemaService();
|
$schemaService = new SchemaService();
|
||||||
$schemasCollection = (new Collection($schemasArray["schemas"] ?? []))->map([$schemaService, 'fromArray']);
|
$schemasCollection = (new Collection($schemasArray["schemas"] ?? []))->map([$schemaService, 'fromArray']);
|
||||||
|
|
||||||
|
$userCommands = [];
|
||||||
|
foreach (config("lucent.commands") as $signature => $desc) {
|
||||||
|
$userCommands[] = new UserCommand($desc, $signature);
|
||||||
|
}
|
||||||
|
|
||||||
$channel = new Channel(
|
$channel = new Channel(
|
||||||
name: config("lucent.name") ?? "",
|
name: config("lucent.name") ?? "",
|
||||||
url: rtrim(config("lucent.url") ?? "", "/"),
|
url: rtrim(config("lucent.url") ?? "", "/"),
|
||||||
previewTarget: rtrim(config("lucent.previewTarget") ?? "", "/"),
|
previewTarget: rtrim(config("lucent.previewTarget") ?? "", "/"),
|
||||||
generateCommand: config("lucent.generateCommand") ?? "",
|
commands: Collection::make($userCommands),
|
||||||
schemas: $schemasCollection,
|
schemas: $schemasCollection,
|
||||||
imageFilters: config("lucent.imageFilters") ?? [],
|
imageFilters: config("lucent.imageFilters") ?? [],
|
||||||
roles: $schemasArray["roles"] ?? []
|
roles: $schemasArray["roles"] ?? []
|
||||||
|
|||||||
@@ -0,0 +1,15 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Lucent\Channel\Data;
|
||||||
|
|
||||||
|
class UserCommand
|
||||||
|
{
|
||||||
|
public function __construct(
|
||||||
|
public string $name,
|
||||||
|
public string $signature,
|
||||||
|
)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
+1
-1
@@ -7,7 +7,7 @@ return [
|
|||||||
"name" => env("LUCENT_NAME", "Lucent"),
|
"name" => env("LUCENT_NAME", "Lucent"),
|
||||||
"url" => env("LUCENT_URL", env('APP_URL')),
|
"url" => env("LUCENT_URL", env('APP_URL')),
|
||||||
"previewTarget" => env("LUCENT_PREVIEW_TARGET", "previewTarget"),
|
"previewTarget" => env("LUCENT_PREVIEW_TARGET", "previewTarget"),
|
||||||
"generateCommand" => env("LUCENT_GENERATE_COMMAND", "generate:static"),
|
"commands" => [],
|
||||||
"imageFilters" => [],
|
"imageFilters" => [],
|
||||||
"canInvite" => ["admin"],
|
"canInvite" => ["admin"],
|
||||||
"canBuild" => ["admin"],
|
"canBuild" => ["admin"],
|
||||||
|
|||||||
@@ -5,11 +5,8 @@ namespace Lucent\Http\Controller;
|
|||||||
use App\Http\Controllers\Controller;
|
use App\Http\Controllers\Controller;
|
||||||
use Illuminate\Contracts\View\View;
|
use Illuminate\Contracts\View\View;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use Illuminate\Http\Response;
|
|
||||||
use Illuminate\Support\Facades\Artisan;
|
|
||||||
use Lucent\Channel\ChannelService;
|
use Lucent\Channel\ChannelService;
|
||||||
use Lucent\Svelte\Svelte;
|
use Lucent\Svelte\Svelte;
|
||||||
use function Lucent\Response\ok;
|
|
||||||
|
|
||||||
class BuildController extends Controller
|
class BuildController extends Controller
|
||||||
{
|
{
|
||||||
@@ -20,36 +17,46 @@ class BuildController extends Controller
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public function build()
|
public function build(Request $request)
|
||||||
{
|
{
|
||||||
|
$commandSignature = $request->route("signature");
|
||||||
$buildLogFile = storage_path("lucent/build.log");
|
$buildLogFile = $this->getLogFile($commandSignature);
|
||||||
|
$pidFile = $this->getPidFile($commandSignature);
|
||||||
if (file_exists($buildLogFile)) {
|
if (file_exists($buildLogFile)) {
|
||||||
unlink($buildLogFile);
|
unlink($buildLogFile);
|
||||||
}
|
}
|
||||||
|
if (file_exists($pidFile)) {
|
||||||
exec("cd " . base_path() . " && php8.3 artisan {$this->channelService->channel->generateCommand} > " . $buildLogFile . " 2>&1 & echo $!", $op);
|
unlink($pidFile);
|
||||||
$pid = (int)$op[0];
|
|
||||||
return redirect($this->channelService->channel->lucentUrl . "/build-report");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function report(): View
|
exec("cd " . base_path() . " && php8.3 artisan {$commandSignature} > " . $buildLogFile . " 2>&1 & echo $!", $op);
|
||||||
|
$pid = (int)$op[0];
|
||||||
|
file_put_contents($pidFile, $pid);
|
||||||
|
return redirect($this->channelService->channel->lucentUrl . "/command-report/" . $commandSignature);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function report(Request $request): View
|
||||||
{
|
{
|
||||||
|
$commandSignature = $request->route("signature");
|
||||||
|
$command = $this->channelService->channel->commands->firstWhere("signature", $commandSignature);
|
||||||
|
|
||||||
return $this->svelte->render(
|
return $this->svelte->render(
|
||||||
layout: "channel",
|
layout: "channel",
|
||||||
view: "buildReport",
|
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) {
|
while (true) {
|
||||||
// sleep(1); // 50ms
|
|
||||||
$data["date"] = date("Y-m-d H:i:s");
|
$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"]);
|
// $lines = explode("\n",$data["logs"]);
|
||||||
|
|
||||||
echo 'data: ' . json_encode($data);
|
echo 'data: ' . json_encode($data);
|
||||||
@@ -58,11 +65,18 @@ class BuildController extends Controller
|
|||||||
ob_flush();
|
ob_flush();
|
||||||
flush();
|
flush();
|
||||||
|
|
||||||
if(str_contains($data["logs"],"Finito")){
|
$pidFile = $this->getPidFile($commandSignature);
|
||||||
|
if (file_exists($pidFile)) {
|
||||||
|
$pid = file_get_contents($pidFile);
|
||||||
|
} else {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(str_contains($data["logs"],"Exception")){
|
if (empty($pid)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!file_exists("/proc/$pid")) {
|
||||||
break;
|
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");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-3
@@ -33,9 +33,9 @@ Route::group([
|
|||||||
Route::get('/profile', [AccountController::class, 'profile']);
|
Route::get('/profile', [AccountController::class, 'profile']);
|
||||||
Route::post('/account/update-name', [AccountController::class, 'updateName']);
|
Route::post('/account/update-name', [AccountController::class, 'updateName']);
|
||||||
Route::post('/account/update-email', [AccountController::class, 'updateEmail']);
|
Route::post('/account/update-email', [AccountController::class, 'updateEmail']);
|
||||||
Route::get('/build-report', [BuildController::class, 'report']);
|
Route::get('/command-report/{signature}', [BuildController::class, 'report']);
|
||||||
Route::get('/build-report-source', [BuildController::class, 'reportSource']);
|
Route::get('/command-report-source/{signature}', [BuildController::class, 'reportSource']);
|
||||||
Route::post('/build', [BuildController::class, 'build']);
|
Route::post('/command/{signature}', [BuildController::class, 'build']);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -27,11 +27,11 @@ class StaticGenerator
|
|||||||
try {
|
try {
|
||||||
$callback($this->writer);
|
$callback($this->writer);
|
||||||
}catch (Throwable $th){
|
}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();
|
$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{
|
private function removeBuildDirectory() :void{
|
||||||
|
|||||||
Reference in New Issue
Block a user