forked from osl-incubator/scicookie
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcli.py
110 lines (85 loc) · 3.06 KB
/
cli.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
"""Module with CLI functions."""
import json
import os
import sys
from pathlib import Path
from typing import Union
import sh
from scicookie.logs import SciCookieErrorType, SciCookieLogs
from scicookie.profile import Profile
from scicookie.ui import make_questions
PACKAGE_PATH = Path(__file__).parent
COOKIECUTTER_FILE_PATH = PACKAGE_PATH / "cookiecutter.json"
def _get_cookiecutter_default_answer(
answer_definition: Union[str, list]
) -> str:
if not isinstance(answer_definition, (str, list)):
SciCookieLogs.raise_error(
"Invalid cookiecutter configuration.",
SciCookieErrorType.SCICOOKIE_INVALID_CONFIGURATION,
)
if isinstance(answer_definition, str):
return answer_definition
return answer_definition[0]
def call_cookiecutter(profile: Profile, answers: dict):
"""Call coociecutter/cookieninja with the parameters from the TUI."""
answers_profile = {}
cookie_args = []
questions = profile.config
with open(COOKIECUTTER_FILE_PATH) as f:
coockiecutter_config = json.load(f)
# fill the answers with default value
for question_id, question in questions.items():
if not question.get("enabled", False) or question.get("control_flow"):
continue
if question.get("type") == "multiple-choices":
for choice in question.get("choices", {}):
choice_id = f"use_{choice.replace('-', '_')}"
answers_profile[choice_id] = "no"
continue
answers_profile[question_id] = question.get(
"default"
) or _get_cookiecutter_default_answer(
coockiecutter_config[question_id]
)
for question_id, answer in answers.items():
if answer in [None, ""] or questions[question_id].get("control_flow"):
continue
if questions[question_id].get("type") != "multiple-choices":
answers_profile[question_id] = answer
continue
for choice in answer:
choice_id = f"use_{choice.replace('-', '_')}"
answers_profile[choice_id] = "yes"
for question_id, answer in answers_profile.items():
cookie_args.append(f"{question_id}={answer}")
sh_extras = {
"_in": sys.stdin,
"_out": sys.stdout,
"_err": sys.stderr,
"_no_err": True,
"_env": os.environ,
"_bg": True,
"_bg_exc": False,
}
p = sh.cookieninja("--no-input", PACKAGE_PATH, *cookie_args, **sh_extras)
try:
p.wait()
except sh.ErrorReturnCode as e:
SciCookieLogs.raise_error(
str(e), SciCookieErrorType.SH_ERROR_RETURN_CODE
)
except KeyboardInterrupt:
pid = p.pid
p.kill()
SciCookieLogs.raise_error(
f"Process {pid} killed.", SciCookieErrorType.SH_KEYBOARD_INTERRUPT
)
def app():
"""Run SciCookie."""
# note: this parameter should be provided by a CLI argument
profile = Profile("osl")
answers = make_questions(profile.config)
if not answers:
return
call_cookiecutter(profile, answers)