driver(); if (! $driver instanceof RendersCompose) { throw new InvalidArgumentException("Driver [{$service->driver_name}] cannot render Docker Compose."); } $composeService = $driver->composeService(); if ($service->default_cpu_limit && ! isset($composeService['cpus'])) { $composeService['cpus'] = (string) $service->default_cpu_limit; } if ($service->default_memory_limit_mb && ! isset($composeService['mem_limit'])) { $composeService['mem_limit'] = "{$service->default_memory_limit_mb}m"; $composeService['memswap_limit'] = "{$service->default_memory_limit_mb}m"; } $document = [ 'services' => [ $this->serviceKey($service) => $composeService, ], ]; $volumes = array_filter($driver->composeVolumes(), fn (mixed $volume): bool => $volume !== false); if ($volumes !== []) { $document['volumes'] = $volumes; } return $this->toYaml($document); } public function renderEnvironmentFile(Service $service): string { $driver = $service->driver(); if (! method_exists($driver, 'environmentExports')) { return ''; } return collect($driver->environmentExports()) ->map(fn (mixed $value, string $key): string => $key.'='.$this->formatEnvValue($value)) ->implode("\n"); } private function serviceKey(Service $service): string { return str($service->name)->slug('_')->value() ?: 'service'; } /** * @param array $document */ private function toYaml(array $document, int $indent = 0): string { $lines = []; foreach ($document as $key => $value) { $prefix = str_repeat(' ', $indent); if (is_array($value)) { if ($value === []) { $lines[] = "{$prefix}{$key}: []"; continue; } $lines[] = "{$prefix}{$key}:"; $lines[] = $this->arrayToYaml($value, $indent + 1); continue; } if ($value === null) { $lines[] = "{$prefix}{$key}: {}"; continue; } $lines[] = "{$prefix}{$key}: ".$this->formatScalar($value); } return implode("\n", array_filter($lines))."\n"; } /** * @param array $items */ private function arrayToYaml(array $items, int $indent): string { if (array_is_list($items)) { return $this->listToYaml($items, $indent); } return $this->toYaml($items, $indent); } /** * @param array $items */ private function listToYaml(array $items, int $indent): string { $lines = []; $prefix = str_repeat(' ', $indent); foreach ($items as $item) { if (is_array($item)) { $lines[] = "{$prefix}-"; $lines[] = $this->arrayToYaml($item, $indent + 1); continue; } $lines[] = "{$prefix}- ".$this->formatScalar($item); } return implode("\n", $lines); } private function formatScalar(mixed $value): string { if (is_bool($value)) { return $value ? 'true' : 'false'; } if (is_numeric($value)) { return (string) $value; } return '"'.str_replace('"', '\"', (string) $value).'"'; } private function formatEnvValue(mixed $value): string { return str_replace(["\n", "\r"], ['\n', ''], (string) $value); } }