Merge pull request #3830 from lucasmichot/feat/services-generation

Simplify and optimize the `service-templates.yaml` generation command
This commit is contained in:
🏔️ Peak
2024-10-31 16:37:55 +01:00
committed by GitHub

View File

@@ -3,128 +3,82 @@
namespace App\Console\Commands; namespace App\Console\Commands;
use Illuminate\Console\Command; use Illuminate\Console\Command;
use Illuminate\Support\Arr;
use Symfony\Component\Yaml\Yaml; use Symfony\Component\Yaml\Yaml;
class ServicesGenerate extends Command class ServicesGenerate extends Command
{ {
/** /**
* The name and signature of the console command. * {@inheritdoc}
*
* @var string
*/ */
protected $signature = 'services:generate'; protected $signature = 'services:generate';
/** /**
* The console command description. * {@inheritdoc}
*
* @var string
*/ */
protected $description = 'Generate service-templates.yaml based on /templates/compose directory'; protected $description = 'Generate service-templates.yaml based on /templates/compose directory';
/** public function handle(): int
* Execute the console command.
*/
public function handle()
{ {
$files = array_diff(scandir(base_path('templates/compose')), ['.', '..']); $serviceTemplatesJson = collect(glob(base_path('templates/compose/*.yaml')))
$files = array_filter($files, function ($file) { ->mapWithKeys(function ($file): array {
return strpos($file, '.yaml') !== false; $file = basename($file);
}); $parsed = $this->processFile($file);
$serviceTemplatesJson = [];
foreach ($files as $file) { return $parsed === false ? [] : [
$parsed = $this->process_file($file); Arr::pull($parsed, 'name') => $parsed,
if ($parsed) { ];
$name = data_get($parsed, 'name'); })->toJson(JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES);
$parsed = data_forget($parsed, 'name');
$serviceTemplatesJson[$name] = $parsed;
}
}
$serviceTemplatesJson = json_encode($serviceTemplatesJson, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES);
file_put_contents(base_path('templates/service-templates.json'), $serviceTemplatesJson.PHP_EOL); file_put_contents(base_path('templates/service-templates.json'), $serviceTemplatesJson.PHP_EOL);
return self::SUCCESS;
} }
private function process_file($file) private function processFile(string $file): false|array
{ {
$serviceName = str($file)->before('.yaml')->value();
$content = file_get_contents(base_path("templates/compose/$file")); $content = file_get_contents(base_path("templates/compose/$file"));
// $this->info($content);
$ignore = collect(preg_grep('/^# ignore:/', explode("\n", $content)))->values(); $data = collect(explode(PHP_EOL, $content))->mapWithKeys(function ($line): array {
if ($ignore->count() > 0) { preg_match('/^#(?<key>.*):(?<value>.*)$/U', $line, $m);
$ignore = (bool) str($ignore[0])->after('# ignore:')->trim()->value();
} else { return $m ? [trim($m['key']) => trim($m['value'])] : [];
$ignore = false; });
}
if ($ignore) { if (str($data->get('ignore'))->toBoolean()) {
$this->info("Ignoring $file"); $this->info("Ignoring $file");
return; return false;
} }
$this->info("Processing $file"); $this->info("Processing $file");
$documentation = collect(preg_grep('/^# documentation:/', explode("\n", $content)))->values();
if ($documentation->count() > 0) {
$documentation = str($documentation[0])->after('# documentation:')->trim()->value();
$documentation = str($documentation)->append('?utm_source=coolify.io');
} else {
$documentation = 'https://coolify.io/docs';
}
$slogan = collect(preg_grep('/^# slogan:/', explode("\n", $content)))->values(); $documentation = $data->get('documentation');
if ($slogan->count() > 0) { $documentation = $documentation ? $documentation.'?utm_source=coolify.io' : 'https://coolify.io/docs';
$slogan = str($slogan[0])->after('# slogan:')->trim()->value();
} else {
$slogan = str($file)->headline()->value();
}
$logo = collect(preg_grep('/^# logo:/', explode("\n", $content)))->values();
if ($logo->count() > 0) {
$logo = str($logo[0])->after('# logo:')->trim()->value();
} else {
$logo = 'svgs/coolify.png';
}
$minversion = collect(preg_grep('/^# minversion:/', explode("\n", $content)))->values();
if ($minversion->count() > 0) {
$minversion = str($minversion[0])->after('# minversion:')->trim()->value();
} else {
$minversion = '0.0.0';
}
$env_file = collect(preg_grep('/^# env_file:/', explode("\n", $content)))->values();
if ($env_file->count() > 0) {
$env_file = str($env_file[0])->after('# env_file:')->trim()->value();
} else {
$env_file = null;
}
$tags = collect(preg_grep('/^# tags:/', explode("\n", $content)))->values();
if ($tags->count() > 0) {
$tags = str($tags[0])->after('# tags:')->trim()->explode(',')->map(function ($tag) {
return str($tag)->trim()->lower()->value();
})->values();
} else {
$tags = null;
}
$port = collect(preg_grep('/^# port:/', explode("\n", $content)))->values();
if ($port->count() > 0) {
$port = str($port[0])->after('# port:')->trim()->value();
} else {
$port = null;
}
$json = Yaml::parse($content); $json = Yaml::parse($content);
$yaml = base64_encode(Yaml::dump($json, 10, 2)); $compose = base64_encode(Yaml::dump($json, 10, 2));
$tags = str($data->get('tags'))->lower()->explode(',')->map(fn ($tag) => trim($tag))->filter();
$tags = $tags->isEmpty() ? null : $tags->all();
$payload = [ $payload = [
'name' => $serviceName, 'name' => pathinfo($file, PATHINFO_FILENAME),
'documentation' => $documentation, 'documentation' => $documentation,
'slogan' => $slogan, 'slogan' => $data->get('slogan', str($file)->headline()),
'compose' => $yaml, 'compose' => $compose,
'tags' => $tags, 'tags' => $tags,
'logo' => $logo, 'logo' => $data->get('logo', 'svgs/coolify.png'),
'minversion' => $minversion, 'minversion' => $data->get('minversion', '0.0.0'),
]; ];
if ($port) {
if ($port = $data->get('port')) {
$payload['port'] = $port; $payload['port'] = $port;
} }
if ($env_file) {
$env_file_content = file_get_contents(base_path("templates/compose/$env_file")); if ($envFile = $data->get('env_file')) {
$env_file_base64 = base64_encode($env_file_content); $envFileContent = file_get_contents(base_path("templates/compose/$envFile"));
$payload['envs'] = $env_file_base64; $payload['envs'] = base64_encode($envFileContent);
} }
return $payload; return $payload;