Merge branch 'master' into fix/diff
All checks were successful
build / build (push) Successful in 1m48s

This commit is contained in:
李衍志523370910113 2025-05-14 18:07:25 +08:00
commit ba456cf7f0
18 changed files with 126 additions and 46 deletions

View File

@ -30,6 +30,7 @@ jobs:
run: |
pdm run coverage
- name: Upload Coverage to Codacy
if: github.ref == 'refs/heads/master'
env:
CODACY_PROJECT_TOKEN: ${{ secrets.CODACY_PROJECT_TOKEN }}
run: |

View File

@ -1,5 +1,5 @@
from pathlib import Path
from typing import Tuple
from typing import Tuple, Type, cast
import inquirer
import tomli
@ -10,9 +10,16 @@ from joj3_config_generator.models import answer, joj1, repo, task
def load_joj3_task_toml_answers() -> answer.Answers:
name = inquirer.text("What's the task name?", default="hw0")
language: answer.LanguageInterface = inquirer.list_input(
"What's the language?", choices=answer.LANGUAGES
language = inquirer.list_input(
"What's the language?", choices=[(cls.name, cls) for cls in answer.LANGUAGES]
)
language = cast(Type[answer.LanguageInterface], language)
if inquirer.confirm("Load content from templates?", default=True):
answers = inquirer.prompt(language.get_template_questions())
template_file_content: str = answers["template_file_content"]
return answer.Answers(
name=name, language=language, template_file_content=template_file_content
)
stages = inquirer.checkbox(
"What's the stages?",
choices=[member.value for member in language.Stage],

View File

@ -1,14 +1,14 @@
from abc import ABC, abstractmethod
from enum import Enum
from typing import Any, ClassVar, Dict, List
from importlib import resources
from typing import Any, ClassVar, Dict, List, Type
import inquirer
from pydantic import BaseModel, ConfigDict
class LanguageInterface(ABC):
@abstractmethod
def __str__(self) -> str: ...
name: ClassVar[str]
@abstractmethod
class Stage(str, Enum): ...
@ -31,10 +31,25 @@ class LanguageInterface(ABC):
@abstractmethod
def get_attribute_questions(cls) -> List[Any]: ...
@classmethod
def get_template_questions(cls) -> List[Any]:
anchor = "joj3_config_generator.templates"
templates_dir = resources.files(anchor).joinpath(cls.name)
choices = []
for entry in templates_dir.iterdir():
if entry.is_file() and entry.name.endswith(".toml"):
choices.append((entry.name, entry.read_text()))
return [
inquirer.List(
"template_file_content",
message="Which template file do you want?",
choices=choices,
),
]
class Cpp(LanguageInterface):
def __str__(self) -> str:
return "C++"
name = "C++"
class Stage(str, Enum):
COMPILATION = "Compilation"
@ -52,23 +67,23 @@ class Cpp(LanguageInterface):
@classmethod
def get_attribute_questions(cls) -> List[Any]:
attribute: Cpp.Attribute = cls.attribute
return [
inquirer.Text(
name="compile_command",
message="Compile command",
default=cls.attribute.compile_command,
default=attribute.compile_command,
),
inquirer.Text(
name="run_command",
message="Run command",
default=cls.attribute.run_command,
default=attribute.run_command,
),
]
class Python(LanguageInterface):
def __str__(self) -> str:
return "Python"
name = "Python"
class Stage(str, Enum):
RUN = "Run"
@ -81,18 +96,18 @@ class Python(LanguageInterface):
@classmethod
def get_attribute_questions(cls) -> List[Any]:
attribute: Python.Attribute = cls.attribute
return [
inquirer.Text(
name="run_command",
message="Run command",
default=cls.attribute.run_command,
default=attribute.run_command,
),
]
class Rust(LanguageInterface):
def __str__(self) -> str:
return "Rust"
name = "Rust"
class Stage(str, Enum):
COMPILATION = "Compilation"
@ -107,18 +122,20 @@ class Rust(LanguageInterface):
@classmethod
def get_attribute_questions(cls) -> List[Any]:
attribute: Rust.Attribute = cls.attribute
return []
LANGUAGES = [
Cpp(),
Python(),
Rust(),
LANGUAGES: List[Type[LanguageInterface]] = [
Cpp,
Python,
Rust,
]
class Answers(BaseModel):
name: str
language: LanguageInterface
language: Type[LanguageInterface]
template_file_content: str = ""
model_config = ConfigDict(arbitrary_types_allowed=True)

View File

@ -3,7 +3,7 @@ from pathlib import Path
from joj3_config_generator.models.common import Memory, Time
DEFAULT_CPU_LIMIT = Time("1s")
DEFAULT_MEMORY_LIMIT = Memory("128m")
DEFAULT_MEMORY_LIMIT = Memory("256m")
DEFAULT_FILE_LIMIT = Memory("32m")
JOJ3_CONFIG_ROOT = Path("/home/tt/.config/joj")

View File

@ -0,0 +1,13 @@
[[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 = "65m"
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

View File

@ -0,0 +1,12 @@
[[stages]]
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 = "65m"
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

View File

@ -0,0 +1,12 @@
[[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 = "65m"
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

View File

@ -0,0 +1,3 @@
[[stages]]
name = "Run"
command = "python3 main.py"

View File

@ -0,0 +1,3 @@
[[stages]]
name = "Run"
command = "cargo run"

View File

@ -1,19 +1,27 @@
from typing import Any, Callable, Dict, List, Type
import tomli
from joj3_config_generator.models import answer, task
def get_task_conf_from_answers(answers: answer.Answers) -> task.Config:
if answers.template_file_content:
toml_dict = tomli.loads(answers.template_file_content)
return task.Config(
task=task.Task(name=answers.name),
stages=toml_dict["stages"],
)
language = answers.language
transformer_dict = get_transformer_dict()
transformer = transformer_dict[type(language)]
transformer = transformer_dict[language]
stages = transformer(language)
return task.Config(task=task.Task(name=answers.name), stages=stages)
def get_transformer_dict() -> Dict[
Type[Any],
Callable[[Any], List[task.Stage]],
Type[answer.LanguageInterface],
Callable[[Type[Any]], List[task.Stage]],
]:
return {
answer.Cpp: get_cpp_stages,
@ -23,7 +31,7 @@ def get_transformer_dict() -> Dict[
# TODO: implement
def get_cpp_stages(language: answer.Cpp) -> List[task.Stage]:
def get_cpp_stages(language: Type[answer.Cpp]) -> List[task.Stage]:
stages = language.stages
attribute: answer.Cpp.Attribute = language.attribute
task_stages = []
@ -39,14 +47,14 @@ def get_cpp_stages(language: answer.Cpp) -> List[task.Stage]:
# TODO: implement
def get_python_stages(language: answer.Python) -> List[task.Stage]:
def get_python_stages(language: Type[answer.Python]) -> List[task.Stage]:
stages = language.stages
attribute: answer.Python.Attribute = language.attribute
return []
# TODO: implement
def get_rust_stages(language: answer.Rust) -> List[task.Stage]:
def get_rust_stages(language: Type[answer.Rust]) -> List[task.Stage]:
stages = language.stages
attribute: answer.Rust.Attribute = language.attribute
return []

View File

@ -2,7 +2,7 @@ import hashlib
from pathlib import Path
from typing import List
from joj3_config_generator.models import repo, result
from joj3_config_generator.models import common, repo, result
from joj3_config_generator.models.const import TEAPOT_CONFIG_ROOT, TEAPOT_LOG_PATH
@ -25,6 +25,8 @@ def get_teapot_stage(repo_conf: repo.Config) -> result.StageDetail:
default=result.Cmd(
args=args,
env=[f"LOG_FILE_PATH={TEAPOT_LOG_PATH}"],
cpu_limit=common.Time("30s"),
clock_limit=common.Time("60s"),
),
cases=[],
),
@ -71,7 +73,9 @@ def get_health_check_stage(repo_conf: repo.Config) -> result.StageDetail:
executor=result.Executor(
name="local",
with_=result.ExecutorWith(
default=result.Cmd(),
default=result.Cmd(
cpu_limit=common.Time("10s"), clock_limit=common.Time("20s")
),
cases=[
result.OptionalCmd(
args=get_health_check_args(repo_conf),

View File

@ -32,9 +32,9 @@
"max": 33554432,
"pipe": true
},
"cpuLimit": 1000000000,
"clockLimit": 2000000000,
"memoryLimit": 134217728,
"cpuLimit": 10000000000,
"clockLimit": 20000000000,
"memoryLimit": 268435456,
"stackLimit": 0,
"procLimit": 50,
"cpuRateLimit": 0,
@ -124,7 +124,7 @@
},
"cpuLimit": 1000000000,
"clockLimit": 2000000000,
"memoryLimit": 134217728,
"memoryLimit": 268435456,
"stackLimit": 0,
"procLimit": 50,
"cpuRateLimit": 0,
@ -211,7 +211,7 @@
},
"cpuLimit": 1000000000,
"clockLimit": 2000000000,
"memoryLimit": 134217728,
"memoryLimit": 268435456,
"stackLimit": 0,
"procLimit": 50,
"cpuRateLimit": 0,
@ -311,7 +311,7 @@
},
"cpuLimit": 1000000000,
"clockLimit": 2000000000,
"memoryLimit": 134217728,
"memoryLimit": 268435456,
"stackLimit": 0,
"procLimit": 50,
"cpuRateLimit": 0,
@ -437,7 +437,7 @@
},
"cpuLimit": 1000000000,
"clockLimit": 2000000000,
"memoryLimit": 134217728,
"memoryLimit": 268435456,
"stackLimit": 0,
"procLimit": 50,
"cpuRateLimit": 0,
@ -582,7 +582,7 @@
},
"cpuLimit": 1000000000,
"clockLimit": 2000000000,
"memoryLimit": 134217728,
"memoryLimit": 268435456,
"stackLimit": 0,
"procLimit": 50,
"cpuRateLimit": 0,
@ -806,9 +806,9 @@
"max": 33554432,
"pipe": true
},
"cpuLimit": 1000000000,
"clockLimit": 2000000000,
"memoryLimit": 134217728,
"cpuLimit": 30000000000,
"clockLimit": 60000000000,
"memoryLimit": 268435456,
"stackLimit": 0,
"procLimit": 50,
"cpuRateLimit": 0,

View File

@ -42,7 +42,7 @@
},
"cpuLimit": 1000000000,
"clockLimit": 2000000000,
"memoryLimit": 134217728,
"memoryLimit": 268435456,
"stackLimit": 0,
"procLimit": 50,
"cpuRateLimit": 0,

View File

@ -42,7 +42,7 @@
},
"cpuLimit": 1000000000,
"clockLimit": 2000000000,
"memoryLimit": 134217728,
"memoryLimit": 268435456,
"stackLimit": 0,
"procLimit": 50,
"cpuRateLimit": 0,

View File

@ -41,7 +41,7 @@
},
"cpuLimit": 1000000000,
"clockLimit": 2000000000,
"memoryLimit": 134217728,
"memoryLimit": 268435456,
"stackLimit": 0,
"procLimit": 50,
"cpuRateLimit": 0,

View File

@ -40,7 +40,7 @@
},
"cpuLimit": 1000000000,
"clockLimit": 2000000000,
"memoryLimit": 134217728,
"memoryLimit": 268435456,
"stackLimit": 0,
"procLimit": 50,
"cpuRateLimit": 0,

View File

@ -40,7 +40,7 @@
},
"cpuLimit": 1000000000,
"clockLimit": 2000000000,
"memoryLimit": 134217728,
"memoryLimit": 268435456,
"stackLimit": 0,
"procLimit": 50,
"cpuRateLimit": 0,

View File

@ -13,7 +13,7 @@ def load_case(case_name: str) -> None:
answers_json_path = root / case_name / "answers.json"
task_toml_path = root / case_name / "task.toml"
answers_dict = json.loads(answers_json_path.read_text())
language = next(x for x in answer.LANGUAGES if str(x) == answers_dict["language"])
language = next(x for x in answer.LANGUAGES if x.name == answers_dict["language"])
language.set_stages(answers_dict["stages"])
language.set_attribute(answers_dict["attribute"])
answers = answer.Answers(name=answers_dict["name"], language=language)