...

Source file src/edge-infra.dev/pkg/f8n/warehouse/lift/cmd/graph/d2.go

Documentation: edge-infra.dev/pkg/f8n/warehouse/lift/cmd/graph

     1  package graph
     2  
     3  import (
     4  	"context"
     5  	_ "embed"
     6  	"fmt"
     7  
     8  	"oss.terrastruct.com/d2/d2graph"
     9  	"oss.terrastruct.com/d2/d2layouts/d2elklayout"
    10  	"oss.terrastruct.com/d2/d2lib"
    11  	"oss.terrastruct.com/d2/d2oracle"
    12  	"oss.terrastruct.com/d2/d2target"
    13  	"oss.terrastruct.com/d2/lib/textmeasure"
    14  )
    15  
    16  var (
    17  	//go:embed style.d2
    18  	style string
    19  )
    20  
    21  type d2 struct {
    22  	g *d2graph.Graph
    23  	d *d2target.Diagram
    24  }
    25  
    26  func (g *graph) toD2(ctx context.Context, providerLabels bool) (*d2, error) {
    27  	// Initialize a ruler to measure font glyphs
    28  	ruler, err := textmeasure.NewRuler()
    29  	if err != nil {
    30  		return nil, err
    31  	}
    32  	d, d2g, err := d2lib.Compile(ctx, style, &d2lib.CompileOptions{
    33  		LayoutResolver: func(_ string) (d2graph.LayoutGraph, error) {
    34  			return d2elklayout.DefaultLayout, nil
    35  		},
    36  		Ruler: ruler,
    37  	}, nil)
    38  	if err != nil {
    39  		return nil, err
    40  	}
    41  
    42  	// First create all nodes, then connections, so we don't implicitly create the
    43  	// same node twice due to `Create()` creating any pieces that dont exist when
    44  	// creating edges or containers.
    45  	for _, key := range g.keys {
    46  		n := g.nodes[key]
    47  		id := d2NodeID(n)
    48  		d2g, id, err = d2oracle.Create(d2g, nil, id)
    49  		if err != nil {
    50  			return nil, err
    51  		}
    52  
    53  		d2g, err = d2oracle.Set(d2g, nil, fmt.Sprintf("%s.class", id), nil, &n.nodeType)
    54  		if err != nil {
    55  			return nil, err
    56  		}
    57  
    58  		if n.nodeType == objectsNode {
    59  			y := "yaml"
    60  			d2g, err = d2oracle.Set(d2g, nil, id, &y, &n.data)
    61  			if err != nil {
    62  				return nil, err
    63  			}
    64  			continue
    65  		}
    66  
    67  		label := n.label()
    68  		d2g, err = d2oracle.Set(d2g, nil, fmt.Sprintf("%s.label", id), nil, &label)
    69  		if err != nil {
    70  			return nil, err
    71  		}
    72  	}
    73  
    74  	for _, key := range g.keys {
    75  		n := g.nodes[key]
    76  		id := d2NodeID(n)
    77  		for _, d := range n.deps {
    78  			id := fmt.Sprintf("%s -> %s", id, d2NodeID(d))
    79  			d2g, id, err = d2oracle.Create(d2g, nil, id)
    80  			if err != nil {
    81  				return nil, err
    82  			}
    83  
    84  			if providerLabels &&
    85  				n.nodeType == idxNode &&
    86  				d.nodeType == imgNode &&
    87  				d.labels["providers"] != "" {
    88  				p := d.labels["providers"]
    89  				d2g, err = d2oracle.Set(d2g, nil, id, nil, &p)
    90  				if err != nil {
    91  					return nil, err
    92  				}
    93  			}
    94  		}
    95  	}
    96  
    97  	return &d2{d2g, d}, nil
    98  }
    99  
   100  // d2NodeID creates an ID for d2 graphs separate from the visible label
   101  func d2NodeID(n *node) string {
   102  	return fmt.Sprintf("%s-%s-%s", n.name, n.nodeType, n.digest.Hex[:4])
   103  }
   104  

View as plain text