From 423e87494b8324b67dbef69fcb4d6c78d8d9b96f Mon Sep 17 00:00:00 2001 From: Zeni Kim Date: Tue, 29 Oct 2024 06:49:38 -0500 Subject: [PATCH] add prod mode --- cmd/root.go | 2 +- cmd/{run.go => rundev.go} | 44 +++++------ cmd/runprod.go | 154 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 177 insertions(+), 23 deletions(-) rename cmd/{run.go => rundev.go} (84%) create mode 100644 cmd/runprod.go diff --git a/cmd/root.go b/cmd/root.go index 48a4554..d27893d 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -14,7 +14,7 @@ var cfgFile string // rootCmd represents the base command when called without any subcommands var rootCmd = &cobra.Command{ Use: "goffee", - Version: "v1.6.1", + Version: "v1.7.1", Short: "Goffee is the cli tool", Long: `Goffee is the cli tool for creating new projects and performing other tasks`, diff --git a/cmd/run.go b/cmd/rundev.go similarity index 84% rename from cmd/run.go rename to cmd/rundev.go index 74f9325..a516b00 100644 --- a/cmd/run.go +++ b/cmd/rundev.go @@ -19,10 +19,10 @@ import ( "github.com/spf13/cobra" ) -var pid int +var piddev int // runCmd represents the run command -var runCmd = &cobra.Command{ +var runCmdDev = &cobra.Command{ Use: "run:dev", Short: "Start the app in hot reloading mode", Long: `To Start the app in hot reloading mode for development run the following command: @@ -67,16 +67,16 @@ goffee run:dev go func() { startAppChan <- true }() - go startServerJob(pidChan, startAppChan) - go startRestartControllerJob(fileChangeChan, pidChan, startAppChan) + go startServerJobDev(pidChan, startAppChan) + go startRestartControllerJobDev(fileChangeChan, pidChan, startAppChan) signal.Notify(termSigsChan, syscall.SIGINT, syscall.SIGTERM) go func(termSigsChan chan os.Signal) { for { <-termSigsChan - if pid == 0 { + if piddev == 0 { os.Exit(0) } else { - pgid, err := syscall.Getpgid(pid) + pgid, err := syscall.Getpgid(piddev) if err != nil { fmt.Println("error getting pgid: ", err) } @@ -98,21 +98,21 @@ goffee run:dev }, } -func startRestartControllerJob(fileChangeChan chan bool, pidChan chan int, startAppChan chan bool) { +func startRestartControllerJobDev(fileChangeChan chan bool, pidChan chan int, startAppChan chan bool) { for { fileChanged := <-fileChangeChan if fileChanged { fmt.Println("Restarting...") - pid := <-pidChan - if pid != 0 { + piddev := <-pidChan + if piddev != 0 { if runtime.GOOS == "windows" { - killCmd := exec.Command("taskkill", "/T", "/F", "/PID", strconv.Itoa(pid)) + killCmd := exec.Command("taskkill", "/T", "/F", "/PID", strconv.Itoa(piddev)) err := killCmd.Run() if err != nil { fmt.Println("error stopping the dev server", err.Error()) } } else if runtime.GOOS == "darwin" { - pgid, err := syscall.Getpgid(pid) + pgid, err := syscall.Getpgid(piddev) if err != nil { fmt.Println("error getting pgid: ", err.Error()) } @@ -121,7 +121,7 @@ func startRestartControllerJob(fileChangeChan chan bool, pidChan chan int, start fmt.Println("error stopping process: ", err.Error()) } } else if runtime.GOOS == "linux" { - pgid, err := syscall.Getpgid(pid) + pgid, err := syscall.Getpgid(piddev) if err != nil { fmt.Println("error getting pgid: ", err.Error()) } @@ -147,12 +147,12 @@ func startRestartControllerJob(fileChangeChan chan bool, pidChan chan int, start } } -func startServerJob(pidChan chan int, startAppChan chan bool) { +func startServerJobDev(pidChan chan int, startAppChan chan bool) { for { shouldStartApp := <-startAppChan if shouldStartApp { fmt.Println("\n\nBuilding...") - err := compileApp() + err := compileAppDev() if err != nil { fmt.Println("error building: ", err.Error()) go func() { @@ -167,7 +167,7 @@ func startServerJob(pidChan chan int, startAppChan chan bool) { if lookErr != nil { panic(lookErr) } - args := []string{"/bin/sh", "-c", execFile} + args := []string{"/bin/sh", "-c", execFile, "dev"} execSpec := &syscall.ProcAttr{ Dir: pwd, Env: os.Environ(), @@ -176,7 +176,7 @@ func startServerJob(pidChan chan int, startAppChan chan bool) { Setpgid: true, }, } - pid, _, err = syscall.StartProcess(binary, args, execSpec) + piddev, _, err = syscall.StartProcess(binary, args, execSpec) if err != nil { fmt.Println("error starting process: ", err.Error()) go func() { @@ -184,7 +184,7 @@ func startServerJob(pidChan chan int, startAppChan chan bool) { }() } else { go func() { - pidChan <- pid + pidChan <- piddev }() } } else if runtime.GOOS == "linux" { @@ -193,7 +193,7 @@ func startServerJob(pidChan chan int, startAppChan chan bool) { if lookErr != nil { panic(lookErr) } - args := []string{"/bin/sh", "-c", execFile} + args := []string{"/bin/sh", "-c", execFile, "dev"} execSpec := &syscall.ProcAttr{ Dir: pwd, Env: os.Environ(), @@ -202,7 +202,7 @@ func startServerJob(pidChan chan int, startAppChan chan bool) { Setpgid: true, }, } - pid, _, err = syscall.StartProcess(binary, args, execSpec) + piddev, _, err = syscall.StartProcess(binary, args, execSpec) if err != nil { fmt.Println("error starting process: ", err.Error()) go func() { @@ -210,7 +210,7 @@ func startServerJob(pidChan chan int, startAppChan chan bool) { }() } else { go func() { - pidChan <- pid + pidChan <- piddev }() } } else { @@ -221,7 +221,7 @@ func startServerJob(pidChan chan int, startAppChan chan bool) { } } -func compileApp() error { +func compileAppDev() error { pwd, _ := os.Getwd() var command *exec.Cmd command = exec.Command("/bin/sh", "-c", fmt.Sprintf("go build -o %v/tmp/", pwd)) @@ -241,5 +241,5 @@ func compileApp() error { } func init() { - rootCmd.AddCommand(runCmd) + rootCmd.AddCommand(runCmdDev) } diff --git a/cmd/runprod.go b/cmd/runprod.go new file mode 100644 index 0000000..bc3a1a3 --- /dev/null +++ b/cmd/runprod.go @@ -0,0 +1,154 @@ +// Use of this source code is governed by MIT-style +// license that can be found in the LICENSE file. + +package cmd + +import ( + "fmt" + "os" + "os/exec" + "os/signal" + "path" + "runtime" + "syscall" + "time" + + "github.com/spf13/cobra" +) + +var pid int + +// runCmd represents the run command +var runCmdPro = &cobra.Command{ + Use: "run:prod", + Short: "Start the app in production mode", + Long: `To Start the app in production mode the following command: + +goffee run:prod + +`, + Run: func(cmd *cobra.Command, args []string) { + + startAppChan := make(chan bool, 1) + pidChan := make(chan int, 1) + termSigsChan := make(chan os.Signal, 1) + + startAppChan <- true + + go startServerJob(pidChan, startAppChan) + + signal.Notify(termSigsChan, syscall.SIGINT, syscall.SIGTERM) + go func(termSigsChan chan os.Signal) { + for { + <-termSigsChan + if pid == 0 { + os.Exit(0) + } else { + pgid, err := syscall.Getpgid(pid) + if err != nil { + fmt.Println("error getting pgid: ", err) + } + err = syscall.Kill(-pgid, syscall.SIGKILL) + if err != nil { + fmt.Println("error stopping process: ", err) + } + os.Exit(0) + } + } + + }(termSigsChan) + + func() { + time.Sleep(time.Second * 5) + }() + }, +} + +func startServerJob(pidChan chan int, startAppChan chan bool) { + for { + shouldStartApp := <-startAppChan + if shouldStartApp { + fmt.Println("\n\nBuilding...") + err := compileApp() + if err != nil { + fmt.Println("error building: ", err.Error()) + go func() { + pidChan <- 0 + }() + } else { + fmt.Println("Starting...") + pwd, _ := os.Getwd() + if runtime.GOOS == "darwin" { + execFile := pwd + "/tmp/" + path.Base(pwd) + args := []string{execFile, "prod"} + execSpec := &syscall.ProcAttr{ + Dir: pwd, + Env: os.Environ(), + Files: []uintptr{os.Stdin.Fd(), os.Stdout.Fd(), os.Stderr.Fd()}, + Sys: &syscall.SysProcAttr{ + Setpgid: true, + }, + } + pid, _, err = syscall.StartProcess(execFile, args, execSpec) + if err != nil { + fmt.Println("error starting process: ", err.Error()) + go func() { + pidChan <- 0 + }() + } else { + go func() { + pidChan <- pid + }() + } + } else if runtime.GOOS == "linux" { + execFile := pwd + "/tmp/" + path.Base(pwd) + args := []string{execFile, "prod"} + execSpec := &syscall.ProcAttr{ + Dir: pwd, + Env: os.Environ(), + Files: []uintptr{os.Stdin.Fd(), os.Stdout.Fd(), os.Stderr.Fd()}, + Sys: &syscall.SysProcAttr{ + Setpgid: true, + }, + } + pid, _, err = syscall.StartProcess(execFile, args, execSpec) + if err != nil { + fmt.Println("error starting process: ", err.Error()) + go func() { + pidChan <- 0 + }() + } else { + go func() { + pidChan <- pid + }() + } + } else { + fmt.Println("not implemented for os: ", runtime.GOOS) + } + } + } + } +} + +func compileApp() error { + pwd, _ := os.Getwd() + var command *exec.Cmd + command = exec.Command("/bin/sh", "-c", fmt.Sprintf("go build -o %v/tmp/", pwd)) + command.Env = os.Environ() + command.SysProcAttr = &syscall.SysProcAttr{ + Setpgid: true, + } + command.Dir = pwd + o, err := command.CombinedOutput() + if string(o) != "" { + fmt.Println(string(o)) + } + if err != nil { + return err + } + return nil +} + +func init() { + rootCmd.AddCommand(runCmdPro) +}