Monorepo for Tangled tangled.org
2

Configure Feed

Select the types of activity you want to include in your feed.

1package pipelines 2 3import ( 4 "html/template" 5 "regexp" 6 "strings" 7 8 terminal "github.com/buildkite/terminal-to-html/v3" 9 "github.com/gorilla/websocket" 10 "tangled.org/core/appview/pages/markup" 11) 12 13// matches any ANSI escape sequence: ESC [ <params> m 14var sequenceRe = regexp.MustCompile(`\x1b\[([\d;]*)m`) 15 16// ansiState tracks the active stack across log lines 17// each non-reset SGR code is pushed onto the stack; a reset clears it. 18// 19// the stack contents are prepended to each new line so colours carry over. 20type ansiState struct { 21 stack []string 22 sanitizer markup.Sanitizer 23} 24 25func NewAnsiState() *ansiState { 26 return &ansiState{ 27 stack: []string{}, 28 sanitizer: markup.NewSanitizer(), 29 } 30} 31 32func (a *ansiState) Render(line string) template.HTML { 33 // prepend whatever sequences are still open from the previous line 34 prefix := strings.Join(a.stack, "") 35 // render current line with the existing prefix 36 rendered := terminal.Render([]byte(prefix + line)) 37 // sanitize 38 sanitized := a.sanitizer.SanitizeLogs(rendered) 39 40 // update the stack with sequences from current line 41 for _, m := range sequenceRe.FindAllStringSubmatch(line, -1) { 42 params := m[1] 43 if params == "" || params == "0" || params == "00" { 44 a.stack = a.stack[:0] 45 } else { 46 a.stack = append(a.stack, m[0]) 47 } 48 } 49 50 return template.HTML(sanitized) 51} 52 53type LogEvent struct { 54 Msg []byte 55 Err error 56} 57 58func (ev *LogEvent) IsCloseError() bool { 59 return websocket.IsCloseError( 60 ev.Err, 61 websocket.CloseNormalClosure, 62 websocket.CloseGoingAway, 63 websocket.CloseAbnormalClosure, 64 ) 65} 66 67func ReadLogs(conn *websocket.Conn, ch chan LogEvent) { 68 defer close(ch) 69 for { 70 if conn == nil { 71 return 72 } 73 _, msg, err := conn.ReadMessage() 74 if err != nil { 75 ch <- LogEvent{Err: err} 76 return 77 } 78 ch <- LogEvent{Msg: msg} 79 } 80} 81 82func SpindleURL(dev bool, spindle, knot, rkey, workflow string) string { 83 scheme := "wss" 84 if dev { 85 scheme = "ws" 86 } 87 return scheme + "://" + strings.Join([]string{spindle, "logs", knot, rkey, workflow}, "/") 88}