JOJ3-config-generator/joj3_config_generator/models/task.py
李衍志523370910113 45765e29e0
All checks were successful
build / build (push) Successful in 2m35s
build / build (pull_request) Successful in 2m33s
fix: unit of time
2025-03-02 11:47:31 +08:00

117 lines
3.4 KiB
Python

from datetime import datetime
from pathlib import Path
from typing import Any, Dict, List, Optional, Type
import humanfriendly
from pydantic import BaseModel, Field, model_validator
class ParserResultDetail(BaseModel):
time: Optional[bool] = True # Display run time
mem: Optional[bool] = True # Display memory usage
stdout: Optional[bool] = False # Display stdout messages
stderr: Optional[bool] = False # Display stderr messages
exitstatus: Optional[bool] = False
class ParserFile(BaseModel):
name: Optional[str] = None
class ParserLog(BaseModel):
fileName: Optional[str] = None
msg: Optional[str] = None
level: Optional[str] = None
class ParserDummy(BaseModel):
comment: Optional[str] = ""
score: Optional[int] = 0
forcequit: Optional[bool] = False
class ParserKeyword(BaseModel):
keyword: Optional[list[str]] = []
weight: Optional[list[int]] = []
class Outputs(BaseModel):
score: Optional[int] = 0
ignorespaces: Optional[bool] = True
hide: Optional[bool] = False
forcequit: Optional[bool] = False
class ParserDiff(BaseModel):
output: Optional[Outputs] = Outputs()
class Files(BaseModel):
import_: Optional[list[str]] = Field([], alias="import")
export: Optional[list[str]] = []
class Limit(BaseModel):
mem: int = humanfriendly.parse_size("128M")
cpu: int = 1_000_000_000
stderr: int = humanfriendly.parse_size("128M")
stdout: int = humanfriendly.parse_size("128M")
class Stage(BaseModel):
name: Optional[str] = None # Stage name
env: Optional[list[str]] = None
command: Optional[str] = None # Command to run
files: Optional[Files] = None
in_: Optional[str] = Field(None, alias="in")
out_: Optional[str] = Field(None, alias="out")
score: Optional[int] = 0
parsers: Optional[list[str]] = [] # list of parsers
limit: Optional[Limit] = Limit()
dummy: Optional[ParserDummy] = ParserDummy()
result_status: Optional[ParserDummy] = Field(ParserDummy(), alias="result-status")
keyword: Optional[ParserKeyword] = ParserKeyword()
clangtidy: Optional[ParserKeyword] = ParserKeyword()
cppcheck: Optional[ParserKeyword] = ParserKeyword()
cpplint: Optional[ParserKeyword] = ParserKeyword()
result_detail: Optional[ParserResultDetail] = Field(
ParserResultDetail(), alias="result-detail"
)
file: Optional[ParserFile] = ParserFile()
skip: Optional[list[str]] = []
# cases related
cases: Optional[Dict[str, "Stage"]] = None
diff: Optional[ParserDiff] = ParserDiff()
model_config = {"extra": "allow"}
@model_validator(mode="before")
@classmethod
def gather_cases(cls: Type["Stage"], values: Dict[str, Any]) -> Dict[str, Any]:
cases = {k: v for k, v in values.items() if k.startswith("case")}
for key in cases:
values.pop(key)
values["cases"] = {k: v for k, v in cases.items()}
return values
class Release(BaseModel):
end_time: Optional[datetime] = None # RFC 3339 formatted date-time with offset
begin_time: Optional[datetime] = None
class Task(BaseModel):
type_: Optional[str] = Field(
"", serialization_alias="type", validation_alias="type"
)
name: str
class Config(BaseModel):
root: Optional[Path] = None
path: Optional[Path] = None
task: Task # Task name (e.g., hw3 ex5)
release: Release # Release configuration
stages: List[Stage] # list of stage configurations