github.com/helmwave/helmwave@v0.36.4-0.20240509190856-b35563eba4c6/pkg/plan/build_graph.go (about) 1 package plan 2 3 import ( 4 "fmt" 5 "strings" 6 7 "github.com/helmwave/asciigraph" 8 "github.com/helmwave/asciigraph/ascii" 9 "github.com/helmwave/asciigraph/core" 10 "github.com/helmwave/helmwave/pkg/helper" 11 "github.com/helmwave/helmwave/pkg/release" 12 log "github.com/sirupsen/logrus" 13 ) 14 15 func buildGraphMD(releases release.Configs) string { 16 md := "# Depends On\n\n" + 17 "```mermaid\ngraph RL\n" 18 19 for _, r := range releases { 20 for _, dep := range r.DependsOn() { 21 md += fmt.Sprintf( 22 "\t%s[%q] --> %s[%q]\n", 23 strings.ReplaceAll(r.Uniq().String(), "@", "_"), r.Uniq(), 24 strings.ReplaceAll(dep.Uniq().String(), "@", "_"), dep.Uniq().String(), 25 ) 26 } 27 } 28 29 md += "```" 30 31 return md 32 } 33 34 func buildGraphASCII(releases release.Configs, width int) string { 35 list, maxLength, minLength := getGraphNodesForReleases(releases) 36 37 o := ascii.DrawOptions{ 38 CellHeight: 3, 39 MinCellWidth: 3, 40 MaxWidth: 3, 41 Padding: 1, 42 } 43 44 switch { 45 case 0 == width: 46 if minLength < o.MinCellWidth { 47 o.MinCellWidth = minLength 48 } 49 if maxLength > o.MaxWidth { 50 o.MaxWidth = maxLength + 4 // need to add a little bit so that it won't be shortened 51 } 52 case 1 == width: 53 return "" 54 case 1 < width: 55 o.MinCellWidth = width 56 o.MaxWidth = width 57 case 0 > width: 58 o.MinCellWidth = minLength + width 59 o.MaxWidth = maxLength + width 60 } 61 62 log.WithFields(log.Fields{ 63 "graph-width": width, 64 "max-word-length": maxLength, 65 "min-word-length": minLength, 66 "min-cell-width": o.MinCellWidth, 67 "max-cell-width": o.MaxWidth, 68 }).Debug("graph draw options") 69 70 if o.MinCellWidth < 0 { 71 log.Error("cannot output graph with no width available") 72 73 return "" 74 } 75 76 canvas, err := dgraph.DrawGraph(list, o) 77 if err != nil { 78 log.Fatal(err) 79 } 80 81 return canvas.String() 82 } 83 84 func getGraphNodesForReleases(releases release.Configs) ([]core.NodeInput, int, int) { 85 list := make([]core.NodeInput, 0, len(releases)) 86 87 maxLength := 0 88 minLength := 9999 89 90 for _, rel := range releases { 91 deps := helper.SlicesMap(rel.DependsOn(), func(d *release.DependsOnReference) string { 92 return d.Uniq().String() 93 }) 94 95 uniq := rel.Uniq().String() 96 if len(uniq) > maxLength { 97 maxLength = len(uniq) 98 } 99 100 if len(uniq) < minLength { 101 minLength = len(uniq) 102 } 103 104 l := core.NodeInput{ 105 Id: uniq, 106 Next: deps, 107 } 108 109 list = append(list, l) 110 } 111 112 return list, maxLength, minLength 113 } 114 115 func (p *Plan) BuildGraphASCII(width int) string { 116 return buildGraphASCII(p.body.Releases, width) 117 }