feat(cmd/joj3): check with teapot before stages
This commit is contained in:
parent
e7c25ca80c
commit
aa0b33d1e7
|
@ -35,6 +35,12 @@ type ConfStage struct {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type ConfGroup struct {
|
||||||
|
Name string
|
||||||
|
MaxCount int
|
||||||
|
TimePeriodHour int
|
||||||
|
}
|
||||||
|
|
||||||
type Conf struct {
|
type Conf struct {
|
||||||
Name string `default:"unknown"`
|
Name string `default:"unknown"`
|
||||||
LogPath string `default:""`
|
LogPath string `default:""`
|
||||||
|
@ -57,7 +63,8 @@ type Conf struct {
|
||||||
SkipScoreboard bool `default:"false"`
|
SkipScoreboard bool `default:"false"`
|
||||||
SkipFailedTable bool `default:"false"`
|
SkipFailedTable bool `default:"false"`
|
||||||
SubmitterInIssueTitle bool `default:"true"`
|
SubmitterInIssueTitle bool `default:"true"`
|
||||||
MaxTotalScore int `default:"-1"` // TODO: remove me
|
Groups []ConfGroup
|
||||||
|
MaxTotalScore int `default:"-1"` // TODO: remove me
|
||||||
}
|
}
|
||||||
// TODO: remove the following backward compatibility fields
|
// TODO: remove the following backward compatibility fields
|
||||||
SandboxExecServer string `default:"localhost:5051"`
|
SandboxExecServer string `default:"localhost:5051"`
|
||||||
|
|
|
@ -106,6 +106,14 @@ func mainImpl() (err error) {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
groups := conf.MatchGroups(confObj, conventionalCommit)
|
groups := conf.MatchGroups(confObj, conventionalCommit)
|
||||||
|
if len(confObj.Teapot.Groups) != 0 {
|
||||||
|
if err = teapot.Check(confObj); 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)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
slog.Error("stage run", "error", err)
|
slog.Error("stage run", "error", err)
|
||||||
|
|
43
cmd/joj3/teapot/check.go
Normal file
43
cmd/joj3/teapot/check.go
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
package teapot
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"log/slog"
|
||||||
|
"os"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/joint-online-judge/JOJ3/cmd/joj3/conf"
|
||||||
|
"github.com/joint-online-judge/JOJ3/cmd/joj3/env"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Check(conf *conf.Conf) (err error) {
|
||||||
|
os.Setenv("LOG_FILE_PATH", conf.Teapot.LogPath)
|
||||||
|
os.Setenv("_TYPER_STANDARD_TRACEBACK", "1")
|
||||||
|
if env.Attr.Actor == "" ||
|
||||||
|
env.Attr.Repository == "" ||
|
||||||
|
strings.Count(env.Attr.Repository, "/") != 1 {
|
||||||
|
slog.Error("teapot env not set")
|
||||||
|
err = fmt.Errorf("teapot env not set")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
repoParts := strings.Split(env.Attr.Repository, "/")
|
||||||
|
repoName := repoParts[1]
|
||||||
|
var formattedGroups []string
|
||||||
|
for _, group := range conf.Teapot.Groups {
|
||||||
|
groupConfig := fmt.Sprintf("%s=%d:%d",
|
||||||
|
group.Name, group.MaxCount, group.TimePeriodHour)
|
||||||
|
formattedGroups = append(formattedGroups, groupConfig)
|
||||||
|
}
|
||||||
|
args := []string{
|
||||||
|
"joj3-check", conf.Teapot.EnvFilePath,
|
||||||
|
env.Attr.Actor, conf.Teapot.GradingRepoName, repoName,
|
||||||
|
conf.Teapot.ScoreboardPath, conf.Name,
|
||||||
|
"--group-config", strings.Join(formattedGroups, ","),
|
||||||
|
}
|
||||||
|
_, err = runCommand(args)
|
||||||
|
if err != nil {
|
||||||
|
slog.Error("teapot check exec", "error", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
57
cmd/joj3/teapot/exec.go
Normal file
57
cmd/joj3/teapot/exec.go
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
package teapot
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bufio"
|
||||||
|
"bytes"
|
||||||
|
"log/slog"
|
||||||
|
"os/exec"
|
||||||
|
"regexp"
|
||||||
|
"sync"
|
||||||
|
)
|
||||||
|
|
||||||
|
func runCommand(args []string) (
|
||||||
|
stdoutBuf *bytes.Buffer, err error,
|
||||||
|
) {
|
||||||
|
re := regexp.MustCompile(`\x1b\[[0-9;]*[a-zA-Z]`)
|
||||||
|
cmd := exec.Command("joint-teapot", args...) // #nosec G204
|
||||||
|
stdoutBuf = new(bytes.Buffer)
|
||||||
|
cmd.Stdout = stdoutBuf
|
||||||
|
stderr, err := cmd.StderrPipe()
|
||||||
|
if err != nil {
|
||||||
|
slog.Error("stderr pipe", "error", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
var wg sync.WaitGroup
|
||||||
|
wg.Add(1)
|
||||||
|
scanner := bufio.NewScanner(stderr)
|
||||||
|
go func() {
|
||||||
|
for scanner.Scan() {
|
||||||
|
text := re.ReplaceAllString(scanner.Text(), "")
|
||||||
|
if text == "" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
slog.Info("joint-teapot", "stderr", text)
|
||||||
|
}
|
||||||
|
wg.Done()
|
||||||
|
if scanner.Err() != nil {
|
||||||
|
slog.Error("stderr scanner", "error", scanner.Err())
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
if err = cmd.Start(); err != nil {
|
||||||
|
slog.Error("cmd start", "error", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
wg.Wait()
|
||||||
|
if err = cmd.Wait(); err != nil {
|
||||||
|
if exitErr, ok := err.(*exec.ExitError); ok {
|
||||||
|
exitCode := exitErr.ExitCode()
|
||||||
|
slog.Error("cmd completed with non-zero exit code",
|
||||||
|
"error", err,
|
||||||
|
"exitCode", exitCode)
|
||||||
|
} else {
|
||||||
|
slog.Error("cmd wait", "error", err)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
|
@ -1,17 +1,12 @@
|
||||||
package teapot
|
package teapot
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bufio"
|
|
||||||
"bytes"
|
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"log/slog"
|
"log/slog"
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
|
||||||
"regexp"
|
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
|
||||||
|
|
||||||
"github.com/joint-online-judge/JOJ3/cmd/joj3/conf"
|
"github.com/joint-online-judge/JOJ3/cmd/joj3/conf"
|
||||||
"github.com/joint-online-judge/JOJ3/cmd/joj3/env"
|
"github.com/joint-online-judge/JOJ3/cmd/joj3/env"
|
||||||
|
@ -54,8 +49,7 @@ func Run(conf *conf.Conf, groups []string) (
|
||||||
if conf.Teapot.SubmitterInIssueTitle {
|
if conf.Teapot.SubmitterInIssueTitle {
|
||||||
submitterInIssueTitleArg = "--submitter-in-issue-title"
|
submitterInIssueTitleArg = "--submitter-in-issue-title"
|
||||||
}
|
}
|
||||||
re := regexp.MustCompile(`\x1b\[[0-9;]*[a-zA-Z]`)
|
args := []string{
|
||||||
cmd := exec.Command("joint-teapot",
|
|
||||||
"joj3-all", conf.Teapot.EnvFilePath, conf.Stage.OutputPath,
|
"joj3-all", conf.Teapot.EnvFilePath, conf.Stage.OutputPath,
|
||||||
env.Attr.Actor, conf.Teapot.GradingRepoName, repoName,
|
env.Attr.Actor, conf.Teapot.GradingRepoName, repoName,
|
||||||
env.Attr.RunNumber, conf.Teapot.ScoreboardPath,
|
env.Attr.RunNumber, conf.Teapot.ScoreboardPath,
|
||||||
|
@ -65,44 +59,10 @@ func Run(conf *conf.Conf, groups []string) (
|
||||||
"--max-total-score", strconv.Itoa(conf.MaxTotalScore),
|
"--max-total-score", strconv.Itoa(conf.MaxTotalScore),
|
||||||
skipIssueArg, skipScoreboardArg,
|
skipIssueArg, skipScoreboardArg,
|
||||||
skipFailedTableArg, submitterInIssueTitleArg,
|
skipFailedTableArg, submitterInIssueTitleArg,
|
||||||
) // #nosec G204
|
}
|
||||||
stdoutBuf := new(bytes.Buffer)
|
stdoutBuf, err := runCommand(args)
|
||||||
cmd.Stdout = stdoutBuf
|
|
||||||
stderr, err := cmd.StderrPipe()
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
slog.Error("stderr pipe", "error", err)
|
slog.Error("teapot run exec", "error", err)
|
||||||
return
|
|
||||||
}
|
|
||||||
var wg sync.WaitGroup
|
|
||||||
wg.Add(1)
|
|
||||||
scanner := bufio.NewScanner(stderr)
|
|
||||||
go func() {
|
|
||||||
for scanner.Scan() {
|
|
||||||
text := re.ReplaceAllString(scanner.Text(), "")
|
|
||||||
if text == "" {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
slog.Info("joint-teapot", "stderr", text)
|
|
||||||
}
|
|
||||||
wg.Done()
|
|
||||||
if scanner.Err() != nil {
|
|
||||||
slog.Error("stderr scanner", "error", scanner.Err())
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
if err = cmd.Start(); err != nil {
|
|
||||||
slog.Error("cmd start", "error", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
wg.Wait()
|
|
||||||
if err = cmd.Wait(); err != nil {
|
|
||||||
if exitErr, ok := err.(*exec.ExitError); ok {
|
|
||||||
exitCode := exitErr.ExitCode()
|
|
||||||
slog.Error("cmd completed with non-zero exit code",
|
|
||||||
"error", err,
|
|
||||||
"exitCode", exitCode)
|
|
||||||
} else {
|
|
||||||
slog.Error("cmd wait", "error", err)
|
|
||||||
}
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if json.Unmarshal(stdoutBuf.Bytes(), &teapotResult) != nil {
|
if json.Unmarshal(stdoutBuf.Bytes(), &teapotResult) != nil {
|
||||||
|
|
Loading…
Reference in New Issue
Block a user