refactoring stage 5

- fix export command
This commit is contained in:
2026-05-05 20:04:07 +09:00
parent 97f1636c57
commit df8fb68a1d

144
run.py
View File

@@ -207,6 +207,17 @@ class Language(Enum):
case _: case _:
return Language.UNDEFINED return Language.UNDEFINED
@staticmethod
def languages() -> list["Language"]:
return [
Language.PYTHON,
Language.C,
Language.CPP,
Language.RUST,
Language.KOTLIN,
Language.LUA,
]
def _dispatch_target(target: str) -> tuple[str, str, Language]: def _dispatch_target(target: str) -> tuple[str, str, Language]:
splited = target.split("/") splited = target.split("/")
@@ -341,7 +352,12 @@ class StorageManager:
return None return None
def save_file( def save_file(
self, location: str, lang: Language, filename: str, content: bytes, completed: bool self,
location: str,
lang: Language,
filename: str,
content: bytes,
completed: bool,
) -> None: ) -> None:
path = STORAGE_DIR / location / lang.value / ("completed" if completed else "") path = STORAGE_DIR / location / lang.value / ("completed" if completed else "")
os.makedirs(path, exist_ok=True) os.makedirs(path, exist_ok=True)
@@ -392,6 +408,18 @@ class StorageManager:
if os.path.isfile(completed_file): if os.path.isfile(completed_file):
os.rename(completed_file, uncompleted_file) os.rename(completed_file, uncompleted_file)
@staticmethod
def construct_target_path(
location: str, lang: Language, filename: str, completed: bool
) -> pathlib.Path:
return (
STORAGE_DIR
/ location
/ lang.value
/ ("completed" if completed else "")
/ f"{filename}.{lang.value}"
)
# ======================= # =======================
# MAIN CLI LOGIC # MAIN CLI LOGIC
@@ -482,7 +510,7 @@ def create(target: str, completed: bool, template: bool, force: bool):
@click.argument("lang", type=str, nargs=1, required=True) @click.argument("lang", type=str, nargs=1, required=True)
@click.option("--testcase", "-t", default=["1"], multiple=True) @click.option("--testcase", "-t", default=["1"], multiple=True)
@click.option("--verbose/--no-verbose", "-v/-nv", default=True) @click.option("--verbose/--no-verbose", "-v/-nv", default=True)
def run(lang: str, testcase: list[str], verbose: bool): def run(lang: str, testcase: tuple[str, ...], verbose: bool):
""" """
지정된 언어로 빌드 및 실행하는 명령어 지정된 언어로 빌드 및 실행하는 명령어
""" """
@@ -500,6 +528,7 @@ def run(lang: str, testcase: list[str], verbose: bool):
) )
# 테케 분석 # 테케 분석
testcase: list[str] = list(testcase)
tcs: list[int] = _parse_range_string_list(testcase) tcs: list[int] = _parse_range_string_list(testcase)
# build # build
@@ -608,73 +637,72 @@ def load(target: str, force: bool):
@click.command(name="export") @click.command(name="export")
@click.option("--from", "from_", type=str, required=True) @click.argument("from", "from_", type=str, nargs=-1)
@click.option( @click.option(
"--completed/--no-completed", "-c/-nc", is_flag=True, flag_value=False, default=None "--all", "all_", default=False, is_flag=True, help="Export all files in the space"
) )
@click.option("--copy", is_flag=True, help="is copy from state or move") @click.option(
def export(from_: str, completed: bool, copy: bool): "--force",
# Language 알기 "-f",
from_language = Language.convert_name(from_) is_flag=True,
help="Overwrite existing file in storage if it already exists",
)
def export(from_: tuple[str, ...], all_: bool, force: bool):
"""
space에 있는 파일을 storage의 각 location으로 이동시키는 명령.
"""
if from_language is Language.UNDEFINED: def _export_sub_command(from_language: Language):
raise click.ClickException("Undefined Language Exception") space = StateManager().get_space(from_language)
try:
with open("state.yml", "r", encoding="utf-8") as f:
state = yaml.safe_load(f)
except FileNotFoundError as e:
raise click.ClickException(e)
except yaml.YAMLError as e:
raise click.ClickException(e)
if "space" not in state: s_file, s_loc, s_is_completed = (
raise click.ClickException("State(state.yml) Exception") space["file"],
elif not state["space"]: space["location"],
click.secho("state.space has no member", fg="yellow", bold=True) space["is_completed"],
state["space"] = {}
lang_space_state: dict | None
if from_language.value not in state["space"]:
lang_space_state = None
else:
lang_space_state = state["space"][from_language.value]
if lang_space_state is None or not lang_space_state:
raise click.ClickException("Export Exception: There are no pre-defined state")
s_file = lang_space_state["file"]
s_loc = lang_space_state["location"]
s_is_completed = lang_space_state["is_completed"]
if not s_file:
raise click.ClickException(
f"Export Exception: There is no file in {from_language.value} space"
) )
if not s_loc: path = StorageManager.construct_target_path(
raise click.ClickException(f"Export Exception: Location {s_loc} is not defined") s_loc, from_language, s_file, s_is_completed
)
if completed: if path.is_file() and not force:
s_is_completed = True raise click.ClickException(
f"File '{path.name}' already exists in location '{s_loc}'. Use --force to overwrite."
)
dest_path: str = f"{STORAGE_DIR}/{s_loc}/{from_language.value}{'/completed' if s_is_completed else ''}/{s_file}.{from_language.value}" src_path = (
source_path: str = ( SRC_SPACE_DIR
f"{SRC_SPACE_DIR}/src-{from_language.value}/src/main.{from_language.value}" / f"src-{from_language.value}"
) / "src"
/ f"main.{from_language.value}"
)
os.makedirs(os.path.dirname(dest_path), exist_ok=True) with open(src_path, "rb") as f_src:
content = f_src.read()
with open(source_path, "rb") as f_src, open(dest_path, "wb") as f_dst: StorageManager().save_file(
f_dst.write(f_src.read()) s_loc, from_language, s_file, content, s_is_completed
)
click.secho(
f"Exported '{s_file}.{from_language.value}' to location '{s_loc}'",
fg="cyan",
bold=True,
)
click.echo(f"File {s_file}.{from_language.value} successfully ") if all_:
for l in Language.languages():
if not copy: if StateManager().check_space(l):
with open("state.yml", "w", encoding="utf-8") as f: _export_sub_command(l)
state["space"][from_language.value] = {} else:
yaml.safe_dump(state, f) froms = map(lambda x: Language.convert_name(x), from_)
for l in froms:
os.remove(source_path) if not StateManager().check_space(l):
click.secho(
f"No loaded file for language '{l.value}' in space. Skipping export for this language.",
fg="yellow",
)
continue
_export_sub_command(l)
@click.command(name="state") @click.command(name="state")