Merge branch 'master' into feat/reposize
This commit is contained in:
		
						commit
						74ad5d6a8a
					
				
							
								
								
									
										2
									
								
								Makefile
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								Makefile
									
									
									
									
									
								
							| 
						 | 
					@ -30,4 +30,4 @@ test:
 | 
				
			||||||
ci-test:
 | 
					ci-test:
 | 
				
			||||||
	./scripts/prepare_test_repos.sh $(TMP_DIR)
 | 
						./scripts/prepare_test_repos.sh $(TMP_DIR)
 | 
				
			||||||
	./scripts/run_foreach_test_repos.sh $(TMP_DIR) "sed -i '2i \ \ \"sandboxExecServer\": \"172.17.0.1:5051\",' conf.json"
 | 
						./scripts/run_foreach_test_repos.sh $(TMP_DIR) "sed -i '2i \ \ \"sandboxExecServer\": \"172.17.0.1:5051\",' conf.json"
 | 
				
			||||||
	go test -coverprofile cover.out -v ./...
 | 
						GITHUB_ACTIONS="test" go test -coverprofile cover.out -v ./...
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -13,16 +13,48 @@ import (
 | 
				
			||||||
	"github.com/koding/multiconfig"
 | 
						"github.com/koding/multiconfig"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type ConfStage struct {
 | 
				
			||||||
 | 
						Name     string
 | 
				
			||||||
 | 
						Group    string
 | 
				
			||||||
 | 
						Executor struct {
 | 
				
			||||||
 | 
							Name string
 | 
				
			||||||
 | 
							With struct {
 | 
				
			||||||
 | 
								Default stage.Cmd
 | 
				
			||||||
 | 
								Cases   []OptionalCmd
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						Parsers []struct {
 | 
				
			||||||
 | 
							Name string
 | 
				
			||||||
 | 
							With interface{}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type Conf struct {
 | 
					type Conf struct {
 | 
				
			||||||
 | 
						Name    string `default:"unknown"`
 | 
				
			||||||
 | 
						LogPath string `default:""`
 | 
				
			||||||
 | 
						Stage   struct {
 | 
				
			||||||
 | 
							SandboxExecServer string `default:"localhost:5051"`
 | 
				
			||||||
 | 
							SandboxToken      string `default:""`
 | 
				
			||||||
 | 
							OutputPath        string `default:"joj3_result.json"`
 | 
				
			||||||
 | 
							Stages            []ConfStage
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						Teapot struct {
 | 
				
			||||||
 | 
							LogPath         string `default:"/home/tt/.cache/joint-teapot-debug.log"`
 | 
				
			||||||
 | 
							ScoreboardPath  string `default:"scoreboard.csv"`
 | 
				
			||||||
 | 
							FailedTablePath string `default:"failed-table.md"`
 | 
				
			||||||
 | 
							GradingRepoName string `default:""`
 | 
				
			||||||
 | 
							SkipIssue       bool   `default:"false"`
 | 
				
			||||||
 | 
							SkipScoreboard  bool   `default:"false"`
 | 
				
			||||||
 | 
							SkipFailedTable bool   `default:"false"`
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						// TODO: remove the following backward compatibility fields
 | 
				
			||||||
	SandboxExecServer string `default:"localhost:5051"`
 | 
						SandboxExecServer string `default:"localhost:5051"`
 | 
				
			||||||
	SandboxToken      string `default:""`
 | 
						SandboxToken      string `default:""`
 | 
				
			||||||
	LogPath           string `default:""`
 | 
					 | 
				
			||||||
	OutputPath        string `default:"joj3_result.json"`
 | 
						OutputPath        string `default:"joj3_result.json"`
 | 
				
			||||||
	GradingRepoName   string `default:""`
 | 
						GradingRepoName   string `default:""`
 | 
				
			||||||
	SkipTeapot        bool   `default:"true"`
 | 
						SkipTeapot        bool   `default:"true"`
 | 
				
			||||||
	ScoreboardPath    string `default:"scoreboard.csv"`
 | 
						ScoreboardPath    string `default:"scoreboard.csv"`
 | 
				
			||||||
	FailedTablePath   string `default:"failed-table.md"`
 | 
						FailedTablePath   string `default:"failed-table.md"`
 | 
				
			||||||
	Name              string `default:"unknown"`
 | 
					 | 
				
			||||||
	Stages            []struct {
 | 
						Stages            []struct {
 | 
				
			||||||
		Name     string
 | 
							Name     string
 | 
				
			||||||
		Group    string
 | 
							Group    string
 | 
				
			||||||
| 
						 | 
					@ -127,6 +159,35 @@ func parseConfFile(path string) (conf Conf, err error) {
 | 
				
			||||||
		slog.Error("validate stages conf", "error", err)
 | 
							slog.Error("validate stages conf", "error", err)
 | 
				
			||||||
		return
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						// TODO: remove the following backward compatibility codes
 | 
				
			||||||
 | 
						if len(conf.Stage.Stages) == 0 {
 | 
				
			||||||
 | 
							conf.Stage.SandboxExecServer = conf.SandboxExecServer
 | 
				
			||||||
 | 
							conf.Stage.SandboxToken = conf.SandboxToken
 | 
				
			||||||
 | 
							conf.Stage.OutputPath = conf.OutputPath
 | 
				
			||||||
 | 
							conf.Stage.Stages = make([]ConfStage, len(conf.Stages))
 | 
				
			||||||
 | 
							for i, stage := range conf.Stages {
 | 
				
			||||||
 | 
								conf.Stage.Stages[i].Name = stage.Name
 | 
				
			||||||
 | 
								conf.Stage.Stages[i].Group = stage.Group
 | 
				
			||||||
 | 
								conf.Stage.Stages[i].Executor = stage.Executor
 | 
				
			||||||
 | 
								conf.Stage.Stages[i].Parsers = []struct {
 | 
				
			||||||
 | 
									Name string
 | 
				
			||||||
 | 
									With interface{}
 | 
				
			||||||
 | 
								}{
 | 
				
			||||||
 | 
									{
 | 
				
			||||||
 | 
										Name: stage.Parser.Name,
 | 
				
			||||||
 | 
										With: stage.Parser.With,
 | 
				
			||||||
 | 
									},
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							conf.Teapot.GradingRepoName = conf.GradingRepoName
 | 
				
			||||||
 | 
							conf.Teapot.ScoreboardPath = conf.ScoreboardPath
 | 
				
			||||||
 | 
							conf.Teapot.FailedTablePath = conf.FailedTablePath
 | 
				
			||||||
 | 
							if conf.SkipTeapot {
 | 
				
			||||||
 | 
								conf.Teapot.SkipScoreboard = true
 | 
				
			||||||
 | 
								conf.Teapot.SkipFailedTable = true
 | 
				
			||||||
 | 
								conf.Teapot.SkipIssue = true
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	return
 | 
						return
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -16,7 +16,7 @@ import (
 | 
				
			||||||
func generateStages(conf conf.Conf, group string) ([]stage.Stage, error) {
 | 
					func generateStages(conf conf.Conf, group string) ([]stage.Stage, error) {
 | 
				
			||||||
	stages := []stage.Stage{}
 | 
						stages := []stage.Stage{}
 | 
				
			||||||
	existNames := map[string]bool{}
 | 
						existNames := map[string]bool{}
 | 
				
			||||||
	for _, s := range conf.Stages {
 | 
						for _, s := range conf.Stage.Stages {
 | 
				
			||||||
		if s.Group != "" && group != s.Group {
 | 
							if s.Group != "" && group != s.Group {
 | 
				
			||||||
			continue
 | 
								continue
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
| 
						 | 
					@ -50,12 +50,20 @@ func generateStages(conf conf.Conf, group string) ([]stage.Stage, error) {
 | 
				
			||||||
		if len(s.Executor.With.Cases) == 0 {
 | 
							if len(s.Executor.With.Cases) == 0 {
 | 
				
			||||||
			cmds = []stage.Cmd{defaultCmd}
 | 
								cmds = []stage.Cmd{defaultCmd}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
							parsers := []stage.StageParser{}
 | 
				
			||||||
 | 
							for _, p := range s.Parsers {
 | 
				
			||||||
 | 
								parsers = append(parsers, stage.StageParser{
 | 
				
			||||||
 | 
									Name: p.Name,
 | 
				
			||||||
 | 
									Conf: p.With,
 | 
				
			||||||
 | 
								})
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
		stages = append(stages, stage.Stage{
 | 
							stages = append(stages, stage.Stage{
 | 
				
			||||||
			Name:         s.Name,
 | 
								Name: s.Name,
 | 
				
			||||||
			ExecutorName: s.Executor.Name,
 | 
								Executor: stage.StageExecutor{
 | 
				
			||||||
			ExecutorCmds: cmds,
 | 
									Name: s.Executor.Name,
 | 
				
			||||||
			ParserName:   s.Parser.Name,
 | 
									Cmds: cmds,
 | 
				
			||||||
			ParserConf:   s.Parser.With,
 | 
								},
 | 
				
			||||||
 | 
								Parsers: parsers,
 | 
				
			||||||
		})
 | 
							})
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	slog.Debug("stages generated", "stages", stages)
 | 
						slog.Debug("stages generated", "stages", stages)
 | 
				
			||||||
| 
						 | 
					@ -74,7 +82,10 @@ func outputResult(outputPath string, results []stage.StageResult) error {
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func Run(conf conf.Conf, group string) error {
 | 
					func Run(conf conf.Conf, group string) error {
 | 
				
			||||||
	executors.InitWithConf(conf.SandboxExecServer, conf.SandboxToken)
 | 
						executors.InitWithConf(
 | 
				
			||||||
 | 
							conf.Stage.SandboxExecServer,
 | 
				
			||||||
 | 
							conf.Stage.SandboxToken,
 | 
				
			||||||
 | 
						)
 | 
				
			||||||
	stages, err := generateStages(conf, group)
 | 
						stages, err := generateStages(conf, group)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		slog.Error("generate stages", "error", err)
 | 
							slog.Error("generate stages", "error", err)
 | 
				
			||||||
| 
						 | 
					@ -86,7 +97,7 @@ func Run(conf conf.Conf, group string) error {
 | 
				
			||||||
		slog.Error("run stages", "error", err)
 | 
							slog.Error("run stages", "error", err)
 | 
				
			||||||
		return err
 | 
							return err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if err := outputResult(conf.OutputPath, results); err != nil {
 | 
						if err := outputResult(conf.Stage.OutputPath, results); err != nil {
 | 
				
			||||||
		slog.Error("output result", "error", err)
 | 
							slog.Error("output result", "error", err)
 | 
				
			||||||
		return err
 | 
							return err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -12,12 +12,16 @@ import (
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func Run(conf conf.Conf) error {
 | 
					func Run(conf conf.Conf) error {
 | 
				
			||||||
	if conf.SkipTeapot {
 | 
						actions := os.Getenv("GITHUB_ACTIONS")
 | 
				
			||||||
 | 
						if actions != "true" {
 | 
				
			||||||
 | 
							slog.Info("teapot exit", "GITHUB_ACTIONS", actions)
 | 
				
			||||||
		return nil
 | 
							return nil
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	os.Setenv("LOG_FILE_PATH", "/home/tt/.cache/joint-teapot-debug.log")
 | 
						os.Setenv("LOG_FILE_PATH", conf.Teapot.LogPath)
 | 
				
			||||||
	os.Setenv("_TYPER_STANDARD_TRACEBACK", "1")
 | 
						os.Setenv("_TYPER_STANDARD_TRACEBACK", "1")
 | 
				
			||||||
	envFilePath := "/home/tt/.config/teapot/teapot.env"
 | 
						envFilePath := "/home/tt/.config/teapot/teapot.env"
 | 
				
			||||||
 | 
						// TODO: pass sha to joint-teapot
 | 
				
			||||||
 | 
						// sha := os.Getenv("GITHUB_SHA")
 | 
				
			||||||
	actor := os.Getenv("GITHUB_ACTOR")
 | 
						actor := os.Getenv("GITHUB_ACTOR")
 | 
				
			||||||
	repository := os.Getenv("GITHUB_REPOSITORY")
 | 
						repository := os.Getenv("GITHUB_REPOSITORY")
 | 
				
			||||||
	runNumber := os.Getenv("GITHUB_RUN_NUMBER")
 | 
						runNumber := os.Getenv("GITHUB_RUN_NUMBER")
 | 
				
			||||||
| 
						 | 
					@ -29,49 +33,55 @@ func Run(conf conf.Conf) error {
 | 
				
			||||||
	repoParts := strings.Split(repository, "/")
 | 
						repoParts := strings.Split(repository, "/")
 | 
				
			||||||
	repoName := repoParts[1]
 | 
						repoName := repoParts[1]
 | 
				
			||||||
	re := regexp.MustCompile(`\x1b\[[0-9;]*[a-zA-Z]`)
 | 
						re := regexp.MustCompile(`\x1b\[[0-9;]*[a-zA-Z]`)
 | 
				
			||||||
	cmd := exec.Command("joint-teapot", "joj3-scoreboard",
 | 
						if !conf.Teapot.SkipScoreboard {
 | 
				
			||||||
		envFilePath, conf.OutputPath, actor, conf.GradingRepoName, repoName,
 | 
							cmd := exec.Command("joint-teapot", "joj3-scoreboard",
 | 
				
			||||||
		runNumber, conf.ScoreboardPath, conf.Name) // #nosec G204
 | 
								envFilePath, conf.Stage.OutputPath, actor, conf.Teapot.GradingRepoName,
 | 
				
			||||||
	outputBytes, err := cmd.CombinedOutput()
 | 
								repoName, runNumber, conf.Teapot.ScoreboardPath, conf.Name) // #nosec G204
 | 
				
			||||||
	output := re.ReplaceAllString(string(outputBytes), "")
 | 
							outputBytes, err := cmd.CombinedOutput()
 | 
				
			||||||
	for _, line := range strings.Split(output, "\n") {
 | 
							output := re.ReplaceAllString(string(outputBytes), "")
 | 
				
			||||||
		if line == "" {
 | 
							for _, line := range strings.Split(output, "\n") {
 | 
				
			||||||
			continue
 | 
								if line == "" {
 | 
				
			||||||
 | 
									continue
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								slog.Info("joint-teapot joj3-scoreboard", "output", line)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		slog.Info("joint-teapot joj3-scoreboard", "output", line)
 | 
							if err != nil {
 | 
				
			||||||
	}
 | 
								slog.Error("joint-teapot joj3-scoreboard", "err", err)
 | 
				
			||||||
	if err != nil {
 | 
								return err
 | 
				
			||||||
		slog.Error("joint-teapot joj3-scoreboard", "err", err)
 | 
					 | 
				
			||||||
		return err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	cmd = exec.Command("joint-teapot", "joj3-failed-table",
 | 
					 | 
				
			||||||
		envFilePath, conf.OutputPath, actor, conf.GradingRepoName, repoName,
 | 
					 | 
				
			||||||
		runNumber, conf.FailedTablePath, conf.Name) // #nosec G204
 | 
					 | 
				
			||||||
	outputBytes, err = cmd.CombinedOutput()
 | 
					 | 
				
			||||||
	output = re.ReplaceAllString(string(outputBytes), "")
 | 
					 | 
				
			||||||
	for _, line := range strings.Split(output, "\n") {
 | 
					 | 
				
			||||||
		if line == "" {
 | 
					 | 
				
			||||||
			continue
 | 
					 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		slog.Info("joint-teapot joj3-failed-table", "output", line)
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if err != nil {
 | 
						if !conf.Teapot.SkipFailedTable {
 | 
				
			||||||
		slog.Error("joint-teapot joj3-failed-table", "err", err)
 | 
							cmd := exec.Command("joint-teapot", "joj3-failed-table",
 | 
				
			||||||
		return err
 | 
								envFilePath, conf.Stage.OutputPath, actor, conf.Teapot.GradingRepoName,
 | 
				
			||||||
	}
 | 
								repoName, runNumber, conf.Teapot.FailedTablePath, conf.Name) // #nosec G204
 | 
				
			||||||
	cmd = exec.Command("joint-teapot", "joj3-create-result-issue",
 | 
							outputBytes, err := cmd.CombinedOutput()
 | 
				
			||||||
		envFilePath, conf.OutputPath, repoName, runNumber, conf.Name) // #nosec G204
 | 
							output := re.ReplaceAllString(string(outputBytes), "")
 | 
				
			||||||
	outputBytes, err = cmd.CombinedOutput()
 | 
							for _, line := range strings.Split(output, "\n") {
 | 
				
			||||||
	output = re.ReplaceAllString(string(outputBytes), "")
 | 
								if line == "" {
 | 
				
			||||||
	for _, line := range strings.Split(output, "\n") {
 | 
									continue
 | 
				
			||||||
		if line == "" {
 | 
								}
 | 
				
			||||||
			continue
 | 
								slog.Info("joint-teapot joj3-failed-table", "output", line)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								slog.Error("joint-teapot joj3-failed-table", "err", err)
 | 
				
			||||||
 | 
								return err
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		slog.Info("joint-teapot joj3-create-result-issue", "output", line)
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if err != nil {
 | 
						if !conf.Teapot.SkipIssue {
 | 
				
			||||||
		slog.Error("joint-teapot joj3-create-result-issue", "err", err)
 | 
							cmd := exec.Command("joint-teapot", "joj3-create-result-issue",
 | 
				
			||||||
		return err
 | 
								envFilePath, conf.Stage.OutputPath, repoName, runNumber, conf.Name) // #nosec G204
 | 
				
			||||||
 | 
							outputBytes, err := cmd.CombinedOutput()
 | 
				
			||||||
 | 
							output := re.ReplaceAllString(string(outputBytes), "")
 | 
				
			||||||
 | 
							for _, line := range strings.Split(output, "\n") {
 | 
				
			||||||
 | 
								if line == "" {
 | 
				
			||||||
 | 
									continue
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								slog.Info("joint-teapot joj3-create-result-issue", "output", line)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								slog.Error("joint-teapot joj3-create-result-issue", "err", err)
 | 
				
			||||||
 | 
								return err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return nil
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -21,7 +21,9 @@ const (
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type Conf struct {
 | 
					type Conf struct {
 | 
				
			||||||
	Cases []struct {
 | 
						PassComment string `default:"🥳Passed!\n"`
 | 
				
			||||||
 | 
						FailComment string `default:"🧐Failed...\n"`
 | 
				
			||||||
 | 
						Cases       []struct {
 | 
				
			||||||
		IgnoreResultStatus bool
 | 
							IgnoreResultStatus bool
 | 
				
			||||||
		Outputs            []struct {
 | 
							Outputs            []struct {
 | 
				
			||||||
			Score        int
 | 
								Score        int
 | 
				
			||||||
| 
						 | 
					@ -72,9 +74,9 @@ func (*Diff) Run(results []stage.ExecutorResult, confAny any) (
 | 
				
			||||||
				if compareChars(string(answer), result.Files[output.FileName],
 | 
									if compareChars(string(answer), result.Files[output.FileName],
 | 
				
			||||||
					output.CompareSpace) {
 | 
										output.CompareSpace) {
 | 
				
			||||||
					score += output.Score
 | 
										score += output.Score
 | 
				
			||||||
					comment += "Pass!\n"
 | 
										comment += conf.PassComment
 | 
				
			||||||
				} else {
 | 
									} else {
 | 
				
			||||||
					comment += "Fail!\n"
 | 
										comment += conf.FailComment
 | 
				
			||||||
					comment += fmt.Sprintf("Difference found in `%s`.\n",
 | 
										comment += fmt.Sprintf("Difference found in `%s`.\n",
 | 
				
			||||||
						output.FileName)
 | 
											output.FileName)
 | 
				
			||||||
					if !output.AlwaysHide {
 | 
										if !output.AlwaysHide {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -49,7 +49,7 @@ func (*ResultDetail) Run(results []stage.ExecutorResult, confAny any) (
 | 
				
			||||||
			content, ok := result.Files[file]
 | 
								content, ok := result.Files[file]
 | 
				
			||||||
			comment += fmt.Sprintf("File: `%s`.\n", file)
 | 
								comment += fmt.Sprintf("File: `%s`.\n", file)
 | 
				
			||||||
			if ok {
 | 
								if ok {
 | 
				
			||||||
				comment += fmt.Sprintf("```%s```\n", content)
 | 
									comment += fmt.Sprintf("```%s\n```\n", content)
 | 
				
			||||||
			} else {
 | 
								} else {
 | 
				
			||||||
				comment += "Not found.\n"
 | 
									comment += "Not found.\n"
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -150,12 +150,19 @@ func (r ExecutorResult) String() string {
 | 
				
			||||||
	return fmt.Sprintf("%+v", d)
 | 
						return fmt.Sprintf("%+v", d)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type StageExecutor struct {
 | 
				
			||||||
 | 
						Name string
 | 
				
			||||||
 | 
						Cmds []Cmd
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					type StageParser struct {
 | 
				
			||||||
 | 
						Name string
 | 
				
			||||||
 | 
						Conf any
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type Stage struct {
 | 
					type Stage struct {
 | 
				
			||||||
	Name         string
 | 
						Name     string
 | 
				
			||||||
	ExecutorName string
 | 
						Executor StageExecutor
 | 
				
			||||||
	ExecutorCmds []Cmd
 | 
						Parsers  []StageParser
 | 
				
			||||||
	ParserName   string
 | 
					 | 
				
			||||||
	ParserConf   any
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type ParserResult struct {
 | 
					type ParserResult struct {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -8,51 +8,68 @@ import (
 | 
				
			||||||
func Run(stages []Stage) (stageResults []StageResult, err error) {
 | 
					func Run(stages []Stage) (stageResults []StageResult, err error) {
 | 
				
			||||||
	var executorResults []ExecutorResult
 | 
						var executorResults []ExecutorResult
 | 
				
			||||||
	var parserResults []ParserResult
 | 
						var parserResults []ParserResult
 | 
				
			||||||
 | 
						var tmpParserResults []ParserResult
 | 
				
			||||||
	var forceQuit bool
 | 
						var forceQuit bool
 | 
				
			||||||
	slog.Info("stage run start")
 | 
						slog.Info("stage run start")
 | 
				
			||||||
	for _, stage := range stages {
 | 
						for _, stage := range stages {
 | 
				
			||||||
		slog.Info("stage start", "name", stage.Name)
 | 
							slog.Info("stage start", "name", stage.Name)
 | 
				
			||||||
		slog.Info("executor run start", "name", stage.ExecutorName)
 | 
							slog.Info("executor run start", "name", stage.Executor.Name)
 | 
				
			||||||
		slog.Debug("executor run start", "name", stage.ExecutorName,
 | 
							slog.Debug("executor run start", "name", stage.Executor.Name,
 | 
				
			||||||
			"cmds", stage.ExecutorCmds)
 | 
								"cmds", stage.Executor.Cmds)
 | 
				
			||||||
		executor, ok := executorMap[stage.ExecutorName]
 | 
							executor, ok := executorMap[stage.Executor.Name]
 | 
				
			||||||
		if !ok {
 | 
							if !ok {
 | 
				
			||||||
			slog.Error("executor not found", "name", stage.ExecutorName)
 | 
								slog.Error("executor not found", "name", stage.Executor.Name)
 | 
				
			||||||
			err = fmt.Errorf("executor not found: %s", stage.ExecutorName)
 | 
								err = fmt.Errorf("executor not found: %s", stage.Executor.Name)
 | 
				
			||||||
			return
 | 
								return
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		executorResults, err = executor.Run(stage.ExecutorCmds)
 | 
							executorResults, err = executor.Run(stage.Executor.Cmds)
 | 
				
			||||||
		if err != nil {
 | 
							if err != nil {
 | 
				
			||||||
			slog.Error("executor run error", "name", stage.ExecutorName, "error", err)
 | 
								slog.Error("executor run error", "name", stage.Executor.Name, "error", err)
 | 
				
			||||||
			return
 | 
								return
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		slog.Debug("executor run done", "results", executorResults)
 | 
							slog.Debug("executor run done", "results", executorResults)
 | 
				
			||||||
		for _, executorResult := range executorResults {
 | 
							for _, executorResult := range executorResults {
 | 
				
			||||||
			slog.Debug("executor run done", "result.Files", executorResult.Files)
 | 
								slog.Debug("executor run done", "result.Files", executorResult.Files)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		slog.Info("parser run start", "name", stage.ParserName)
 | 
							parserResults = []ParserResult{}
 | 
				
			||||||
		slog.Debug("parser run start", "name", stage.ParserName,
 | 
							stageForceQuit := false
 | 
				
			||||||
			"conf", stage.ParserConf)
 | 
							for _, stageParser := range stage.Parsers {
 | 
				
			||||||
		parser, ok := parserMap[stage.ParserName]
 | 
								slog.Info("parser run start", "name", stageParser.Name)
 | 
				
			||||||
		if !ok {
 | 
								slog.Debug("parser run start", "name", stageParser.Name,
 | 
				
			||||||
			slog.Error("parser not found", "name", stage.ParserName)
 | 
									"conf", stageParser.Conf)
 | 
				
			||||||
			err = fmt.Errorf("parser not found: %s", stage.ParserName)
 | 
								parser, ok := parserMap[stageParser.Name]
 | 
				
			||||||
			return
 | 
								if !ok {
 | 
				
			||||||
 | 
									slog.Error("parser not found", "name", stageParser.Name)
 | 
				
			||||||
 | 
									err = fmt.Errorf("parser not found: %s", stageParser.Name)
 | 
				
			||||||
 | 
									return
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								tmpParserResults, forceQuit, err = parser.Run(
 | 
				
			||||||
 | 
									executorResults, stageParser.Conf)
 | 
				
			||||||
 | 
								if err != nil {
 | 
				
			||||||
 | 
									slog.Error("parser run error", "name", stageParser.Name, "error", err)
 | 
				
			||||||
 | 
									return
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								stageForceQuit = stageForceQuit || forceQuit
 | 
				
			||||||
 | 
								slog.Debug("parser run done", "results", tmpParserResults)
 | 
				
			||||||
 | 
								if len(parserResults) == 0 {
 | 
				
			||||||
 | 
									parserResults = tmpParserResults
 | 
				
			||||||
 | 
								} else {
 | 
				
			||||||
 | 
									for i := range len(parserResults) {
 | 
				
			||||||
 | 
										parserResults[i].Score += tmpParserResults[i].Score
 | 
				
			||||||
 | 
										parserResults[i].Comment += tmpParserResults[i].Comment
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								if forceQuit {
 | 
				
			||||||
 | 
									slog.Error("parser force quit", "name", stageParser.Name)
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		parserResults, forceQuit, err = parser.Run(executorResults, stage.ParserConf)
 | 
					 | 
				
			||||||
		if err != nil {
 | 
					 | 
				
			||||||
			slog.Error("parser run error", "name", stage.ParserName, "error", err)
 | 
					 | 
				
			||||||
			return
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		slog.Debug("parser run done", "results", parserResults)
 | 
					 | 
				
			||||||
		stageResults = append(stageResults, StageResult{
 | 
							stageResults = append(stageResults, StageResult{
 | 
				
			||||||
			Name:      stage.Name,
 | 
								Name:      stage.Name,
 | 
				
			||||||
			Results:   parserResults,
 | 
								Results:   parserResults,
 | 
				
			||||||
			ForceQuit: forceQuit,
 | 
								ForceQuit: stageForceQuit,
 | 
				
			||||||
		})
 | 
							})
 | 
				
			||||||
		if forceQuit {
 | 
							if stageForceQuit {
 | 
				
			||||||
			slog.Error("parser force quit", "name", stage.ParserName)
 | 
								break
 | 
				
			||||||
			return
 | 
					 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return
 | 
						return
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue
	
	Block a user