Monorepo for Tangled tangled.org
5

Configure Feed

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

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