From 6620f9bc28841fe2dc41a5176feab9562e9ec53b Mon Sep 17 00:00:00 2001 From: Boming Zhang Date: Wed, 9 Oct 2024 18:50:06 -0400 Subject: [PATCH] feat!: support multiple parsers in one stage (#52) --- cmd/joj3/conf/conf.go | 2 +- cmd/joj3/stage/main.go | 20 +++++++++---- internal/stage/model.go | 17 +++++++---- internal/stage/run.go | 64 +++++++++++++++++++++++++---------------- 4 files changed, 67 insertions(+), 36 deletions(-) diff --git a/cmd/joj3/conf/conf.go b/cmd/joj3/conf/conf.go index f17efd7..b038cda 100644 --- a/cmd/joj3/conf/conf.go +++ b/cmd/joj3/conf/conf.go @@ -30,7 +30,7 @@ type Conf struct { Cases []OptionalCmd } } - Parser struct { + Parsers []struct { Name string With interface{} } diff --git a/cmd/joj3/stage/main.go b/cmd/joj3/stage/main.go index 51a857e..33fd449 100644 --- a/cmd/joj3/stage/main.go +++ b/cmd/joj3/stage/main.go @@ -16,7 +16,7 @@ import ( func generateStages(conf conf.Conf, group string) ([]stage.Stage, error) { stages := []stage.Stage{} existNames := map[string]bool{} - for _, s := range conf.Stages { + for _, s := range conf.Stage.Stages { if s.Group != "" && group != s.Group { continue } @@ -50,12 +50,20 @@ func generateStages(conf conf.Conf, group string) ([]stage.Stage, error) { if len(s.Executor.With.Cases) == 0 { 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{ - Name: s.Name, - ExecutorName: s.Executor.Name, - ExecutorCmds: cmds, - ParserName: s.Parser.Name, - ParserConf: s.Parser.With, + Name: s.Name, + Executor: stage.StageExecutor{ + Name: s.Executor.Name, + Cmds: cmds, + }, + Parsers: parsers, }) } slog.Debug("stages generated", "stages", stages) diff --git a/internal/stage/model.go b/internal/stage/model.go index bd21dd7..a6c7e79 100644 --- a/internal/stage/model.go +++ b/internal/stage/model.go @@ -150,12 +150,19 @@ func (r ExecutorResult) String() string { return fmt.Sprintf("%+v", d) } +type StageExecutor struct { + Name string + Cmds []Cmd +} +type StageParser struct { + Name string + Conf any +} + type Stage struct { - Name string - ExecutorName string - ExecutorCmds []Cmd - ParserName string - ParserConf any + Name string + Executor StageExecutor + Parsers []StageParser } type ParserResult struct { diff --git a/internal/stage/run.go b/internal/stage/run.go index 4e346bc..aa95468 100644 --- a/internal/stage/run.go +++ b/internal/stage/run.go @@ -8,51 +8,67 @@ import ( func Run(stages []Stage) (stageResults []StageResult, err error) { var executorResults []ExecutorResult var parserResults []ParserResult + var tmpParserResults []ParserResult var forceQuit bool slog.Info("stage run start") for _, stage := range stages { slog.Info("stage start", "name", stage.Name) - slog.Info("executor run start", "name", stage.ExecutorName) - slog.Debug("executor run start", "name", stage.ExecutorName, - "cmds", stage.ExecutorCmds) - executor, ok := executorMap[stage.ExecutorName] + slog.Info("executor run start", "name", stage.Executor.Name) + slog.Debug("executor run start", "name", stage.Executor.Name, + "cmds", stage.Executor.Cmds) + executor, ok := executorMap[stage.Executor.Name] if !ok { - slog.Error("executor not found", "name", stage.ExecutorName) - err = fmt.Errorf("executor not found: %s", stage.ExecutorName) + slog.Error("executor not found", "name", stage.Executor.Name) + err = fmt.Errorf("executor not found: %s", stage.Executor.Name) return } - executorResults, err = executor.Run(stage.ExecutorCmds) + executorResults, err = executor.Run(stage.Executor.Cmds) 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 } slog.Debug("executor run done", "results", executorResults) for _, executorResult := range executorResults { slog.Debug("executor run done", "result.Files", executorResult.Files) } - slog.Info("parser run start", "name", stage.ParserName) - slog.Debug("parser run start", "name", stage.ParserName, - "conf", stage.ParserConf) - parser, ok := parserMap[stage.ParserName] - if !ok { - slog.Error("parser not found", "name", stage.ParserName) - err = fmt.Errorf("parser not found: %s", stage.ParserName) - return + parserResults = []ParserResult{} + for _, stageParser := range stage.Parsers { + slog.Info("parser run start", "name", stageParser.Name) + slog.Debug("parser run start", "name", stageParser.Name, + "conf", stageParser.Conf) + parser, ok := parserMap[stageParser.Name] + 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 + } + 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) + break + } } - 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{ Name: stage.Name, Results: parserResults, ForceQuit: forceQuit, }) if forceQuit { - slog.Error("parser force quit", "name", stage.ParserName) - return + break } } return