WIP: dev #4
| 
						 | 
				
			
			@ -1,5 +1,10 @@
 | 
			
		|||
from joj3_config_generator.lib.repo import getHealthcheckConfig, getTeapotConfig
 | 
			
		||||
from joj3_config_generator.lib.task import fix_comment, fix_keyword, fix_result_detail
 | 
			
		||||
from joj3_config_generator.lib.task import (
 | 
			
		||||
    fix_comment,
 | 
			
		||||
    fix_diff,
 | 
			
		||||
    fix_keyword,
 | 
			
		||||
    fix_result_detail,
 | 
			
		||||
)
 | 
			
		||||
from joj3_config_generator.models import (
 | 
			
		||||
    Cmd,
 | 
			
		||||
    CmdFile,
 | 
			
		||||
| 
						 | 
				
			
			@ -17,6 +22,7 @@ from joj3_config_generator.models import (
 | 
			
		|||
 | 
			
		||||
# FIXME: LLM generated convert function, only for demostration
 | 
			
		||||
def convert(repo_conf: Repo, task_conf: Task) -> ResultConfig:
 | 
			
		||||
    print(task_conf)
 | 
			
		||||
    # Create the base ResultConf object
 | 
			
		||||
    # FIXME: wrap things in functions
 | 
			
		||||
    result_conf = ResultConfig(
 | 
			
		||||
| 
						 | 
				
			
			@ -54,9 +60,12 @@ def convert(repo_conf: Repo, task_conf: Task) -> ResultConfig:
 | 
			
		|||
            and (task_stage.files is not None)
 | 
			
		||||
            else []
 | 
			
		||||
        )
 | 
			
		||||
        # TODO: the global limit field
 | 
			
		||||
        executor_with_config = ExecutorWithConfig(
 | 
			
		||||
            default=Cmd(
 | 
			
		||||
                args=task_stage.command.split(),
 | 
			
		||||
                args=(
 | 
			
		||||
                    task_stage.command.split() if task_stage.command is not None else []
 | 
			
		||||
                ),
 | 
			
		||||
                copy_in={
 | 
			
		||||
                    file: CmdFile(src=f"/home/tt/.config/joj/{file}")
 | 
			
		||||
                    for file in copy_in_files
 | 
			
		||||
| 
						 | 
				
			
			@ -71,22 +80,28 @@ def convert(repo_conf: Repo, task_conf: Task) -> ResultConfig:
 | 
			
		|||
                if file not in cached:
 | 
			
		||||
                    cached.append(file)
 | 
			
		||||
        conf_stage = Stage(
 | 
			
		||||
            name=task_stage.name,
 | 
			
		||||
            name=task_stage.name if task_stage.name is not None else "",
 | 
			
		||||
            # TODO: we may have cq in future
 | 
			
		||||
            group="joj" if "judge" in task_stage.name else None,
 | 
			
		||||
            group=(
 | 
			
		||||
                "joj"
 | 
			
		||||
                if (task_stage.name is not None) and ("judge" in task_stage.name)
 | 
			
		||||
                else None
 | 
			
		||||
            ),
 | 
			
		||||
            executor=ExecutorConfig(
 | 
			
		||||
                name="sandbox",
 | 
			
		||||
                with_=executor_with_config,
 | 
			
		||||
            ),
 | 
			
		||||
            parsers=[
 | 
			
		||||
                ParserConfig(name=parser, with_={}) for parser in task_stage.parsers
 | 
			
		||||
            ],
 | 
			
		||||
            parsers=(
 | 
			
		||||
                [ParserConfig(name=parser, with_={}) for parser in task_stage.parsers]
 | 
			
		||||
                if task_stage.parsers is not None
 | 
			
		||||
                else []
 | 
			
		||||
            ),
 | 
			
		||||
        )
 | 
			
		||||
        conf_stage = fix_result_detail(task_stage, conf_stage)
 | 
			
		||||
        conf_stage = fix_comment(task_stage, conf_stage)
 | 
			
		||||
        conf_stage = fix_keyword(task_stage, conf_stage)
 | 
			
		||||
        # TODO: fix diff parser here
 | 
			
		||||
 | 
			
		||||
        conf_stage = fix_diff(task_stage, conf_stage)
 | 
			
		||||
        result_conf.stage.stages.append(conf_stage)
 | 
			
		||||
 | 
			
		||||
    return result_conf
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,27 +1,32 @@
 | 
			
		|||
import rtoml
 | 
			
		||||
 | 
			
		||||
from joj3_config_generator.models.result import Stage as ResultStage
 | 
			
		||||
from joj3_config_generator.models.task import Stage as TaskStage
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def fix_keyword(task_stage: TaskStage, conf_stage: ResultStage) -> ResultStage:
 | 
			
		||||
    keyword_parser = ["clangtidy", "keyword", "cppcheck"]  # TODO: may add cpplint
 | 
			
		||||
    for parser in task_stage.parsers:
 | 
			
		||||
        if parser in keyword_parser:
 | 
			
		||||
            keyword_parser_ = next(p for p in conf_stage.parsers if p.name == parser)
 | 
			
		||||
            keyword_weight = []
 | 
			
		||||
            if getattr(task_stage, parser, None) is not None:
 | 
			
		||||
                for _, keyword in enumerate(getattr(task_stage, parser).keyword):
 | 
			
		||||
                    keyword_weight.append({"keyword": [keyword], "score": 0})
 | 
			
		||||
                for idx, weight in enumerate(getattr(task_stage, parser).weight):
 | 
			
		||||
                    keyword_weight[idx]["score"] = weight
 | 
			
		||||
    if task_stage.parsers is not None:
 | 
			
		||||
        for parser in task_stage.parsers:
 | 
			
		||||
            if parser in keyword_parser:
 | 
			
		||||
                keyword_parser_ = next(
 | 
			
		||||
                    p for p in conf_stage.parsers if p.name == parser
 | 
			
		||||
                )
 | 
			
		||||
                keyword_weight = []
 | 
			
		||||
                if getattr(task_stage, parser, None) is not None:
 | 
			
		||||
                    for _, keyword in enumerate(getattr(task_stage, parser).keyword):
 | 
			
		||||
                        keyword_weight.append({"keyword": [keyword], "score": 0})
 | 
			
		||||
                    for idx, weight in enumerate(getattr(task_stage, parser).weight):
 | 
			
		||||
                        keyword_weight[idx]["score"] = weight
 | 
			
		||||
 | 
			
		||||
            keyword_parser_.with_.update({"match": keyword_weight})
 | 
			
		||||
        else:
 | 
			
		||||
            continue
 | 
			
		||||
                keyword_parser_.with_.update({"match": keyword_weight})
 | 
			
		||||
            else:
 | 
			
		||||
                continue
 | 
			
		||||
    return conf_stage
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def fix_result_detail(task_stage: TaskStage, conf_stage: ResultStage) -> ResultStage:
 | 
			
		||||
    if "result-detail" in task_stage.parsers:
 | 
			
		||||
    if (task_stage.parsers is not None) and ("result-detail" in task_stage.parsers):
 | 
			
		||||
        result_detail_parser = next(
 | 
			
		||||
            p for p in conf_stage.parsers if p.name == "result-detail"
 | 
			
		||||
        )
 | 
			
		||||
| 
						 | 
				
			
			@ -57,13 +62,21 @@ def fix_comment(task_stage: TaskStage, conf_stage: ResultStage) -> ResultStage:
 | 
			
		|||
        "result-status",
 | 
			
		||||
        "cpplint",
 | 
			
		||||
    ]  # FIXME: determine where cpplint should be
 | 
			
		||||
    for parser in task_stage.parsers:
 | 
			
		||||
        if parser in comment_parser:
 | 
			
		||||
            comment_parser_ = next(p for p in conf_stage.parsers if p.name == parser)
 | 
			
		||||
            if getattr(task_stage, parser.replace("-", "_"), None) is not None:
 | 
			
		||||
                comment_parser_.with_.update(
 | 
			
		||||
                    getattr(task_stage, parser.replace("-", "_"))
 | 
			
		||||
    if task_stage.parsers is not None:
 | 
			
		||||
        for parser in task_stage.parsers:
 | 
			
		||||
            if parser in comment_parser:
 | 
			
		||||
                comment_parser_ = next(
 | 
			
		||||
                    p for p in conf_stage.parsers if p.name == parser
 | 
			
		||||
                )
 | 
			
		||||
        else:
 | 
			
		||||
            continue
 | 
			
		||||
                if getattr(task_stage, parser.replace("-", "_"), None) is not None:
 | 
			
		||||
                    comment_parser_.with_.update(
 | 
			
		||||
                        getattr(task_stage, parser.replace("-", "_"))
 | 
			
		||||
                    )
 | 
			
		||||
            else:
 | 
			
		||||
                continue
 | 
			
		||||
    return conf_stage
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def fix_diff(task_stage: TaskStage, conf_stage: ResultStage) -> ResultStage:
 | 
			
		||||
 | 
			
		||||
    return conf_stage
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -7,6 +7,8 @@ import rtoml
 | 
			
		|||
import typer
 | 
			
		||||
 | 
			
		||||
from joj3_config_generator.convert import convert as convert_conf
 | 
			
		||||
 | 
			
		||||
# from joj3_config_generator.lib.task import get_processed_task_obj
 | 
			
		||||
from joj3_config_generator.models import Repo, Task
 | 
			
		||||
from joj3_config_generator.utils.logger import logger
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,7 +1,7 @@
 | 
			
		|||
from datetime import datetime
 | 
			
		||||
from typing import Optional
 | 
			
		||||
from typing import Any, Dict, Optional, Type
 | 
			
		||||
 | 
			
		||||
from pydantic import BaseModel, Field
 | 
			
		||||
from pydantic import BaseModel, Field, root_validator
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class ParserResultDetail(BaseModel):
 | 
			
		||||
| 
						 | 
				
			
			@ -21,6 +21,17 @@ class ParserKeyword(BaseModel):
 | 
			
		|||
    weight: Optional[list[int]] = []
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Outputs(BaseModel):
 | 
			
		||||
    score: Optional[int] = 0
 | 
			
		||||
    ignorespaces: Optional[bool] = False
 | 
			
		||||
    hide: Optional[bool] = False
 | 
			
		||||
    forcequit: Optional[bool] = True
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class ParserDiff(BaseModel):
 | 
			
		||||
    output: Optional[Outputs] = Outputs()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Files(BaseModel):
 | 
			
		||||
    import_: Optional[list[str]] = Field([], alias="import")
 | 
			
		||||
    export: Optional[list[str]] = []
 | 
			
		||||
| 
						 | 
				
			
			@ -34,11 +45,11 @@ class Limit(BaseModel):
 | 
			
		|||
 | 
			
		||||
 | 
			
		||||
class Stage(BaseModel):
 | 
			
		||||
    name: str  # Stage name
 | 
			
		||||
    command: str  # Command to run
 | 
			
		||||
    name: Optional[str] = None  # Stage name
 | 
			
		||||
    command: Optional[str] = None  # Command to run
 | 
			
		||||
    files: Optional[Files] = None
 | 
			
		||||
    score: Optional[int] = 0
 | 
			
		||||
    parsers: list[str]  # list of parsers
 | 
			
		||||
    parsers: Optional[list[str]] = []  # list of parsers
 | 
			
		||||
    limit: Optional[Limit] = None
 | 
			
		||||
    dummy: Optional[ParserDummy] = ParserDummy()
 | 
			
		||||
    result_status: Optional[ParserDummy] = Field(ParserDummy(), alias="result-status")
 | 
			
		||||
| 
						 | 
				
			
			@ -51,6 +62,20 @@ class Stage(BaseModel):
 | 
			
		|||
    result_detail: Optional[ParserResultDetail] = Field(
 | 
			
		||||
        ParserResultDetail(), alias="result-detail"
 | 
			
		||||
    )
 | 
			
		||||
    skip: Optional[list[str]] = []
 | 
			
		||||
    diff: Optional[ParserDiff] = ParserDiff()
 | 
			
		||||
    cases: Optional[Dict[str, "Stage"]] = {}
 | 
			
		||||
 | 
			
		||||
    class Config:
 | 
			
		||||
        extra = "allow"
 | 
			
		||||
 | 
			
		||||
    @root_validator(pre=True)
 | 
			
		||||
    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: Stage(**v) for k, v in cases.items()}
 | 
			
		||||
        return values
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Release(BaseModel):
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,6 +1,6 @@
 | 
			
		|||
{
 | 
			
		||||
    "name": "Homework 1 exercise 2",
 | 
			
		||||
    "logPath": "Homework-1-exercise-2.log",
 | 
			
		||||
    "name": "h4 ex1",
 | 
			
		||||
    "logPath": "h4-ex1.log",
 | 
			
		||||
    "expireUnixTimestamp": 1728748740,
 | 
			
		||||
    "stage": {
 | 
			
		||||
        "sandboxExecServer": "172.17.0.1:5051",
 | 
			
		||||
| 
						 | 
				
			
			@ -18,7 +18,7 @@
 | 
			
		|||
                                "/<function",
 | 
			
		||||
| 
					
	
	
	
	
	
	
	
	 | 
			||||
                                "get_temp_directory",
 | 
			
		||||
                                "at",
 | 
			
		||||
                                "0x7fd3bed4f1a0>/repo-health-checker",
 | 
			
		||||
                                "0x7f932c5e31a0>/repo-health-checker",
 | 
			
		||||
                                "-root=.",
 | 
			
		||||
                                "-repoSize=50.5",
 | 
			
		||||
                                "-meta=main.py",
 | 
			
		||||
| 
						 | 
				
			
			@ -71,8 +71,8 @@
 | 
			
		|||
                            "cpuRateLimit": 0,
 | 
			
		||||
                            "cpuSetLimit": "",
 | 
			
		||||
                            "copyIn": {
 | 
			
		||||
                                "//tmp/repo-checker-9z61g608/repo-health-checker": {
 | 
			
		||||
                                    "src": "//tmp/repo-checker-19d98f6u/repo-health-checker",
 | 
			
		||||
                                "//tmp/repo-checker-tw0902sa/repo-health-checker": {
 | 
			
		||||
                                    "src": "//tmp/repo-checker-4sy3g0ro/repo-health-checker",
 | 
			
		||||
                                    "content": null,
 | 
			
		||||
                                    "fileId": null,
 | 
			
		||||
                                    "name": null,
 | 
			
		||||
| 
						 | 
				
			
			@ -234,11 +234,6 @@
 | 
			
		|||
                    {
 | 
			
		||||
                        "name": "result-detail",
 | 
			
		||||
                        "with": {
 | 
			
		||||
                            "time": false,
 | 
			
		||||
                            "mem": false,
 | 
			
		||||
                            "stdout": false,
 | 
			
		||||
                            "stderr": true,
 | 
			
		||||
                            "exitstatus": true,
 | 
			
		||||
                            "score": 0,
 | 
			
		||||
                            "comment": "",
 | 
			
		||||
                            "showFiles": [
 | 
			
		||||
| 
						 | 
				
			
			@ -379,11 +374,6 @@
 | 
			
		|||
                    {
 | 
			
		||||
                        "name": "result-detail",
 | 
			
		||||
                        "with": {
 | 
			
		||||
                            "time": false,
 | 
			
		||||
                            "mem": false,
 | 
			
		||||
                            "stdout": false,
 | 
			
		||||
                            "stderr": true,
 | 
			
		||||
                            "exitstatus": false,
 | 
			
		||||
                            "score": 0,
 | 
			
		||||
                            "comment": "",
 | 
			
		||||
                            "showFiles": [
 | 
			
		||||
| 
						 | 
				
			
			@ -571,11 +561,6 @@
 | 
			
		|||
                    {
 | 
			
		||||
                        "name": "result-detail",
 | 
			
		||||
                        "with": {
 | 
			
		||||
                            "time": false,
 | 
			
		||||
                            "mem": false,
 | 
			
		||||
                            "stdout": true,
 | 
			
		||||
                            "stderr": false,
 | 
			
		||||
                            "exitstatus": true,
 | 
			
		||||
                            "score": 0,
 | 
			
		||||
                            "comment": "",
 | 
			
		||||
                            "showFiles": [
 | 
			
		||||
| 
						 | 
				
			
			@ -713,11 +698,6 @@
 | 
			
		|||
                    {
 | 
			
		||||
                        "name": "result-detail",
 | 
			
		||||
                        "with": {
 | 
			
		||||
                            "time": false,
 | 
			
		||||
                            "mem": false,
 | 
			
		||||
                            "stdout": false,
 | 
			
		||||
                            "stderr": true,
 | 
			
		||||
                            "exitstatus": true,
 | 
			
		||||
                            "score": 0,
 | 
			
		||||
                            "comment": "",
 | 
			
		||||
                            "showFiles": [
 | 
			
		||||
| 
						 | 
				
			
			@ -820,11 +800,6 @@
 | 
			
		|||
                    {
 | 
			
		||||
                        "name": "result-detail",
 | 
			
		||||
                        "with": {
 | 
			
		||||
                            "time": false,
 | 
			
		||||
                            "mem": false,
 | 
			
		||||
                            "stdout": true,
 | 
			
		||||
                            "stderr": false,
 | 
			
		||||
                            "exitstatus": true,
 | 
			
		||||
                            "score": 0,
 | 
			
		||||
                            "comment": "",
 | 
			
		||||
                            "showFiles": [
 | 
			
		||||
| 
						 | 
				
			
			@ -921,11 +896,6 @@
 | 
			
		|||
                    {
 | 
			
		||||
                        "name": "result-detail",
 | 
			
		||||
                        "with": {
 | 
			
		||||
                            "time": true,
 | 
			
		||||
                            "mem": true,
 | 
			
		||||
                            "stdout": false,
 | 
			
		||||
                            "stderr": true,
 | 
			
		||||
                            "exitstatus": true,
 | 
			
		||||
                            "score": 0,
 | 
			
		||||
                            "comment": "",
 | 
			
		||||
                            "showFiles": [
 | 
			
		||||
| 
						 | 
				
			
			@ -1022,11 +992,6 @@
 | 
			
		|||
                    {
 | 
			
		||||
                        "name": "result-detail",
 | 
			
		||||
                        "with": {
 | 
			
		||||
                            "time": true,
 | 
			
		||||
                            "mem": true,
 | 
			
		||||
                            "stdout": false,
 | 
			
		||||
                            "stderr": true,
 | 
			
		||||
                            "exitstatus": true,
 | 
			
		||||
                            "score": 0,
 | 
			
		||||
                            "comment": "",
 | 
			
		||||
                            "showFiles": [
 | 
			
		||||
| 
						 | 
				
			
			@ -1042,9 +1007,9 @@
 | 
			
		|||
        ]
 | 
			
		||||
    },
 | 
			
		||||
    "teapot": {
 | 
			
		||||
        "logPath": "Homework-1-exercise-2-joint-teapot-debug.log",
 | 
			
		||||
        "scoreboardPath": "Homework-1-exercise-2-scoreboard.csv",
 | 
			
		||||
        "failedTablePath": "Homework-1-exercise-2-failed-table.md",
 | 
			
		||||
        "logPath": "h4-ex1-joint-teapot-debug.log",
 | 
			
		||||
        "scoreboardPath": "h4-ex1-scoreboard.csv",
 | 
			
		||||
        "failedTablePath": "h4-ex1-failed-table.md",
 | 
			
		||||
        "gradingRepoName": "engr151-joj",
 | 
			
		||||
        "skipIssue": false,
 | 
			
		||||
        "skipScoreboard": false,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,5 +1,5 @@
 | 
			
		|||
# general task configuration
 | 
			
		||||
task="Homework 1 exercise 2" # task name
 | 
			
		||||
task="h4 ex1" # task name
 | 
			
		||||
 | 
			
		||||
release.deadline = 2024-10-12 23:59:00+08:00
 | 
			
		||||
release.stages = [ "compile" ]
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue
	
	Block a user
	
?