1
0
mirror of https://github.com/SAP/jenkins-library.git synced 2024-12-12 10:55:20 +02:00
sap-jenkins-library/pkg/log/url.go

116 lines
2.4 KiB
Go
Raw Normal View History

package log
import (
"bytes"
"encoding/json"
"fmt"
"io"
"os"
"sync"
"mvdan.cc/xurls/v2"
)
type (
step struct {
Step map[string]u `json:"step"`
}
u struct {
URLs []string `json:"url"`
}
)
const (
urlLogFileName = "url-log.json"
)
type URLLogger struct {
buf struct {
data [][]byte
sync.RWMutex
}
stepName string
}
func NewURLLogger(stepName string) *URLLogger {
return &URLLogger{stepName: stepName}
}
func (cl *URLLogger) WriteURLsLogToJSON() error {
cl.buf.Lock()
defer cl.buf.Unlock()
if len(cl.buf.data) == 0 {
return nil
}
2022-08-08 10:10:35 +02:00
file, err := os.OpenFile(urlLogFileName, os.O_CREATE|os.O_RDWR, 0666)
if err != nil {
return fmt.Errorf("failed to open file: %w", err)
}
defer func() {
dErr := file.Close()
if dErr != nil {
err = fmt.Errorf("can't close file: %w", dErr)
}
}()
fileBuf, err := io.ReadAll(file)
if err != nil {
return fmt.Errorf("can't read from gile: %w", err)
}
urlsLog := step{make(map[string]u)}
if len(fileBuf) != 0 {
err = json.Unmarshal(fileBuf, &urlsLog)
if err != nil {
return fmt.Errorf("can't unmarshal log: %w", err)
}
fileBuf = fileBuf[:0]
}
var urls []string
if stepLogs, ok := urlsLog.Step[cl.stepName]; ok {
urls = stepLogs.URLs
}
for _, url := range cl.buf.data {
urls = append(urls, string(url))
}
urlsLog.Step[cl.stepName] = u{urls}
encoderBuf := bytes.NewBuffer(fileBuf)
jsonEncoder := json.NewEncoder(encoderBuf)
jsonEncoder.SetEscapeHTML(false)
jsonEncoder.SetIndent("", " ")
err = jsonEncoder.Encode(urlsLog)
if err != nil {
return fmt.Errorf("json encode error: %w", err)
}
_, err = file.WriteAt(encoderBuf.Bytes(), 0)
if err != nil {
return fmt.Errorf("failed to write log: %w", err)
}
return err
}
func (cl *URLLogger) Parse(buf bytes.Buffer) {
cl.buf.Lock()
defer cl.buf.Unlock()
classifier := returnURLStrictClassifier(cl.stepName)
cl.buf.data = append(cl.buf.data, parseURLs(buf.Bytes(), classifier)...)
}
func parseURLs(src []byte, classifier string) [][]byte {
if classifier == "Strict" {
return xurls.Strict().FindAll(src, -1)
} else {
return xurls.Relaxed().FindAll(src, -1)
}
}
func returnURLStrictClassifier(stepName string) string {
switch stepName {
// golang cli output urls without the http protocol hence making the search less strict
//ToDo: other cases where the url is without protocol
case "golangBuild":
return "Relaxed"
default:
return "Strict"
}
}