github.com/nektos/act@v0.2.63/pkg/common/draw.go (about)

     1  package common
     2  
     3  import (
     4  	"fmt"
     5  	"io"
     6  	"os"
     7  	"strings"
     8  )
     9  
    10  // Style is a specific style
    11  type Style int
    12  
    13  // Styles
    14  const (
    15  	StyleDoubleLine = iota
    16  	StyleSingleLine
    17  	StyleDashedLine
    18  	StyleNoLine
    19  )
    20  
    21  // NewPen creates a new pen
    22  func NewPen(style Style, color int) *Pen {
    23  	bgcolor := 49
    24  	if os.Getenv("CLICOLOR") == "0" {
    25  		color = 0
    26  		bgcolor = 0
    27  	}
    28  	return &Pen{
    29  		style:   style,
    30  		color:   color,
    31  		bgcolor: bgcolor,
    32  	}
    33  }
    34  
    35  type styleDef struct {
    36  	cornerTL string
    37  	cornerTR string
    38  	cornerBL string
    39  	cornerBR string
    40  	lineH    string
    41  	lineV    string
    42  }
    43  
    44  var styleDefs = []styleDef{
    45  	{"\u2554", "\u2557", "\u255a", "\u255d", "\u2550", "\u2551"},
    46  	{"\u256d", "\u256e", "\u2570", "\u256f", "\u2500", "\u2502"},
    47  	{"\u250c", "\u2510", "\u2514", "\u2518", "\u254c", "\u254e"},
    48  	{" ", " ", " ", " ", " ", " "},
    49  }
    50  
    51  // Pen struct
    52  type Pen struct {
    53  	style   Style
    54  	color   int
    55  	bgcolor int
    56  }
    57  
    58  // Drawing struct
    59  type Drawing struct {
    60  	buf   *strings.Builder
    61  	width int
    62  }
    63  
    64  func (p *Pen) drawTopBars(buf io.Writer, labels ...string) {
    65  	style := styleDefs[p.style]
    66  	for _, label := range labels {
    67  		bar := strings.Repeat(style.lineH, len(label)+2)
    68  		fmt.Fprintf(buf, " ")
    69  		fmt.Fprintf(buf, "\x1b[%d;%dm", p.color, p.bgcolor)
    70  		fmt.Fprintf(buf, "%s%s%s", style.cornerTL, bar, style.cornerTR)
    71  		fmt.Fprintf(buf, "\x1b[%dm", 0)
    72  	}
    73  	fmt.Fprintf(buf, "\n")
    74  }
    75  func (p *Pen) drawBottomBars(buf io.Writer, labels ...string) {
    76  	style := styleDefs[p.style]
    77  	for _, label := range labels {
    78  		bar := strings.Repeat(style.lineH, len(label)+2)
    79  		fmt.Fprintf(buf, " ")
    80  		fmt.Fprintf(buf, "\x1b[%d;%dm", p.color, p.bgcolor)
    81  		fmt.Fprintf(buf, "%s%s%s", style.cornerBL, bar, style.cornerBR)
    82  		fmt.Fprintf(buf, "\x1b[%dm", 0)
    83  	}
    84  	fmt.Fprintf(buf, "\n")
    85  }
    86  func (p *Pen) drawLabels(buf io.Writer, labels ...string) {
    87  	style := styleDefs[p.style]
    88  	for _, label := range labels {
    89  		fmt.Fprintf(buf, " ")
    90  		fmt.Fprintf(buf, "\x1b[%d;%dm", p.color, p.bgcolor)
    91  		fmt.Fprintf(buf, "%s %s %s", style.lineV, label, style.lineV)
    92  		fmt.Fprintf(buf, "\x1b[%dm", 0)
    93  	}
    94  	fmt.Fprintf(buf, "\n")
    95  }
    96  
    97  // DrawArrow between boxes
    98  func (p *Pen) DrawArrow() *Drawing {
    99  	drawing := &Drawing{
   100  		buf:   new(strings.Builder),
   101  		width: 1,
   102  	}
   103  	fmt.Fprintf(drawing.buf, "\x1b[%dm", p.color)
   104  	fmt.Fprintf(drawing.buf, "\u2b07")
   105  	fmt.Fprintf(drawing.buf, "\x1b[%dm", 0)
   106  	return drawing
   107  }
   108  
   109  // DrawBoxes to draw boxes
   110  func (p *Pen) DrawBoxes(labels ...string) *Drawing {
   111  	width := 0
   112  	for _, l := range labels {
   113  		width += len(l) + 2 + 2 + 1
   114  	}
   115  	drawing := &Drawing{
   116  		buf:   new(strings.Builder),
   117  		width: width,
   118  	}
   119  	p.drawTopBars(drawing.buf, labels...)
   120  	p.drawLabels(drawing.buf, labels...)
   121  	p.drawBottomBars(drawing.buf, labels...)
   122  
   123  	return drawing
   124  }
   125  
   126  // Draw to writer
   127  func (d *Drawing) Draw(writer io.Writer, centerOnWidth int) {
   128  	padSize := (centerOnWidth - d.GetWidth()) / 2
   129  	if padSize < 0 {
   130  		padSize = 0
   131  	}
   132  	for _, l := range strings.Split(d.buf.String(), "\n") {
   133  		if len(l) > 0 {
   134  			padding := strings.Repeat(" ", padSize)
   135  			fmt.Fprintf(writer, "%s%s\n", padding, l)
   136  		}
   137  	}
   138  }
   139  
   140  // GetWidth of drawing
   141  func (d *Drawing) GetWidth() int {
   142  	return d.width
   143  }