drone-template-lib/template/helpers.go

153 lines
2.9 KiB
Go
Raw Permalink Normal View History

2021-09-18 17:21:41 +00:00
// Copyright (c) 2018, Drone.IO Inc
// Copyright (c) 2021, Robert Kaussow <mail@thegeeklab.de>
// Use of this source code is governed by an Apache 2.0 license that can be
// found in the LICENSE file.
2018-03-29 23:04:58 +00:00
package template
import (
"fmt"
2020-09-18 18:00:31 +00:00
"math"
2020-09-25 16:24:10 +00:00
"net/url"
"reflect"
2018-09-24 22:41:34 +00:00
"regexp"
2018-03-29 23:04:58 +00:00
"strings"
"time"
"unicode"
"unicode/utf8"
2020-09-25 16:24:10 +00:00
"github.com/Masterminds/sprig/v3"
"github.com/flowchartsman/handlebars/v3"
2018-03-29 23:04:58 +00:00
)
func init() {
funcs := map[string]interface{}{
2018-03-29 23:04:58 +00:00
"duration": toDuration,
"datetime": toDatetime,
"success": isSuccess,
"failure": isFailure,
"truncate": truncate,
"urlencode": urlencode,
"since": since,
"uppercasefirst": uppercaseFirst,
"uppercase": strings.ToUpper,
"lowercase": strings.ToLower,
2018-09-25 20:41:51 +00:00
"regexReplace": regexReplace,
2018-03-29 23:04:58 +00:00
}
for name, f := range sprig.GenericFuncMap() {
if _, ok := funcs[name]; ok || !validHelper(f) {
2019-02-19 09:04:44 +00:00
continue
}
funcs[name] = f
2019-02-19 09:04:44 +00:00
}
handlebars.RegisterHelpers(funcs)
2018-03-29 23:04:58 +00:00
}
2018-08-01 09:05:11 +00:00
func toDuration(started, finished int64) string {
2018-03-29 23:04:58 +00:00
return fmt.Sprint(time.Duration(finished-started) * time.Second)
}
2018-08-01 09:05:11 +00:00
func toDatetime(timestamp int64, layout, zone string) string {
2018-03-29 23:04:58 +00:00
if len(zone) == 0 {
2018-08-01 09:05:11 +00:00
return time.Unix(timestamp, 0).Format(layout)
2018-03-29 23:04:58 +00:00
}
loc, err := time.LoadLocation(zone)
if err != nil {
2018-08-01 09:05:11 +00:00
return time.Unix(timestamp, 0).Local().Format(layout)
2018-03-29 23:04:58 +00:00
}
2018-08-01 09:05:11 +00:00
return time.Unix(timestamp, 0).In(loc).Format(layout)
2018-03-29 23:04:58 +00:00
}
func isSuccess(conditional bool, options *handlebars.Options) string {
2018-03-29 23:04:58 +00:00
if !conditional {
return options.Inverse()
}
switch options.ParamStr(0) {
case "success":
return options.Fn()
default:
return options.Inverse()
}
}
func isFailure(conditional bool, options *handlebars.Options) string {
2018-03-29 23:04:58 +00:00
if !conditional {
return options.Inverse()
}
switch options.ParamStr(0) {
case "failure", "error", "killed":
return options.Fn()
default:
return options.Inverse()
}
}
func truncate(s string, len int) string {
if utf8.RuneCountInString(s) <= int(math.Abs(float64(len))) {
2018-03-29 23:04:58 +00:00
return s
}
runes := []rune(s)
if len < 0 {
2020-09-25 16:24:10 +00:00
len = -len
return string(runes[len:])
}
2020-09-18 18:00:31 +00:00
return string(runes[:len])
2018-03-29 23:04:58 +00:00
}
func urlencode(options *handlebars.Options) string {
2018-03-29 23:04:58 +00:00
return url.QueryEscape(options.Fn())
}
func since(start int64) string {
now := time.Unix(time.Now().Unix(), 0)
return fmt.Sprint(now.Sub(time.Unix(start, 0)))
}
func uppercaseFirst(s string) string {
a := []rune(s)
a[0] = unicode.ToUpper(a[0])
s = string(a)
return s
}
2018-09-24 22:41:34 +00:00
func regexReplace(pattern, input, replacement string) string {
2018-09-24 22:41:34 +00:00
re := regexp.MustCompile(pattern)
return re.ReplaceAllString(input, replacement)
}
2019-02-19 09:04:44 +00:00
func validHelper(f interface{}) bool {
typ := reflect.TypeOf(f)
if typ.NumOut() != 1 {
return false
2019-02-19 09:04:44 +00:00
}
v := reflect.Zero(typ.Out(0))
switch v.Interface().(type) {
case
bool,
float64,
[]int,
int,
int64,
[][]interface{},
[]interface{},
map[string]interface{},
map[string]string,
[]string,
string,
time.Time,
interface{}:
return true
2019-02-19 09:04:44 +00:00
}
return false
}