diff --git a/README.md b/README.md index d553c59..5dadaa1 100644 --- a/README.md +++ b/README.md @@ -87,7 +87,7 @@ These steps are executed in runner-images. We use `sudo -u tt` to elevate the pe - We have `conf-root` and `conf-name` specified in the CLI argument. Then the full path of configuration file is `//`. 3. Generate stages. - We have an empty list of stages at the beginning. - - We check all the stages from the configuration file. Stages with empty `group` field will always be added. And stages with `group = joj` will be added when `description` contains "joj" (case insensitive). + - We check all the stages from the configuration file. Stages with empty `group` field will always be added. And stages with `group = joj` will be added when `description` contains "joj" (case insensitive). You can set arbitrary group keywords in config file, in `groupKeywords` field, but by default the only group keyword is joj. - Every stage needs to have an unique `name`, which means if two stages have the same name, only the first one will be added. 4. Run stages. - By default, all the stages will run sequentially. diff --git a/cmd/joj3/conf/conf.go b/cmd/joj3/conf/conf.go index fc92c69..cb79bd6 100644 --- a/cmd/joj3/conf/conf.go +++ b/cmd/joj3/conf/conf.go @@ -35,9 +35,10 @@ type ConfStage struct { } type Conf struct { - Name string `default:"unknown"` - LogPath string `default:""` - ExpireUnixTimestamp int64 `default:"-1"` + Name string `default:"unknown"` + LogPath string `default:""` + ExpireUnixTimestamp int64 `default:"-1"` + GroupKeywords []string `default:"joj"` Stage struct { SandboxExecServer string `default:"localhost:5051"` SandboxToken string `default:""` @@ -217,10 +218,10 @@ func GetSHA256(filePath string) (string, error) { } func parseMsg(confRoot, confName, msg, tag string) ( - confPath, group string, err error, + confPath string, conventionalCommit *ConventionalCommit, err error, ) { slog.Info("parse msg", "msg", msg) - conventionalCommit, err := parseConventionalCommit(msg) + conventionalCommit, err = parseConventionalCommit(msg) if err != nil { return } @@ -240,14 +241,6 @@ func parseMsg(confRoot, confName, msg, tag string) ( conventionalCommit.Scope) return } - groupKeywords := []string{"joj"} - for _, groupKeyword := range groupKeywords { - if strings.Contains( - strings.ToLower(conventionalCommit.Description), groupKeyword) { - group = groupKeyword - break - } - } return } @@ -282,9 +275,10 @@ func hintValidScopes(confRoot, confName string) { } func GetConfPath(confRoot, confName, fallbackConfName, msg, tag string) ( - confPath, group string, confStat fs.FileInfo, err error, + confPath string, confStat fs.FileInfo, + conventionalCommit *ConventionalCommit, err error, ) { - confPath, group, err = parseMsg(confRoot, confName, msg, tag) + confPath, conventionalCommit, err = parseMsg(confRoot, confName, msg, tag) if err != nil { slog.Error("parse msg", "error", err) // fallback to conf file in conf root on parse error @@ -316,3 +310,16 @@ func CheckExpire(conf *Conf) error { } return nil } + +func MatchGroups(conf *Conf, conventionalCommit *ConventionalCommit) []string { + keywords := conf.GroupKeywords + groups := []string{} + loweredDescription := strings.ToLower(conventionalCommit.Description) + for _, keyword := range keywords { + loweredKeyword := strings.ToLower(keyword) + if strings.Contains(loweredDescription, loweredKeyword) { + groups = append(groups, loweredKeyword) + } + } + return groups +} diff --git a/cmd/joj3/main.go b/cmd/joj3/main.go index 51f4174..3d7bd44 100644 --- a/cmd/joj3/main.go +++ b/cmd/joj3/main.go @@ -50,7 +50,7 @@ func mainImpl() error { slog.Error("get commit msg", "error", err) return err } - confPath, group, confStat, err := conf.GetConfPath( + confPath, confStat, conventionalCommit, err := conf.GetConfPath( confRoot, confName, fallbackConfName, msg, tag) if err != nil { slog.Error("get conf path", "error", err) @@ -78,7 +78,8 @@ func mainImpl() error { slog.Error("conf check expire", "error", err) return err } - stageResults, stageForceQuit, err := stage.Run(confObj, group) + groups := conf.MatchGroups(confObj, conventionalCommit) + stageResults, stageForceQuit, err := stage.Run(confObj, groups) if err != nil { slog.Error("stage run", "error", err) } diff --git a/cmd/joj3/stage/run.go b/cmd/joj3/stage/run.go index 1bc940a..6281034 100644 --- a/cmd/joj3/stage/run.go +++ b/cmd/joj3/stage/run.go @@ -3,6 +3,7 @@ package stage import ( "fmt" "log/slog" + "strings" "github.com/joint-online-judge/JOJ3/cmd/joj3/conf" executors "github.com/joint-online-judge/JOJ3/internal/executor" @@ -12,12 +13,22 @@ import ( "github.com/jinzhu/copier" ) -func generateStages(conf *conf.Conf, group string) ([]stage.Stage, error) { +func generateStages(conf *conf.Conf, groups []string) ([]stage.Stage, error) { stages := []stage.Stage{} existNames := map[string]bool{} for _, s := range conf.Stage.Stages { - if s.Group != "" && group != s.Group { - continue + if s.Group != "" { + var ok bool + loweredStageGroup := strings.ToLower(s.Group) + for _, group := range groups { + if group == loweredStageGroup { + ok = true + break + } + } + if !ok { + continue + } } _, ok := existNames[s.Name] // check for existence if ok { @@ -84,14 +95,14 @@ func newErrorStageResults(err error) []stage.StageResult { } } -func Run(conf *conf.Conf, group string) ( +func Run(conf *conf.Conf, groups []string) ( stageResults []stage.StageResult, forceQuit bool, err error, ) { executors.InitWithConf( conf.Stage.SandboxExecServer, conf.Stage.SandboxToken, ) - stages, err := generateStages(conf, group) + stages, err := generateStages(conf, groups) if err != nil { slog.Error("generate stages", "error", err) stageResults = newErrorStageResults(err)