7
7
"io"
8
8
"os"
9
9
"path/filepath"
10
+ "slices"
10
11
"sort"
11
12
"strings"
12
13
@@ -33,6 +34,7 @@ func NewMermaidWriter(opts ...MermaidOption) *MermaidWriter {
33
34
m := & MermaidWriter {
34
35
MinEdgeName : minEdgeName ,
35
36
SpecifiedPackageName : specifiedPackageName ,
37
+ UseV0Semantics : true ,
36
38
}
37
39
38
40
for _ , opt := range opts {
@@ -53,9 +55,9 @@ func WithSpecifiedPackageName(specifiedPackageName string) MermaidOption {
53
55
}
54
56
}
55
57
56
- func WithV0Semantics () MermaidOption {
58
+ func WithV0Semantics (useV0Semantics bool ) MermaidOption {
57
59
return func (o * MermaidWriter ) {
58
- o .UseV0Semantics = true
60
+ o .UseV0Semantics = useV0Semantics
59
61
}
60
62
}
61
63
@@ -131,7 +133,8 @@ func (writer *MermaidWriter) WriteChannels(cfg DeclarativeConfig, out io.Writer)
131
133
}
132
134
133
135
var deprecatedPackage string
134
- deprecatedChannels := []string {}
136
+ deprecatedChannelIDs := []string {}
137
+ decoratedBundleIDs := map [string ][]string {"deprecated" : {}, "skipped" : {}, "deprecatedskipped" : {}}
135
138
linkID := 0
136
139
skippedLinkIDs := []string {}
137
140
@@ -154,7 +157,7 @@ func (writer *MermaidWriter) WriteChannels(cfg DeclarativeConfig, out io.Writer)
154
157
}
155
158
156
159
if depByChannel .Has (filteredChannel .Name ) {
157
- deprecatedChannels = append (deprecatedChannels , channelID )
160
+ deprecatedChannelIDs = append (deprecatedChannelIDs , channelID )
158
161
}
159
162
160
163
// sort edges by decreasing version
@@ -169,29 +172,45 @@ func (writer *MermaidWriter) WriteChannels(cfg DeclarativeConfig, out io.Writer)
169
172
170
173
skippedEntities := sets.Set [string ]{}
171
174
175
+ const (
176
+ captureNewEntry = true
177
+ processExisting = false
178
+ )
179
+ handleSemantics := func (edge string , linkID int , captureNew bool ) {
180
+ if writer .UseV0Semantics {
181
+ if captureNew {
182
+ if skippedEntities .Has (edge ) {
183
+ skippedLinkIDs = append (skippedLinkIDs , fmt .Sprintf ("%d" , linkID ))
184
+ } else {
185
+ skippedEntities .Insert (edge )
186
+ }
187
+ } else {
188
+ if skippedEntities .Has (edge ) {
189
+ skippedLinkIDs = append (skippedLinkIDs , fmt .Sprintf ("%d" , linkID ))
190
+ }
191
+ }
192
+ }
193
+ }
194
+
172
195
for _ , ce := range sortedEntries {
173
- bundleDecoration := ""
196
+ entryID := fmt .Sprintf ("%s-%s" , channelID , ce .Name )
197
+ fmt .Fprintf (pkgBuilder , " %s[%q]\n " , entryID , ce .Name )
198
+
199
+ // mermaid allows specification of only a single decoration class, so any combinations must be independently represented
174
200
switch {
175
201
case depByBundle .Has (ce .Name ) && skippedEntities .Has (ce .Name ):
176
- bundleDecoration = ":::depandskip"
202
+ decoratedBundleIDs [ "deprecatedskipped" ] = append ( decoratedBundleIDs [ "deprecatedskipped" ], entryID )
177
203
case depByBundle .Has (ce .Name ):
178
- bundleDecoration = "::: deprecated"
204
+ decoratedBundleIDs [ "deprecated" ] = append ( decoratedBundleIDs [ " deprecated"], entryID )
179
205
case skippedEntities .Has (ce .Name ):
180
- bundleDecoration = "::: skipped"
206
+ decoratedBundleIDs [ "skipped" ] = append ( decoratedBundleIDs [ " skipped"], entryID )
181
207
}
182
208
183
- entryID := fmt .Sprintf ("%s-%s" , channelID , ce .Name )
184
- fmt .Fprintf (pkgBuilder , " %s[%q]%s\n " , entryID , ce .Name , bundleDecoration )
185
-
186
209
if len (ce .Skips ) > 0 {
187
210
for _ , s := range ce .Skips {
188
211
skipsID := fmt .Sprintf ("%s-%s" , channelID , s )
189
212
fmt .Fprintf (pkgBuilder , " %s[%q]-- %s --> %s[%q]\n " , skipsID , s , "skip" , entryID , ce .Name )
190
- if skippedEntities .Has (s ) {
191
- skippedLinkIDs = append (skippedLinkIDs , fmt .Sprintf ("%d" , linkID ))
192
- } else {
193
- skippedEntities .Insert (s )
194
- }
213
+ handleSemantics (s , linkID , captureNewEntry )
195
214
linkID ++
196
215
}
197
216
}
@@ -202,9 +221,7 @@ func (writer *MermaidWriter) WriteChannels(cfg DeclarativeConfig, out io.Writer)
202
221
if skipRange (versionMap [edgeName .Name ]) {
203
222
skipRangeID := fmt .Sprintf ("%s-%s" , channelID , edgeName .Name )
204
223
fmt .Fprintf (pkgBuilder , " %s[%q]-- \" %s(%s)\" --> %s[%q]\n " , skipRangeID , edgeName .Name , "skipRange" , ce .SkipRange , entryID , ce .Name )
205
- if skippedEntities .Has (ce .Name ) {
206
- skippedLinkIDs = append (skippedLinkIDs , fmt .Sprintf ("%d" , linkID ))
207
- }
224
+ handleSemantics (ce .Name , linkID , processExisting )
208
225
linkID ++
209
226
}
210
227
}
@@ -216,9 +233,7 @@ func (writer *MermaidWriter) WriteChannels(cfg DeclarativeConfig, out io.Writer)
216
233
if len (ce .Replaces ) > 0 {
217
234
replacesID := fmt .Sprintf ("%s-%s" , channelID , ce .Replaces )
218
235
fmt .Fprintf (pkgBuilder , " %s[%q]-- %s --> %s[%q]\n " , replacesID , ce .Replaces , "replace" , entryID , ce .Name )
219
- if skippedEntities .Has (ce .Name ) {
220
- skippedLinkIDs = append (skippedLinkIDs , fmt .Sprintf ("%d" , linkID ))
221
- }
236
+ handleSemantics (ce .Name , linkID , processExisting )
222
237
linkID ++
223
238
}
224
239
}
@@ -229,7 +244,7 @@ func (writer *MermaidWriter) WriteChannels(cfg DeclarativeConfig, out io.Writer)
229
244
_ , _ = out .Write ([]byte ("graph LR\n " ))
230
245
_ , _ = out .Write ([]byte (" classDef deprecated fill:#E8960F\n " ))
231
246
_ , _ = out .Write ([]byte (" classDef skipped stroke:#FF0000,stroke-width:4px\n " ))
232
- _ , _ = out .Write ([]byte (" classDef depandskip fill:#E8960 ,stroke:#FF0000,stroke-width:4px\n " ))
247
+ _ , _ = out .Write ([]byte (" classDef deprecatedskipped fill:#E8960F ,stroke:#FF0000,stroke-width:4px\n " ))
233
248
pkgNames := []string {}
234
249
for pname := range pkgs {
235
250
pkgNames = append (pkgNames , pname )
@@ -248,14 +263,23 @@ func (writer *MermaidWriter) WriteChannels(cfg DeclarativeConfig, out io.Writer)
248
263
_ , _ = out .Write ([]byte (fmt .Sprintf ("style %s fill:#989695\n " , deprecatedPackage )))
249
264
}
250
265
251
- if len (deprecatedChannels ) > 0 {
252
- for _ , deprecatedChannel := range deprecatedChannels {
266
+ if len (deprecatedChannelIDs ) > 0 {
267
+ for _ , deprecatedChannel := range deprecatedChannelIDs {
253
268
_ , _ = out .Write ([]byte (fmt .Sprintf ("style %s fill:#DCD0FF\n " , deprecatedChannel )))
254
269
}
255
270
}
256
271
272
+ // express the decoration classes
273
+ for key := range decoratedBundleIDs {
274
+ if len (decoratedBundleIDs [key ]) > 0 {
275
+ b := slices .Clone (decoratedBundleIDs [key ])
276
+ slices .Sort (b )
277
+ _ , _ = out .Write ([]byte (fmt .Sprintf ("class %s %s\n " , strings .Join (b , "," ), key )))
278
+ }
279
+ }
280
+
257
281
if len (skippedLinkIDs ) > 0 {
258
- _ , _ = out .Write ([]byte ("linkStyle " + strings .Join (skippedLinkIDs , "," ) + " stroke:#FF0000,stroke-width:3px,stroke-dasharray:5;" ))
282
+ _ , _ = out .Write ([]byte ("linkStyle " + strings .Join (skippedLinkIDs , "," ) + " stroke:#FF0000,stroke-width:3px,stroke-dasharray:5;\n " ))
259
283
}
260
284
261
285
return nil
0 commit comments