Compare commits

...

3 Commits

Author SHA1 Message Date
454df2c6fc
feat(conf): pre-stages and post-stages (#83)
Some checks failed
build / build (push) Failing after 1s
build / trigger-build-image (push) Has been skipped
submodules sync / sync (push) Failing after 0s
2025-01-29 08:13:33 -05:00
0f339656aa
chore(internal/conf): split models to a new file 2025-01-29 07:57:58 -05:00
46f2375165
docs(cmd/joj3): comments 2025-01-29 07:55:45 -05:00
4 changed files with 148 additions and 95 deletions

View File

@ -36,6 +36,8 @@ func mainImpl() (err error) {
var forceQuitStageName string
var teapotRunResult teapot.RunResult
var commitMsg string
// summarize
defer func() {
totalScore := 0
for _, stageResult := range stageResults {
@ -64,6 +66,8 @@ func mainImpl() (err error) {
slog.Error("setup slog", "error", err)
return err
}
// parse flag & conf file
flag.Parse()
if *showVersion {
fmt.Println(Version)
@ -96,6 +100,8 @@ func mainImpl() (err error) {
slog.Error("setup slog", "error", err)
return err
}
// log conf file info
sha256, err := conf.GetSHA256(confPath)
if err != nil {
slog.Error("get sha256", "error", err)
@ -107,6 +113,8 @@ func mainImpl() (err error) {
slog.Error("conf check expire", "error", err)
return err
}
// run stages
groups := conf.MatchGroups(confObj, conventionalCommit)
stageResults, forceQuitStageName, err = stage.Run(
confObj, groups,
@ -118,6 +126,8 @@ func mainImpl() (err error) {
slog.Error("stage write", "error", err)
return err
}
// run teapot
teapotRunResult, err = teapot.Run(confObj, groups)
if err != nil {
slog.Error("teapot run", "error", err)

View File

@ -15,10 +15,12 @@ import (
type StageResult stage.StageResult
func generateStages(conf *conf.Conf, groups []string) ([]stage.Stage, error) {
func generateStages(confStages []conf.ConfStage, groups []string) (
[]stage.Stage, error,
) {
stages := []stage.Stage{}
existNames := map[string]bool{}
for _, s := range conf.Stage.Stages {
for _, s := range confStages {
if s.Group != "" {
var ok bool
for _, group := range groups {
@ -137,18 +139,41 @@ func Run(conf *conf.Conf, groups []string) (
conf.Stage.SandboxExecServer,
conf.Stage.SandboxToken,
)
stages, err := generateStages(conf, groups)
preStages, err := generateStages(conf.Stage.PreStages, groups)
if err != nil {
slog.Error("generate preStages", "error", err)
stageResults, forceQuitStageName = newErrorStageResults(err)
return
}
stages, err := generateStages(conf.Stage.Stages, groups)
if err != nil {
slog.Error("generate stages", "error", err)
stageResults, forceQuitStageName = newErrorStageResults(err)
return
}
postStages, err := generateStages(conf.Stage.PostStages, groups)
if err != nil {
slog.Error("generate postStages", "error", err)
stageResults, forceQuitStageName = newErrorStageResults(err)
return
}
defer stage.Cleanup()
// ignore force quit in preStages & postStages
slog.Info("run preStages")
_, _, err = stage.Run(preStages)
if err != nil {
slog.Error("run preStages", "error", err)
}
slog.Info("run stages")
stageResults, forceQuitStageName, err = stage.Run(stages)
if err != nil {
slog.Error("run stages", "error", err)
stageResults, forceQuitStageName = newErrorStageResults(err)
return
}
slog.Info("run postStages")
_, _, err = stage.Run(postStages)
if err != nil {
slog.Error("run postStages", "error", err)
}
return
}

View File

@ -14,98 +14,9 @@ import (
"time"
"github.com/go-git/go-git/v5"
"github.com/joint-online-judge/JOJ3/internal/stage"
"github.com/koding/multiconfig"
)
type ConfStage struct {
Name string
Group string
Executor struct {
Name string
With struct {
Default stage.Cmd
Cases []OptionalCmd
}
}
Parsers []struct {
Name string
With interface{}
}
}
type ConfGroup struct {
Name string
MaxCount int
TimePeriodHour int
}
type Conf struct {
Name string `default:"unknown"`
LogPath string `default:""`
ActorCsvPath string `default:""`
ExpireUnixTimestamp int64 `default:"-1"`
MaxTotalScore int `default:"-1"`
Stage struct {
SandboxExecServer string `default:"localhost:5051"`
SandboxToken string `default:""`
OutputPath string `default:"joj3_result.json"`
Stages []ConfStage
}
Teapot struct {
LogPath string `default:"/home/tt/.cache/joint-teapot-debug.log"`
EnvFilePath string `default:"/home/tt/.config/teapot/teapot.env"`
ScoreboardPath string `default:"scoreboard.csv"`
FailedTablePath string `default:"failed-table.md"`
GradingRepoName string `default:""`
SkipIssue bool `default:"false"`
SkipScoreboard bool `default:"false"`
SkipFailedTable bool `default:"false"`
SubmitterInIssueTitle bool `default:"true"`
Groups []ConfGroup
}
}
type OptionalCmd struct {
Args *[]string
Env *[]string
Stdin *stage.CmdFile
Stdout *stage.CmdFile
Stderr *stage.CmdFile
CPULimit *uint64
RealCPULimit *uint64
ClockLimit *uint64
MemoryLimit *uint64
StackLimit *uint64
ProcLimit *uint64
CPURateLimit *uint64
CPUSetLimit *string
CopyIn *map[string]stage.CmdFile
CopyInCached *map[string]string
CopyInDir *string
CopyOut *[]string
CopyOutCached *[]string
CopyOutMax *uint64
CopyOutDir *string
TTY *bool
StrictMemoryLimit *bool
DataSegmentLimit *bool
AddressSpaceLimit *bool
}
type ConventionalCommit struct {
Type string
Scope string
Description string
Group string
Body string
Footer string
}
func GetCommitMsg() (msg string, err error) {
r, err := git.PlainOpen(".")
if err != nil {
@ -275,10 +186,22 @@ func MatchGroups(conf *Conf, conventionalCommit *ConventionalCommit) []string {
seen := make(map[string]bool)
keywords := []string{}
loweredCommitGroup := strings.ToLower(conventionalCommit.Group)
for i, stage := range conf.Stage.Stages {
if loweredCommitGroup == "all" {
if loweredCommitGroup == "all" {
for i := range conf.Stage.PreStages {
conf.Stage.PreStages[i].Group = ""
}
for i := range conf.Stage.Stages {
conf.Stage.Stages[i].Group = ""
}
for i := range conf.Stage.PostStages {
conf.Stage.PostStages[i].Group = ""
}
}
confStages := []ConfStage{}
confStages = append(confStages, conf.Stage.PreStages...)
confStages = append(confStages, conf.Stage.Stages...)
confStages = append(confStages, conf.Stage.PostStages...)
for _, stage := range confStages {
if stage.Group == "" {
continue
}

95
internal/conf/model.go Normal file
View File

@ -0,0 +1,95 @@
package conf
import (
"github.com/joint-online-judge/JOJ3/internal/stage"
)
type ConfStage struct {
Name string
Group string
Executor struct {
Name string
With struct {
Default stage.Cmd
Cases []OptionalCmd
}
}
Parsers []struct {
Name string
With interface{}
}
}
type ConfGroup struct {
Name string
MaxCount int
TimePeriodHour int
}
type Conf struct {
Name string `default:"unknown"`
LogPath string `default:""`
ActorCsvPath string `default:""`
ExpireUnixTimestamp int64 `default:"-1"`
MaxTotalScore int `default:"-1"`
Stage struct {
SandboxExecServer string `default:"localhost:5051"`
SandboxToken string `default:""`
OutputPath string `default:"joj3_result.json"`
PreStages []ConfStage
Stages []ConfStage
PostStages []ConfStage
}
Teapot struct {
LogPath string `default:"/home/tt/.cache/joint-teapot-debug.log"`
EnvFilePath string `default:"/home/tt/.config/teapot/teapot.env"`
ScoreboardPath string `default:"scoreboard.csv"`
FailedTablePath string `default:"failed-table.md"`
GradingRepoName string `default:""`
SkipIssue bool `default:"false"`
SkipScoreboard bool `default:"false"`
SkipFailedTable bool `default:"false"`
SubmitterInIssueTitle bool `default:"true"`
Groups []ConfGroup
}
}
type OptionalCmd struct {
Args *[]string
Env *[]string
Stdin *stage.CmdFile
Stdout *stage.CmdFile
Stderr *stage.CmdFile
CPULimit *uint64
RealCPULimit *uint64
ClockLimit *uint64
MemoryLimit *uint64
StackLimit *uint64
ProcLimit *uint64
CPURateLimit *uint64
CPUSetLimit *string
CopyIn *map[string]stage.CmdFile
CopyInCached *map[string]string
CopyInDir *string
CopyOut *[]string
CopyOutCached *[]string
CopyOutMax *uint64
CopyOutDir *string
TTY *bool
StrictMemoryLimit *bool
DataSegmentLimit *bool
AddressSpaceLimit *bool
}
type ConventionalCommit struct {
Type string
Scope string
Description string
Group string
Body string
Footer string
}