feat: decide which stage to run based on commit msg
This commit is contained in:
		
							parent
							
								
									8d0000016a
								
							
						
					
					
						commit
						2d08a435a8
					
				
							
								
								
									
										105
									
								
								cmd/joj3/conf.go
									
									
									
									
									
								
							
							
						
						
									
										105
									
								
								cmd/joj3/conf.go
									
									
									
									
									
								
							| 
						 | 
					@ -11,25 +11,35 @@ import (
 | 
				
			||||||
	"github.com/koding/multiconfig"
 | 
						"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 {
 | 
					type Conf struct {
 | 
				
			||||||
	SandboxExecServer string `default:"localhost:5051"`
 | 
						SandboxExecServer string `default:"localhost:5051"`
 | 
				
			||||||
	SandboxToken      string `default:""`
 | 
						SandboxToken      string `default:""`
 | 
				
			||||||
	LogLevel          int    `default:"0"`
 | 
						LogLevel          int    `default:"0"`
 | 
				
			||||||
	OutputPath        string `default:"joj3_result.json"`
 | 
						OutputPath        string `default:"joj3_result.json"`
 | 
				
			||||||
	Stages            []struct {
 | 
						Stages            []Stage
 | 
				
			||||||
		Name     string
 | 
					 | 
				
			||||||
		Executor struct {
 | 
					 | 
				
			||||||
			Name string
 | 
					 | 
				
			||||||
			With struct {
 | 
					 | 
				
			||||||
				Default stage.Cmd
 | 
					 | 
				
			||||||
				Cases   []OptionalCmd
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		Parser struct {
 | 
					 | 
				
			||||||
			Name string
 | 
					 | 
				
			||||||
			With interface{}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type OptionalCmd struct {
 | 
					type OptionalCmd struct {
 | 
				
			||||||
| 
						 | 
					@ -63,24 +73,51 @@ type OptionalCmd struct {
 | 
				
			||||||
	AddressSpaceLimit *bool
 | 
						AddressSpaceLimit *bool
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func parseConfFile(path string) (conf Conf, err error) {
 | 
					func parseConfFile(path string, jobtype JobType) (conf Conf, err error) {
 | 
				
			||||||
	d := &multiconfig.DefaultLoader{}
 | 
						d := &multiconfig.DefaultLoader{}
 | 
				
			||||||
	d.Loader = multiconfig.MultiLoader(
 | 
						d.Loader = multiconfig.MultiLoader(
 | 
				
			||||||
		&multiconfig.TagLoader{},
 | 
							&multiconfig.TagLoader{},
 | 
				
			||||||
		&multiconfig.JSONLoader{Path: path},
 | 
							&multiconfig.JSONLoader{Path: path},
 | 
				
			||||||
	)
 | 
						)
 | 
				
			||||||
	d.Validator = multiconfig.MultiValidator(&multiconfig.RequiredValidator{})
 | 
						d.Validator = multiconfig.MultiValidator(&multiconfig.RequiredValidator{})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if err = d.Load(&conf); err != nil {
 | 
						if err = d.Load(&conf); err != nil {
 | 
				
			||||||
		slog.Error("parse stages conf", "error", err)
 | 
							slog.Error("parse stages conf", "error", err)
 | 
				
			||||||
		return
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if err = d.Validate(&conf); err != nil {
 | 
						if err = d.Validate(&conf); err != nil {
 | 
				
			||||||
		slog.Error("validate stages conf", "error", err)
 | 
							slog.Error("validate stages conf", "error", err)
 | 
				
			||||||
		return
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						filteredStages := []Stage{}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for _, stage := range conf.Stages {
 | 
				
			||||||
 | 
							if filterStage(stage, jobtype) {
 | 
				
			||||||
 | 
								filteredStages = append(filteredStages, stage)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						conf.Stages = filteredStages
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return
 | 
						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 {
 | 
					func validateHw(hw string) error {
 | 
				
			||||||
	matched, err := regexp.MatchString(`^hw[0-9]+$`, hw)
 | 
						matched, err := regexp.MatchString(`^hw[0-9]+$`, hw)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
| 
						 | 
					@ -109,11 +146,12 @@ func commitMsgToConf() (conf Conf, err error) {
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	file := "conf.json"
 | 
						file := "conf.json"
 | 
				
			||||||
 | 
						jobtype := HC
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	msg := commit.Message
 | 
						msg := commit.Message
 | 
				
			||||||
	slog.Debug("commit msg to conf", "msg", msg)
 | 
						slog.Debug("commit msg to conf", "msg", msg)
 | 
				
			||||||
	if msg == "" {
 | 
						if msg == "" {
 | 
				
			||||||
		conf, err = parseConfFile(file)
 | 
							conf, err = parseConfFile(file, jobtype)
 | 
				
			||||||
		return
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -128,31 +166,22 @@ func commitMsgToConf() (conf Conf, err error) {
 | 
				
			||||||
		head = head[:len(head)-1]
 | 
							head = head[:len(head)-1]
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	switch head {
 | 
						if len(words) == 3 {
 | 
				
			||||||
	case "feat", "fix", "refactor", "perf", "test", "build", "revert":
 | 
							hw = words[1]
 | 
				
			||||||
		// TODO: Decide strategy to give students error
 | 
							if err = validateHw(hw); err != nil {
 | 
				
			||||||
		// if len(words) < 2 {
 | 
								return
 | 
				
			||||||
		// 	return Conf{}, fmt.Errorf("error: hw not assigned")
 | 
					 | 
				
			||||||
		// }
 | 
					 | 
				
			||||||
		if len(words) >= 2 {
 | 
					 | 
				
			||||||
			hw = words[1]
 | 
					 | 
				
			||||||
			if err = validateHw(hw); err == nil {
 | 
					 | 
				
			||||||
				file = strings.Replace(file, "conf", "conf-"+hw+"-cq", 1)
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	case "joj", "grading":
 | 
					
 | 
				
			||||||
		// TODO: Decide strategy to give students error
 | 
							switch head {
 | 
				
			||||||
		// if len(words) < 2 {
 | 
							case "feat", "fix", "refactor", "perf", "test", "build", "revert":
 | 
				
			||||||
		// 	return Conf{}, fmt.Errorf("error: hw not assigned")
 | 
								file = strings.Replace(file, "conf", "conf-"+hw, 1)
 | 
				
			||||||
		// }
 | 
								jobtype = CQ
 | 
				
			||||||
		if len(words) >= 2 {
 | 
							case "joj", "grading":
 | 
				
			||||||
			hw = words[1]
 | 
								file = strings.Replace(file, "conf", "conf-"+hw, 1)
 | 
				
			||||||
			if err = validateHw(hw); err == nil {
 | 
								jobtype = OJ
 | 
				
			||||||
				file = strings.Replace(file, "conf", "conf-"+hw+"-oj", 1)
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	conf, err = parseConfFile(file)
 | 
						conf, err = parseConfFile(file, jobtype)
 | 
				
			||||||
	return
 | 
						return
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue
	
	Block a user