diff --git a/internal/mrunners/options.go b/internal/mrunners/options.go new file mode 100644 index 0000000..06047eb --- /dev/null +++ b/internal/mrunners/options.go @@ -0,0 +1,33 @@ +package mrunners + +import ( + "github.com/yankeguo/minit/internal/mexec" + "github.com/yankeguo/minit/internal/mlog" + "github.com/yankeguo/minit/internal/munit" +) + +type RunnerOptions struct { + Unit munit.Unit + Exec mexec.Manager + Logger mlog.ProcLogger +} + +func (ro RunnerOptions) Print(message string) { + ro.Logger.Print("minit: " + ro.Unit.Kind + "/" + ro.Unit.Name + ": " + message) +} + +func (ro RunnerOptions) Printf(layout string, items ...any) { + ro.Logger.Printf("minit: "+ro.Unit.Kind+"/"+ro.Unit.Name+": "+layout, items...) +} + +func (ro RunnerOptions) Error(message string) { + ro.Logger.Error("minit: " + ro.Unit.Kind + "/" + ro.Unit.Name + ": " + message) +} + +func (ro RunnerOptions) Errorf(layout string, items ...any) { + ro.Logger.Errorf("minit: "+ro.Unit.Kind+"/"+ro.Unit.Name+": "+layout, items...) +} + +func (ro RunnerOptions) Execute() error { + return ro.Exec.Execute(ro.Unit.ExecuteOptions(ro.Logger)) +} diff --git a/internal/mrunners/runner.go b/internal/mrunners/runner.go index 05a1cf2..87f3c62 100644 --- a/internal/mrunners/runner.go +++ b/internal/mrunners/runner.go @@ -4,16 +4,14 @@ import ( "context" "errors" "sync" - - "github.com/yankeguo/minit/internal/mexec" - "github.com/yankeguo/minit/internal/mlog" - "github.com/yankeguo/minit/internal/munit" ) +// RunnerAction is the interface of runner action type RunnerAction interface { Do(ctx context.Context) (err error) } +// Runner is the struct of runner type Runner struct { Order int Long bool @@ -25,22 +23,10 @@ var ( factoriesLock sync.Locker = &sync.Mutex{} ) -type RunnerOptions struct { - Unit munit.Unit - Exec mexec.Manager - Logger mlog.ProcLogger -} - -func (ro RunnerOptions) Print(message string) { - ro.Logger.Print("minit: " + ro.Unit.Kind + "/" + ro.Unit.Name + ": " + message) -} - -func (ro RunnerOptions) Error(message string) { - ro.Logger.Error("minit: " + ro.Unit.Kind + "/" + ro.Unit.Name + ": " + message) -} - +// RunnerFactory is the type of runner factory type RunnerFactory = func(opts RunnerOptions) (Runner, error) +// Register registers a runner factory func Register(name string, factory RunnerFactory) { factoriesLock.Lock() defer factoriesLock.Unlock() @@ -48,6 +34,7 @@ func Register(name string, factory RunnerFactory) { factories[name] = factory } +// Create creates a runner from options func Create(opts RunnerOptions) (Runner, error) { factoriesLock.Lock() defer factoriesLock.Unlock() diff --git a/internal/mrunners/runner_cron.go b/internal/mrunners/runner_cron.go index fa13058..543a4cc 100644 --- a/internal/mrunners/runner_cron.go +++ b/internal/mrunners/runner_cron.go @@ -21,21 +21,21 @@ func init() { runner.Order = 30 runner.Long = true - runner.Action = &runnerCron{RunnerOptions: opts} + runner.Action = &actionCron{RunnerOptions: opts} return }) } -type runnerCron struct { +type actionCron struct { RunnerOptions } -func (r *runnerCron) Do(ctx context.Context) (err error) { +func (r *actionCron) Do(ctx context.Context) (err error) { r.Print("controller started") defer r.Print("controller exited") if r.Unit.Immediate { - if err = r.Exec.Execute(r.Unit.ExecuteOptions(r.Logger)); err != nil { + if err = r.Execute(); err != nil { r.Error("failed executing: " + err.Error()) if r.Unit.Critical { return @@ -55,7 +55,7 @@ func (r *runnerCron) Do(ctx context.Context) (err error) { if _, err = cr.AddFunc(r.Unit.Cron, func() { r.Print("triggered") - if err := r.Exec.Execute(r.Unit.ExecuteOptions(r.Logger)); err != nil { + if err := r.Execute(); err != nil { r.Error("failed executing: " + err.Error()) if chErr != nil { select { diff --git a/internal/mrunners/runner_cron_test.go b/internal/mrunners/runner_cron_test.go index b0c81fc..907c940 100644 --- a/internal/mrunners/runner_cron_test.go +++ b/internal/mrunners/runner_cron_test.go @@ -20,12 +20,12 @@ func TestRunnerCron(t *testing.T) { buf := &bytes.Buffer{} - r := &runnerCron{ + r := &actionCron{ RunnerOptions: RunnerOptions{ Unit: munit.Unit{ Kind: munit.KindCron, Name: "test", - Cron: "@every 1s", + Cron: "@every 2s", Immediate: true, Command: []string{ "echo", "hhhlll", @@ -56,7 +56,7 @@ func TestRunnerCron(t *testing.T) { wg.Wait() - require.Equal(t, 3, strings.Count(buf.String(), "hhhlll\n")) + require.Equal(t, 2, strings.Count(buf.String(), "hhhlll\n")) } func TestRunnerCronCritical(t *testing.T) { @@ -64,7 +64,7 @@ func TestRunnerCronCritical(t *testing.T) { buf := &bytes.Buffer{} - r := &runnerCron{ + r := &actionCron{ RunnerOptions: RunnerOptions{ Unit: munit.Unit{ Kind: munit.KindCron, diff --git a/internal/mrunners/runner_daemon.go b/internal/mrunners/runner_daemon.go index 1e12767..d2ef420 100644 --- a/internal/mrunners/runner_daemon.go +++ b/internal/mrunners/runner_daemon.go @@ -15,16 +15,16 @@ func init() { runner.Order = 40 runner.Long = true - runner.Action = &runnerDaemon{RunnerOptions: opts} + runner.Action = &actionDaemon{RunnerOptions: opts} return }) } -type runnerDaemon struct { +type actionDaemon struct { RunnerOptions } -func (r *runnerDaemon) Do(ctx context.Context) (err error) { +func (r *actionDaemon) Do(ctx context.Context) (err error) { r.Print("controller started") defer r.Print("controller exited") @@ -34,7 +34,7 @@ forLoop: break forLoop } - if err = r.Exec.Execute(r.Unit.ExecuteOptions(r.Logger)); err != nil { + if err = r.Execute(); err != nil { r.Error("failed executing:" + err.Error()) if r.Unit.Critical { diff --git a/internal/mrunners/runner_daemon_test.go b/internal/mrunners/runner_daemon_test.go index 7b3c2b8..14c40e8 100644 --- a/internal/mrunners/runner_daemon_test.go +++ b/internal/mrunners/runner_daemon_test.go @@ -19,7 +19,7 @@ func TestRunnerDaemon(t *testing.T) { buf := &bytes.Buffer{} - r := &runnerDaemon{ + r := &actionDaemon{ RunnerOptions: RunnerOptions{ Unit: munit.Unit{ Kind: munit.KindDaemon, @@ -64,7 +64,7 @@ func TestRunnerDaemonCritical(t *testing.T) { buf := &bytes.Buffer{} - r := &runnerDaemon{ + r := &actionDaemon{ RunnerOptions: RunnerOptions{ Unit: munit.Unit{ Kind: munit.KindDaemon, diff --git a/internal/mrunners/runner_once.go b/internal/mrunners/runner_once.go index 46d1ec6..4d160d4 100644 --- a/internal/mrunners/runner_once.go +++ b/internal/mrunners/runner_once.go @@ -13,22 +13,22 @@ func init() { } runner.Order = 20 - runner.Action = &runnerOnce{RunnerOptions: opts} + runner.Action = &actionOnce{RunnerOptions: opts} return }) } -type runnerOnce struct { +type actionOnce struct { RunnerOptions } -func (r *runnerOnce) Do(ctx context.Context) (err error) { +func (r *actionOnce) Do(ctx context.Context) (err error) { r.Print("controller started") defer r.Print("controller exited") if r.Unit.Blocking != nil && !*r.Unit.Blocking { go func() { - if err := r.Exec.Execute(r.Unit.ExecuteOptions(r.Logger)); err != nil { + if err := r.Execute(); err != nil { r.Error("failed executing (non-blocking): " + err.Error()) return } @@ -36,7 +36,7 @@ func (r *runnerOnce) Do(ctx context.Context) (err error) { return } - if err = r.Exec.Execute(r.Unit.ExecuteOptions(r.Logger)); err != nil { + if err = r.Execute(); err != nil { r.Error("failed executing: " + err.Error()) if r.Unit.Critical { return diff --git a/internal/mrunners/runner_once_test.go b/internal/mrunners/runner_once_test.go index fc74296..7563650 100644 --- a/internal/mrunners/runner_once_test.go +++ b/internal/mrunners/runner_once_test.go @@ -18,7 +18,7 @@ func TestRunnerOnce(t *testing.T) { buf := &bytes.Buffer{} - r := &runnerOnce{ + r := &actionOnce{ RunnerOptions: RunnerOptions{ Unit: munit.Unit{ Kind: munit.KindOnce, @@ -47,7 +47,7 @@ func TestRunnerOnceCritical(t *testing.T) { buf := &bytes.Buffer{} - r := &runnerOnce{ + r := &actionOnce{ RunnerOptions: RunnerOptions{ Unit: munit.Unit{ Kind: munit.KindOnce, @@ -78,7 +78,7 @@ func TestRunnerOnceCriticalNonBlocking(t *testing.T) { blocking := false - r := &runnerOnce{ + r := &actionOnce{ RunnerOptions: RunnerOptions{ Unit: munit.Unit{ Kind: munit.KindOnce, diff --git a/internal/mrunners/runner_render.go b/internal/mrunners/runner_render.go index 49d9505..ffbbce9 100644 --- a/internal/mrunners/runner_render.go +++ b/internal/mrunners/runner_render.go @@ -20,16 +20,16 @@ func init() { } runner.Order = 10 - runner.Action = &runnerRender{RunnerOptions: opts} + runner.Action = &actionRender{RunnerOptions: opts} return }) } -type runnerRender struct { +type actionRender struct { RunnerOptions } -func (r *runnerRender) doFile(ctx context.Context, name string, env map[string]string) (err error) { +func (r *actionRender) doFile(ctx context.Context, name string, env map[string]string) (err error) { var buf []byte if buf, err = os.ReadFile(name); err != nil { err = fmt.Errorf("failed reading %s: %s", name, err.Error()) @@ -52,7 +52,7 @@ func (r *runnerRender) doFile(ctx context.Context, name string, env map[string]s return } -func (r *runnerRender) Do(ctx context.Context) (err error) { +func (r *actionRender) Do(ctx context.Context) (err error) { r.Print("controller started") defer r.Print("controller exited") @@ -69,7 +69,7 @@ func (r *runnerRender) Do(ctx context.Context) (err error) { var names []string if names, err = filepath.Glob(filePattern); err != nil { - r.Error(fmt.Sprintf("failed globbing: %s: %s", filePattern, err.Error())) + r.Errorf("failed globbing: %s: %s", filePattern, err.Error()) if r.Unit.Critical { return @@ -104,6 +104,7 @@ func (r *runnerRender) Do(ctx context.Context) (err error) { return } +// sanitizeLines removes empty lines and trailing spaces func sanitizeLines(s []byte) []byte { var out [][]byte for _, line := range bytes.Split(s, []byte("\n")) { diff --git a/internal/mrunners/runner_render_test.go b/internal/mrunners/runner_render_test.go index 41448a1..cfcaa3f 100644 --- a/internal/mrunners/runner_render_test.go +++ b/internal/mrunners/runner_render_test.go @@ -24,7 +24,7 @@ func TestRunnerRender(t *testing.T) { buf := &bytes.Buffer{} - r := &runnerRender{ + r := &actionRender{ RunnerOptions: RunnerOptions{ Unit: munit.Unit{ Kind: munit.KindRender,