Skip to content

Commit b26ed1a

Browse files
committed
pkg/workflows/sdk: add WorkflowSpec.FormatChart for mermaid flowcharts
1 parent dd59341 commit b26ed1a

17 files changed

+841
-88
lines changed

Makefile

+4
Original file line numberDiff line numberDiff line change
@@ -47,3 +47,7 @@ lint-workspace:
4747

4848
lint:
4949
@./script/lint.sh $(GOLANGCI_LINT_VERSION) "$(GOLANGCI_LINT_COMMON_OPTS)" $(GOLANGCI_LINT_DIRECTORY) "--new-from-rev=origin/main"
50+
51+
.PHONY: test-quiet
52+
test-quiet:
53+
go test ./... | grep -v "\[no test files\]" | grep -v "\(cached\)"

go.mod

+1-3
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
module github.com/smartcontractkit/chainlink-common
22

3-
go 1.22.0
4-
5-
toolchain go1.22.7
3+
go 1.23
64

75
require (
86
github.com/andybalholm/brotli v1.1.0

pkg/capabilities/capabilities.go

+21
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package capabilities
22

33
import (
4+
"cmp"
45
"context"
56
"fmt"
67
"regexp"
@@ -53,6 +54,26 @@ func (c CapabilityType) IsValid() error {
5354
return fmt.Errorf("invalid capability type: %s", c)
5455
}
5556

57+
func (c CapabilityType) cmpOrder() int {
58+
switch c {
59+
case CapabilityTypeTrigger:
60+
return 0
61+
case CapabilityTypeAction:
62+
return 1
63+
case CapabilityTypeConsensus:
64+
return 2
65+
case CapabilityTypeTarget:
66+
return 3
67+
case CapabilityTypeUnknown:
68+
return 4
69+
default:
70+
return 5
71+
}
72+
}
73+
func (c CapabilityType) Compare(c2 CapabilityType) int {
74+
return cmp.Compare(c.cmpOrder(), c2.cmpOrder())
75+
}
76+
5677
// CapabilityResponse is a struct for the Execute response of a capability.
5778
type CapabilityResponse struct {
5879
Value *values.Map

pkg/workflows/dependency_graph.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ func BuildDependencyGraph(spec sdk.WorkflowSpec) (*DependencyGraph, error) {
104104
step.Dependencies = refs
105105

106106
if stepRef != KeywordTrigger && len(refs) == 0 {
107-
return nil, fmt.Errorf("invalid refs %+v for step %s", inputs, stepRef)
107+
return nil, fmt.Errorf("invalid refs %#v for step %s", inputs, stepRef)
108108
}
109109

110110
for _, r := range refs {
@@ -129,7 +129,7 @@ func BuildDependencyGraph(spec sdk.WorkflowSpec) (*DependencyGraph, error) {
129129
Graph: g,
130130
Triggers: triggerSteps,
131131
}
132-
return wf, err
132+
return wf, nil
133133
}
134134

135135
var (
+63
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
package workflows
2+
3+
import (
4+
"cmp"
5+
"slices"
6+
"strings"
7+
"text/template"
8+
9+
"github.com/smartcontractkit/chainlink-common/pkg/workflows/sdk"
10+
)
11+
12+
func (g *DependencyGraph) FormatChart() (string, error) {
13+
var sb strings.Builder
14+
steps := slices.Clone(g.Spec.Triggers)
15+
steps = append(steps, g.Spec.Steps()...)
16+
slices.SortFunc(steps, func(a, b sdk.StepDefinition) int {
17+
return cmp.Or(
18+
a.CapabilityType.Compare(b.CapabilityType),
19+
cmp.Compare(a.Ref, b.Ref),
20+
cmp.Compare(a.ID, b.ID),
21+
)
22+
})
23+
err := tmpl.Execute(&sb, steps)
24+
if err != nil {
25+
return "", err
26+
}
27+
return sb.String(), nil
28+
}
29+
30+
var tmpl = template.Must(template.New("").Funcs(map[string]any{
31+
"replace": strings.ReplaceAll,
32+
}).Parse(`flowchart
33+
{{ range $i, $step := . }}
34+
{{ $ref := .Ref -}}
35+
{{ $id := replace .ID "@" "[at]" -}}
36+
{{ $name := printf "%s<br><i>(%s)</i>" .CapabilityType $id -}}
37+
{{ if .Ref -}}
38+
{{ $name = printf "<b>%s</b><br>%s" .Ref $name -}}
39+
{{ else -}}
40+
{{ $ref = printf "%s%d" "unnamed" $i -}}
41+
{{ end -}}
42+
{{ if eq .CapabilityType "trigger" -}}
43+
{{ $ref }}[\"{{$name}}"/]
44+
{{ else if eq .CapabilityType "consensus" -}}
45+
{{ $ref }}[["{{$name}}"]]
46+
{{ else if eq .CapabilityType "target" -}}
47+
{{ $ref }}[/"{{$name}}"\]
48+
{{ else -}}
49+
{{ $ref }}["{{$name}}"]
50+
{{ end -}}
51+
{{ if .Inputs.OutputRef -}}
52+
{{ .Inputs.OutputRef }} --> {{ $step.Ref }}
53+
{{ else -}}
54+
{{ range $out := .Inputs.Outputs -}}
55+
{{ if $out.Name -}}
56+
{{ $out.Ref }} -- {{ $out.Name }} --> {{ $ref}}
57+
{{ else -}}
58+
{{ $out.Ref }} --> {{ $ref}}
59+
{{ end -}}
60+
{{ end -}}
61+
{{ end -}}
62+
{{ end -}}
63+
`))

0 commit comments

Comments
 (0)