Merge pull request #1 from tboerger/initial

Migrated initial version
This commit is contained in:
Brad Rydzewski 2018-04-01 10:04:47 -07:00 committed by GitHub
commit 5748d3149f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 380 additions and 0 deletions

18
.drone.yml Normal file
View 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
View File

@ -22,3 +22,6 @@ _testmain.go
*.exe *.exe
*.test *.test
*.prof *.prof
vendor/
coverage.out

38
Gopkg.lock generated Normal file
View 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
View 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
View 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
View 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
View 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
View 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
}