mirror of
https://github.com/thegeeklab/drone-template-lib.git
synced 2024-11-25 14:10:40 +00:00
commit
5748d3149f
18
.drone.yml
Normal file
18
.drone.yml
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
workspace:
|
||||||
|
base: /go
|
||||||
|
path: src/github.com/drone/drone-template-lib
|
||||||
|
|
||||||
|
pipeline:
|
||||||
|
deps:
|
||||||
|
image: golang:1.10
|
||||||
|
pull: true
|
||||||
|
commands:
|
||||||
|
- go get -u github.com/golang/dep/cmd/dep
|
||||||
|
- dep ensure
|
||||||
|
|
||||||
|
test:
|
||||||
|
image: golang:1.10
|
||||||
|
pull: true
|
||||||
|
commands:
|
||||||
|
- go vet ./...
|
||||||
|
- go test -cover ./...
|
3
.gitignore
vendored
3
.gitignore
vendored
@ -22,3 +22,6 @@ _testmain.go
|
|||||||
*.exe
|
*.exe
|
||||||
*.test
|
*.test
|
||||||
*.prof
|
*.prof
|
||||||
|
|
||||||
|
vendor/
|
||||||
|
coverage.out
|
||||||
|
38
Gopkg.lock
generated
Normal file
38
Gopkg.lock
generated
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
# This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'.
|
||||||
|
|
||||||
|
|
||||||
|
[[projects]]
|
||||||
|
name = "github.com/aymerick/raymond"
|
||||||
|
packages = [
|
||||||
|
".",
|
||||||
|
"ast",
|
||||||
|
"lexer",
|
||||||
|
"parser"
|
||||||
|
]
|
||||||
|
revision = "2eebd0f5dd9564c0c6e439df11d8a3c7b9b9ab11"
|
||||||
|
version = "v2.0.2"
|
||||||
|
|
||||||
|
[[projects]]
|
||||||
|
branch = "master"
|
||||||
|
name = "github.com/bouk/monkey"
|
||||||
|
packages = ["."]
|
||||||
|
revision = "5df1f207ff77e025801505ae4d903133a0b4353f"
|
||||||
|
|
||||||
|
[[projects]]
|
||||||
|
name = "github.com/pkg/errors"
|
||||||
|
packages = ["."]
|
||||||
|
revision = "645ef00459ed84a119197bfb8d8205042c6df63d"
|
||||||
|
version = "v0.8.0"
|
||||||
|
|
||||||
|
[[projects]]
|
||||||
|
branch = "master"
|
||||||
|
name = "github.com/tkuchiki/faketime"
|
||||||
|
packages = ["."]
|
||||||
|
revision = "a4500a4f4643cbc8c5855ed1dbbf161d6cfc77a5"
|
||||||
|
|
||||||
|
[solve-meta]
|
||||||
|
analyzer-name = "dep"
|
||||||
|
analyzer-version = 1
|
||||||
|
inputs-digest = "1ad80a88b5f0b1ddd8f2a548af68aea9c1c6e25c6fc0870a5fa5a5b03b25d414"
|
||||||
|
solver-name = "gps-cdcl"
|
||||||
|
solver-version = 1
|
15
Gopkg.toml
Normal file
15
Gopkg.toml
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
[[constraint]]
|
||||||
|
name = "github.com/aymerick/raymond"
|
||||||
|
version = "2.0.2"
|
||||||
|
|
||||||
|
[[constraint]]
|
||||||
|
name = "github.com/pkg/errors"
|
||||||
|
version = "0.8.0"
|
||||||
|
|
||||||
|
[prune]
|
||||||
|
go-tests = true
|
||||||
|
unused-packages = true
|
||||||
|
|
||||||
|
[[constraint]]
|
||||||
|
branch = "master"
|
||||||
|
name = "github.com/tkuchiki/faketime"
|
23
README.md
Normal file
23
README.md
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
# drone-template-lib
|
||||||
|
|
||||||
|
[![Build Status](http://beta.drone.io/api/badges/drone/drone-template-lib/status.svg)](http://beta.drone.io/drone/drone-template-lib)
|
||||||
|
[![Join the discussion at https://discourse.drone.io](https://img.shields.io/badge/discourse-forum-orange.svg)](https://discourse.drone.io)
|
||||||
|
[![Drone questions at https://stackoverflow.com](https://img.shields.io/badge/drone-stackoverflow-orange.svg)](https://stackoverflow.com/questions/tagged/drone.io)
|
||||||
|
[![Go Doc](https://godoc.org/github.com/drone/drone-template-lib?status.svg)](http://godoc.org/github.com/drone/drone-template-lib)
|
||||||
|
[![Go Report](https://goreportcard.com/badge/github.com/drone/drone-template-lib)](https://goreportcard.com/report/github.com/drone/drone-template-lib)
|
||||||
|
|
||||||
|
A Go client library for creating templateable [plugins](http://plugins.drone.io).
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
### Download the packe
|
||||||
|
|
||||||
|
```bash
|
||||||
|
go get -d github.com/drone/drone-template-lib
|
||||||
|
```
|
||||||
|
|
||||||
|
### Import the package
|
||||||
|
|
||||||
|
```Go
|
||||||
|
import "github.com/drone/drone-template-lib/template"
|
||||||
|
```
|
119
template/helpers.go
Normal file
119
template/helpers.go
Normal file
@ -0,0 +1,119 @@
|
|||||||
|
// Copyright 2018 Drone.IO Inc
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
package template
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"net/url"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
"unicode"
|
||||||
|
"unicode/utf8"
|
||||||
|
|
||||||
|
"github.com/aymerick/raymond"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
funcs = map[string]interface{}{
|
||||||
|
"duration": toDuration,
|
||||||
|
"datetime": toDatetime,
|
||||||
|
"success": isSuccess,
|
||||||
|
"failure": isFailure,
|
||||||
|
"truncate": truncate,
|
||||||
|
"urlencode": urlencode,
|
||||||
|
"since": since,
|
||||||
|
"uppercasefirst": uppercaseFirst,
|
||||||
|
"uppercase": strings.ToUpper,
|
||||||
|
"lowercase": strings.ToLower,
|
||||||
|
"trim": strings.TrimSpace,
|
||||||
|
"title": strings.Title,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
raymond.RegisterHelpers(funcs)
|
||||||
|
}
|
||||||
|
|
||||||
|
func toDuration(started, finished float64) string {
|
||||||
|
return fmt.Sprint(time.Duration(finished-started) * time.Second)
|
||||||
|
}
|
||||||
|
|
||||||
|
func toDatetime(timestamp float64, layout, zone string) string {
|
||||||
|
if len(zone) == 0 {
|
||||||
|
return time.Unix(int64(timestamp), 0).Format(layout)
|
||||||
|
}
|
||||||
|
|
||||||
|
loc, err := time.LoadLocation(zone)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return time.Unix(int64(timestamp), 0).Local().Format(layout)
|
||||||
|
}
|
||||||
|
|
||||||
|
return time.Unix(int64(timestamp), 0).In(loc).Format(layout)
|
||||||
|
}
|
||||||
|
|
||||||
|
func isSuccess(conditional bool, options *raymond.Options) string {
|
||||||
|
if !conditional {
|
||||||
|
return options.Inverse()
|
||||||
|
}
|
||||||
|
|
||||||
|
switch options.ParamStr(0) {
|
||||||
|
case "success":
|
||||||
|
return options.Fn()
|
||||||
|
default:
|
||||||
|
return options.Inverse()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func isFailure(conditional bool, options *raymond.Options) string {
|
||||||
|
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) <= len {
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
|
||||||
|
runes := []rune(s)
|
||||||
|
|
||||||
|
return string(runes[:len])
|
||||||
|
}
|
||||||
|
|
||||||
|
func urlencode(options *raymond.Options) string {
|
||||||
|
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
|
||||||
|
}
|
92
template/helpers_test.go
Normal file
92
template/helpers_test.go
Normal file
@ -0,0 +1,92 @@
|
|||||||
|
// Copyright 2018 Drone.IO Inc
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
package template
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/tkuchiki/faketime"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestToDuration(t *testing.T) {
|
||||||
|
from := float64(time.Date(2017, time.November, 15, 23, 0, 0, 0, time.UTC).Unix())
|
||||||
|
|
||||||
|
vals := map[int64]string{
|
||||||
|
time.Date(2018, time.November, 15, 23, 0, 0, 0, time.UTC).Unix(): "8760h0m0s",
|
||||||
|
time.Date(2017, time.November, 16, 23, 0, 0, 0, time.UTC).Unix(): "24h0m0s",
|
||||||
|
time.Date(2017, time.November, 15, 23, 30, 0, 0, time.UTC).Unix(): "30m0s",
|
||||||
|
time.Date(2017, time.November, 15, 23, 10, 15, 0, time.UTC).Unix(): "10m15s",
|
||||||
|
time.Date(2017, time.October, 15, 23, 0, 0, 0, time.UTC).Unix(): "-744h0m0s",
|
||||||
|
}
|
||||||
|
|
||||||
|
for input, want := range vals {
|
||||||
|
if got := toDuration(from, float64(input)); got != want {
|
||||||
|
t.Errorf("Want transform %f-%f to %s, got %s", from, float64(input), want, got)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestTruncate(t *testing.T) {
|
||||||
|
vals := map[string]string{
|
||||||
|
"foobarz": "fooba",
|
||||||
|
"foöäüüu": "foöäü",
|
||||||
|
"üpsßßßk": "üpsßß",
|
||||||
|
"1234567": "12345",
|
||||||
|
"!'§$%&/": "!'§$%",
|
||||||
|
}
|
||||||
|
|
||||||
|
for input, want := range vals {
|
||||||
|
if got := truncate(input, 5); got != want {
|
||||||
|
t.Errorf("Want transform %s to %s, got %s", input, want, got)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestSince(t *testing.T) {
|
||||||
|
f := faketime.NewFaketime(2017, time.November, 15, 23, 0, 0, 0, time.UTC)
|
||||||
|
defer f.Undo()
|
||||||
|
f.Do()
|
||||||
|
|
||||||
|
vals := map[int64]string{
|
||||||
|
time.Date(2016, time.November, 15, 23, 0, 0, 0, time.UTC).Unix(): "8760h0m0s",
|
||||||
|
time.Date(2017, time.November, 14, 23, 0, 0, 0, time.UTC).Unix(): "24h0m0s",
|
||||||
|
time.Date(2017, time.November, 15, 22, 30, 0, 0, time.UTC).Unix(): "30m0s",
|
||||||
|
time.Date(2017, time.November, 15, 22, 10, 15, 0, time.UTC).Unix(): "49m45s",
|
||||||
|
time.Date(2017, time.December, 15, 23, 0, 0, 0, time.UTC).Unix(): "-720h0m0s",
|
||||||
|
}
|
||||||
|
|
||||||
|
for input, want := range vals {
|
||||||
|
if got := since(input); got != want {
|
||||||
|
t.Errorf("Want transform %d to %s, got %s", input, want, got)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestUppercaseFirst(t *testing.T) {
|
||||||
|
vals := map[string]string{
|
||||||
|
"hello": "Hello",
|
||||||
|
"ßqwert": "ßqwert",
|
||||||
|
"üps": "Üps",
|
||||||
|
"12345": "12345",
|
||||||
|
"Foobar": "Foobar",
|
||||||
|
}
|
||||||
|
|
||||||
|
for input, want := range vals {
|
||||||
|
if got := uppercaseFirst(input); got != want {
|
||||||
|
t.Errorf("Want transform %s to %s, got %s", input, want, got)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
72
template/template.go
Normal file
72
template/template.go
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
// Copyright 2018 Drone.IO Inc
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
package template
|
||||||
|
|
||||||
|
import (
|
||||||
|
"io/ioutil"
|
||||||
|
"net/http"
|
||||||
|
"net/url"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/aymerick/raymond"
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Render parses and executes a template, returning the results in string
|
||||||
|
// format. Trailing or leading spaces or new-lines are not getting truncated. It
|
||||||
|
// is able to read templates from remote paths, local files or directly from the
|
||||||
|
// string.
|
||||||
|
func Render(template string, payload interface{}) (s string, err error) {
|
||||||
|
u, err := url.Parse(template)
|
||||||
|
|
||||||
|
if err == nil {
|
||||||
|
switch u.Scheme {
|
||||||
|
case "http", "https":
|
||||||
|
res, err := http.Get(template)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return s, errors.Wrap(err, "failed to fetch")
|
||||||
|
}
|
||||||
|
|
||||||
|
defer res.Body.Close()
|
||||||
|
|
||||||
|
out, err := ioutil.ReadAll(res.Body)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return s, errors.Wrap(err, "failed to read")
|
||||||
|
}
|
||||||
|
|
||||||
|
template = string(out)
|
||||||
|
case "file":
|
||||||
|
out, err := ioutil.ReadFile(u.Path)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return s, errors.Wrap(err, "failed to read")
|
||||||
|
}
|
||||||
|
|
||||||
|
template = string(out)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return raymond.Render(template, payload)
|
||||||
|
}
|
||||||
|
|
||||||
|
// RenderTrim parses and executes a template, returning the results in string
|
||||||
|
// format. The result is trimmed to remove left and right padding and newlines
|
||||||
|
// that may be added unintentially in the template markup.
|
||||||
|
func RenderTrim(template string, playload interface{}) (string, error) {
|
||||||
|
out, err := Render(template, playload)
|
||||||
|
return strings.Trim(out, " \n"), err
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user