|
2 | 2 | import shlex |
3 | 3 | import subprocess |
4 | 4 | import sys |
| 5 | +import shutil |
5 | 6 | from pathlib import Path |
6 | 7 | from rich.panel import Panel |
7 | 8 | from rich.progress import Progress, SpinnerColumn, TextColumn |
@@ -88,26 +89,46 @@ def _write_docker_compose(output_path): |
88 | 89 | if not services: |
89 | 90 | return None |
90 | 91 |
|
91 | | - compose_lines = ["services:"] |
| 92 | + compose_lines = [ |
| 93 | + "networks:", |
| 94 | + " concore-net:", |
| 95 | + " driver: bridge", |
| 96 | + "", |
| 97 | + "services:", |
| 98 | + ] |
92 | 99 |
|
| 100 | + named_volumes = set() |
93 | 101 | for index, service in enumerate(services, start=1): |
94 | 102 | service_name = re.sub(r"[^A-Za-z0-9_.-]", "-", service["container_name"]).strip( |
95 | 103 | "-." |
96 | 104 | ) |
97 | 105 | if not service_name: |
98 | 106 | service_name = f"service-{index}" |
99 | | - elif not service_name[0].isalnum(): |
| 107 | + elif not service_name[0].isalpha(): |
100 | 108 | service_name = f"service-{service_name}" |
101 | 109 |
|
102 | | - compose_lines.append(f" {service_name}:") |
| 110 | + compose_lines.append(f" {_yaml_quote(service_name)}:") |
103 | 111 | compose_lines.append(f" image: {_yaml_quote(service['image'])}") |
104 | 112 | compose_lines.append( |
105 | 113 | f" container_name: {_yaml_quote(service['container_name'])}" |
106 | 114 | ) |
| 115 | + compose_lines.append(" restart: on-failure") |
| 116 | + compose_lines.append(" networks:") |
| 117 | + compose_lines.append(" - concore-net") |
| 118 | + |
107 | 119 | if service["volumes"]: |
108 | 120 | compose_lines.append(" volumes:") |
109 | 121 | for volume_spec in service["volumes"]: |
110 | 122 | compose_lines.append(f" - {_yaml_quote(volume_spec)}") |
| 123 | + part1 = volume_spec.split(":")[0] |
| 124 | + if re.match(r"^[a-zA-Z0-9_-]+$", part1): |
| 125 | + named_volumes.add(part1) |
| 126 | + |
| 127 | + if named_volumes: |
| 128 | + compose_lines.append("") |
| 129 | + compose_lines.append("volumes:") |
| 130 | + for v in sorted(named_volumes): |
| 131 | + compose_lines.append(f" {v}:") |
111 | 132 |
|
112 | 133 | compose_lines.append("") |
113 | 134 | compose_path = output_path / "docker-compose.yml" |
@@ -180,6 +201,35 @@ def build_workflow( |
180 | 201 |
|
181 | 202 | progress.update(task, completed=True) |
182 | 203 |
|
| 204 | + if exec_type == "docker": |
| 205 | + req_src = Path.cwd() / "requirements.txt" |
| 206 | + if not req_src.exists(): |
| 207 | + req_src = source_path / "requirements.txt" |
| 208 | + req_dest = output_path / "src" / "requirements.txt" |
| 209 | + if req_src.exists() and (output_path / "src").exists(): |
| 210 | + shutil.copy2(req_src, req_dest) |
| 211 | + elif (output_path / "src").exists(): |
| 212 | + req_dest.touch() |
| 213 | + |
| 214 | + # Append requirement copying to generated scripts robustly |
| 215 | + for s_name in ["build", "build.bat"]: |
| 216 | + s_path = output_path / s_name |
| 217 | + if s_path.exists(): |
| 218 | + content = s_path.read_text(encoding="utf-8") |
| 219 | + lines = content.splitlines() |
| 220 | + if s_name == "build": |
| 221 | + insert_line = "cp ../src/requirements.txt ." |
| 222 | + else: |
| 223 | + insert_line = "copy ..\\src\\requirements.txt ." |
| 224 | + |
| 225 | + new_lines = [] |
| 226 | + for line in lines: |
| 227 | + if " build" in line and "-t " in line: |
| 228 | + new_lines.append(insert_line) |
| 229 | + new_lines.append(line) |
| 230 | + |
| 231 | + s_path.write_text("\n".join(new_lines) + "\n", encoding="utf-8") |
| 232 | + |
183 | 233 | if result.stdout: |
184 | 234 | console.print(result.stdout) |
185 | 235 |
|
|
0 commit comments