From c41031c2c37a0cec9e0b04939713b6b3d5c00355 Mon Sep 17 00:00:00 2001 From: Boming Zhang Date: Tue, 26 Nov 2024 00:25:24 -0500 Subject: [PATCH] feat(cmd/joj3): show teapot check result in issue --- cmd/joj3/main.go | 19 +++++++------ cmd/joj3/stage/run.go | 60 ++++++++++++++++++++++++++++++++++------ cmd/joj3/teapot/check.go | 18 ++++++++++-- cmd/joj3/teapot/run.go | 8 +++--- 4 files changed, 83 insertions(+), 22 deletions(-) diff --git a/cmd/joj3/main.go b/cmd/joj3/main.go index 08b76e0..5dd2042 100644 --- a/cmd/joj3/main.go +++ b/cmd/joj3/main.go @@ -33,7 +33,8 @@ func mainImpl() (err error) { confObj := new(conf.Conf) var stageResults []internalStage.StageResult var forceQuitStageName string - var teapotResult teapot.TeapotResult + var teapotCheckResults []teapot.CheckResult + var teapotRunResult teapot.RunResult var commitMsg string defer func() { totalScore := 0 @@ -52,9 +53,9 @@ func mainImpl() (err error) { "cappedTotalScore", cappedTotalScore, "forceQuit", forceQuitStageName != "", "forceQuitStageName", forceQuitStageName, - "issue", teapotResult.Issue, - "action", teapotResult.Action, - "sha", teapotResult.Sha, + "issue", teapotRunResult.Issue, + "action", teapotRunResult.Action, + "sha", teapotRunResult.Sha, "commitMsg", commitMsg, "error", err, ) @@ -107,14 +108,16 @@ func mainImpl() (err error) { } groups := conf.MatchGroups(confObj, conventionalCommit) if len(confObj.Teapot.Groups) != 0 { - if err = teapot.Check(confObj); err != nil { + teapotCheckResults, err = teapot.Check(confObj) + if err != nil { slog.Error("teapot check", "error", err) - return err } } else { slog.Info("teapot check disabled") } - stageResults, forceQuitStageName, err = stage.Run(confObj, groups) + stageResults, forceQuitStageName, err = stage.Run( + confObj, groups, teapotCheckResults, + ) if err != nil { slog.Error("stage run", "error", err) } @@ -122,7 +125,7 @@ func mainImpl() (err error) { slog.Error("stage write", "error", err) return err } - teapotResult, err = teapot.Run(confObj, groups) + teapotRunResult, err = teapot.Run(confObj, groups) if err != nil { slog.Error("teapot run", "error", err) return err diff --git a/cmd/joj3/stage/run.go b/cmd/joj3/stage/run.go index 4883dc6..6bc13d7 100644 --- a/cmd/joj3/stage/run.go +++ b/cmd/joj3/stage/run.go @@ -6,6 +6,7 @@ import ( "strings" "github.com/joint-online-judge/JOJ3/cmd/joj3/conf" + "github.com/joint-online-judge/JOJ3/cmd/joj3/teapot" executors "github.com/joint-online-judge/JOJ3/internal/executor" _ "github.com/joint-online-judge/JOJ3/internal/parser" "github.com/joint-online-judge/JOJ3/internal/stage" @@ -116,7 +117,7 @@ func generateStages(conf *conf.Conf, groups []string) ([]stage.Stage, error) { return stages, nil } -func newErrorStageResults(err error) []stage.StageResult { +func newErrorStageResults(err error) ([]stage.StageResult, string) { return []stage.StageResult{ { Name: "Internal Error", @@ -128,12 +129,56 @@ func newErrorStageResults(err error) []stage.StageResult { }}, ForceQuit: true, }, - } + }, "Internal Error" } -func Run(conf *conf.Conf, groups []string) ( +func newTeapotCheckStageResults( + checkResults []teapot.CheckResult, +) (stageResults []stage.StageResult, forceQuitStageName string, err error) { + if len(checkResults) == 0 { + return + } + comment := "" + forceQuit := false + for _, checkResult := range checkResults { + comment += fmt.Sprintf( + "Keyword `%s` in last %d hour(s): submit count %d, max count %d\n", + checkResult.Name, + checkResult.TimePeriod, + checkResult.SubmitCount, + checkResult.MaxCount, + ) + if checkResult.SubmitCount+1 > checkResult.MaxCount { + forceQuit = true + err = fmt.Errorf("submit count exceeded") + } + } + stageResults = []stage.StageResult{ + { + Name: "Teapot Check", + Results: []stage.ParserResult{{ + Score: 0, + Comment: comment, + }}, + ForceQuit: forceQuit, + }, + } + forceQuitStageName = "Teapot Check" + return +} + +func Run( + conf *conf.Conf, groups []string, checkResults []teapot.CheckResult, +) ( stageResults []stage.StageResult, forceQuitStageName string, err error, ) { + stageResults, forceQuitStageName, err = newTeapotCheckStageResults( + checkResults, + ) + if err != nil { + slog.Error("teapot check", "error", err) + return + } executors.InitWithConf( conf.Stage.SandboxExecServer, conf.Stage.SandboxToken, @@ -141,17 +186,16 @@ func Run(conf *conf.Conf, groups []string) ( stages, err := generateStages(conf, groups) if err != nil { slog.Error("generate stages", "error", err) - stageResults = newErrorStageResults(err) - forceQuitStageName = "internal" + stageResults, forceQuitStageName = newErrorStageResults(err) return } defer stage.Cleanup() - stageResults, forceQuitStageName, err = stage.Run(stages) + newStageResults, forceQuitStageName, err := stage.Run(stages) if err != nil { slog.Error("run stages", "error", err) - stageResults = newErrorStageResults(err) - forceQuitStageName = "internal" + stageResults, forceQuitStageName = newErrorStageResults(err) return } + stageResults = append(stageResults, newStageResults...) return } diff --git a/cmd/joj3/teapot/check.go b/cmd/joj3/teapot/check.go index 9efbc13..3eb0bcd 100644 --- a/cmd/joj3/teapot/check.go +++ b/cmd/joj3/teapot/check.go @@ -1,6 +1,7 @@ package teapot import ( + "encoding/json" "fmt" "log/slog" "os" @@ -10,7 +11,14 @@ import ( "github.com/joint-online-judge/JOJ3/cmd/joj3/env" ) -func Check(conf *conf.Conf) (err error) { +type CheckResult struct { + Name string `json:"name"` + SubmitCount int `json:"submit_count"` + MaxCount int `json:"max_count"` + TimePeriod int `json:"time_period"` +} + +func Check(conf *conf.Conf) (checkResults []CheckResult, err error) { os.Setenv("LOG_FILE_PATH", conf.Teapot.LogPath) os.Setenv("_TYPER_STANDARD_TRACEBACK", "1") if env.Attr.Actor == "" || @@ -34,10 +42,16 @@ func Check(conf *conf.Conf) (err error) { conf.Teapot.ScoreboardPath, conf.Name, "--group-config", strings.Join(formattedGroups, ","), } - _, err = runCommand(args) + stdoutBuf, err := runCommand(args) if err != nil { slog.Error("teapot check exec", "error", err) return } + if json.Unmarshal(stdoutBuf.Bytes(), &checkResults) != nil { + slog.Error("unmarshal teapot result", "error", err, + "stdout", stdoutBuf.String()) + return + } + slog.Info("teapot result", "result", checkResults) return } diff --git a/cmd/joj3/teapot/run.go b/cmd/joj3/teapot/run.go index dadadf2..3b685b1 100644 --- a/cmd/joj3/teapot/run.go +++ b/cmd/joj3/teapot/run.go @@ -12,14 +12,14 @@ import ( "github.com/joint-online-judge/JOJ3/cmd/joj3/env" ) -type TeapotResult struct { +type RunResult struct { Issue int `json:"issue"` Action int `json:"action"` Sha string `json:"sha"` } func Run(conf *conf.Conf, groups []string) ( - teapotResult TeapotResult, err error, + runResult RunResult, err error, ) { os.Setenv("LOG_FILE_PATH", conf.Teapot.LogPath) os.Setenv("_TYPER_STANDARD_TRACEBACK", "1") @@ -65,11 +65,11 @@ func Run(conf *conf.Conf, groups []string) ( slog.Error("teapot run exec", "error", err) return } - if json.Unmarshal(stdoutBuf.Bytes(), &teapotResult) != nil { + if json.Unmarshal(stdoutBuf.Bytes(), &runResult) != nil { slog.Error("unmarshal teapot result", "error", err, "stdout", stdoutBuf.String()) return } - slog.Info("teapot result", "result", teapotResult) + slog.Info("teapot result", "result", runResult) return }