dev #10
|  | @ -5,10 +5,10 @@ from typing import Any, List | |||
| import rtoml | ||||
| 
 | ||||
| from joj3_config_generator.models import joj1, repo, result, task | ||||
| from joj3_config_generator.processers.repo import ( | ||||
| from joj3_config_generator.processers.repo import (  # get_teapotcheck_config, | ||||
|     get_healthcheck_config, | ||||
|     get_teapot_config, | ||||
|     get_teapotcheck_config, | ||||
|     get_teapot_stage, | ||||
| ) | ||||
| from joj3_config_generator.processers.task import ( | ||||
|     fix_diff, | ||||
|  | @ -34,13 +34,17 @@ def convert(repo_conf: repo.Config, task_conf: task.Config) -> result.Config: | |||
|         ), | ||||
|         # FIXME: don't hardcode | ||||
|         actor_csv_path="/home/tt/.config/joj/students.csv", | ||||
|         stage=result.Stage(stages=[], sandbox_token=repo_conf.sandbox_token), | ||||
|         stage=result.Stage( | ||||
| 
					
					jon-lee marked this conversation as resolved
					
						
						
							Outdated
						
					
				 | ||||
|             stages=[], | ||||
|             sandbox_token=repo_conf.sandbox_token, | ||||
|             poststages=[get_teapot_stage(repo_conf)], | ||||
|         ), | ||||
|         teapot=get_teapot_config(repo_conf, task_conf), | ||||
|     ) | ||||
| 
 | ||||
|     # Construct healthcheck stage | ||||
|     healthcheck_stage = get_healthcheck_config(repo_conf) | ||||
|     teapotcheck_stage = get_teapotcheck_config(repo_conf, task_conf) | ||||
|     # teapotcheck_stage = get_teapotcheck_config(repo_conf, task_conf) | ||||
|     result_conf.stage.stages.append(healthcheck_stage) | ||||
| 
					
					jon-lee marked this conversation as resolved
					
						
						
							Outdated
						
					
				 
				
					
						张泊明518370910136
						commented  why? why? 
				
					
						李衍志523370910113
						commented  forgot to uncommented 😭 forgot to uncommented 😭 
				
					
						李衍志523370910113
						commented  fixed fixed | ||||
|     cached: List[str] = [] | ||||
|     # Convert each stage in the task configuration | ||||
|  | @ -65,7 +69,7 @@ def convert_joj1(joj1_conf: joj1.Config) -> task.Config: | |||
|         # You can define a command based on language properties | ||||
|         command = f"run {language.language}" | ||||
|         # Assuming we don't have explicit files, we will set empty ones or default behavior | ||||
|         files = task.Files(import_=[], export=[]) | ||||
|         files = task.Files(import_=[], export=[])  # type: ignore | ||||
|         # Score can be derived from the first case or set to a default | ||||
|         score = 0 | ||||
|         parsers: List[str] = []  # Define parsers if applicable | ||||
|  | @ -121,4 +125,3 @@ def distribute_json(folder_path: str, repo_obj: Any) -> None: | |||
|                     assert os.path.exists( | ||||
|                         json_file_path | ||||
|                     ), f"Failed to convert {toml_file_path} into json!" | ||||
|     return 0 | ||||
|  |  | |||
|  | @ -15,9 +15,7 @@ class Group(BaseModel): | |||
| 
 | ||||
| 
 | ||||
| class Config(BaseModel): | ||||
|     teaching_team: List[str] | ||||
|     max_size: float = Field(..., ge=0) | ||||
|     release_tags: List[str] | ||||
|     files: Files | ||||
|     sandbox_token: str | ||||
|     max_total_score: int = Field(100) | ||||
|  |  | |||
|  | @ -16,8 +16,8 @@ class CmdFile(BaseModel): | |||
| 
 | ||||
| 
 | ||||
| class Cmd(BaseModel): | ||||
|     args: list[str] | ||||
|     env: list[str] = ["PATH=/usr/bin:/bin:/usr/local/bin"] | ||||
|     args: Optional[List[str]] = None | ||||
|     env: Optional[List[str]] = ["PATH=/usr/bin:/bin:/usr/local/bin"] | ||||
|     stdin: Optional[CmdFile] = CmdFile(content="") | ||||
|     stdout: Optional[CmdFile] = CmdFile(name="stdout", max=4 * 1024) | ||||
|     stderr: Optional[CmdFile] = CmdFile(name="stderr", max=4 * 1024) | ||||
|  | @ -27,12 +27,12 @@ class Cmd(BaseModel): | |||
|     memory_limit: int = Field(800 * 1024 * 1024, serialization_alias="memoryLimit") | ||||
|     stack_limit: int = Field(0, serialization_alias="stackLimit") | ||||
|     proc_limit: int = Field(50, serialization_alias="procLimit") | ||||
|     proc_limit: int = Field(50, serialization_alias="procLimit") | ||||
|     cpu_rate_limit: int = Field(0, serialization_alias="cpuRateLimit") | ||||
| 
					
					jon-lee marked this conversation as resolved
					
						
						
							Outdated
						
					
				 
				
					
						张泊明518370910136
						commented  unit? unit? 
				
					
						李衍志523370910113
						commented  I think  I think `timeparse` and `humanfriendly` would deal wth that? 
				
					
						李衍志523370910113
						commented  resolved. resolved. | ||||
|     cpu_set_limit: str = Field("", serialization_alias="cpuSetLimit") | ||||
|     copy_in: Dict[str, CmdFile] = Field({}, serialization_alias="copyIn") | ||||
|     copy_in_cached: Dict[str, str] = Field({}, serialization_alias="copyInCached") | ||||
|     copy_in_dir: str = Field(".", serialization_alias="copyInDir") | ||||
|     # reconsider this default situation | ||||
|     copy_out: List[str] = Field(["stdout", "stderr"], serialization_alias="copyOut") | ||||
|     copy_out_cached: List[str] = Field([], serialization_alias="copyOutCached") | ||||
|     copy_out_max: int = Field(0, serialization_alias="copyOutMax") | ||||
|  | @ -46,7 +46,6 @@ class Cmd(BaseModel): | |||
| class OptionalCmd(BaseModel): | ||||
|     args: Optional[list[str]] = None | ||||
|     env: Optional[list[str]] = ["PATH=/usr/bin:/bin:/usr/local/bin"] | ||||
|     env: Optional[list[str]] = ["PATH=/usr/bin:/bin:/usr/local/bin"] | ||||
|     stdin: Optional[CmdFile] = None | ||||
|     stdout: Optional[CmdFile] = None | ||||
|     stderr: Optional[CmdFile] = None | ||||
|  | @ -60,7 +59,6 @@ class OptionalCmd(BaseModel): | |||
|     ) | ||||
|     stack_limit: Optional[int] = Field(None, serialization_alias="stackLimit") | ||||
|     proc_limit: Optional[int] = Field(50, serialization_alias="procLimit") | ||||
| 
					
					jon-lee marked this conversation as resolved
					
						
						
							Outdated
						
					
				 
				
					
						张泊明518370910136
						commented  What is the conclusion? What is the conclusion? 
				
					
						李衍志523370910113
						commented  should be already solved. should be already solved. | ||||
|     proc_limit: Optional[int] = Field(50, serialization_alias="procLimit") | ||||
|     cpu_rate_limit: Optional[int] = Field(None, serialization_alias="cpuRateLimit") | ||||
|     cpu_set_limit: Optional[str] = Field(None, serialization_alias="cpuSetLimit") | ||||
|     copy_in: Optional[Dict[str, CmdFile]] = Field(None, serialization_alias="copyIn") | ||||
|  | @ -88,14 +86,7 @@ class OptionalCmd(BaseModel): | |||
|     ) | ||||
| 
 | ||||
| 
 | ||||
| class Stage(BaseModel): | ||||
|     name: str | ||||
|     group: Optional[str] = None | ||||
|     executor: "ExecutorConfig" | ||||
|     parsers: list["ParserConfig"] | ||||
| 
 | ||||
| 
 | ||||
| class ExecutorWithConfig(BaseModel): | ||||
| class ExecutorWith(BaseModel): | ||||
|     default: Cmd | ||||
|     cases: List[OptionalCmd] | ||||
| 
 | ||||
|  | @ -105,7 +96,7 @@ class Executor(BaseModel): | |||
|     with_: ExecutorWith = Field(..., serialization_alias="with") | ||||
| 
 | ||||
| 
 | ||||
| class Parser(BaseModel): | ||||
| class ParserConfig(BaseModel): | ||||
|     name: str | ||||
|     with_: Dict[str, Any] = Field(..., serialization_alias="with") | ||||
| 
 | ||||
|  | @ -114,7 +105,7 @@ class StageDetail(BaseModel): | |||
|     name: str | ||||
|     group: Optional[str] = "" | ||||
|     executor: Executor | ||||
|     parsers: List[Parser] | ||||
|     parsers: List[ParserConfig] | ||||
| 
 | ||||
| 
 | ||||
| class Stage(BaseModel): | ||||
|  | @ -126,6 +117,8 @@ class Stage(BaseModel): | |||
|         "/tmp/joj3_result.json", serialization_alias="outputPath" | ||||
|     )  # nosec: B108 | ||||
|     stages: List[StageDetail] | ||||
|     prestages: Optional[List[StageDetail]] = None | ||||
|     poststages: List[StageDetail] | ||||
| 
 | ||||
| 
 | ||||
| class Teapot(BaseModel): | ||||
| 
					
					jon-lee marked this conversation as resolved
					
						
						
							Outdated
						
					
				 
				
					
						张泊明518370910136
						commented  Should it be optional? Should it be optional? | ||||
|  | @ -147,9 +140,10 @@ class Teapot(BaseModel): | |||
| 
 | ||||
| 
 | ||||
| class Config(BaseModel): | ||||
|     name: str = "unknown" | ||||
|     name: str = "" | ||||
|     log_path: str = Field("", serialization_alias="logPath") | ||||
|     expire_unix_timestamp: int = Field(-1, serialization_alias="expireUnixTimestamp") | ||||
|     actor_csv_path: str = Field("", serialization_alias="actorCsvPath") | ||||
|     actor_csv_path: str = Field("", serialization_alias="actorpostStagesCsvPath") | ||||
|     max_total_score: int = Field(100, serialization_alias="maxTotalScore") | ||||
|     stage: Stage | ||||
|     teapot: Teapot | ||||
|     teapot: Teapot  # FIXME: remove this | ||||
|  |  | |||
|  | @ -1,5 +1,5 @@ | |||
| from datetime import datetime | ||||
| 
					
					jon-lee marked this conversation as resolved
					
						
						
							Outdated
						
					
				 
				
					
						张泊明518370910136
						commented  every field in this file should not be optional. we give an default value here if any field does not exist every field in this file should not be optional. we give an default value here if any field does not exist 
				
					
						张泊明518370910136
						commented  and use underscore naming in this file and use underscore naming in this file 
				
					
						李衍志523370910113
						commented  
 fixed > every field in this file should not be optional. we give an default value here if any field does not exist
fixed 
				
					
						李衍志523370910113
						commented  
 fixed. > and use underscore naming in this file
fixed. | ||||
| from typing import Any, Dict, Optional, Type | ||||
| from typing import Any, Dict, List, Optional, Type | ||||
| 
 | ||||
| from pydantic import BaseModel, Field, root_validator | ||||
| 
 | ||||
|  | @ -13,7 +13,13 @@ class ParserResultDetail(BaseModel): | |||
| 
 | ||||
| 
 | ||||
| class ParserFile(BaseModel): | ||||
|     name: str = None | ||||
|     name: Optional[str] = None | ||||
| 
 | ||||
| 
 | ||||
| class ParserLog(BaseModel): | ||||
|     fileName: Optional[str] = None | ||||
|     msg: Optional[str] = None | ||||
|     level: Optional[str] = None | ||||
| 
 | ||||
| 
 | ||||
| class ParserDummy(BaseModel): | ||||
|  | @ -54,6 +60,7 @@ class Stage(BaseModel): | |||
|     name: Optional[str] = None  # Stage name | ||||
|     group: Optional[str] = None  # TODO: may need to formulate this | ||||
|     path: Optional[str] = None  # FIXME: this is highly possible to be removed in future | ||||
|     env: Optional[list[str]] = None | ||||
|     command: Optional[str] = None  # Command to run | ||||
|     files: Optional[Files] = None | ||||
|     in_: Optional[str] = Field(None, alias="in") | ||||
|  | @ -72,8 +79,9 @@ class Stage(BaseModel): | |||
|     ) | ||||
|     file: Optional[ParserFile] = ParserFile() | ||||
|     skip: Optional[list[str]] = [] | ||||
|     diff: Optional[ParserDiff] = ParserDiff() | ||||
|     # cases related | ||||
|     cases: Optional[Dict[str, "Stage"]] = {} | ||||
|     diff: Optional[ParserDiff] = ParserDiff() | ||||
| 
 | ||||
| 
					
					jon-lee marked this conversation as resolved
					
						
						
							Outdated
						
					
				 
				
					
						张泊明518370910136
						commented  deprecated deprecated 
				
					
						李衍志523370910113
						commented  @bomingzh any suggestions on the structure? @bomingzh any suggestions on the structure? 
				
					
						张泊明518370910136
						commented  ```
PydanticDeprecatedSince20: Support for class-based `config` is deprecated, use ConfigDict instead. Deprecated in Pydantic V2.0 to be removed in V3.0. See Pydantic V2 Migration Guide at https://errors.pydantic.dev/2.9/migration/
``` 
				
					
						李衍志523370910113
						commented  fixed with  fixed with `model_config` 
				
					
						张泊明518370910136
						commented  str here need to be a  str here need to be a `StrEnum` now. 
				
					
						李衍志523370910113
						commented  But I guess we don't know the set of case in advance, making it dynamic  But I guess we don't know the set of case in advance, making it dynamic `StrEnum` is meaningless 
				
					
						张泊明518370910136
						commented  line changed, the comment is for  line changed, the comment is for `parsers` | ||||
|     class Config: | ||||
|         extra = "allow" | ||||
| 
					
					jon-lee marked this conversation as resolved
					
						
						
							Outdated
						
					
				 
				
					
						李衍志523370910113
						commented  this should be the  this should be the `StrEnum` 
				
					
						张泊明518370910136
						commented  yes yes 
				
					
						李衍志523370910113
						commented  It is supported now. It is supported now. | ||||
|  |  | |||
|  | @ -1,5 +1,6 @@ | |||
| import hashlib | ||||
| import shlex | ||||
| import socket | ||||
| from pathlib import Path | ||||
| 
 | ||||
| from joj3_config_generator.models import repo, result, task | ||||
|  | @ -7,8 +8,8 @@ from joj3_config_generator.models import repo, result, task | |||
| 
 | ||||
| def get_grading_repo_name() -> str: | ||||
|     # FIXME: uncomment back when everything is ready! | ||||
| 
					
					jon-lee marked this conversation as resolved
					
						
						
							Outdated
						
					
				 
				
					
						张泊明518370910136
						commented  make it a field in repo.toml, if it is unset, then use  make it a field in repo.toml, if it is unset, then use `socket.gethostname`. We set this value to pass the test. 
				
					
						李衍志523370910113
						commented  resolved. resolved. | ||||
|     host_name = "engr151" | ||||
|     # host_name = socket.gethostname() | ||||
|     # host_name = "engr151" | ||||
|     host_name = socket.gethostname() | ||||
|     return f"{host_name.split('-')[0]}-joj" | ||||
| 
 | ||||
| 
 | ||||
|  | @ -50,7 +51,33 @@ def get_teapot_config(repo_conf: repo.Config, task_conf: task.Config) -> result. | |||
|     return teapot | ||||
| 
 | ||||
| 
 | ||||
| def get_healthcheck_cmd(repo_conf: repo.Config) -> result.Cmd: | ||||
| def get_teapot_stage(repo_conf: repo.Config) -> result.StageDetail: | ||||
| 
					
					jon-lee marked this conversation as resolved
					
						
						
							Outdated
						
					
				 
				
					
						张泊明518370910136
						commented  why not  why not `args = "hc -root=. "` 
				
					
						李衍志523370910113
						commented  resolved. resolved. | ||||
|     args_ = "" | ||||
|     args_ = ( | ||||
|         args_ | ||||
|         + f"/usr/local/bin/joint-teapot joj3-all-env /home/tt/.config/teapot/teapot.env --grading-repo-name {get_grading_repo_name()} --max-total-score {repo_conf.max_total_score}" | ||||
| 
					
					jon-lee marked this conversation as resolved
					
						
						
							Outdated
						
					
				 
				
					
						张泊明518370910136
						commented  do we need that default? do we need that default? 
				
					
						李衍志523370910113
						commented  what is the situation internally in JOJ3? I just added that blindly when I reached that stage. Overall I think 100 times per day should be a reasonable and safe default? considering that there may be group works and due date what is the situation internally in JOJ3? I just added that blindly when I reached that stage. Overall I think 100 times per day should be a reasonable and safe default? considering that there may be group works and due date 
				
					
						张泊明518370910136
						commented  They can manually add it if needed. Or just move it to the model default. They can manually add it if needed. Or just move it to the model default. 
				
					
						李衍志523370910113
						commented  removed. removed. | ||||
|     ) | ||||
| 
 | ||||
|     stage_conf = result.StageDetail( | ||||
|         name="teapot", | ||||
|         executor=result.Executor( | ||||
|             name="local", | ||||
|             with_=result.ExecutorWith( | ||||
|                 default=result.Cmd( | ||||
|                     args=shlex.split(args_), | ||||
|                     env=[ | ||||
|                         "LOG_FILE_PATH=/home/tt/.cache/joint-teapot-debug.log" | ||||
|                     ],  # TODO: fix it according to the task name | ||||
|                 ), | ||||
|                 cases=[], | ||||
|             ), | ||||
|         ), | ||||
|         parsers=[result.ParserConfig(name="log", with_={"msg": "joj3 summary"})], | ||||
|     ) | ||||
|     return stage_conf | ||||
| 
 | ||||
| 
 | ||||
| def get_healthcheck_args(repo_conf: repo.Config) -> str: | ||||
|     repoSize = repo_conf.max_size | ||||
|     immutable = repo_conf.files.immutable | ||||
|     repo_size = f"-repoSize={str(repoSize)} " | ||||
|  | @ -59,13 +86,13 @@ def get_healthcheck_cmd(repo_conf: repo.Config) -> result.Cmd: | |||
|     for i, meta in enumerate(required_files): | ||||
|         required_files[i] = f"-meta={meta} " | ||||
| 
 | ||||
|     immutable_files = f"-checkFileNameList=" | ||||
|     immutable_files = "-checkFileNameList=" | ||||
|     for i, name in enumerate(immutable): | ||||
|         if i == len(immutable) - 1: | ||||
|             immutable_files = immutable_files + name + " " | ||||
|         else: | ||||
|             immutable_files = immutable_files + name + "," | ||||
|     chore = f"/tmp/repo-health-checker -root=. " | ||||
|     chore = "/usr/local/bin/repo-health-checker -root=. " | ||||
|     args = "" | ||||
|     args = args + chore | ||||
|     args = args + repo_size | ||||
|  | @ -76,26 +103,25 @@ def get_healthcheck_cmd(repo_conf: repo.Config) -> result.Cmd: | |||
| 
 | ||||
|     args = args + immutable_files | ||||
| 
 | ||||
|     cmd = result.Cmd( | ||||
|         args=shlex.split(args), | ||||
|         copy_in={ | ||||
|             # This path is hardcoded | ||||
|             f"/tmp/repo-health-checker": result.CmdFile( | ||||
|                 src="/usr/local/bin/repo-health-checker" | ||||
|             ) | ||||
|         }, | ||||
|     return args | ||||
| 
 | ||||
| 
 | ||||
| def get_debug_args(repo_conf: repo.Config) -> str: | ||||
|     args = "" | ||||
|     args = ( | ||||
|         args | ||||
|         + f"/usr/local/bin/joint-teapot joj3-check-env /home/tt/.config/teapot/teapot.env --grading-repo-name {get_grading_repo_name()} --group-config" | ||||
|     ) | ||||
|     return cmd | ||||
| 
 | ||||
| 
 | ||||
| def get_teapotcheck_cmd(repo_conf: repo.Config, task_conf: task.Config) -> result.Cmd: | ||||
|     return 0 | ||||
| 
 | ||||
| 
 | ||||
| def get_teapotcheck_config( | ||||
|     repo_conf: repo.Config, task_conf: task.Config | ||||
| ) -> result.StageDetail: | ||||
|     return 0 | ||||
|     group_config = "" | ||||
|     for i, name in enumerate(repo_conf.groups.name): | ||||
|         group_config = ( | ||||
|             group_config | ||||
|             + f"{name}={repo_conf.groups.max_count[i]}:{repo_conf.groups.time_period_hour[i]}," | ||||
|         ) | ||||
|     # default value hardcoded | ||||
|     group_config = group_config + "=100:24" | ||||
|     args = args + group_config | ||||
|     return args | ||||
| 
 | ||||
| 
 | ||||
| def get_healthcheck_config(repo_conf: repo.Config) -> result.StageDetail: | ||||
|  | @ -103,10 +129,24 @@ def get_healthcheck_config(repo_conf: repo.Config) -> result.StageDetail: | |||
|         name="healthcheck", | ||||
|         group="", | ||||
|         executor=result.Executor( | ||||
|             name="sandbox", | ||||
|             with_=result.ExecutorWith(default=get_healthcheck_cmd(repo_conf), cases=[]), | ||||
|             name="local", | ||||
|             with_=result.ExecutorWith( | ||||
|                 default=result.Cmd(), | ||||
|                 cases=[ | ||||
|                     result.OptionalCmd( | ||||
|                         args=shlex.split(get_healthcheck_args(repo_conf)), | ||||
|                     ), | ||||
|                     result.OptionalCmd( | ||||
|                         args=shlex.split(get_debug_args(repo_conf)), | ||||
|                         env=["LOG_FILE_PATH=/home/tt/.cache/joint-teapot-debug.log"], | ||||
|                     ), | ||||
|                 ], | ||||
|             ), | ||||
|         ), | ||||
|         parsers=[ParserConfig(name="healthcheck", with_={"score": 0, "comment": ""})], | ||||
|         parsers=[ | ||||
|             result.ParserConfig(name="healthcheck", with_={"score": 1}), | ||||
|             result.ParserConfig(name="debug", with_={"score": 1}), | ||||
|         ], | ||||
|     ) | ||||
|     return healthcheck_stage | ||||
| 
 | ||||
|  | @ -124,9 +164,6 @@ def get_hash(immutable_files: list[str]) -> str:  # input should be a list | |||
|     current_file_path = Path(__file__).resolve() | ||||
|     project_root = current_file_path.parents[2] | ||||
|     file_path = f"{project_root}/tests/immutable_p3-test/" | ||||
|     # file_path = f"{project_root}/tests/immutable_hteam/" | ||||
|     # file_path = f"{project_root}/tests/immutable_hteam-test/" | ||||
|     # file_path = f"{project_root}/tests/immutable_p3/" | ||||
|     immutable_hash = [] | ||||
|     for i, file in enumerate(immutable_files): | ||||
|         immutable_files[i] = file_path + file.rsplit("/", 1)[-1] | ||||
|  |  | |||
|  | @ -21,7 +21,10 @@ def get_conf_stage( | |||
|             with_=executor_with_config, | ||||
|         ), | ||||
|         parsers=( | ||||
|             [result.Parser(name=parser, with_={}) for parser in task_stage.parsers] | ||||
|             [ | ||||
|                 result.ParserConfig(name=parser, with_={}) | ||||
|                 for parser in task_stage.parsers | ||||
|             ] | ||||
|             if task_stage.parsers is not None | ||||
|             else [] | ||||
|         ), | ||||
|  | @ -69,7 +72,12 @@ def get_executorWithConfig( | |||
|                 for file in copy_in_files | ||||
|             }, | ||||
|             stdin=( | ||||
|                 result.CmdFile(content="") if "diff" not in task_stage.parsers else None | ||||
|                 result.CmdFile(content="") | ||||
|                 if ( | ||||
| 
					
					jon-lee marked this conversation as resolved
					
						
						
							Outdated
						
					
				 
				
					
						张泊明518370910136
						commented  do not use  do not use `getattr`, visit the field explictly 
				
					
						李衍志523370910113
						commented  resolved. resolved. | ||||
|                     (task_stage.parsers is not None) | ||||
|                     and ("diff" not in task_stage.parsers) | ||||
|                 ) | ||||
| 
					
					jon-lee marked this conversation as resolved
					
						
						
							Outdated
						
					
				 
				
					
						张泊明518370910136
						commented  is there a conclusion now? or it should have a prefix  is there a conclusion now? or it should have a prefix `TODO: `? 
				
					
						李衍志523370910113
						commented  so far works fine on 280 sides, indicating that pbs in 151 can be resolved with proper guidelines I think. so far works fine on 280 sides, indicating that pbs in 151 can be resolved with proper guidelines I think. 
				
					
						张泊明518370910136
						commented  ok, then add that prefix ok, then add that prefix | ||||
|                 else None | ||||
| 
					
					jon-lee marked this conversation as resolved
					
						
						
							Outdated
						
					
				 
				
					
						张泊明518370910136
						commented  is it in the correct unit? is it in the correct unit?
Give all the fields in `Limit` a default value and make it non optional in task_stage.limit 
				
					
						李衍志523370910113
						commented  resolved resolved | ||||
|             ), | ||||
|             copy_out=copy_out_files, | ||||
|             copy_in_cached={file: file for file in cached}, | ||||
|  | @ -274,9 +282,7 @@ def fix_diff( | |||
|                         src=f"/home/tt/.config/joj/{task_conf.task.type_}/{stdin}" | ||||
|                         # src=f"/home/tt/.config/joj/{task_stage.path}/{stdin}" | ||||
|                     ), | ||||
|                     args=( | ||||
|                         shlex.split(case_stage.command) if command is not None else None | ||||
|                     ), | ||||
|                     args=(shlex.split(command) if command is not None else None), | ||||
|                     cpu_limit=cpu_limit, | ||||
|                     clock_limit=clock_limit, | ||||
|                     memory_limit=memory_limit, | ||||
|  |  | |||
|  | @ -1,23 +1,15 @@ | |||
| teaching_team = ["prof_john", "ta_alice", "ta_bob"] | ||||
| max_size = 50.5 | ||||
| release_tags = ["v1.0", "v2.0", "final"] | ||||
| sandbox_token = "test" | ||||
| 
 | ||||
| # reconfigure later | ||||
| max_total_score = 100 | ||||
| 
 | ||||
| # for projects | ||||
| #groups.name = ["build", "run"] | ||||
| #groups.max_count = [8, 5] | ||||
| #groups.time_period_hour = [24, 24] | ||||
| 
 | ||||
| max_size = 50.5 | ||||
| 
 | ||||
| # for tests | ||||
| groups.name = ["joj", "run"] | ||||
| groups.max_count = [1000, 1000] | ||||
| groups.time_period_hour = [24, 24] | ||||
| [groups] | ||||
| name = ["joj", "run"] | ||||
| max_count = [1000, 1000] | ||||
| time_period_hour = [24, 24] | ||||
| 
 | ||||
| [files] | ||||
| # projects | ||||
| # required = ["README.md", "Changelog.md"] | ||||
| required = ["README.md"] | ||||
| immutable = [".gitignore", ".gitattributes",".gitea/workflows/push.yaml", ".gitea/workflows/release.yaml" ] | ||||
| required = ["README.md", "Changelog.md"] | ||||
| immutable = [".gitignore", ".gitattributes",".gitea/workflows/push.yaml", ".gitea/workflows/release.yaml"] | ||||
|  |  | |||
|  | @ -1,22 +1,460 @@ | |||
| # general task configuration | ||||
| task.name = "e2" # task name | ||||
| task.type = "exam/e2" | ||||
| task.name = "hw7 ex2" # task name | ||||
| task.type = "homework/h7/e2" | ||||
| 
 | ||||
| release.deadline = 2024-12-30 23:59:59+08:00 | ||||
| release.stages = [ "compile" ] | ||||
| 
 | ||||
| [[stages]] | ||||
| name = "[cq] Compilation" | ||||
| command = "./tools/compile" # eg. script running cmake commands | ||||
| files.import = [ "tools/compile", "h6/build/ex3-main.c", "h6/build/ex4-main.c", "h6/build/ex5-main.c", "h6/build/ex7-main.c" ] | ||||
| files.export = [ "h6/build/ex2", "h6/build/ex2-asan", "h6/build/ex2-ubsan", "h6/build/ex2-msan", "h6/build/ex3", "h6/build/ex3-asan", "h6/build/ex3-ubsan", "h6/build/ex3-msan", "h6/build/ex4", "h6/build/ex4-asan", "h6/build/ex4-ubsan", "h6/build/ex4-msan", "h6/build/ex5", "h6/build/ex5-asan", "h6/build/ex5-ubsan", "h6/build/ex5-msan", "h6/build/ex6", "h6/build/ex6-asan", "h6/build/ex6-ubsan", "h6/build/ex6-msan", "h6/build/ex7", "h6/build/ex7-asan", "h6/build/ex7-ubsan", "h6/build/ex7-msan", "h6/build/ex3-main.c", "h6/build/ex4-main.c", "h6/build/ex5-main.c", "h6/build/ex7-main.c", "h6/build/compile_commands.json" ] | ||||
| name = "healthcheck" | ||||
| score = 1 | ||||
| 
 | ||||
| # compile parsers ex | ||||
| parsers = [ "result-detail", "result-status", "file" ] | ||||
| # healthcheck parsers | ||||
| parsers = ["healthcheck", "debug"] | ||||
| cases0.command = "/usr/local/bin/repo-health-checker -repoSize=100" | ||||
| case1.command = """/usr/local/bin/joint-teapot | ||||
|                   joj3-check-env | ||||
|                   /home/tt/.config/teapot/teapot.env" | ||||
|                   --grading-repo-name | ||||
|                   JOJ3-actions-examples | ||||
|                   --group-config | ||||
|                   joj=50:24,=100:24""" | ||||
| case1.env = ["LOG_FILE_PATH=/home/tt/.cache/joint-teapot-debug.log"] | ||||
| 
 | ||||
| [[stages]] | ||||
| name = "Compilation" | ||||
| command = "./tools/compile" # eg. script running cmake commands | ||||
| files.import = [ "tools/compile" ] | ||||
| files.export = [ "h7/build/ex2", "h7/build/ex2-asan", "h7/build/ex2-ubsan", "h7/build/ex2-msan", "h7/build/compile_commands.json" ] | ||||
| score = 1 | ||||
| 
 | ||||
| # compile parsers | ||||
| parsers = [ "result-detail", "result-status" ] | ||||
| result-status.comment = "Congratulations! Your code compiled successfully." | ||||
| result-detail.exitstatus = true | ||||
| result-detail.stderr = true | ||||
| result-detail.time = false | ||||
| result-detail.mem = false | ||||
| result-status.forcequit = true | ||||
| file.name = "stdout" | ||||
| 
 | ||||
| [[stages]] | ||||
| name = "[cq] Filelength" | ||||
| command = "./tools/filelength 400 300 *.cpp *.h" | ||||
| files.import = [ "tools/filelength" ] | ||||
| 
 | ||||
| parsers = [ "keyword", "result-detail" ] | ||||
| keyword.keyword = [ "max", "recommended"] | ||||
| keyword.weight = [ 20, 10 ] | ||||
| result-detail.exitstatus = true | ||||
| result-detail.stdout = true | ||||
| result-detail.time = false | ||||
| result-detail.mem = false | ||||
| 
 | ||||
| [[stages]] | ||||
| name = "[cq] Clang-tidy" | ||||
| command = "run-clang-tidy-18 -header-filter=.* -quiet -load=/usr/local/lib/libcodequality.so -p h7/build h7/ex2.cpp" | ||||
| files.import = [ "tests/homework/h7/.clang-tidy", "h7/build/compile_commands.json" ] | ||||
| limit.stdout = 65 | ||||
| 
 | ||||
| parsers = [ "clangtidy", "result-detail" ] | ||||
| clangtidy.keyword = [ "codequality-unchecked-malloc-result", "codequality-no-global-variables", "codequality-no-header-guard", "codequality-no-fflush-stdin", "readability-function-size", "readability-duplicate-include", "readability-identifier-naming", "readability-redundant", "readability-misleading-indentation", "readability-misplaced-array-index", "cppcoreguidelines-init-variables", "bugprone-suspicious-string-compare", "google-global-names-in-headers", "clang-diagnostic", "clang-analyzer", "misc", "performance", "portability" ] | ||||
| clangtidy.weight = [ 5, 20, 20, 20, 10, 5, 5, 5, 15, 5, 5, 5, 5, 5, 5, 5, 5, 5] | ||||
| result-detail.exitstatus = true | ||||
| result-detail.stdout = true | ||||
| result-detail.time = false | ||||
| result-detail.mem = false | ||||
| 
 | ||||
| [[stages]] | ||||
| 
					
					jon-lee marked this conversation as resolved
					
						
						
							Outdated
						
					
				 
				
					
						张泊明518370910136
						commented  is it used? is it used? 
				
					
						李衍志523370910113
						commented  testcases in basic is intend to show a comprehensive situation. testcases in basic is intend to show a comprehensive situation. 
				
					
						张泊明518370910136
						commented  if unused, leave a comment if unused, leave a comment 
				
					
						张泊明518370910136
						commented  Then why is there a  Then why is there a `stdout` field in `class Limit` 
				
					
						李衍志523370910113
						commented  @bomingzh in toml now should we accept both  @bomingzh in toml now should we accept both `32m` and `32` or just `32m` now? 
				
					
						李衍志523370910113
						commented  I reckon only  I reckon only `32m` would be good 
				
					
						张泊明518370910136
						commented  yes, just str yes, just str | ||||
| name = "[cq] Cppcheck" | ||||
| command = "cppcheck --template='{\"file\":\"{file}\",\"line\":{line}, \"column\":{column}, \"severity\":\"{severity}\", \"message\":\"{message}\", \"id\":\"{id}\"}' --force --enable=all --suppress=missingIncludeSystem  --quiet h7/ex2.cpp" | ||||
| limit.stderr = 65 | ||||
| 
 | ||||
| parsers = [ "cppcheck", "result-detail" ] | ||||
| cppcheck.keyword = ["error", "warning", "portability", "performance", "style"] | ||||
| cppcheck.weight = [15, 5, 5, 5, 5] | ||||
| result-detail.exitstatus = true | ||||
| result-detail.stderr = true | ||||
| result-detail.time = false | ||||
| result-detail.mem = false | ||||
| 
 | ||||
| [[stages]] | ||||
| name = "[cq] Cpplint" | ||||
| command = "cpplint --linelength=120 --filter=-legal,-readability/casting,-whitespace,-runtime/printf,-runtime/threadsafe_fn,-runtime/int,-readability/todo,-build/include_subdir,-build/header_guard,-build/include_what_you_use --recursive --exclude=build h7/ex2.cpp" | ||||
| limit.stdout = 65 | ||||
| 
 | ||||
| parsers = [ "cpplint", "result-detail" ] | ||||
| cpplint.keyword = [ "runtime", "readability", "build" ] | ||||
| cpplint.weight = [ 5, 20, 10] | ||||
| result-detail.exitstatus = true | ||||
| result-detail.stderr = true | ||||
| result-detail.time = false | ||||
| result-detail.mem = false | ||||
| 
 | ||||
| [[stages]] | ||||
| name = "[joj] ex2-asan" | ||||
| group = "run" | ||||
| command="./h7/build/ex2-asan -a" | ||||
| files.import = [ "h7/build/ex2-asan" ] | ||||
| limit.mem = 91224961 | ||||
| 
 | ||||
| parsers = [ "diff", "result-detail" ] | ||||
| result-detail.exitstatus = true | ||||
| result-detail.stderr = true | ||||
| 
 | ||||
| # will be removed as long as the name is fixed | ||||
| case0.diff.output.score = 5 | ||||
| case0.limit.cpu = 1 | ||||
| case0.limit.mem = 91224961 | ||||
| case0.diff.output.ignorespaces = true | ||||
| #case0.limit.stdout = 8 | ||||
| #case0.command = "./h7/build/ex2" | ||||
| case0.in = "case0.in" | ||||
| 
 | ||||
| case1.diff.output.score = 5 | ||||
| case1.limit.cpu = 1 | ||||
| case1.limit.mem = 91224961 | ||||
| case1.diff.output.ignorespaces = true | ||||
| #case1.limit.stdout = 8 | ||||
| #case1.command = "./h7/build/ex2" | ||||
| case1.in = "case1.in" | ||||
| 
 | ||||
| case2.diff.output.score = 5 | ||||
| case2.limit.cpu = 1 | ||||
| case2.limit.mem = 91224961 | ||||
| case2.diff.output.ignorespaces = true | ||||
| #case2.limit.stdout = 8 | ||||
| #case2.command = "./h7/build/ex2" | ||||
| case2.in = "case2.in" | ||||
| 
 | ||||
| case3.diff.output.score = 5 | ||||
| case3.limit.cpu = 1 | ||||
| case3.limit.mem = 91224961 | ||||
| case3.diff.output.ignorespaces = true | ||||
| #case3.limit.stdout = 8 | ||||
| #case3.command = "./h7/build/ex2" | ||||
| case3.in = "case3.in" | ||||
| 
 | ||||
| case4.diff.output.score = 10 | ||||
| case4.limit.cpu = 1 | ||||
| case4.limit.mem = 91224961 | ||||
| case4.diff.output.ignorespaces = true | ||||
| #case4.limit.stdout = 8 | ||||
| #case4.command = "./h7/build/ex2" | ||||
| case4.in = "case4.in" | ||||
| 
 | ||||
| case5.diff.output.score = 10 | ||||
| case5.limit.cpu = 1 | ||||
| case5.limit.mem = 91224961 | ||||
| case5.diff.output.ignorespaces = true | ||||
| #case5.limit.stdout = 8 | ||||
| #case5.command = "./h7/build/ex2" | ||||
| case5.in = "case5.in" | ||||
| 
 | ||||
| case6.diff.output.score = 15 | ||||
| case6.limit.cpu = 1 | ||||
| case6.limit.mem = 91224961 | ||||
| case6.diff.output.ignorespaces = true | ||||
| #case6.limit.stdout = 8 | ||||
| #case6.command = "./h7/build/ex2" | ||||
| case6.in = "case6.in" | ||||
| 
 | ||||
| case7.diff.output.score = 15 | ||||
| case7.limit.cpu = 1 | ||||
| case7.limit.mem = 91224961 | ||||
| case7.diff.output.ignorespaces = true | ||||
| #case7.limit.stdout = 8 | ||||
| #case7.command = "./h7/build/ex2" | ||||
| case7.in = "case7.in" | ||||
| 
 | ||||
| case8.diff.output.score = 15 | ||||
| case8.limit.cpu = 1 | ||||
| case8.limit.mem = 91224961 | ||||
| case8.diff.output.ignorespaces = true | ||||
| #case8.limit.stdout = 8 | ||||
| #case8.command = "./h7/build/ex2" | ||||
| case8.in = "case8.in" | ||||
| 
 | ||||
| case9.diff.output.score = 15 | ||||
| case9.limit.cpu = 1 | ||||
| case9.limit.mem = 91224961 | ||||
| case9.diff.output.ignorespaces = true | ||||
| #case9.limit.stdout = 8 | ||||
| #case9.command = "./h7/build/ex2" | ||||
| case9.in = "case9.in" | ||||
| 
 | ||||
| [[stages]] | ||||
| name = "[joj] ex2-msan" | ||||
| group = "joj" | ||||
| command="./h7/build/ex2-msan -a" | ||||
| files.import = [ "h7/build/ex2-msan" ] | ||||
| limit.mem = 91224961 | ||||
| 
 | ||||
| parsers = [ "diff", "result-detail" ] | ||||
| result-detail.exitstatus = true | ||||
| result-detail.stderr = true | ||||
| 
 | ||||
| # will be removed as long as the name is fixed | ||||
| case0.diff.output.score = 5 | ||||
| case0.limit.cpu = 1 | ||||
| case0.limit.mem = 91224961 | ||||
| case0.diff.output.ignorespaces = true | ||||
| #case0.limit.stdout = 8 | ||||
| #case0.command = "./h7/build/ex2" | ||||
| case0.in = "case0.in" | ||||
| 
 | ||||
| case1.diff.output.score = 5 | ||||
| case1.limit.cpu = 1 | ||||
| case1.limit.mem = 91224961 | ||||
| case1.diff.output.ignorespaces = true | ||||
| #case1.limit.stdout = 8 | ||||
| #case1.command = "./h7/build/ex2" | ||||
| case1.in = "case1.in" | ||||
| 
 | ||||
| case2.diff.output.score = 5 | ||||
| case2.limit.cpu = 1 | ||||
| case2.limit.mem = 91224961 | ||||
| case2.diff.output.ignorespaces = true | ||||
| #case2.limit.stdout = 8 | ||||
| #case2.command = "./h7/build/ex2" | ||||
| case2.in = "case2.in" | ||||
| 
 | ||||
| case3.diff.output.score = 5 | ||||
| case3.limit.cpu = 1 | ||||
| case3.limit.mem = 91224961 | ||||
| case3.diff.output.ignorespaces = true | ||||
| #case3.limit.stdout = 8 | ||||
| #case3.command = "./h7/build/ex2" | ||||
| case3.in = "case3.in" | ||||
| 
 | ||||
| case4.diff.output.score = 10 | ||||
| case4.limit.cpu = 1 | ||||
| case4.limit.mem = 91224961 | ||||
| case4.diff.output.ignorespaces = true | ||||
| #case4.limit.stdout = 8 | ||||
| #case4.command = "./h7/build/ex2" | ||||
| case4.in = "case4.in" | ||||
| 
 | ||||
| case5.diff.output.score = 10 | ||||
| case5.limit.cpu = 1 | ||||
| case5.limit.mem = 91224961 | ||||
| case5.diff.output.ignorespaces = true | ||||
| #case5.limit.stdout = 8 | ||||
| #case5.command = "./h7/build/ex2" | ||||
| case5.in = "case5.in" | ||||
| 
 | ||||
| case6.diff.output.score = 15 | ||||
| case6.limit.cpu = 1 | ||||
| case6.limit.mem = 91224961 | ||||
| case6.diff.output.ignorespaces = true | ||||
| #case6.limit.stdout = 8 | ||||
| #case6.command = "./h7/build/ex2" | ||||
| case6.in = "case6.in" | ||||
| 
 | ||||
| case7.diff.output.score = 15 | ||||
| case7.limit.cpu = 1 | ||||
| case7.limit.mem = 91224961 | ||||
| case7.diff.output.ignorespaces = true | ||||
| #case7.limit.stdout = 8 | ||||
| #case7.command = "./h7/build/ex2" | ||||
| case7.in = "case7.in" | ||||
| 
 | ||||
| case8.diff.output.score = 15 | ||||
| case8.limit.cpu = 1 | ||||
| case8.limit.mem = 91224961 | ||||
| case8.diff.output.ignorespaces = true | ||||
| #case8.limit.stdout = 8 | ||||
| #case8.command = "./h7/build/ex2" | ||||
| case8.in = "case8.in" | ||||
| 
 | ||||
| case9.diff.output.score = 15 | ||||
| case9.limit.cpu = 1 | ||||
| case9.limit.mem = 91224961 | ||||
| case9.diff.output.ignorespaces = true | ||||
| #case9.limit.stdout = 8 | ||||
| #case9.command = "./h7/build/ex2" | ||||
| case9.in = "case9.in" | ||||
| 
 | ||||
| 
 | ||||
| [[stages]] | ||||
| name = "[joj] ex2-ubsan" | ||||
| command="./h7/build/ex2-ubsan -a" | ||||
| files.import = [ "h7/build/ex2-ubsan" ] | ||||
| 
 | ||||
| parsers = [ "diff", "result-detail" ] | ||||
| result-detail.exitstatus = true | ||||
| result-detail.stderr = true | ||||
| 
 | ||||
| # will be removed as long as the name is fixed | ||||
| case0.diff.output.score = 5 | ||||
| case0.limit.cpu = 1 | ||||
| case0.limit.mem = 91224961 | ||||
| case0.diff.output.ignorespaces = true | ||||
| #case0.limit.stdout = 8 | ||||
| #case0.command = "./h7/build/ex2" | ||||
| case0.in = "case0.in" | ||||
| 
 | ||||
| case1.diff.output.score = 5 | ||||
| case1.limit.cpu = 1 | ||||
| case1.limit.mem = 91224961 | ||||
| case1.diff.output.ignorespaces = true | ||||
| #case1.limit.stdout = 8 | ||||
| #case1.command = "./h7/build/ex2" | ||||
| case1.in = "case1.in" | ||||
| 
 | ||||
| case2.diff.output.score = 5 | ||||
| case2.limit.cpu = 1 | ||||
| case2.limit.mem = 91224961 | ||||
| case2.diff.output.ignorespaces = true | ||||
| #case2.limit.stdout = 8 | ||||
| #case2.command = "./h7/build/ex2" | ||||
| case2.in = "case2.in" | ||||
| 
 | ||||
| case3.diff.output.score = 5 | ||||
| case3.limit.cpu = 1 | ||||
| case3.limit.mem = 91224961 | ||||
| case3.diff.output.ignorespaces = true | ||||
| #case3.limit.stdout = 8 | ||||
| #case3.command = "./h7/build/ex2" | ||||
| case3.in = "case3.in" | ||||
| 
 | ||||
| case4.diff.output.score = 10 | ||||
| case4.limit.cpu = 1 | ||||
| case4.limit.mem = 91224961 | ||||
| case4.diff.output.ignorespaces = true | ||||
| #case4.limit.stdout = 8 | ||||
| #case4.command = "./h7/build/ex2" | ||||
| case4.in = "case4.in" | ||||
| 
 | ||||
| case5.diff.output.score = 10 | ||||
| case5.limit.cpu = 1 | ||||
| case5.limit.mem = 91224961 | ||||
| case5.diff.output.ignorespaces = true | ||||
| #case5.limit.stdout = 8 | ||||
| #case5.command = "./h7/build/ex2" | ||||
| case5.in = "case5.in" | ||||
| 
 | ||||
| case6.diff.output.score = 15 | ||||
| case6.limit.cpu = 1 | ||||
| case6.limit.mem = 91224961 | ||||
| case6.diff.output.ignorespaces = true | ||||
| #case6.limit.stdout = 8 | ||||
| #case6.command = "./h7/build/ex2" | ||||
| case6.in = "case6.in" | ||||
| 
 | ||||
| case7.diff.output.score = 15 | ||||
| case7.limit.cpu = 1 | ||||
| case7.limit.mem = 91224961 | ||||
| case7.diff.output.ignorespaces = true | ||||
| #case7.limit.stdout = 8 | ||||
| #case7.command = "./h7/build/ex2" | ||||
| case7.in = "case7.in" | ||||
| 
 | ||||
| case8.diff.output.score = 15 | ||||
| case8.limit.cpu = 1 | ||||
| case8.limit.mem = 91224961 | ||||
| case8.diff.output.ignorespaces = true | ||||
| #case8.limit.stdout = 8 | ||||
| #case8.command = "./h7/build/ex2" | ||||
| case8.in = "case8.in" | ||||
| 
 | ||||
| case9.diff.output.score = 15 | ||||
| case9.limit.cpu = 1 | ||||
| case9.limit.mem = 91224961 | ||||
| case9.diff.output.ignorespaces = true | ||||
| #case9.limit.stdout = 8 | ||||
| #case9.command = "./h7/build/ex2" | ||||
| case9.in = "case9.in" | ||||
| 
 | ||||
| 
 | ||||
| [[stages]] | ||||
| name = "[joj] ex2" | ||||
| group = "joj" | ||||
| command="./h7/build/ex2" | ||||
| files.import = [ "h7/build/ex2" ] | ||||
| score = 10 | ||||
| 
 | ||||
| parsers = [ "diff", "result-detail" ] | ||||
| result-detail.exitstatus = true | ||||
| result-detail.stderr = true | ||||
| result-status.forcequit = true | ||||
| 
 | ||||
| # will be removed as long as the name is fixed | ||||
| case0.diff.output.score = 5 | ||||
| case0.limit.cpu = 1 | ||||
| case0.limit.mem = 91224961 | ||||
| case0.diff.output.ignorespaces = true | ||||
| #case0.limit.stdout = 8 | ||||
| #case0.command = "./h7/build/ex2" | ||||
| case0.in = "case0.in" | ||||
| 
 | ||||
| case1.diff.output.score = 5 | ||||
| case1.limit.cpu = 1 | ||||
| case1.limit.mem = 91224961 | ||||
| case1.diff.output.ignorespaces = true | ||||
| #case1.limit.stdout = 8 | ||||
| #case1.command = "./h7/build/ex2" | ||||
| case1.in = "case1.in" | ||||
| 
 | ||||
| case2.diff.output.score = 5 | ||||
| case2.limit.cpu = 1 | ||||
| case2.limit.mem = 91224961 | ||||
| case2.diff.output.ignorespaces = true | ||||
| #case2.limit.stdout = 8 | ||||
| #case2.command = "./h7/build/ex2" | ||||
| case2.in = "case2.in" | ||||
| 
 | ||||
| case3.diff.output.score = 5 | ||||
| case3.limit.cpu = 1 | ||||
| case3.limit.mem = 91224961 | ||||
| case3.diff.output.ignorespaces = true | ||||
| #case3.limit.stdout = 8 | ||||
| #case3.command = "./h7/build/ex2" | ||||
| case3.in = "case3.in" | ||||
| 
 | ||||
| case4.diff.output.score = 10 | ||||
| case4.limit.cpu = 1 | ||||
| case4.limit.mem = 91224961 | ||||
| case4.diff.output.ignorespaces = true | ||||
| #case4.limit.stdout = 8 | ||||
| #case4.command = "./h7/build/ex2" | ||||
| case4.in = "case4.in" | ||||
| 
 | ||||
| case5.diff.output.score = 10 | ||||
| case5.limit.cpu = 1 | ||||
| case5.limit.mem = 91224961 | ||||
| case5.diff.output.ignorespaces = true | ||||
| #case5.limit.stdout = 8 | ||||
| #case5.command = "./h7/build/ex2" | ||||
| case5.in = "case5.in" | ||||
| 
 | ||||
| case6.diff.output.score = 15 | ||||
| case6.limit.cpu = 1 | ||||
| case6.limit.mem = 91224961 | ||||
| case6.diff.output.ignorespaces = true | ||||
| #case6.limit.stdout = 8 | ||||
| #case6.command = "./h7/build/ex2" | ||||
| case6.in = "case6.in" | ||||
| 
 | ||||
| case7.diff.output.score = 15 | ||||
| case7.limit.cpu = 1 | ||||
| case7.limit.mem = 91224961 | ||||
| case7.diff.output.ignorespaces = true | ||||
| #case7.limit.stdout = 8 | ||||
| #case7.command = "./h7/build/ex2" | ||||
| case7.in = "case7.in" | ||||
| 
 | ||||
| case8.diff.output.score = 15 | ||||
| case8.limit.cpu = 1 | ||||
| case8.limit.mem = 91224961 | ||||
| case8.diff.output.ignorespaces = true | ||||
| #case8.limit.stdout = 8 | ||||
| #case8.command = "./h7/build/ex2" | ||||
| case8.in = "case8.in" | ||||
| 
 | ||||
| case9.diff.output.score = 15 | ||||
| case9.limit.cpu = 1 | ||||
| case9.limit.mem = 91224961 | ||||
| case9.diff.output.ignorespaces = true | ||||
| #case9.limit.stdout = 8 | ||||
| #case9.command = "./h7/build/ex2" | ||||
| case9.in = "case9.in" | ||||
|  |  | |||
|  | @ -16,4 +16,4 @@ jobs: | |||
|           fetch-depth: 0 | ||||
|       - name: run joj3 | ||||
|         run: | | ||||
|           sudo -E -u tt joj3 -conf-root /home/tt/.config/joj/tests/homework                     | ||||
|           sudo -E -u tt joj3 -conf-root /home/tt/.config/joj/tests/homework | ||||
|  |  | |||
|  | @ -18,4 +18,4 @@ jobs: | |||
|           fetch-depth: 0 | ||||
|       - name: run joj3 | ||||
|         run: | | ||||
|           sudo -E -u tt joj3 -conf-root "/home/tt/.config/joj/tests/homework" -conf-name "conf-release.json" -tag "${{ github.ref_name }}"           | ||||
|           sudo -E -u tt joj3 -conf-root "/home/tt/.config/joj/tests/homework" -conf-name "conf-release.json" -tag "${{ github.ref_name }}" | ||||
|  |  | |||
|  | @ -16,4 +16,4 @@ jobs: | |||
|           fetch-depth: 0 | ||||
|       - name: run joj3 | ||||
|         run: | | ||||
|           sudo -E -u tt joj3 -conf-root /home/tt/.config/joj/homework           | ||||
|           sudo -E -u tt joj3 -conf-root /home/tt/.config/joj/homework | ||||
|  |  | |||
|  | @ -16,5 +16,4 @@ jobs: | |||
|           fetch-depth: 0 | ||||
|       - name: run joj3 | ||||
|         run: | | ||||
|           sudo -E -u tt joj3 -conf-root /home/tt/.config/joj/tests/projects/p3                               | ||||
| 
 | ||||
|           sudo -E -u tt joj3 -conf-root /home/tt/.config/joj/tests/projects/p3 | ||||
|  |  | |||
|  | @ -18,5 +18,4 @@ jobs: | |||
|           fetch-depth: 0 | ||||
|       - name: run joj3 | ||||
|         run: | | ||||
|           sudo -E -u tt joj3 -conf-root "/home/tt/.config/joj/tests/projects/p3" -conf-name "conf-release.json" -tag "${{ github.ref_name }}"                     | ||||
| 
 | ||||
|           sudo -E -u tt joj3 -conf-root "/home/tt/.config/joj/tests/projects/p3" -conf-name "conf-release.json" -tag "${{ github.ref_name }}" | ||||
|  |  | |||
|  | @ -16,5 +16,4 @@ jobs: | |||
|           fetch-depth: 0 | ||||
|       - name: run joj3 | ||||
|         run: | | ||||
|           sudo -E -u tt joj3 -conf-root /home/tt/.config/joj/projects/p3                               | ||||
| 
 | ||||
|           sudo -E -u tt joj3 -conf-root /home/tt/.config/joj/projects/p3 | ||||
|  |  | |||
|  | @ -18,5 +18,4 @@ jobs: | |||
|           fetch-depth: 0 | ||||
|       - name: run joj3 | ||||
|         run: | | ||||
|           sudo -E -u tt joj3 -conf-root "/home/tt/.config/joj/projects/p3" -conf-name "conf-release.json" -tag "${{ github.ref_name }}"                     | ||||
| 
 | ||||
|           sudo -E -u tt joj3 -conf-root "/home/tt/.config/joj/projects/p3" -conf-name "conf-release.json" -tag "${{ github.ref_name }}" | ||||
|  |  | |||
where is it used?
this should be storing all the files that are about to be copy in or out
It is as the input and output for the following functions about parsers
so this feature is not implemented?
it is
this is a loop, so this
cachedwill be updated in every round of stageThe return value is unnecessary.
I have a lazing coding style here, everything has get imported would get exported, so should maintain this until the end of the loop. Everything is exported in previous stage would be imported in the next stage.
settry it yourself
I see why
resolved.