refactor: rename modules

This commit is contained in:
张泊明518370910136 2024-10-05 23:15:18 -04:00
parent f3ebd678a8
commit 7198911f6d
GPG Key ID: D47306D7062CDA9D
8 changed files with 196 additions and 167 deletions

View File

@ -1,170 +1,19 @@
package main package main
import ( import (
"encoding/json"
"flag"
"fmt"
"log/slog" "log/slog"
"os"
"github.com/joint-online-judge/JOJ3/internal/executors" stagerunner "github.com/joint-online-judge/JOJ3/cmd/joj3/stage-runner"
_ "github.com/joint-online-judge/JOJ3/internal/parsers" teapotcaller "github.com/joint-online-judge/JOJ3/cmd/joj3/teapot-caller"
"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 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() { func main() {
if err := mainImpl(); err != nil { // TODO: call stage-runner
slog.Error("main exit", "error", err) if err := stagerunner.Run(); err != nil {
os.Exit(1) slog.Error("stage runner error", "error", err)
}
// TODO: call joint-teapot
if err := teapotcaller.Run(); err != nil {
slog.Error("teapot caller error", "error", err)
} }
} }

View File

@ -1,4 +1,4 @@
package main package stagerunner
import ( import (
"fmt" "fmt"

View File

@ -1,4 +1,4 @@
package main package stagerunner
import ( import (
"reflect" "reflect"

View File

@ -1,4 +1,4 @@
package main package stagerunner
import ( import (
"context" "context"

View File

@ -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
}

View File

@ -1,4 +1,4 @@
package main package stagerunner
import ( import (
"encoding/json" "encoding/json"
@ -61,9 +61,9 @@ func readStageResults(t *testing.T, path string) []stage.StageResult {
return results return results
} }
func TestMain(t *testing.T) { func TestRun(t *testing.T) {
var tests []string 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 { err := filepath.Walk(root, func(path string, info os.FileInfo, err error) error {
if err != nil { if err != nil {
return err return err
@ -105,7 +105,9 @@ func TestMain(t *testing.T) {
os.Args = []string{"./joj3"} os.Args = []string{"./joj3"}
outputFile := "joj3_result.json" outputFile := "joj3_result.json"
defer os.Remove(outputFile) defer os.Remove(outputFile)
main() if err := Run(); err != nil {
t.Fatal(err)
}
stageResults := readStageResults(t, outputFile) stageResults := readStageResults(t, outputFile)
regex := true regex := true
expectedFile := "expected_regex.json" expectedFile := "expected_regex.json"

View File

@ -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
}