func (c *config) Run() error {
	chps := make(chan *os.Process, 1)
	go c.waitSignals(chps, len(c.services))
	for _, service := range c.services {
		if service.isExecute() {
			c.executeRun(service, chps)
		} else if service.isCode() {
			c.executeCallback(service)
		}
		if service.Every == "" {
			time.Sleep(c.interval)
		}
	}
	c.wait(chps)
	return nil
}
Run just like the name.
package golet
import (
	"context"
	"errors"
	"fmt"
	"io"
	"os"
	"os/exec"
	"os/signal"
	"runtime"
	"sync"
	"syscall"
	"time"
	"github.com/Code-Hex/golet/internal/port"
	colorable "github.com/mattn/go-colorable"
	"github.com/robfig/cron"
)
type color int
const (
	red color = iota  
	green
	yellow
	blue
	magenta
	cyan
	colornum int = 5
)
type config struct {
	interval     time.Duration   
	color        bool            
	logger       io.Writer       
	logWorker    bool            
	execNotice   bool            
	cancelSignal syscall.Signal  
	services   []Service
	wg         sync.WaitGroup
	ctx        *signalCtx
	serviceNum int
	tags       map[string]struct{}
	cron       *cron.Cron
}
var shell []string
func init() {
	if runtime.GOOS == "windows" {
		path, err := exec.LookPath("cmd")
		if err != nil {
			panic("Could not find `cmd` command")
		}
		shell = []string{path, "/c"}
	} else {
		path, err := exec.LookPath("bash")
		if err != nil {
			panic("Could not find `bash` command")
		}
		shell = []string{path, "-c"}
	}
}
type Runner interface {
	SetInterval(time.Duration)
	EnableColor()
	SetLogger(io.Writer)
	DisableLogger()
	DisableExecNotice()
	SetCtxCancelSignal(syscall.Signal)
	Env(map[string]string) error
	Add(...Service) error
	Run() error
}
func (c *config) SetInterval(t time.Duration) { c.interval = t }
func (c *config) EnableColor() { c.color = true }
func (c *config) SetLogger(f io.Writer) { c.logger = f }
func (c *config) DisableLogger() { c.logWorker = false }
func (c *config) DisableExecNotice() { c.execNotice = false }
func (c *config) SetCtxCancelSignal(signal syscall.Signal) { c.cancelSignal = signal }
func New(ctx context.Context) Runner {
	signals := make(chan os.Signal, 1)
	signal.Notify(signals, syscall.SIGHUP, syscall.SIGTERM, syscall.SIGINT)
	return &config{
		interval:     0,
		color:        false,
		logger:       colorable.NewColorableStderr(),
		logWorker:    true,
		execNotice:   true,
		cancelSignal: -1,  
		ctx: &signalCtx{
			parent:  ctx,
			sigchan: signals,
		},
		tags: map[string]struct{}{},
		cron: cron.New(),
	}
}
func (c *config) Env(envs map[string]string) error {
	for k := range envs {
		if e := os.Setenv(k, envs[k]); e != nil {
			return e
		}
	}
	return nil
}
func (c *config) Add(services ...Service) error {
	for _, service := range services {
		c.serviceNum++
		if service.Tag == "" {
			service.Tag = fmt.Sprintf("%d", c.serviceNum)
		}
		if service.Worker <= 0 {
			service.Worker = 1
		}
		if _, ok := c.tags[service.Tag]; ok {
			return errors.New("tag: " + service.Tag + " is already exists")
		}
		c.tags[service.Tag] = struct{}{}
		n, err := port.GetPort()
		if err != nil {
			return err
		}
		for i := 0; i < service.Worker; i++ {
			service.id = fmt.Sprintf("%s.%d", service.Tag, i)
			service.ctx = &Context{
				ctx:  c.ctx,
				port: n + i,
				logger: &Logger{
					enable:      c.logWorker,
					enableColor: c.color,
					out:         c.logger,
					sid:         service.id,
					clr:         color(c.serviceNum%colornum + 32),
				},
			}
			c.services = append(c.services, service)
		}
	}
	return nil
}