WIP: commit msg parser #39
120
cmd/joj3/conf.go
120
cmd/joj3/conf.go
|
@ -1,32 +1,45 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log/slog"
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
"focs.ji.sjtu.edu.cn/git/FOCS-dev/JOJ3/internal/stage"
|
||||
"github.com/go-git/go-git/v5"
|
||||
"github.com/koding/multiconfig"
|
||||
)
|
||||
|
||||
type JobType int
|
||||
|
||||
const (
|
||||
HC JobType = iota
|
||||
CQ
|
||||
OJ
|
||||
)
|
||||
|
||||
type Stage struct {
|
||||
Name string
|
||||
Executor struct {
|
||||
Name string
|
||||
With struct {
|
||||
Default stage.Cmd
|
||||
Cases []OptionalCmd
|
||||
}
|
||||
}
|
||||
Parser struct {
|
||||
Name string
|
||||
With interface{}
|
||||
}
|
||||
}
|
||||
|
||||
type Conf struct {
|
||||
SandboxExecServer string `default:"localhost:5051"`
|
||||
SandboxToken string `default:""`
|
||||
LogLevel int `default:"0"`
|
||||
OutputPath string `default:"joj3_result.json"`
|
||||
Stages []struct {
|
||||
Name string
|
||||
Executor struct {
|
||||
Name string
|
||||
With struct {
|
||||
Default stage.Cmd
|
||||
Cases []OptionalCmd
|
||||
}
|
||||
}
|
||||
Parser struct {
|
||||
Name string
|
||||
With interface{}
|
||||
}
|
||||
}
|
||||
Stages []Stage
|
||||
}
|
||||
|
||||
type OptionalCmd struct {
|
||||
|
@ -60,40 +73,113 @@ type OptionalCmd struct {
|
|||
AddressSpaceLimit *bool
|
||||
}
|
||||
|
||||
func parseConfFile(path string) (conf Conf, err error) {
|
||||
func parseConfFile(path string, jobtype JobType) (conf Conf, err error) {
|
||||
d := &multiconfig.DefaultLoader{}
|
||||
d.Loader = multiconfig.MultiLoader(
|
||||
&multiconfig.TagLoader{},
|
||||
&multiconfig.JSONLoader{Path: path},
|
||||
)
|
||||
d.Validator = multiconfig.MultiValidator(&multiconfig.RequiredValidator{})
|
||||
|
||||
if err = d.Load(&conf); err != nil {
|
||||
slog.Error("parse stages conf", "error", err)
|
||||
return
|
||||
}
|
||||
|
||||
if err = d.Validate(&conf); err != nil {
|
||||
slog.Error("validate stages conf", "error", err)
|
||||
return
|
||||
}
|
||||
|
||||
filteredStages := []Stage{}
|
||||
for _, stage := range conf.Stages {
|
||||
if filterStage(stage, jobtype) {
|
||||
filteredStages = append(filteredStages, stage)
|
||||
}
|
||||
}
|
||||
|
||||
conf.Stages = filteredStages
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func filterStage(stage Stage, jobtype JobType) bool {
|
||||
switch jobtype {
|
||||
case HC:
|
||||
return stage.Name == "healthcheck"
|
||||
case CQ:
|
||||
return stage.Name == "compile" || stage.Name == "healthcheck"
|
||||
case OJ:
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
func validateHw(hw string) error {
|
||||
matched, err := regexp.MatchString(`^hw[0-9]+$`, hw)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error compiling regex: %w", err)
|
||||
}
|
||||
if !matched {
|
||||
return fmt.Errorf("error: hw does not match the required pattern")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func commitMsgToConf() (conf Conf, err error) {
|
||||
r, err := git.PlainOpen(".")
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
ref, err := r.Head()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
commit, err := r.CommitObject(ref.Hash())
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
file := "conf.json"
|
||||
jobtype := HC
|
||||
|
||||
msg := commit.Message
|
||||
slog.Debug("commit msg to conf", "msg", msg)
|
||||
// TODO: parse msg to conf name
|
||||
conf, err = parseConfFile("conf.json")
|
||||
if msg == "" {
|
||||
conf, err = parseConfFile(file, jobtype)
|
||||
return
|
||||
}
|
||||
|
||||
line := strings.Split(msg, "\n")[0]
|
||||
|
||||
words := strings.Fields(line)
|
||||
|
||||
head := words[0]
|
||||
var hw string
|
||||
|
||||
if strings.HasSuffix(head, ":") || strings.HasSuffix(head, ".") {
|
||||
head = head[:len(head)-1]
|
||||
}
|
||||
|
||||
if len(words) == 3 {
|
||||
hw = words[1]
|
||||
if err = validateHw(hw); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
switch head {
|
||||
case "feat", "fix", "refactor", "perf", "test", "build", "revert":
|
||||
file = strings.Replace(file, "conf", "conf-"+hw, 1)
|
||||
jobtype = CQ
|
||||
case "joj", "grading":
|
||||
file = strings.Replace(file, "conf", "conf-"+hw, 1)
|
||||
jobtype = OJ
|
||||
}
|
||||
}
|
||||
|
||||
conf, err = parseConfFile(file, jobtype)
|
||||
return
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user