mirror of
https://github.com/thegeeklab/drone-template-lib.git
synced 2024-11-28 23:50:35 +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
|
||||
*.test
|
||||
*.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