From 7198911f6d5fe52586af0e0c909e179cf09dcfc1 Mon Sep 17 00:00:00 2001 From: Boming Zhang Date: Sat, 5 Oct 2024 23:15:18 -0400 Subject: [PATCH] refactor: rename modules --- cmd/joj3/main.go | 169 +----------------- cmd/joj3/{ => stage-runner}/conf.go | 2 +- cmd/joj3/{ => stage-runner}/conf_test.go | 2 +- cmd/joj3/{ => stage-runner}/log.go | 2 +- cmd/joj3/stage-runner/main.go | 160 +++++++++++++++++ cmd/joj3/{ => stage-runner}/main_test.go | 10 +- cmd/joj3/teapot-caller/main.go | 18 ++ .../main.go | 0 8 files changed, 196 insertions(+), 167 deletions(-) rename cmd/joj3/{ => stage-runner}/conf.go (99%) rename cmd/joj3/{ => stage-runner}/conf_test.go (99%) rename cmd/joj3/{ => stage-runner}/log.go (98%) create mode 100644 cmd/joj3/stage-runner/main.go rename cmd/joj3/{ => stage-runner}/main_test.go (94%) create mode 100644 cmd/joj3/teapot-caller/main.go rename cmd/{healthcheck => repo-health-checker}/main.go (100%) diff --git a/cmd/joj3/main.go b/cmd/joj3/main.go index 0fd6385..d756b2a 100644 --- a/cmd/joj3/main.go +++ b/cmd/joj3/main.go @@ -1,170 +1,19 @@ package main import ( - "encoding/json" - "flag" - "fmt" "log/slog" - "os" - "github.com/joint-online-judge/JOJ3/internal/executors" - _ "github.com/joint-online-judge/JOJ3/internal/parsers" - "github.com/joint-online-judge/JOJ3/internal/stage" - - "github.com/go-git/go-git/v5" - "github.com/jinzhu/copier" + stagerunner "github.com/joint-online-judge/JOJ3/cmd/joj3/stage-runner" + teapotcaller "github.com/joint-online-judge/JOJ3/cmd/joj3/teapot-caller" ) -func getCommitMsg() (msg string, 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 - } - msg = commit.Message - return -} - -func generateStages(conf Conf, group string) ([]stage.Stage, error) { - stages := []stage.Stage{} - existNames := map[string]bool{} - for _, s := range conf.Stages { - if s.Group != "" && group != s.Group { - continue - } - _, ok := existNames[s.Name] // check for existence - if ok { - continue - } - existNames[s.Name] = true - var cmds []stage.Cmd - defaultCmd := s.Executor.With.Default - for _, optionalCmd := range s.Executor.With.Cases { - cmd := s.Executor.With.Default - err := copier.Copy(&cmd, &optionalCmd) - if err != nil { - slog.Error("generate stages", "error", err) - return stages, err - } - // since these 3 values are pointers, copier will always copy - // them, so we need to check them manually - if defaultCmd.Stdin != nil && optionalCmd.Stdin == nil { - cmd.Stdin = defaultCmd.Stdin - } - if defaultCmd.Stdout != nil && optionalCmd.Stdout == nil { - cmd.Stdout = defaultCmd.Stdout - } - if defaultCmd.Stderr != nil && optionalCmd.Stderr == nil { - cmd.Stderr = defaultCmd.Stderr - } - cmds = append(cmds, cmd) - } - if len(s.Executor.With.Cases) == 0 { - cmds = []stage.Cmd{defaultCmd} - } - stages = append(stages, stage.Stage{ - Name: s.Name, - ExecutorName: s.Executor.Name, - ExecutorCmds: cmds, - ParserName: s.Parser.Name, - ParserConf: s.Parser.With, - }) - } - slog.Debug("stages generated", "stages", stages) - return stages, nil -} - -func outputResult(outputPath string, results []stage.StageResult) error { - slog.Info("output result start", "path", outputPath) - slog.Debug("output result start", "path", outputPath, "results", results) - content, err := json.Marshal(results) - if err != nil { - return err - } - return os.WriteFile(outputPath, - append(content, []byte("\n")...), 0o600) -} - -var ( - confRoot string - confName string - msg string - showVersion *bool - Version string = "debug" -) - -func init() { - flag.StringVar(&confRoot, "conf-root", ".", "root path for all config files") - flag.StringVar(&confName, "conf-name", "conf.json", "filename for config files") - flag.StringVar(&msg, "msg", "", "message to trigger the running, leave empty to use git commit message on HEAD") - showVersion = flag.Bool("version", false, "print current version") -} - -func mainImpl() error { - for _, e := range os.Environ() { - fmt.Println(e) - } - if err := setupSlog(""); err != nil { // before conf is loaded - return err - } - flag.Parse() - if *showVersion { - fmt.Println(Version) - return nil - } - slog.Info("start joj3", "version", Version) - if msg == "" { - var err error - msg, err = getCommitMsg() - if err != nil { - slog.Error("get commit msg", "error", err) - return err - } - } - conf, group, err := parseMsg(confRoot, confName, msg) - if err != nil { - slog.Error("parse msg", "error", err) - validScopes, scopeErr := listValidScopes( - confRoot, confName, msg) - if scopeErr != nil { - slog.Error("list valid scopes", "error", scopeErr) - return scopeErr - } - slog.Info("hint: valid scopes in commit message", "scopes", validScopes) - return err - } - if err := setupSlog(conf.LogPath); err != nil { // after conf is loaded - return err - } - executors.InitWithConf(conf.SandboxExecServer, conf.SandboxToken) - stages, err := generateStages(conf, group) - if err != nil { - slog.Error("generate stages", "error", err) - return err - } - defer stage.Cleanup() - results, err := stage.Run(stages) - if err != nil { - slog.Error("run stages", "error", err) - return err - } - if err := outputResult(conf.OutputPath, results); err != nil { - slog.Error("output result", "error", err) - return err - } - return nil -} - func main() { - if err := mainImpl(); err != nil { - slog.Error("main exit", "error", err) - os.Exit(1) + // TODO: call stage-runner + if err := stagerunner.Run(); err != nil { + slog.Error("stage runner error", "error", err) + } + // TODO: call joint-teapot + if err := teapotcaller.Run(); err != nil { + slog.Error("teapot caller error", "error", err) } } diff --git a/cmd/joj3/conf.go b/cmd/joj3/stage-runner/conf.go similarity index 99% rename from cmd/joj3/conf.go rename to cmd/joj3/stage-runner/conf.go index 6e63847..09f84cc 100644 --- a/cmd/joj3/conf.go +++ b/cmd/joj3/stage-runner/conf.go @@ -1,4 +1,4 @@ -package main +package stagerunner import ( "fmt" diff --git a/cmd/joj3/conf_test.go b/cmd/joj3/stage-runner/conf_test.go similarity index 99% rename from cmd/joj3/conf_test.go rename to cmd/joj3/stage-runner/conf_test.go index 0906cc3..75631f6 100644 --- a/cmd/joj3/conf_test.go +++ b/cmd/joj3/stage-runner/conf_test.go @@ -1,4 +1,4 @@ -package main +package stagerunner import ( "reflect" diff --git a/cmd/joj3/log.go b/cmd/joj3/stage-runner/log.go similarity index 98% rename from cmd/joj3/log.go rename to cmd/joj3/stage-runner/log.go index bdeccc4..7c671b2 100644 --- a/cmd/joj3/log.go +++ b/cmd/joj3/stage-runner/log.go @@ -1,4 +1,4 @@ -package main +package stagerunner import ( "context" diff --git a/cmd/joj3/stage-runner/main.go b/cmd/joj3/stage-runner/main.go new file mode 100644 index 0000000..f4b3a9b --- /dev/null +++ b/cmd/joj3/stage-runner/main.go @@ -0,0 +1,160 @@ +package stagerunner + +import ( + "encoding/json" + "flag" + "fmt" + "log/slog" + "os" + + "github.com/joint-online-judge/JOJ3/internal/executors" + _ "github.com/joint-online-judge/JOJ3/internal/parsers" + "github.com/joint-online-judge/JOJ3/internal/stage" + + "github.com/go-git/go-git/v5" + "github.com/jinzhu/copier" +) + +func getCommitMsg() (msg string, 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 + } + msg = commit.Message + return +} + +func generateStages(conf Conf, group string) ([]stage.Stage, error) { + stages := []stage.Stage{} + existNames := map[string]bool{} + for _, s := range conf.Stages { + if s.Group != "" && group != s.Group { + continue + } + _, ok := existNames[s.Name] // check for existence + if ok { + continue + } + existNames[s.Name] = true + var cmds []stage.Cmd + defaultCmd := s.Executor.With.Default + for _, optionalCmd := range s.Executor.With.Cases { + cmd := s.Executor.With.Default + err := copier.Copy(&cmd, &optionalCmd) + if err != nil { + slog.Error("generate stages", "error", err) + return stages, err + } + // since these 3 values are pointers, copier will always copy + // them, so we need to check them manually + if defaultCmd.Stdin != nil && optionalCmd.Stdin == nil { + cmd.Stdin = defaultCmd.Stdin + } + if defaultCmd.Stdout != nil && optionalCmd.Stdout == nil { + cmd.Stdout = defaultCmd.Stdout + } + if defaultCmd.Stderr != nil && optionalCmd.Stderr == nil { + cmd.Stderr = defaultCmd.Stderr + } + cmds = append(cmds, cmd) + } + if len(s.Executor.With.Cases) == 0 { + cmds = []stage.Cmd{defaultCmd} + } + stages = append(stages, stage.Stage{ + Name: s.Name, + ExecutorName: s.Executor.Name, + ExecutorCmds: cmds, + ParserName: s.Parser.Name, + ParserConf: s.Parser.With, + }) + } + slog.Debug("stages generated", "stages", stages) + return stages, nil +} + +func outputResult(outputPath string, results []stage.StageResult) error { + slog.Info("output result start", "path", outputPath) + slog.Debug("output result start", "path", outputPath, "results", results) + content, err := json.Marshal(results) + if err != nil { + return err + } + return os.WriteFile(outputPath, + append(content, []byte("\n")...), 0o600) +} + +var ( + confRoot string + confName string + msg string + showVersion *bool + Version string = "debug" +) + +func init() { + flag.StringVar(&confRoot, "conf-root", ".", "root path for all config files") + flag.StringVar(&confName, "conf-name", "conf.json", "filename for config files") + flag.StringVar(&msg, "msg", "", "message to trigger the running, leave empty to use git commit message on HEAD") + showVersion = flag.Bool("version", false, "print current version") +} + +func Run() error { + if err := setupSlog(""); err != nil { // before conf is loaded + return err + } + flag.Parse() + if *showVersion { + fmt.Println(Version) + return nil + } + slog.Info("start joj3", "version", Version) + if msg == "" { + var err error + msg, err = getCommitMsg() + if err != nil { + slog.Error("get commit msg", "error", err) + return err + } + } + conf, group, err := parseMsg(confRoot, confName, msg) + if err != nil { + slog.Error("parse msg", "error", err) + validScopes, scopeErr := listValidScopes( + confRoot, confName, msg) + if scopeErr != nil { + slog.Error("list valid scopes", "error", scopeErr) + return scopeErr + } + slog.Info("hint: valid scopes in commit message", "scopes", validScopes) + return err + } + if err := setupSlog(conf.LogPath); err != nil { // after conf is loaded + return err + } + executors.InitWithConf(conf.SandboxExecServer, conf.SandboxToken) + stages, err := generateStages(conf, group) + if err != nil { + slog.Error("generate stages", "error", err) + return err + } + defer stage.Cleanup() + results, err := stage.Run(stages) + if err != nil { + slog.Error("run stages", "error", err) + return err + } + if err := outputResult(conf.OutputPath, results); err != nil { + slog.Error("output result", "error", err) + return err + } + return nil +} diff --git a/cmd/joj3/main_test.go b/cmd/joj3/stage-runner/main_test.go similarity index 94% rename from cmd/joj3/main_test.go rename to cmd/joj3/stage-runner/main_test.go index e160176..24ea6b6 100644 --- a/cmd/joj3/main_test.go +++ b/cmd/joj3/stage-runner/main_test.go @@ -1,4 +1,4 @@ -package main +package stagerunner import ( "encoding/json" @@ -61,9 +61,9 @@ func readStageResults(t *testing.T, path string) []stage.StageResult { return results } -func TestMain(t *testing.T) { +func TestRun(t *testing.T) { var tests []string - root := "../../tmp/submodules/JOJ3-examples/examples/" + root := "../../../tmp/submodules/JOJ3-examples/examples/" err := filepath.Walk(root, func(path string, info os.FileInfo, err error) error { if err != nil { return err @@ -105,7 +105,9 @@ func TestMain(t *testing.T) { os.Args = []string{"./joj3"} outputFile := "joj3_result.json" defer os.Remove(outputFile) - main() + if err := Run(); err != nil { + t.Fatal(err) + } stageResults := readStageResults(t, outputFile) regex := true expectedFile := "expected_regex.json" diff --git a/cmd/joj3/teapot-caller/main.go b/cmd/joj3/teapot-caller/main.go new file mode 100644 index 0000000..10087f5 --- /dev/null +++ b/cmd/joj3/teapot-caller/main.go @@ -0,0 +1,18 @@ +package teapotcaller + +import ( + "log/slog" + "os/exec" +) + +func Run() error { + // TODO: call teapot + cmd := exec.Command("joint-teapot", "--help") + output, err := cmd.CombinedOutput() + if err != nil { + slog.Error("running git command:", "err", err) + return err + } + slog.Info("joint-teapot run", "output", string(output)) + return nil +} diff --git a/cmd/healthcheck/main.go b/cmd/repo-health-checker/main.go similarity index 100% rename from cmd/healthcheck/main.go rename to cmd/repo-health-checker/main.go