1
0
mirror of https://github.com/go-micro/go-micro.git synced 2025-06-06 22:06:19 +02:00

160 lines
3.0 KiB
Go
Raw Normal View History

2021-08-30 16:48:57 +02:00
package run
import (
"fmt"
"os"
"os/signal"
"path/filepath"
"strings"
2021-08-30 16:48:57 +02:00
"github.com/asim/go-micro/cmd/gomu/cmd"
"github.com/asim/go-micro/v3/runtime"
"github.com/asim/go-micro/v3/runtime/local/git"
2021-08-30 16:48:57 +02:00
"github.com/fsnotify/fsnotify"
"github.com/urfave/cli/v2"
2021-08-30 16:48:57 +02:00
)
var (
DefaultRetries = 3
flags []cli.Flag = []cli.Flag{
&cli.StringFlag{
Name: "command",
Usage: "command to execute",
},
&cli.StringFlag{
Name: "args",
Usage: "command arguments",
},
&cli.StringFlag{
Name: "type",
Usage: "the type of service to operate on",
},
}
)
2021-08-30 16:48:57 +02:00
// NewCommand returns a new run command.
func NewCommand() *cli.Command {
return &cli.Command{
Name: "run",
Usage: "Build and run a service continuously, e.g. gomu run [github.com/auditemarlow/helloworld]",
Flags: flags,
2021-08-30 16:48:57 +02:00
Action: Run,
}
}
// Run runs a service and watches the project directory for change events. On
// write, the service is restarted. Exits on error.
func Run(ctx *cli.Context) error {
wd, err := os.Getwd()
if err != nil {
return err
}
source, err := git.ParseSourceLocal(wd, ctx.Args().First())
if err != nil {
return err
}
svc := &runtime.Service{
Name: source.RuntimeName(),
Source: source.RuntimeSource(),
Version: source.Ref,
Metadata: make(map[string]string),
}
typ := ctx.String("type")
command := strings.TrimSpace(ctx.String("command"))
args := strings.TrimSpace(ctx.String("args"))
r := *cmd.DefaultCmd.Options().Runtime
var retries = DefaultRetries
if ctx.IsSet("retries") {
retries = ctx.Int("retries")
}
opts := []runtime.CreateOption{
runtime.WithOutput(os.Stdout),
runtime.WithRetries(retries),
runtime.CreateType(typ),
}
if len(command) > 0 {
opts = append(opts, runtime.WithCommand(command))
}
if len(args) > 0 {
opts = append(opts, runtime.WithArgs(args))
}
if err := r.Create(svc, opts...); err != nil {
2021-08-30 16:48:57 +02:00
return err
}
done := make(chan bool)
if r.String() == "local" {
sig := make(chan os.Signal)
signal.Notify(sig, os.Interrupt)
go func() {
<-sig
r.Delete(svc)
done <- true
}()
}
if source.Local {
watcher, err := fsnotify.NewWatcher()
if err != nil {
fmt.Println(err)
2021-08-30 16:48:57 +02:00
}
defer watcher.Close()
2021-08-30 16:48:57 +02:00
go func() {
for {
select {
case event, ok := <-watcher.Events:
if !ok {
return
}
if event.Op&fsnotify.Write == fsnotify.Write {
r.Update(svc)
}
if event.Op&fsnotify.Create == fsnotify.Create {
watcher.Add(event.Name)
}
if event.Op&fsnotify.Remove == fsnotify.Remove {
watcher.Remove(event.Name)
}
case err, ok := <-watcher.Errors:
if !ok {
return
}
fmt.Println("ERROR", err)
2021-08-30 16:48:57 +02:00
}
}
}()
2021-08-30 16:48:57 +02:00
var files []string
filepath.Walk(".", func(path string, info os.FileInfo, err error) error {
if err != nil {
return err
}
files = append(files, path)
return nil
})
2021-08-30 16:48:57 +02:00
for _, file := range files {
if err := watcher.Add(file); err != nil {
return err
}
2021-08-30 16:48:57 +02:00
}
}
if r.String() == "local" {
<-done
}
2021-08-30 16:48:57 +02:00
return nil
}