From f3ebd678a892c2d8e95afa59ddd9e56bf0348a1c Mon Sep 17 00:00:00 2001 From: Boming Zhang Date: Sat, 5 Oct 2024 22:37:14 -0400 Subject: [PATCH 1/8] feat: print all environment variables --- cmd/joj3/main.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/cmd/joj3/main.go b/cmd/joj3/main.go index a211105..0fd6385 100644 --- a/cmd/joj3/main.go +++ b/cmd/joj3/main.go @@ -108,6 +108,9 @@ func init() { } func mainImpl() error { + for _, e := range os.Environ() { + fmt.Println(e) + } if err := setupSlog(""); err != nil { // before conf is loaded return err } -- 2.30.2 From 7198911f6d5fe52586af0e0c909e179cf09dcfc1 Mon Sep 17 00:00:00 2001 From: Boming Zhang Date: Sat, 5 Oct 2024 23:15:18 -0400 Subject: [PATCH 2/8] 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 -- 2.30.2 From 6c3de223d1a4cb7fcb581fb1bb87655e23136bc3 Mon Sep 17 00:00:00 2001 From: Boming Zhang Date: Sun, 6 Oct 2024 19:25:15 -0400 Subject: [PATCH 3/8] refactor: rename modules --- cmd/joj3/main.go | 8 ++++---- cmd/joj3/{stage-runner => stage}/conf.go | 2 +- cmd/joj3/{stage-runner => stage}/conf_test.go | 2 +- cmd/joj3/{stage-runner => stage}/log.go | 2 +- cmd/joj3/{stage-runner => stage}/main.go | 2 +- cmd/joj3/{stage-runner => stage}/main_test.go | 2 +- cmd/joj3/{teapot-caller => teapot}/main.go | 2 +- 7 files changed, 10 insertions(+), 10 deletions(-) rename cmd/joj3/{stage-runner => stage}/conf.go (99%) rename cmd/joj3/{stage-runner => stage}/conf_test.go (99%) rename cmd/joj3/{stage-runner => stage}/log.go (98%) rename cmd/joj3/{stage-runner => stage}/main.go (99%) rename cmd/joj3/{stage-runner => stage}/main_test.go (99%) rename cmd/joj3/{teapot-caller => teapot}/main.go (93%) diff --git a/cmd/joj3/main.go b/cmd/joj3/main.go index d756b2a..fc378ce 100644 --- a/cmd/joj3/main.go +++ b/cmd/joj3/main.go @@ -3,17 +3,17 @@ package main import ( "log/slog" - stagerunner "github.com/joint-online-judge/JOJ3/cmd/joj3/stage-runner" - teapotcaller "github.com/joint-online-judge/JOJ3/cmd/joj3/teapot-caller" + "github.com/joint-online-judge/JOJ3/cmd/joj3/stage" + "github.com/joint-online-judge/JOJ3/cmd/joj3/teapot" ) func main() { // TODO: call stage-runner - if err := stagerunner.Run(); err != nil { + if err := stage.Run(); err != nil { slog.Error("stage runner error", "error", err) } // TODO: call joint-teapot - if err := teapotcaller.Run(); err != nil { + if err := teapot.Run(); err != nil { slog.Error("teapot caller error", "error", err) } } diff --git a/cmd/joj3/stage-runner/conf.go b/cmd/joj3/stage/conf.go similarity index 99% rename from cmd/joj3/stage-runner/conf.go rename to cmd/joj3/stage/conf.go index 09f84cc..ff156a3 100644 --- a/cmd/joj3/stage-runner/conf.go +++ b/cmd/joj3/stage/conf.go @@ -1,4 +1,4 @@ -package stagerunner +package stage import ( "fmt" diff --git a/cmd/joj3/stage-runner/conf_test.go b/cmd/joj3/stage/conf_test.go similarity index 99% rename from cmd/joj3/stage-runner/conf_test.go rename to cmd/joj3/stage/conf_test.go index 75631f6..237ffb4 100644 --- a/cmd/joj3/stage-runner/conf_test.go +++ b/cmd/joj3/stage/conf_test.go @@ -1,4 +1,4 @@ -package stagerunner +package stage import ( "reflect" diff --git a/cmd/joj3/stage-runner/log.go b/cmd/joj3/stage/log.go similarity index 98% rename from cmd/joj3/stage-runner/log.go rename to cmd/joj3/stage/log.go index 7c671b2..93ac8cb 100644 --- a/cmd/joj3/stage-runner/log.go +++ b/cmd/joj3/stage/log.go @@ -1,4 +1,4 @@ -package stagerunner +package stage import ( "context" diff --git a/cmd/joj3/stage-runner/main.go b/cmd/joj3/stage/main.go similarity index 99% rename from cmd/joj3/stage-runner/main.go rename to cmd/joj3/stage/main.go index f4b3a9b..fb0759b 100644 --- a/cmd/joj3/stage-runner/main.go +++ b/cmd/joj3/stage/main.go @@ -1,4 +1,4 @@ -package stagerunner +package stage import ( "encoding/json" diff --git a/cmd/joj3/stage-runner/main_test.go b/cmd/joj3/stage/main_test.go similarity index 99% rename from cmd/joj3/stage-runner/main_test.go rename to cmd/joj3/stage/main_test.go index 24ea6b6..cb9bb3c 100644 --- a/cmd/joj3/stage-runner/main_test.go +++ b/cmd/joj3/stage/main_test.go @@ -1,4 +1,4 @@ -package stagerunner +package stage import ( "encoding/json" diff --git a/cmd/joj3/teapot-caller/main.go b/cmd/joj3/teapot/main.go similarity index 93% rename from cmd/joj3/teapot-caller/main.go rename to cmd/joj3/teapot/main.go index 10087f5..4d8142e 100644 --- a/cmd/joj3/teapot-caller/main.go +++ b/cmd/joj3/teapot/main.go @@ -1,4 +1,4 @@ -package teapotcaller +package teapot import ( "log/slog" -- 2.30.2 From 8ffa64de4a8fc4a9b16983c9002aff1411ae301f Mon Sep 17 00:00:00 2001 From: Boming Zhang Date: Sun, 6 Oct 2024 19:41:39 -0400 Subject: [PATCH 4/8] refactor: move modules --- cmd/joj3/{stage => conf}/conf.go | 24 +++++++-- cmd/joj3/{stage => conf}/conf_test.go | 2 +- cmd/joj3/{stage => }/log.go | 2 +- cmd/joj3/main.go | 64 +++++++++++++++++++++--- cmd/joj3/{stage => }/main_test.go | 8 ++- cmd/joj3/stage/main.go | 72 ++------------------------- cmd/joj3/teapot/main.go | 4 +- 7 files changed, 90 insertions(+), 86 deletions(-) rename cmd/joj3/{stage => conf}/conf.go (90%) rename cmd/joj3/{stage => conf}/conf_test.go (99%) rename cmd/joj3/{stage => }/log.go (99%) rename cmd/joj3/{stage => }/main_test.go (96%) diff --git a/cmd/joj3/stage/conf.go b/cmd/joj3/conf/conf.go similarity index 90% rename from cmd/joj3/stage/conf.go rename to cmd/joj3/conf/conf.go index ff156a3..02431cb 100644 --- a/cmd/joj3/stage/conf.go +++ b/cmd/joj3/conf/conf.go @@ -1,4 +1,4 @@ -package stage +package conf import ( "fmt" @@ -8,6 +8,7 @@ import ( "regexp" "strings" + "github.com/go-git/go-git/v5" "github.com/joint-online-judge/JOJ3/internal/stage" "github.com/koding/multiconfig" ) @@ -73,6 +74,23 @@ type ConventionalCommit struct { Footer string } +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 parseConventionalCommit(commit string) (*ConventionalCommit, error) { re := regexp.MustCompile(`(?s)^(\w+)(\(([^)]+)\))?!?: (.+?)(\n\n(.+?))?(\n\n(.+))?$`) matches := re.FindStringSubmatch(strings.TrimSpace(commit)) @@ -107,7 +125,7 @@ func parseConfFile(path string) (conf Conf, err error) { return } -func parseMsg(confRoot, confName, msg string) (conf Conf, group string, err error) { +func ParseMsg(confRoot, confName, msg string) (conf Conf, group string, err error) { slog.Info("parse msg", "msg", msg) conventionalCommit, err := parseConventionalCommit(msg) if err != nil { @@ -142,7 +160,7 @@ func parseMsg(confRoot, confName, msg string) (conf Conf, group string, err erro return } -func listValidScopes(confRoot, confName, msg string) ([]string, error) { +func ListValidScopes(confRoot, confName, msg string) ([]string, error) { conventionalCommit, err := parseConventionalCommit(msg) if err != nil { return []string{}, err diff --git a/cmd/joj3/stage/conf_test.go b/cmd/joj3/conf/conf_test.go similarity index 99% rename from cmd/joj3/stage/conf_test.go rename to cmd/joj3/conf/conf_test.go index 237ffb4..ccab160 100644 --- a/cmd/joj3/stage/conf_test.go +++ b/cmd/joj3/conf/conf_test.go @@ -1,4 +1,4 @@ -package stage +package conf import ( "reflect" diff --git a/cmd/joj3/stage/log.go b/cmd/joj3/log.go similarity index 99% rename from cmd/joj3/stage/log.go rename to cmd/joj3/log.go index 93ac8cb..bdeccc4 100644 --- a/cmd/joj3/stage/log.go +++ b/cmd/joj3/log.go @@ -1,4 +1,4 @@ -package stage +package main import ( "context" diff --git a/cmd/joj3/main.go b/cmd/joj3/main.go index fc378ce..257e108 100644 --- a/cmd/joj3/main.go +++ b/cmd/joj3/main.go @@ -1,19 +1,71 @@ package main import ( + "flag" + "fmt" "log/slog" + "github.com/joint-online-judge/JOJ3/cmd/joj3/conf" "github.com/joint-online-judge/JOJ3/cmd/joj3/stage" "github.com/joint-online-judge/JOJ3/cmd/joj3/teapot" ) +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 main() { - // TODO: call stage-runner - if err := stage.Run(); err != nil { - slog.Error("stage runner error", "error", err) + if err := setupSlog(""); err != nil { // before conf is loaded + slog.Error("setup slog", "error", err) + return } - // TODO: call joint-teapot - if err := teapot.Run(); err != nil { - slog.Error("teapot caller error", "error", err) + flag.Parse() + if *showVersion { + fmt.Println(Version) + return + } + slog.Info("start joj3", "version", Version) + if msg == "" { + var err error + msg, err = conf.GetCommitMsg() + if err != nil { + slog.Error("get commit msg", "error", err) + return + } + } + confObj, group, err := conf.ParseMsg(confRoot, confName, msg) + if err != nil { + slog.Error("parse msg", "error", err) + validScopes, scopeErr := conf.ListValidScopes( + confRoot, confName, msg) + if scopeErr != nil { + slog.Error("list valid scopes", "error", scopeErr) + return + } + slog.Info("hint: valid scopes in commit message", "scopes", validScopes) + return + } + if err := setupSlog(confObj.LogPath); err != nil { // after conf is loaded + slog.Error("setup slog", "error", err) + return + } + if err := stage.Run(confObj, group); err != nil { + slog.Error("stage run", "error", err) + return + } + if err := teapot.Run(confObj); err != nil { + slog.Error("teapot run", "error", err) + return } } diff --git a/cmd/joj3/stage/main_test.go b/cmd/joj3/main_test.go similarity index 96% rename from cmd/joj3/stage/main_test.go rename to cmd/joj3/main_test.go index cb9bb3c..ea442fc 100644 --- a/cmd/joj3/stage/main_test.go +++ b/cmd/joj3/main_test.go @@ -1,4 +1,4 @@ -package stage +package main import ( "encoding/json" @@ -63,7 +63,7 @@ func readStageResults(t *testing.T, path string) []stage.StageResult { 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,9 +105,7 @@ func TestRun(t *testing.T) { os.Args = []string{"./joj3"} outputFile := "joj3_result.json" defer os.Remove(outputFile) - if err := Run(); err != nil { - t.Fatal(err) - } + main() stageResults := readStageResults(t, outputFile) regex := true expectedFile := "expected_regex.json" diff --git a/cmd/joj3/stage/main.go b/cmd/joj3/stage/main.go index fb0759b..1f86c1b 100644 --- a/cmd/joj3/stage/main.go +++ b/cmd/joj3/stage/main.go @@ -2,37 +2,18 @@ package stage import ( "encoding/json" - "flag" - "fmt" "log/slog" "os" + "github.com/joint-online-judge/JOJ3/cmd/joj3/conf" "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) { +func generateStages(conf conf.Conf, group string) ([]stage.Stage, error) { stages := []stage.Stage{} existNames := map[string]bool{} for _, s := range conf.Stages { @@ -92,54 +73,7 @@ func outputResult(outputPath string, results []stage.StageResult) error { 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 - } +func Run(conf conf.Conf, group string) error { executors.InitWithConf(conf.SandboxExecServer, conf.SandboxToken) stages, err := generateStages(conf, group) if err != nil { diff --git a/cmd/joj3/teapot/main.go b/cmd/joj3/teapot/main.go index 4d8142e..f001c7b 100644 --- a/cmd/joj3/teapot/main.go +++ b/cmd/joj3/teapot/main.go @@ -3,9 +3,11 @@ package teapot import ( "log/slog" "os/exec" + + "github.com/joint-online-judge/JOJ3/cmd/joj3/conf" ) -func Run() error { +func Run(conf conf.Conf) error { // TODO: call teapot cmd := exec.Command("joint-teapot", "--help") output, err := cmd.CombinedOutput() -- 2.30.2 From 89a96874ffbc4a54178e159ada134aa9e06b99a7 Mon Sep 17 00:00:00 2001 From: Boming Zhang Date: Sun, 6 Oct 2024 19:46:33 -0400 Subject: [PATCH 5/8] ci: install joint-teapot --- .gitea/workflows/build.yaml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitea/workflows/build.yaml b/.gitea/workflows/build.yaml index 340acfc..f4581db 100644 --- a/.gitea/workflows/build.yaml +++ b/.gitea/workflows/build.yaml @@ -34,6 +34,9 @@ jobs: rm -rf golangci-lint-1.61.0-linux-amd64.tar.gz mkdir -p /root/go/bin mv /tmp/golangci-lint-1.61.0-linux-amd64/golangci-lint /root/go/bin + - name: Setup Joint-Teapot + run: | + pip install git+https://ghp.ci/https://github.com/BoYanZh/Joint-Teapot --break-system-packages - name: Lint run: make lint - name: Build -- 2.30.2 From 5a82e2675d74a5ecc177bdd30c51f94fdf0f67c1 Mon Sep 17 00:00:00 2001 From: Boming Zhang Date: Sun, 6 Oct 2024 19:50:15 -0400 Subject: [PATCH 6/8] ci: fix pip install --- .gitea/workflows/build.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitea/workflows/build.yaml b/.gitea/workflows/build.yaml index f4581db..192ddda 100644 --- a/.gitea/workflows/build.yaml +++ b/.gitea/workflows/build.yaml @@ -36,7 +36,7 @@ jobs: mv /tmp/golangci-lint-1.61.0-linux-amd64/golangci-lint /root/go/bin - name: Setup Joint-Teapot run: | - pip install git+https://ghp.ci/https://github.com/BoYanZh/Joint-Teapot --break-system-packages + pip install git+https://ghp.ci/https://github.com/BoYanZh/Joint-Teapot - name: Lint run: make lint - name: Build -- 2.30.2 From 801f9368d9e89161bd75555957cf3cdc3c4c52c2 Mon Sep 17 00:00:00 2001 From: Boming Zhang Date: Sun, 6 Oct 2024 19:55:59 -0400 Subject: [PATCH 7/8] ci: rename for healthcheck --- Makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/Makefile b/Makefile index 3a56bac..f7123b6 100644 --- a/Makefile +++ b/Makefile @@ -10,6 +10,7 @@ all: build build: $(foreach APP,$(APPS), go build -ldflags=$(FLAGS) -o $(BUILD_DIR)/$(APP) ./cmd/$(APP);) + cp ./build/repo-health-checker ./build/healthcheck clean: rm -rf $(BUILD_DIR)/* -- 2.30.2 From 99235e7c9361d2a71b1deb604e30f9bb86f6452d Mon Sep 17 00:00:00 2001 From: Boming Zhang Date: Mon, 7 Oct 2024 01:21:03 -0400 Subject: [PATCH 8/8] feat: run real teapot commands --- cmd/joj3/conf/conf.go | 2 ++ cmd/joj3/teapot/main.go | 43 ++++++++++++++++++++++++++++++++++++++--- 2 files changed, 42 insertions(+), 3 deletions(-) diff --git a/cmd/joj3/conf/conf.go b/cmd/joj3/conf/conf.go index 02431cb..c385e4e 100644 --- a/cmd/joj3/conf/conf.go +++ b/cmd/joj3/conf/conf.go @@ -18,6 +18,8 @@ type Conf struct { SandboxToken string `default:""` LogPath string `default:""` OutputPath string `default:"joj3_result.json"` + GradingRepoName string `default:""` + SkipTeapot bool `default:"true"` Stages []struct { Name string Group string diff --git a/cmd/joj3/teapot/main.go b/cmd/joj3/teapot/main.go index f001c7b..8cbe38f 100644 --- a/cmd/joj3/teapot/main.go +++ b/cmd/joj3/teapot/main.go @@ -1,20 +1,57 @@ package teapot import ( + "fmt" "log/slog" + "os" "os/exec" + "strings" "github.com/joint-online-judge/JOJ3/cmd/joj3/conf" ) func Run(conf conf.Conf) error { - // TODO: call teapot - cmd := exec.Command("joint-teapot", "--help") + if conf.SkipTeapot { + return nil + } + os.Setenv("LOG_FILE_PATH", "/home/tt/.cache/joint-teapot-debug.log") + os.Setenv("_TYPER_STANDARD_TRACEBACK", "1") + envFilePath := "/home/tt/.config/teapot/teapot.env" + actor := os.Getenv("GITHUB_ACTOR") + repository := os.Getenv("GITHUB_REPOSITORY") + runNumber := os.Getenv("GITHUB_RUN_NUMBER") + if actor == "" || repository == "" || strings.Count(repository, "/") != 1 || + runNumber == "" { + slog.Error("teapot env not set") + return fmt.Errorf("teapot env not set") + } + repoParts := strings.Split(repository, "/") + repoName := repoParts[1] + cmd := exec.Command("joint-teapot", "joj3-scoreboard", + envFilePath, conf.OutputPath, actor, conf.GradingRepoName, repoName, + runNumber) // #nosec G204 output, err := cmd.CombinedOutput() if err != nil { slog.Error("running git command:", "err", err) return err } - slog.Info("joint-teapot run", "output", string(output)) + slog.Info("joint-teapot joj3-scoreboard", "output", string(output)) + cmd = exec.Command("joint-teapot", "joj3-failed-table", + envFilePath, conf.OutputPath, actor, conf.GradingRepoName, repoName, + runNumber) // #nosec G204 + output, err = cmd.CombinedOutput() + if err != nil { + slog.Error("running git command:", "err", err) + return err + } + slog.Info("joint-teapot joj3-failed-table", "output", string(output)) + cmd = exec.Command("joint-teapot", "joj3-create-result-issue", + envFilePath, conf.OutputPath, repoName, runNumber) // #nosec G204 + output, err = cmd.CombinedOutput() + if err != nil { + slog.Error("running git command:", "err", err) + return err + } + slog.Info("joint-teapot joj3-create-result-issue", "output", string(output)) return nil } -- 2.30.2