Skip to content

Commit fae5e44

Browse files
committed
Added Update menu
1 parent f12e247 commit fae5e44

File tree

1 file changed

+97
-26
lines changed

1 file changed

+97
-26
lines changed

src/cli/builder.py

Lines changed: 97 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,13 @@
22

33
import inspect
44
from pathlib import Path
5-
from typing import Any
5+
from random import choice
6+
from typing import Any, cast
67

78
from InquirerPy import inquirer # type: ignore
89
from InquirerPy.validator import EmptyInputValidator # type: ignore
910
from click import Command, Option
10-
from importlib_resources import files # type: ignore
11+
from importlib_resources import as_file, files # type: ignore
1112
from yaspin import yaspin # type: ignore
1213

1314
from ..core.copy_files import copy_files # type: ignore
@@ -108,19 +109,89 @@ def callback(
108109
data: dicts = read_json(path) or {}
109110
compose: dicts = data.get("compose", {}) or {}
110111

111-
services: set[dicts] = set(compose.get("services", []))
112-
networks: set[str] = set(compose.get("networks", []))
113-
envs: set[dicts] = set(data.get("envs", []))
114-
115-
if networks:
116-
pass
117-
if envs:
118-
pass
112+
services: list[dicts] = compose.get("services", []) or []
113+
networks: list[str] = compose.get("networks", []) or []
114+
envs: list[dicts] = data.get("envs", []) or []
119115

120116
if not services:
121117
print("No services found. Use 'create' first.")
122118
return
123119

120+
def find_index_by_name(name: str) -> int | None:
121+
for i, s in enumerate(services):
122+
if s.get("name") == name:
123+
return i
124+
return None
125+
126+
if remove:
127+
target = service
128+
if not target:
129+
names = [s.get("name") for s in services if s.get("name")]
130+
if not names:
131+
print("No services found.")
132+
return
133+
target = inquirer.select( # type: ignore
134+
message="Select a service to remove: ", choices=names
135+
).execute()
136+
137+
idx = find_index_by_name(target)
138+
if idx is None:
139+
print(f"Service '{target}' not found.")
140+
return
141+
142+
if confirm(msg=f"Remove service '{target}'"):
143+
services.pop(idx)
144+
envs = [
145+
e for e in envs if e.get("CONTAINER_NAME") != target
146+
]
147+
compose["services"] = services
148+
compose["networks"] = networks
149+
data["compose"] = compose
150+
data["envs"] = envs
151+
self.__save_files(data)
152+
print(f"Service '{target}' removed and files updated.")
153+
154+
elif add:
155+
name = service
156+
if not name:
157+
name = self.__get_name("Enter the name of the service: ")
158+
if find_index_by_name(name):
159+
if not confirm(
160+
msg=f"Service '{name}' already exists. Overwrite? "
161+
):
162+
print("Add cancelled.")
163+
return
164+
services = [s for s in services if s.get("name") != name]
165+
envs = [e for e in envs if e.get("CONTAINER_NAME") != name]
166+
167+
network = None
168+
if networks:
169+
network = inquirer.select( # type: ignore
170+
message="Select a network: ", choices=networks
171+
).execute()
172+
menu = Menus(network=network)
173+
174+
service_obj, env_obj = self.__get_data(menu, name)
175+
service_obj["name"] = name
176+
env_obj["CONTAINER_NAME"] = name
177+
178+
services.append(service_obj)
179+
envs.append(env_obj)
180+
181+
if confirm(msg=f"Add/Update service '{name}'"):
182+
compose["services"] = services
183+
compose["networks"] = networks
184+
data["compose"] = compose
185+
data["envs"] = envs
186+
self.__save_files(data)
187+
print(f"Service '{name}' removed and files updated.")
188+
189+
else:
190+
print("Use --add or --remove flag.")
191+
print("Use --services [service] for faster output.")
192+
for s in services:
193+
print(f" - {s.get("name")}")
194+
124195
return Command(
125196
name=inspect.currentframe().f_code.co_name, # type: ignore
126197
help=help,
@@ -161,19 +232,15 @@ def callback(
161232
)
162233

163234
def __get_data(
164-
self, menu: Menus, get_service: bool = True, get_env: bool = True
235+
self, menu: Menus, name: str | None = None
165236
) -> tuple[dicts, dicts]:
166237
clear(0.5)
167238

168-
name = self.__get_name(message="Enter the name of the service: ")
169-
170-
service = {}
171-
if get_service:
172-
service = menu.service(name=name)
239+
if not name:
240+
name = self.__get_name(message="Enter the name of the service: ")
173241

174-
env = {}
175-
if get_env:
176-
env = menu.env(name=name)
242+
service = menu.service(name=name)
243+
env = menu.env(name=name)
177244

178245
return (service, env)
179246

@@ -189,7 +256,7 @@ def __get_name(self, message: str) -> str:
189256

190257
return name
191258

192-
@yaspin(text="Creating files...", color="cyan")
259+
@yaspin(text="Saving files...", color="cyan")
193260
def __save_files(self, data: dicts, build: bool = False) -> None:
194261
tmps_path = files("minecraft-docker-cli.assets.templates")
195262
composer_template = tmps_path.joinpath("docker-compose.yml.j2")
@@ -199,9 +266,11 @@ def __save_files(self, data: dicts, build: bool = False) -> None:
199266
write_json(self.cwd.joinpath("data.json"), data)
200267

201268
composer: dicts = data.get("composer") or {}
202-
template_to_file(
203-
composer_template, composer, self.cwd.joinpath("docker-compose.yml")
204-
)
269+
with as_file(composer_template) as composer_path: # type: ignore
270+
composer_path = cast(Path, composer_path)
271+
template_to_file(
272+
composer_path, composer, self.cwd.joinpath("docker-compose.yml")
273+
)
205274

206275
services: list[dicts] = composer.get("services", []) or []
207276
names: list[str] = [service.get("name") for service in services] # type: ignore
@@ -210,6 +279,8 @@ def __save_files(self, data: dicts, build: bool = False) -> None:
210279
envs: list[dicts] = data.get("envs") or []
211280
for env in envs:
212281
relative_path = f"servers/{env.get("CONTAINER_NAME")}/.env" # type: ignore
213-
template_to_file(
214-
env_template, env, self.cwd.joinpath(relative_path)
215-
)
282+
with as_file(env_template) as env_path: # type: ignore
283+
env_path = cast(Path, env_path)
284+
template_to_file(
285+
env_path, env, self.cwd.joinpath(relative_path)
286+
)

0 commit comments

Comments
 (0)