From 78620cf6cba75d24f0080e151c4d56b391b5e579 Mon Sep 17 00:00:00 2001 From: 3343780376 <3343780376@qq.com> Date: Sat, 14 Jan 2023 21:52:38 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0go=E8=AF=AD=E8=A8=80=E8=BF=90?= =?UTF-8?q?=E8=A1=8C=E6=94=AF=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/ci.yml | 3 ++- service/cron/manager.go | 35 +++++++++++++++++++++++---- utils/run.go | 51 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 84 insertions(+), 5 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8666eb3..e12f715 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -8,6 +8,7 @@ env: COMMIT_ID: "${{ github.sha }}" PR_PROMPT: "::warning:: Build artifact will not be uploaded due to the workflow is trigged by pull request." LD_FLAGS: "-w -s" + VERSION: "action" jobs: build: @@ -50,7 +51,7 @@ jobs: if [ $GOOS = "windows" ]; then export BINARY_SUFFIX="$BINARY_SUFFIX.exe"; fi if $IS_PR ; then echo $PR_PROMPT; fi export BINARY_NAME="$BINARY_PREFIX$GOOS_$GOARCH$BINARY_SUFFIX" - export LD_FLAGS="-w -s -X github.com/huoxue1/qinglong-go/service/config.VERSION=$COMMIT_ID" + export LD_FLAGS="-w -s -X github.com/huoxue1/qinglong-go/service/config.VERSION=${{VERSION}}" go mod tidy go build -o "output/$BINARY_NAME" -trimpath -ldflags "$LD_FLAGS" ./ - name: Upload artifact diff --git a/service/cron/manager.go b/service/cron/manager.go index 2b67a18..ad8efc0 100644 --- a/service/cron/manager.go +++ b/service/cron/manager.go @@ -13,6 +13,8 @@ import ( "io" "os" "os/exec" + "path" + "path/filepath" "strconv" "strings" "sync" @@ -34,6 +36,7 @@ type task struct { isNow bool isCon bool envs map[string][]int + dir string } func initTask() { @@ -112,11 +115,18 @@ func runCron(crontabs *models.Crontabs) { now := time.Now() _ = os.Mkdir("data/log/"+time.Now().Format("2006-01-02"), 0666) file, _ := os.OpenFile(crontabs.LogPath, os.O_RDWR|os.O_CREATE, 0666) - go utils.RunTask(ctx, ta.cmd, envFromDb, - func(ctx context.Context) { + cmdDir := "./data/scripts/" + if strings.HasPrefix(ta.cmd, "go") { + cmdDir = ta.dir + } + go utils.RunWithOption(ctx, &utils.RunOption{ + Command: ta.cmd, + Env: envFromDb, + OnStart: func(ctx context.Context) { writer := ctx.Value("log").(io.Writer) writer.Write([]byte(fmt.Sprintf("##开始执行.. %s\n\n", now.Format("2006-01-02 15:04:05")))) - }, func(ctx context.Context) { + }, + OnEnd: func(ctx context.Context) { writer := ctx.Value("log").(io.Writer) writer.Write([]byte(fmt.Sprintf("\n##执行结束.. %s,耗时%.1f秒\n\n", time.Now().Format("2006-01-02 15:04:05"), time.Now().Sub(now).Seconds()))) crontabs.Status = 1 @@ -125,7 +135,10 @@ func runCron(crontabs *models.Crontabs) { models.UpdateCron(crontabs) execManager.LoadAndDelete(crontabs.Id) file.Close() - }, file) + }, + LogFile: file, + CmdDir: cmdDir, + }) } } @@ -171,6 +184,11 @@ func handCommand(command string) *task { ta.cmd = ShCmd + " " + commands[1] } else if strings.HasSuffix(commands[1], ".ts") { ta.cmd = "ts-node-transpile-only " + commands[1] + } else if strings.HasSuffix(commands[1], ".go") { + + log.Infoln(filepath.Base(commands[1])) + ta.cmd = fmt.Sprintf(`go run %s`, filepath.Base(commands[1])) + ta.dir = path.Join("./data", "scripts", filepath.Dir(commands[1])) } if len(commands) > 2 { if commands[2] == "now" { @@ -207,3 +225,12 @@ func handCommand(command string) *task { } return ta } + +func getGoModule(filePath string) string { + file, err := os.ReadFile(filePath) + if err != nil { + log.Errorln("not get the go module name") + return "" + } + return strings.TrimSpace(strings.TrimPrefix(strings.Split(string(file), "\n")[0], "module")) +} diff --git a/utils/run.go b/utils/run.go index d4e1847..6a75aa5 100644 --- a/utils/run.go +++ b/utils/run.go @@ -51,3 +51,54 @@ func RunTask(ctx context.Context, command string, env map[string]string, onStart } } + +type RunOption struct { + Command string + Env map[string]string + OnStart func(ctx context.Context) + OnEnd func(ctx context.Context) + LogFile io.Writer + CmdDir string +} + +func RunWithOption(ctx context.Context, option *RunOption) { + cmd := exec.Command(strings.Split(option.Command, " ")[0], strings.Split(option.Command, " ")[1:]...) + for s, s2 := range option.Env { + cmd.Env = append(cmd.Env, s+"="+s2) + } + environ := os.Environ() + cmd.Env = append(cmd.Env, environ...) + stdoutPipe, _ := cmd.StdoutPipe() + stderrPipe, _ := cmd.StderrPipe() + cmd.Dir = option.CmdDir + option.OnStart(context.WithValue(ctx, "log", option.LogFile)) + ch := make(chan int, 1) + go func() { + err := cmd.Start() + if err != nil { + ch <- 1 + return + } + go io.Copy(option.LogFile, stderrPipe) + go io.Copy(option.LogFile, stdoutPipe) + err = cmd.Wait() + if err != nil { + ch <- 1 + return + } + ch <- 1 + }() + cancel := ctx.Value("cancel").(chan int) + select { + case <-ch: + { + option.OnEnd(context.WithValue(ctx, "log", option.LogFile)) + } + case <-cancel: + { + _ = cmd.Process.Kill() + option.OnEnd(context.WithValue(context.Background(), "log", option.LogFile)) + } + + } +}