Compare commits

..

No commits in common. "7c764ab2cb507d181f81f16096cc88082a6e9fde" and "26824fd93cbf0c2834a6bc524b4e8f5b8e6f19e8" have entirely different histories.

5 changed files with 42 additions and 51 deletions

View File

@ -27,7 +27,7 @@ def convert_joj1_conf(joj1_conf: joj1.Config) -> task.Config:
def convert_joj3_conf(repo_conf: repo.Config, task_conf: task.Config) -> result.Config: def convert_joj3_conf(repo_conf: repo.Config, task_conf: task.Config) -> result.Config:
# Create the base ResultConf object # Create the base ResultConf object
result_conf = result.Config( result_conf = result.Config(
name=task_conf.name, name=task_conf.task.name,
# exact folder difference specified by type # exact folder difference specified by type
log_path=str(JOJ3_LOG_BASE_PATH / task_conf.suffix / JOJ3_LOG_FILENAME), log_path=str(JOJ3_LOG_BASE_PATH / task_conf.suffix / JOJ3_LOG_FILENAME),
# TODO: remove these 2 fields, will be handled in the health check stage # TODO: remove these 2 fields, will be handled in the health check stage

View File

@ -7,7 +7,6 @@ from pydantic import AliasChoices, BaseModel, Field, model_validator
class Files(BaseModel): class Files(BaseModel):
required: List[str] = [] required: List[str] = []
# TODO: remove immutable in the future
immutable: List[str] = [] immutable: List[str] = []
@ -35,24 +34,6 @@ class Issue(BaseModel):
class Config(BaseModel): class Config(BaseModel):
root: Path = Field(Path("."), exclude=True)
path: Path = Field(Path("repo.toml"), exclude=True)
force_skip_health_check_on_test: bool = Field(
False,
validation_alias=AliasChoices(
"force-skip-health-check-on-test", "force_skip_health_check_on_test"
),
exclude=True,
)
force_skip_teapot_on_test: bool = Field(
False,
validation_alias=AliasChoices(
"force-skip-teapot-on-test", "force_skip_teapot_on_test"
),
exclude=True,
)
max_size: float = Field( max_size: float = Field(
10, ge=0, validation_alias=AliasChoices("max-size", "max_size") 10, ge=0, validation_alias=AliasChoices("max-size", "max_size")
) )
@ -60,10 +41,32 @@ class Config(BaseModel):
sandbox_token: str = Field( sandbox_token: str = Field(
"", validation_alias=AliasChoices("sandbox-token", "sandbox_token") "", validation_alias=AliasChoices("sandbox-token", "sandbox_token")
) )
gitea_token: str = Field(
"", validation_alias=AliasChoices("gitea-token", "gitea_token")
)
gitea_org: str = Field("", validation_alias=AliasChoices("gitea-org", "gitea_org"))
max_total_score: int = Field( max_total_score: int = Field(
100, validation_alias=AliasChoices("max-total-score", "max_total_score") 100, validation_alias=AliasChoices("max-total-score", "max_total_score")
) )
force_skip_health_check_on_test: bool = Field(
False,
validation_alias=AliasChoices(
"force-skip-health-check-on-test", "force_skip_health_check_on_test"
),
)
force_skip_teapot_on_test: bool = Field(
False,
validation_alias=AliasChoices(
"force-skip-teapot-on-test", "force_skip_teapot_on_test"
),
)
groups: Groups = Groups() groups: Groups = Groups()
root: Path = Path(".")
path: Path = Path("repo.toml")
grading_repo_name: str = Field(
"",
validation_alias=AliasChoices("grading-repo-name", "grading_repo_name"),
)
health_check_score: int = Field( health_check_score: int = Field(
0, validation_alias=AliasChoices("health-check-score", "health_check_score") 0, validation_alias=AliasChoices("health-check-score", "health_check_score")
) )
@ -72,15 +75,6 @@ class Config(BaseModel):
Path("immutable"), Path("immutable"),
validation_alias=AliasChoices("immutable-path", "immutable_path"), validation_alias=AliasChoices("immutable-path", "immutable_path"),
) )
grading_repo_name: str = Field(
"",
validation_alias=AliasChoices("grading-repo-name", "grading_repo_name"),
)
# TODO: remove gitea_token and gitea_org in the future
gitea_token: str = Field(
"", validation_alias=AliasChoices("gitea-token", "gitea_token")
)
gitea_org: str = Field("", validation_alias=AliasChoices("gitea-org", "gitea_org"))
@model_validator(mode="after") @model_validator(mode="after")
def set_grading_repo_name_from_cwd(self) -> "Config": def set_grading_repo_name_from_cwd(self) -> "Config":

View File

@ -198,6 +198,7 @@ class Case(BaseModel):
class Stage(Case): class Stage(Case):
name: str = "" # stage name name: str = "" # stage name
skip: List[str] = []
parsers: List[Parser] = [] # list of parsers parsers: List[Parser] = [] # list of parsers
dummy: ParserDummy = ParserDummy() dummy: ParserDummy = ParserDummy()
@ -262,33 +263,25 @@ class Penalties(BaseModel):
class Config(BaseModel): class Config(BaseModel):
root: Path = Field(Path("."), exclude=True) root: Path = Path(".")
path: Path = Field(Path("task.toml"), exclude=True) path: Path = Path("task.toml")
suffix: str = Field("", exclude=True) task: Task = Task() # Task name (e.g., hw3 ex5)
time: SubmissionTime = SubmissionTime() # Valid time configuration
task: Task = Task() # TODO: remove it in the future release: Release = Release() # Release configuration
name: str = "unknown" # Task name (e.g., hw3 ex5) stages: List[Stage] = [] # list of stage configurations
groups: Groups = Groups()
penalties: Penalties = Penalties()
max_total_score: Optional[int] = Field( max_total_score: Optional[int] = Field(
None, validation_alias=AliasChoices("max-total-score", "max_total_score") None, validation_alias=AliasChoices("max-total-score", "max_total_score")
) )
scoreboard: str = "scoreboard.csv" scoreboard: str = "scoreboard.csv"
time: SubmissionTime = SubmissionTime() # Valid time configuration
release: Release = Release() # Release configuration
groups: Groups = Groups()
penalties: Penalties = Penalties()
stages: List[Stage] = [] # list of stage configurations
# TODO: remove this validator in the future suffix: str = Field("", exclude=True)
@model_validator(mode="after")
def set_name(self) -> "Config":
if "task" in self.model_fields_set and "name" in self.task.model_fields_set:
self.name = self.task.name
return self
@model_validator(mode="after") @model_validator(mode="after")
def set_suffix(self) -> "Config": def set_suffix(self) -> "Config":
if not self.suffix: if not self.suffix:
self.suffix = re.split(r"[-_/\s]+", self.name)[0] self.suffix = re.split(r"[-_/\s]+", self.task.name)[0]
return self return self
@model_validator(mode="after") @model_validator(mode="after")

View File

@ -9,16 +9,16 @@ def get_task_conf_from_answers(answers: answer.Answers) -> task.Config:
if answers.template_file_content: if answers.template_file_content:
toml_dict = tomli.loads(answers.template_file_content) toml_dict = tomli.loads(answers.template_file_content)
return task.Config( return task.Config(
name=answers.name, task=task.Task(name=answers.name),
stages=toml_dict["stages"], stages=toml_dict["stages"],
) )
language = answers.language language = answers.language
transformer_dict = get_transformer_dict() transformer_dict = get_transformer_dict()
if language not in transformer_dict: if language not in transformer_dict:
return task.Config(name=answers.name, stages=[]) return task.Config(task=task.Task(name=answers.name), stages=[])
transformer = transformer_dict[language] transformer = transformer_dict[language]
stages = transformer(language) stages = transformer(language)
return task.Config(name=answers.name, stages=stages) return task.Config(task=task.Task(name=answers.name), stages=stages)
def get_transformer_dict() -> Dict[ def get_transformer_dict() -> Dict[

View File

@ -193,7 +193,11 @@ def fix_diff(
# cases not specified in the toml config (auto-detected) # cases not specified in the toml config (auto-detected)
unspecified_cases = get_unspecified_cases(task_root, task_path, task_stage.cases) unspecified_cases = get_unspecified_cases(task_root, task_path, task_stage.cases)
# cases specified in toml config but not skipped # cases specified in toml config but not skipped
specified_cases = [(case, task_stage.cases[case]) for case in task_stage.cases] specified_cases = [
(case, task_stage.cases[case])
for case in task_stage.cases
if case not in task_stage.skip
]
stage_cases = [] stage_cases = []
parser_cases = [] parser_cases = []
for case_name, case in specified_cases: for case_name, case in specified_cases: