refactoring stage 5
- fix export command
This commit is contained in:
144
run.py
144
run.py
@@ -207,6 +207,17 @@ class Language(Enum):
|
||||
case _:
|
||||
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]:
|
||||
splited = target.split("/")
|
||||
@@ -341,7 +352,12 @@ class StorageManager:
|
||||
return None
|
||||
|
||||
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:
|
||||
path = STORAGE_DIR / location / lang.value / ("completed" if completed else "")
|
||||
os.makedirs(path, exist_ok=True)
|
||||
@@ -392,6 +408,18 @@ class StorageManager:
|
||||
if os.path.isfile(completed_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
|
||||
@@ -482,7 +510,7 @@ def create(target: str, completed: bool, template: bool, force: bool):
|
||||
@click.argument("lang", type=str, nargs=1, required=True)
|
||||
@click.option("--testcase", "-t", default=["1"], multiple=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)
|
||||
|
||||
# build
|
||||
@@ -608,73 +637,72 @@ def load(target: str, force: bool):
|
||||
|
||||
|
||||
@click.command(name="export")
|
||||
@click.option("--from", "from_", type=str, required=True)
|
||||
@click.argument("from", "from_", type=str, nargs=-1)
|
||||
@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")
|
||||
def export(from_: str, completed: bool, copy: bool):
|
||||
# Language 알기
|
||||
from_language = Language.convert_name(from_)
|
||||
@click.option(
|
||||
"--force",
|
||||
"-f",
|
||||
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:
|
||||
raise click.ClickException("Undefined Language Exception")
|
||||
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)
|
||||
def _export_sub_command(from_language: Language):
|
||||
space = StateManager().get_space(from_language)
|
||||
|
||||
if "space" not in state:
|
||||
raise click.ClickException("State(state.yml) Exception")
|
||||
elif not state["space"]:
|
||||
click.secho("state.space has no member", fg="yellow", bold=True)
|
||||
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"
|
||||
s_file, s_loc, s_is_completed = (
|
||||
space["file"],
|
||||
space["location"],
|
||||
space["is_completed"],
|
||||
)
|
||||
|
||||
if not s_loc:
|
||||
raise click.ClickException(f"Export Exception: Location {s_loc} is not defined")
|
||||
path = StorageManager.construct_target_path(
|
||||
s_loc, from_language, s_file, s_is_completed
|
||||
)
|
||||
|
||||
if completed:
|
||||
s_is_completed = True
|
||||
if path.is_file() and not force:
|
||||
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}"
|
||||
source_path: str = (
|
||||
f"{SRC_SPACE_DIR}/src-{from_language.value}/src/main.{from_language.value}"
|
||||
)
|
||||
src_path = (
|
||||
SRC_SPACE_DIR
|
||||
/ 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:
|
||||
f_dst.write(f_src.read())
|
||||
StorageManager().save_file(
|
||||
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 not copy:
|
||||
with open("state.yml", "w", encoding="utf-8") as f:
|
||||
state["space"][from_language.value] = {}
|
||||
yaml.safe_dump(state, f)
|
||||
|
||||
os.remove(source_path)
|
||||
if all_:
|
||||
for l in Language.languages():
|
||||
if StateManager().check_space(l):
|
||||
_export_sub_command(l)
|
||||
else:
|
||||
froms = map(lambda x: Language.convert_name(x), from_)
|
||||
for l in froms:
|
||||
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")
|
||||
|
||||
Reference in New Issue
Block a user