From 67f75f85dad8fa1a0f99aa9b24a37713c60c0fc0 Mon Sep 17 00:00:00 2001 From: Artem Golub Date: Fri, 13 Feb 2026 13:35:31 +0200 Subject: [PATCH] cleanup --- services/backend/src/manifest_generation.py | 49 +++++++++++++----- services/frontend/public/favicon.png | Bin 1015 -> 8526 bytes services/frontend/public/index.html | 2 +- .../src/components/Project/CodeBox.tsx | 26 +++++----- .../src/components/Project/ManifestSelect.tsx | 14 ++--- services/frontend/src/types/index.ts | 2 +- 6 files changed, 56 insertions(+), 37 deletions(-) diff --git a/services/backend/src/manifest_generation.py b/services/backend/src/manifest_generation.py index 1c88435..0f0ed0a 100644 --- a/services/backend/src/manifest_generation.py +++ b/services/backend/src/manifest_generation.py @@ -59,8 +59,17 @@ def _parse_version(version: str) -> int | float: return float(version) +def _is_latest_compose_spec(version: str) -> bool: + return version.strip().lower() in { + "latest", + "latest (spec)", + "spec", + "compose-spec", + } + + def generate_docker_compose_yaml(payload: dict[str, Any]) -> str: - version = str(payload.get("version", "3")) + version = str(payload.get("version", "latest")).strip() services = payload.get("services") volumes = payload.get("volumes") networks = payload.get("networks") @@ -70,27 +79,39 @@ def generate_docker_compose_yaml(payload: dict[str, Any]) -> str: yaml.indent(mapping=2, sequence=4, offset=2) yaml.preserve_quotes = True yaml.explicit_start = True - - specified_version = _parse_version(version) - major_version = int(specified_version) - - yaml.dump({"version": DoubleQuotedScalarString(str(specified_version))}, output) - yaml.explicit_start = False - output.write("\n") + wrote_document = False + + def dump_chunk(data: dict[str, Any], transform: Any = None) -> None: + nonlocal wrote_document + yaml.explicit_start = not wrote_document + if transform: + yaml.dump(data, output, transform=transform) + else: + yaml.dump(data, output) + wrote_document = True + + latest_compose_spec = _is_latest_compose_spec(version) + major_version = 3 + + if not latest_compose_spec: + specified_version = _parse_version(version) + major_version = int(specified_version) + dump_chunk({"version": DoubleQuotedScalarString(str(specified_version))}) + output.write("\n") if services: - if major_version in {2, 3}: - yaml.dump({"services": services}, output, transform=_sequence_indent_four) + if latest_compose_spec or major_version in {2, 3}: + dump_chunk({"services": services}, transform=_sequence_indent_four) elif major_version == 1: - yaml.dump(services, output, transform=_sequence_indent_one) + dump_chunk(services, transform=_sequence_indent_one) output.write("\n") - if major_version in {2, 3} and networks: - yaml.dump({"networks": networks}, output) + if (latest_compose_spec or major_version in {2, 3}) and networks: + dump_chunk({"networks": networks}) output.write("\n") if volumes: - yaml.dump({"volumes": volumes}, output) + dump_chunk({"volumes": volumes}) output.seek(0) return output.read() diff --git a/services/frontend/public/favicon.png b/services/frontend/public/favicon.png index 69dea8d621af53ecad243f3a6c0a1584b1e0752b..9c96541555f9eec85c6a9a37adea8f33cda55f24 100644 GIT binary patch literal 8526 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 bf^R|O6}$AbHMI`OY`Qqmw%xb)z3{&PyzXfF delta 979 zcmV;^11$W`LiYzDiBL{Q4GJ0x0000DNk~Le0000$0000$2nGNE0IF$m-jN|Re*=t3 zL_t(|0qvPhYZE~jfZy5B;6Y1@RS*Q@MM@C~^bfTEp#Fl!W1~pULhVMubNoU)+5Q9n zL3{LMm);CW7ZeH>u@p}>*>T@(GEK>5cRt<;o9#ZArb(EY=joEnP5}xE3JNYU3@ozn z_Gme9U>O)Y=rrcHA%j>8aPQ;qe@zIuJ2aKsS-;)_LjJh53c!`hocqNGO{@eMl^4^I zMfm$_X^jWG9X<>raIf3t59eIZ2SvyOjF%Tv8b|2MZ(SIbgMZo!R#YR921u6|(`rYE zlNY0EL?8ZwiQs?+^zsOA4*y0WAC1bOI#Y6X&NfY>C? z2zG(3f(`oeCoh*)vmlSe2Iw*70X2Pje8?Ez1RE&IBe4O#H|9TwqtTt;4auKzzUw1H zLmnBs59qApf(asw$cLkH{u(IJltP}GmO6bckG!Lt@z4BgAVte7wg9lF!*YM@p=iU|%f=6J2p*$je z9-wq349S;!!A|&0_2R5fegDm^Xltr{B@oC*OHp~VRD?8nF|$DgBKc?;ph#i_S$Q$L zMg&6nXbGS}Yy?$#f3X6E2*mQy^q`4|z~Pud(E8T6*;bYptB{CbK|Y!qh|rc7D@ll8 zNj{nu2r!lxt2vJl9%5EY;lI`y1OM8Fw+ogq4nQV9U?{>Q&^i_$KrWB)pbZm5JAf7W zGb%7av;tU^$18yLMkxj5&j7pfe0%@h?K(^lr2u)8N2CMfe^DNh3XoTMBsD;u<&ney zd6!2LzXr?QZXI$gk0kE{IJ0nin;m&1F@Q63x)uKLfr^aDBZ&dL@C4T>IV(UBA%pUW z)Yo7w{4fkmJ`6J|k4SHXv?F9#9#Pr~D@VwNznczr-DJhdD - Container Toolkit + Container Tool Kit diff --git a/services/frontend/src/components/Project/CodeBox.tsx b/services/frontend/src/components/Project/CodeBox.tsx index d765da2..70e6056 100644 --- a/services/frontend/src/components/Project/CodeBox.tsx +++ b/services/frontend/src/components/Project/CodeBox.tsx @@ -7,7 +7,6 @@ import { checkHttpStatus } from "../../services/helpers"; import { generateHttp } from "../../services/generate"; import { toaster } from "../../utils"; import eventBus from "../../events/eventBus"; -import ManifestSelect from "./ManifestSelect"; import CodeEditor from "../CodeEditor"; import useWindowDimensions from "../../hooks/useWindowDimensions"; @@ -15,11 +14,11 @@ const CodeBox = () => { const versionRef = useRef(); const manifestRef = useRef(); const [language, setLanguage] = useState("yaml"); - const [version, setVersion] = useState("3"); + const [version, setVersion] = useState("latest"); const [copyText, setCopyText] = useState("Copy"); const [generatedCode, setGeneratedCode] = useState(""); const [formattedCode, setFormattedCode] = useState(""); - const [manifest, setManifest] = useState(manifestTypes.DOCKER_COMPOSE); + const [manifest] = useState(manifestTypes.DOCKER_COMPOSE); const { height } = useWindowDimensions(); versionRef.current = version; @@ -98,14 +97,15 @@ const CodeBox = () => { return ( <>