Monorepo for Tangled
tangled.org
1package dummy
2
3import (
4 "context"
5 "fmt"
6 "log/slog"
7 "time"
8
9 "gopkg.in/yaml.v3"
10 "tangled.org/core/api/tangled"
11 "tangled.org/core/spindle/models"
12 "tangled.org/core/spindle/secrets"
13)
14
15// DummyEngine is a no-op engine that logs all lifecycle events via slog and writes
16// step output to the workflow logger. Useful for testing pipeline plumbing
17// without a real execution backend.
18type DummyEngine struct {
19 l *slog.Logger
20}
21
22func New(l *slog.Logger) *DummyEngine {
23 return &DummyEngine{l: l.With("engine", "dummy")}
24}
25
26type Step struct {
27 name string
28 kind models.StepKind
29 command string
30}
31
32func (s Step) Name() string { return s.name }
33func (s Step) Command() string { return s.command }
34func (s Step) Kind() models.StepKind { return s.kind }
35
36func (e *DummyEngine) InitWorkflow(twf tangled.Pipeline_Workflow, _ tangled.Pipeline) (*models.Workflow, error) {
37 dwf := &struct {
38 Steps []struct {
39 Name string `yaml:"name"`
40 Command string `yaml:"command"`
41 } `yaml:"steps"`
42 Environment map[string]string `yaml:"environment"`
43 }{}
44
45 if err := yaml.Unmarshal([]byte(twf.Raw), dwf); err != nil {
46 return nil, err
47 }
48
49 wf := &models.Workflow{
50 Name: twf.Name,
51 Environment: dwf.Environment,
52 }
53 for _, ds := range dwf.Steps {
54 wf.Steps = append(wf.Steps, Step{
55 name: ds.Name,
56 kind: models.StepKindUser,
57 command: ds.Command,
58 })
59 }
60
61 e.l.Info("workflow initialised", "name", twf.Name, "steps", len(wf.Steps))
62 return wf, nil
63}
64
65func (e *DummyEngine) SetupWorkflow(_ context.Context, wid models.WorkflowId, wf *models.Workflow, wfLogger models.WorkflowLogger) error {
66 e.l.Info("setting up workflow", "wid", wid)
67
68 setupStep := Step{name: "dummy setup", kind: models.StepKindSystem}
69 const setupIdx = -1
70
71 wfLogger.ControlWriter(setupIdx, setupStep, models.StepStatusStart).Write([]byte{0})
72 defer wfLogger.ControlWriter(setupIdx, setupStep, models.StepStatusEnd).Write([]byte{0})
73
74 fmt.Fprintf(wfLogger.DataWriter(setupIdx, "stdout"), "dummy engine: workflow %q ready", wf.Name)
75 return nil
76}
77
78func (e *DummyEngine) WorkflowTimeout() time.Duration {
79 return 5 * time.Minute
80}
81
82func (e *DummyEngine) DestroyWorkflow(_ context.Context, wid models.WorkflowId) error {
83 e.l.Info("destroying workflow", "wid", wid)
84 return nil
85}
86
87func (e *DummyEngine) RunStep(_ context.Context, wid models.WorkflowId, w *models.Workflow, idx int, _ []secrets.UnlockedSecret, wfLogger models.WorkflowLogger) error {
88 step := w.Steps[idx]
89 e.l.Info("running step", "wid", wid, "step", step.Name(), "command", step.Command())
90 fmt.Fprintf(wfLogger.DataWriter(idx, "stdout"), "$ %s", step.Command())
91 return nil
92}