Skip to content

Commit 41876d9

Browse files
committed
マージ
1 parent abe4faa commit 41876d9

File tree

3 files changed

+126
-37
lines changed

3 files changed

+126
-37
lines changed

atcodertools/codegen/code_style_config.py

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ class CodeStyleConfigInitError(Exception):
1414

1515

1616
DEFAULT_WORKSPACE_DIR_PATH = os.path.join(expanduser("~"), "atcoder-workspace")
17+
DEFAULT_LANGUAGE = "cpp"
1718

1819

1920
class CodeStyleConfig:
@@ -24,8 +25,7 @@ def __init__(self,
2425
code_generator_file: Optional[str] = None,
2526
template_file: Optional[str] = None,
2627
workspace_dir: Optional[str] = None,
27-
compile_command: Optional[str] = None,
28-
lang: str = "cpp",
28+
lang: str = DEFAULT_LANGUAGE,
2929
):
3030
from atcodertools.common.language import Language, LanguageNotFoundError, ALL_LANGUAGE_NAMES
3131

@@ -56,9 +56,6 @@ def __init__(self,
5656
template_file)
5757
)
5858

59-
if compile_command is not None:
60-
lang.compile_command = compile_command
61-
6259
self.indent_type = indent_type
6360

6461
if indent_width is not None:

atcodertools/config/config.py

Lines changed: 113 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,62 @@
1-
from argparse import Namespace
21
from typing import TextIO, Dict, Any, Optional
32

43
import os
54
import argparse
65
from os.path import expanduser
76
import toml
7+
from colorama import Fore
8+
9+
from atcodertools.common.language import Language
810
from atcodertools.common.logging import logger
911

10-
from atcodertools.codegen.code_style_config import CodeStyleConfig
12+
from atcodertools.codegen.code_style_config import CodeStyleConfig, DEFAULT_LANGUAGE
1113
from atcodertools.config.etc_config import EtcConfig
1214
from atcodertools.config.postprocess_config import PostprocessConfig
15+
from atcodertools.config.run_config import RunConfig
1316
from atcodertools.tools import get_default_config_path
17+
from atcodertools.tools.utils import with_color
18+
19+
_POST_PROCESS_CONFIG_KEY = "postprocess"
20+
21+
_CODE_STYLE_CONFIG_KEY = "codestyle"
22+
23+
_RUN_CONFIG_KEY = "run"
24+
25+
26+
class ProgramArgs:
27+
def __init__(
28+
self,
29+
template: Optional[str] = None,
30+
workspace: Optional[str] = None,
31+
without_login: Optional[bool] = None,
32+
parallel: Optional[bool] = None,
33+
save_no_session_cache: Optional[bool] = None,
34+
lang: Optional[str] = None,
35+
compile_before_testing: Optional[bool] = None,
36+
compile_only_when_diff_detected: Optional[bool] = None
37+
):
38+
self.template = template
39+
self.workspace = workspace
40+
self.without_login = without_login
41+
self.parallel = parallel
42+
self.save_no_session_cache = save_no_session_cache
43+
self.lang = lang
44+
self.compile_before_testing = compile_before_testing
45+
self.compile_only_when_diff_detected = compile_only_when_diff_detected
46+
47+
@classmethod
48+
def load(cls, program_args: argparse.Namespace):
49+
return ProgramArgs(
50+
**{k: v for k, v in program_args.__dict__.items() if k in (
51+
"template",
52+
"workspace",
53+
"without_login",
54+
"parallel",
55+
"save_no_session_cache",
56+
"lang",
57+
"compile_before_testing",
58+
"compile_only_when_diff_detected"
59+
)})
1460

1561

1662
def _update_config_dict(target_dic: Dict[str, Any], update_dic: Dict[str, Any]):
@@ -25,66 +71,101 @@ class Config:
2571
def __init__(self,
2672
code_style_config: CodeStyleConfig = CodeStyleConfig(),
2773
postprocess_config: PostprocessConfig = PostprocessConfig(),
28-
etc_config: EtcConfig = EtcConfig()
74+
etc_config: EtcConfig = EtcConfig(),
75+
run_config: RunConfig = RunConfig()
2976
):
3077
self.code_style_config = code_style_config
3178
self.postprocess_config = postprocess_config
3279
self.etc_config = etc_config
80+
self.run_config = run_config
3381

3482
@classmethod
35-
def load(cls, fp: TextIO, args: Optional[Namespace] = None):
83+
def load(cls, fp: TextIO, args: Optional[ProgramArgs] = None):
3684
"""
3785
:param fp: .toml file's file pointer
3886
:param args: command line arguments
3987
:return: Config instance
4088
"""
4189
config_dic = toml.load(fp)
90+
# Root 'codestyle' is common code style
91+
common_code_style_config_dic = config_dic.get(
92+
_CODE_STYLE_CONFIG_KEY, {})
4293

43-
code_style_config_dic = config_dic.get('codestyle', {})
44-
postprocess_config_dic = config_dic.get('postprocess', {})
94+
postprocess_config_dic = config_dic.get(_POST_PROCESS_CONFIG_KEY, {})
4595
etc_config_dic = config_dic.get('etc', {})
96+
run_config_dic = config_dic.get(_RUN_CONFIG_KEY, {})
97+
code_style_config_dic = {**common_code_style_config_dic}
98+
99+
# Handle config override strategy in the following code
100+
# (Most preferred) program arguments > lang-specific > common config (Least preferred)
101+
lang = (args and args.lang) or common_code_style_config_dic.get(
102+
"lang", DEFAULT_LANGUAGE)
103+
code_style_config_dic = _update_config_dict(
104+
code_style_config_dic, dict(lang=lang))
105+
106+
if lang in config_dic:
107+
lang_specific_config_dic = config_dic[lang] # e.g. [cpp.codestyle]
108+
if _CODE_STYLE_CONFIG_KEY in lang_specific_config_dic:
109+
lang_code_style = lang_specific_config_dic[_CODE_STYLE_CONFIG_KEY]
110+
if "lang" in lang_code_style:
111+
logger.warn(
112+
with_color("'lang' is only valid in common code style config, "
113+
"but detected in language-specific code style config. It will be ignored.",
114+
Fore.RED))
115+
del lang_code_style["lang"]
116+
117+
code_style_config_dic = _update_config_dict(code_style_config_dic,
118+
lang_code_style)
119+
120+
# e.g. [cpp.postprocess]
121+
if _POST_PROCESS_CONFIG_KEY in lang_specific_config_dic:
122+
postprocess_config_dic = _update_config_dict(postprocess_config_dic,
123+
lang_specific_config_dic[_POST_PROCESS_CONFIG_KEY])
124+
125+
if _RUN_CONFIG_KEY in lang_specific_config_dic: # e.g. [cpp.run]
126+
run_config_dic = _update_config_dict(run_config_dic,
127+
lang_specific_config_dic[_RUN_CONFIG_KEY])
46128

47129
if args:
48-
d = dict()
49-
if hasattr(args, 'template'):
50-
d['template_file'] = args.template
51-
if hasattr(args, 'workspace'):
52-
d['workspace_dir'] = args.workspace
53-
if hasattr(args, 'lang'):
54-
d['lang'] = args.lang
55130
code_style_config_dic = _update_config_dict(
56-
code_style_config_dic, d)
57-
58-
lang = code_style_config_dic['lang']
59-
if lang in config_dic:
60-
code_style_config_dic = _update_config_dict(
61-
code_style_config_dic, config_dic[lang])
62-
63-
d = dict()
64-
if hasattr(args, 'without_login'):
65-
d['download_without_login'] = args.without_login
66-
if hasattr(args, 'parallel'):
67-
d['parallel_download'] = args.parallel
68-
if hasattr(args, 'save_no_session_cache'):
69-
d['save_no_session_cache'] = args.save_no_session_cache
70-
71-
etc_config_dic = _update_config_dict(etc_config_dic, d)
131+
code_style_config_dic,
132+
dict(template_file=args.template,
133+
workspace_dir=args.workspace)
134+
)
135+
etc_config_dic = _update_config_dict(
136+
etc_config_dic,
137+
dict(
138+
download_without_login=args.without_login,
139+
parallel_download=args.parallel,
140+
save_no_session_cache=args.save_no_session_cache,
141+
compile_before_testing=args.compile_before_testing,
142+
compile_only_when_diff_detected=args.compile_only_when_diff_detected
143+
)
144+
)
145+
72146
return Config(
73147
code_style_config=CodeStyleConfig(**code_style_config_dic),
74148
postprocess_config=PostprocessConfig(**postprocess_config_dic),
75-
etc_config=EtcConfig(**etc_config_dic)
149+
etc_config=EtcConfig(**etc_config_dic),
150+
run_config=RunConfig(**run_config_dic)
76151
)
77152

78153

79154
USER_CONFIG_PATH = os.path.join(
80155
expanduser("~"), ".atcodertools.toml")
81156

82157

83-
def get_config(args: argparse.Namespace) -> Config:
158+
def get_config(args: argparse.Namespace, language: Language = None) -> Config:
84159
def _load(path: str) -> Config:
85160
logger.info("Going to load {} as config".format(path))
86161
with open(path, 'r') as f:
87-
return Config.load(f, args)
162+
program_args = ProgramArgs.load(args)
163+
164+
if language is not None:
165+
assert program_args.lang is None
166+
program_args.lang = language.name
167+
168+
return Config.load(f, program_args)
88169

89170
if args.config:
90171
return _load(args.config)

atcodertools/config/run_config.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
from typing import Optional
2+
3+
4+
class RunConfig:
5+
6+
def __init__(self,
7+
compile_command: Optional[str] = None,
8+
run_command: Optional[str] = None
9+
):
10+
self.compile_command = compile_command
11+
self.run_command = run_command

0 commit comments

Comments
 (0)