JOJ3-config-generator/joj3_config_generator/models/task.py
张泊明518370910136 4b3668d772
All checks were successful
build / build (pull_request) Successful in 2m33s
build / build (push) Successful in 2m36s
chore: remove joj1 part
2025-03-02 14:41:17 -05:00

135 lines
3.5 KiB
Python

from datetime import datetime, timedelta
from pathlib import Path
from typing import Any, Dict, List, Type
from pydantic import BaseModel, Field, field_validator, model_validator
from joj3_config_generator.models.common import Memory, Time
from joj3_config_generator.models.const import (
DEFAULT_CPU_LIMIT,
DEFAULT_FILE_LIMIT,
DEFAULT_MEMORY_LIMIT,
)
class ParserResultDetail(BaseModel):
time: bool = True # Display run time
mem: bool = True # Display memory usage
stdout: bool = False # Display stdout messages
stderr: bool = False # Display stderr messages
exitstatus: bool = False
class ParserFile(BaseModel):
name: str = ""
class ParserLog(BaseModel):
filename: str
msg: str = ""
level: str = ""
class ParserDummy(BaseModel):
comment: str = ""
score: int = 0
forcequit: bool = False
class ParserKeyword(BaseModel):
keyword: List[str] = []
weight: List[int] = []
class Outputs(BaseModel):
score: int = 0
ignorespaces: bool = True
hide: bool = False
forcequit: bool = False
class ParserDiff(BaseModel):
output: Outputs = Outputs()
class Files(BaseModel):
import_: List[str] = Field([], alias="import")
export: List[str] = []
class Limit(BaseModel):
mem: int = DEFAULT_MEMORY_LIMIT
cpu: int = DEFAULT_CPU_LIMIT
stderr: int = DEFAULT_FILE_LIMIT
stdout: int = DEFAULT_FILE_LIMIT
@field_validator("cpu", mode="before")
@classmethod
def ensure_time(cls, v: Any) -> Time:
return Time(v)
@field_validator("mem", "stdout", "stderr", mode="before")
@classmethod
def ensure_mem(cls, v: Any) -> Memory:
return Memory(v)
class Stage(BaseModel):
name: str = "" # Stage name
env: List[str] = []
command: str = "" # Command to run
files: Files = Files()
in_: str = Field("", alias="in")
out_: str = Field("", alias="out")
score: int = 0
parsers: List[str] = [] # list of parsers
limit: Limit = Limit()
dummy: ParserDummy = ParserDummy()
result_status: ParserDummy = Field(ParserDummy(), alias="result-status")
keyword: ParserKeyword = ParserKeyword()
clangtidy: ParserKeyword = ParserKeyword()
cppcheck: ParserKeyword = ParserKeyword()
cpplint: ParserKeyword = ParserKeyword()
result_detail: ParserResultDetail = Field(
ParserResultDetail(), alias="result-detail"
)
file: ParserFile = ParserFile()
skip: List[str] = []
# cases related
cases: Dict[str, "Stage"] = {}
diff: 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: datetime = datetime.now() + timedelta(
days=365
) # RFC 3339 formatted date-time with offset
begin_time: datetime = datetime.fromtimestamp(
0
) # RFC 3339 formatted date-time with offset
class Task(BaseModel):
type_: str = Field("unknown", serialization_alias="type", validation_alias="type")
name: str = "unknown"
class Config(BaseModel):
root: Path = Path(".")
path: Path = Path("task.toml")
task: Task = Task() # Task name (e.g., hw3 ex5)
release: Release = Release() # Release configuration
stages: List[Stage] = [] # list of stage configurations