feat: language specific create questions
	
		
			
	
		
	
	
		
	
		
			All checks were successful
		
		
	
	
		
			
				
	
				build / build (push) Successful in 1m48s
				
			
		
		
	
	
				
					
				
			
		
			All checks were successful
		
		
	
	build / build (push) Successful in 1m48s
				
			This commit is contained in:
		
							parent
							
								
									80ba2f1451
								
							
						
					
					
						commit
						df14ad801b
					
				|  | @ -9,17 +9,19 @@ from joj3_config_generator.models import answer, joj1, repo, task | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| def load_joj3_task_toml_answers() -> answer.Answers: | def load_joj3_task_toml_answers() -> answer.Answers: | ||||||
|     questions = [ |     name = inquirer.text("What's the task name?", default="hw0") | ||||||
|         inquirer.Text(name="name", message="What's the task name?"), |     language: answer.LanguageInterface = inquirer.list_input( | ||||||
|         inquirer.Checkbox( |         "What's the language?", choices=answer.LANGUAGES | ||||||
|             "stages", |     ) | ||||||
|             message="What kind of stages do you need?", |     stages = inquirer.checkbox( | ||||||
|             choices=[member.value for member in answer.StageEnum], |         "What's the stages?", | ||||||
|             default=[answer.StageEnum.COMPILATION], |         choices=[member.value for member in language.Stage], | ||||||
|         ), |         default=[member.value for member in language.Stage], | ||||||
|     ] |     ) | ||||||
|     answers = inquirer.prompt(questions) |     language.set_stages(stages) | ||||||
|     return answer.Answers(**answers) |     attribute = inquirer.prompt(language.get_attribute_questions()) | ||||||
|  |     language.set_attribute(attribute) | ||||||
|  |     return answer.Answers(name=name, language=language) | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| def load_joj1_yaml(yaml_path: Path) -> joj1.Config: | def load_joj1_yaml(yaml_path: Path) -> joj1.Config: | ||||||
|  |  | ||||||
|  | @ -30,8 +30,6 @@ def create( | ||||||
|     Create a new JOJ3 task toml config file |     Create a new JOJ3 task toml config file | ||||||
|     """ |     """ | ||||||
|     answers = load_joj3_task_toml_answers() |     answers = load_joj3_task_toml_answers() | ||||||
|     answers_dict = answers.model_dump(mode="json", by_alias=True) |  | ||||||
|     logger.debug(f"Got answers: {answers_dict}") |  | ||||||
|     task_model = create_joj3_task_conf(answers) |     task_model = create_joj3_task_conf(answers) | ||||||
|     result_dict = task_model.model_dump( |     result_dict = task_model.model_dump( | ||||||
|         mode="json", by_alias=True, exclude_none=True, exclude_unset=True |         mode="json", by_alias=True, exclude_none=True, exclude_unset=True | ||||||
|  |  | ||||||
|  | @ -1,16 +1,124 @@ | ||||||
|  | from abc import ABC, abstractmethod | ||||||
| from enum import Enum | from enum import Enum | ||||||
| from typing import List | from typing import Any, ClassVar, Dict, List | ||||||
| 
 | 
 | ||||||
| from pydantic import BaseModel | import inquirer | ||||||
|  | from pydantic import BaseModel, ConfigDict | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| class StageEnum(str, Enum): | class LanguageInterface(ABC): | ||||||
|  |     @abstractmethod | ||||||
|  |     def __str__(self) -> str: ... | ||||||
|  | 
 | ||||||
|  |     @abstractmethod | ||||||
|  |     class Stage(str, Enum): ... | ||||||
|  | 
 | ||||||
|  |     @abstractmethod | ||||||
|  |     class Attribute(BaseModel): ... | ||||||
|  | 
 | ||||||
|  |     stages: ClassVar[List[Enum]] | ||||||
|  |     attribute: ClassVar[BaseModel] | ||||||
|  | 
 | ||||||
|  |     @classmethod | ||||||
|  |     def set_stages(cls, stages: List[str]) -> None: | ||||||
|  |         cls.stages = [cls.Stage(stage) for stage in stages] | ||||||
|  | 
 | ||||||
|  |     @classmethod | ||||||
|  |     def set_attribute(cls, attribute_dict: Dict[str, Any]) -> None: | ||||||
|  |         cls.attribute = cls.Attribute(**attribute_dict) | ||||||
|  | 
 | ||||||
|  |     @classmethod | ||||||
|  |     @abstractmethod | ||||||
|  |     def get_attribute_questions(cls) -> List[Any]: ... | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | class Cpp(LanguageInterface): | ||||||
|  |     def __str__(self) -> str: | ||||||
|  |         return "C++" | ||||||
|  | 
 | ||||||
|  |     class Stage(str, Enum): | ||||||
|         COMPILATION = "Compilation" |         COMPILATION = "Compilation" | ||||||
|         CPPCHECK = "Cppcheck" |         CPPCHECK = "Cppcheck" | ||||||
|         CPPLINT = "Cpplint" |         CPPLINT = "Cpplint" | ||||||
|         CLANG_TIDY = "Clang-Tidy" |         CLANG_TIDY = "Clang-Tidy" | ||||||
|  |         RUN = "Run" | ||||||
|  | 
 | ||||||
|  |     class Attribute(BaseModel): | ||||||
|  |         compile_command: str = "make" | ||||||
|  |         run_command: str = "./a.out" | ||||||
|  | 
 | ||||||
|  |     stages = [] | ||||||
|  |     attribute = Attribute() | ||||||
|  | 
 | ||||||
|  |     @classmethod | ||||||
|  |     def get_attribute_questions(cls) -> List[Any]: | ||||||
|  |         return [ | ||||||
|  |             inquirer.Text( | ||||||
|  |                 name="compile_command", | ||||||
|  |                 message="Compile command", | ||||||
|  |                 default=cls.attribute.compile_command, | ||||||
|  |             ), | ||||||
|  |             inquirer.Text( | ||||||
|  |                 name="run_command", | ||||||
|  |                 message="Run command", | ||||||
|  |                 default=cls.attribute.run_command, | ||||||
|  |             ), | ||||||
|  |         ] | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | class Python(LanguageInterface): | ||||||
|  |     def __str__(self) -> str: | ||||||
|  |         return "Python" | ||||||
|  | 
 | ||||||
|  |     class Stage(str, Enum): | ||||||
|  |         RUN = "Run" | ||||||
|  | 
 | ||||||
|  |     class Attribute(BaseModel): | ||||||
|  |         run_command: str = "python3 main.py" | ||||||
|  | 
 | ||||||
|  |     stages = [] | ||||||
|  |     attribute = Attribute() | ||||||
|  | 
 | ||||||
|  |     @classmethod | ||||||
|  |     def get_attribute_questions(cls) -> List[Any]: | ||||||
|  |         return [ | ||||||
|  |             inquirer.Text( | ||||||
|  |                 name="run_command", | ||||||
|  |                 message="Run command", | ||||||
|  |                 default=cls.attribute.run_command, | ||||||
|  |             ), | ||||||
|  |         ] | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | class Rust(LanguageInterface): | ||||||
|  |     def __str__(self) -> str: | ||||||
|  |         return "Rust" | ||||||
|  | 
 | ||||||
|  |     class Stage(str, Enum): | ||||||
|  |         COMPILATION = "Compilation" | ||||||
|  |         CLIPPY = "Clippy" | ||||||
|  |         RUN = "Run" | ||||||
|  | 
 | ||||||
|  |     class Attribute(BaseModel): | ||||||
|  |         pass | ||||||
|  | 
 | ||||||
|  |     stages = [] | ||||||
|  |     attribute = Attribute() | ||||||
|  | 
 | ||||||
|  |     @classmethod | ||||||
|  |     def get_attribute_questions(cls) -> List[Any]: | ||||||
|  |         return [] | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | LANGUAGES = [ | ||||||
|  |     Cpp(), | ||||||
|  |     Python(), | ||||||
|  |     Rust(), | ||||||
|  | ] | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| class Answers(BaseModel): | class Answers(BaseModel): | ||||||
|     name: str |     name: str | ||||||
|     stages: List[str] |     language: LanguageInterface | ||||||
|  | 
 | ||||||
|  |     model_config = ConfigDict(arbitrary_types_allowed=True) | ||||||
|  |  | ||||||
|  | @ -1,6 +1,52 @@ | ||||||
|  | from typing import Any, Callable, Dict, List, Type | ||||||
|  | 
 | ||||||
| from joj3_config_generator.models import answer, task | from joj3_config_generator.models import answer, task | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| # TODO: implement |  | ||||||
| def get_task_conf_from_answers(answers: answer.Answers) -> task.Config: | def get_task_conf_from_answers(answers: answer.Answers) -> task.Config: | ||||||
|     return task.Config(task=task.Task(name=answers.name)) |     language = answers.language | ||||||
|  |     transformer_dict = get_transformer_dict() | ||||||
|  |     transformer = transformer_dict[type(language)] | ||||||
|  |     stages = transformer(language) | ||||||
|  |     return task.Config(task=task.Task(name=answers.name), stages=stages) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def get_transformer_dict() -> Dict[ | ||||||
|  |     Type[Any], | ||||||
|  |     Callable[[Any], List[task.Stage]], | ||||||
|  | ]: | ||||||
|  |     return { | ||||||
|  |         answer.Cpp: get_cpp_stages, | ||||||
|  |         answer.Python: get_python_stages, | ||||||
|  |         answer.Rust: get_rust_stages, | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | # TODO: implement | ||||||
|  | def get_cpp_stages(language: answer.Cpp) -> List[task.Stage]: | ||||||
|  |     stages = language.stages | ||||||
|  |     attribute: answer.Cpp.Attribute = language.attribute | ||||||
|  |     task_stages = [] | ||||||
|  |     if answer.Cpp.Stage.CPPCHECK in stages: | ||||||
|  |         task_stages.append(task.Stage(name=answer.Cpp.Stage.CPPCHECK)) | ||||||
|  |     if answer.Cpp.Stage.CPPLINT in stages: | ||||||
|  |         task_stages.append(task.Stage(name=answer.Cpp.Stage.CPPLINT)) | ||||||
|  |     if answer.Cpp.Stage.CLANG_TIDY in stages: | ||||||
|  |         task_stages.append(task.Stage(name=answer.Cpp.Stage.CLANG_TIDY)) | ||||||
|  |     if answer.Cpp.Stage.RUN in stages: | ||||||
|  |         task_stages.append(task.Stage(name=answer.Cpp.Stage.RUN)) | ||||||
|  |     return task_stages | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | # TODO: implement | ||||||
|  | def get_python_stages(language: answer.Python) -> List[task.Stage]: | ||||||
|  |     stages = language.stages | ||||||
|  |     attribute: answer.Python.Attribute = language.attribute | ||||||
|  |     return [] | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | # TODO: implement | ||||||
|  | def get_rust_stages(language: answer.Rust) -> List[task.Stage]: | ||||||
|  |     stages = language.stages | ||||||
|  |     attribute: answer.Rust.Attribute = language.attribute | ||||||
|  |     return [] | ||||||
|  |  | ||||||
|  | @ -1,4 +0,0 @@ | ||||||
| { |  | ||||||
|   "name": "hw7 ex2", |  | ||||||
|   "stages": ["Compilation"] |  | ||||||
| } |  | ||||||
|  | @ -1,2 +0,0 @@ | ||||||
| [task] |  | ||||||
| name = "hw7 ex2" |  | ||||||
							
								
								
									
										9
									
								
								tests/create/cpp/answers.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								tests/create/cpp/answers.json
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,9 @@ | ||||||
|  | { | ||||||
|  |   "name": "hw7 ex2", | ||||||
|  |   "language": "C++", | ||||||
|  |   "stages": ["Compilation", "Cppcheck", "Cpplint", "Clang-Tidy", "Run"], | ||||||
|  |   "attribute": { | ||||||
|  |     "compile_command": "make", | ||||||
|  |     "run_command": "./ex2" | ||||||
|  |   } | ||||||
|  | } | ||||||
							
								
								
									
										18
									
								
								tests/create/cpp/task.toml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								tests/create/cpp/task.toml
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,18 @@ | ||||||
|  | [task] | ||||||
|  | name = "hw7 ex2" | ||||||
|  | 
 | ||||||
|  | [[stages]] | ||||||
|  | name = "Cppcheck" | ||||||
|  | cases = {} | ||||||
|  | 
 | ||||||
|  | [[stages]] | ||||||
|  | name = "Cpplint" | ||||||
|  | cases = {} | ||||||
|  | 
 | ||||||
|  | [[stages]] | ||||||
|  | name = "Clang-Tidy" | ||||||
|  | cases = {} | ||||||
|  | 
 | ||||||
|  | [[stages]] | ||||||
|  | name = "Run" | ||||||
|  | cases = {} | ||||||
|  | @ -1,5 +1,5 @@ | ||||||
| from tests.create.utils import load_case | from tests.create.utils import load_case | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| def test_basic() -> None: | def test_cpp() -> None: | ||||||
|     load_case("basic") |     load_case("cpp") | ||||||
|  |  | ||||||
|  | @ -11,8 +11,11 @@ def load_case(case_name: str) -> None: | ||||||
|     root = Path(__file__).resolve().parent |     root = Path(__file__).resolve().parent | ||||||
|     answers_json_path = root / case_name / "answers.json" |     answers_json_path = root / case_name / "answers.json" | ||||||
|     task_toml_path = root / case_name / "task.toml" |     task_toml_path = root / case_name / "task.toml" | ||||||
|     answers = answer.Answers(**json.loads(answers_json_path.read_text())) |     answers_dict = json.loads(answers_json_path.read_text()) | ||||||
|     print(answers) |     language = next(x for x in answer.LANGUAGES if str(x) == answers_dict["language"]) | ||||||
|  |     language.set_stages(answers_dict["stages"]) | ||||||
|  |     language.set_attribute(answers_dict["attribute"]) | ||||||
|  |     answers = answer.Answers(name=answers_dict["name"], language=language) | ||||||
|     expected_result = rtoml.loads(task_toml_path.read_text()) |     expected_result = rtoml.loads(task_toml_path.read_text()) | ||||||
|     result = create_joj3_task_conf(answers).model_dump( |     result = create_joj3_task_conf(answers).model_dump( | ||||||
|         mode="json", by_alias=True, exclude_none=True, exclude_unset=True |         mode="json", by_alias=True, exclude_none=True, exclude_unset=True | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue
	
	Block a user