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  }