vendored dependencies

This commit is contained in:
Brad Rydzewski
2015-11-24 15:55:00 -08:00
parent 3260b7237f
commit ebb1852bb7
101 changed files with 18069 additions and 0 deletions
+342
View File
@@ -0,0 +1,342 @@
package drone
//go:generate mockery -all
//go:generate mv mocks/Client.go mocks/client.go
import (
"bytes"
"encoding/json"
"fmt"
"io"
"io/ioutil"
"net/http"
"net/url"
"golang.org/x/oauth2"
)
const (
pathSelf = "%s/api/user"
pathFeed = "%s/api/user/feed"
pathRepos = "%s/api/user/repos"
pathRepo = "%s/api/repos/%s/%s"
pathEncrypt = "%s/api/repos/%s/%s/encrypt"
pathBuilds = "%s/api/repos/%s/%s/builds"
pathBuild = "%s/api/repos/%s/%s/builds/%v"
pathJob = "%s/api/repos/%s/%s/builds/%d/%d"
pathLog = "%s/api/repos/%s/%s/logs/%d/%d"
pathKey = "%s/api/repos/%s/%s/key"
pathNodes = "%s/api/nodes"
pathNode = "%s/api/nodes/%d"
pathUsers = "%s/api/users"
pathUser = "%s/api/users/%s"
)
type client struct {
client *http.Client
base string // base url
}
// NewClient returns a client at the specified url.
func NewClient(uri string) Client {
return &client{http.DefaultClient, uri}
}
// NewClientToken returns a client at the specified url that
// authenticates all outbound requests with the given token.
func NewClientToken(uri, token string) Client {
config := new(oauth2.Config)
auther := config.Client(oauth2.NoContext, &oauth2.Token{AccessToken: token})
return &client{auther, uri}
}
// SetClient sets the default http client. This should be
// used in conjunction with golang.org/x/oauth2 to
// authenticate requests to the Drone server.
func (c *client) SetClient(client *http.Client) {
c.client = client
}
// Self returns the currently authenticated user.
func (c *client) Self() (*User, error) {
out := new(User)
uri := fmt.Sprintf(pathSelf, c.base)
err := c.get(uri, out)
return out, err
}
// User returns a user by login.
func (c *client) User(login string) (*User, error) {
out := new(User)
uri := fmt.Sprintf(pathUser, c.base, login)
err := c.get(uri, out)
return out, err
}
// UserList returns a list of all registered users.
func (c *client) UserList() ([]*User, error) {
out := make([]*User, 0)
uri := fmt.Sprintf(pathUsers, c.base)
err := c.get(uri, &out)
return out, err
}
// UserPost creates a new user account.
func (c *client) UserPost(in *User) (*User, error) {
out := new(User)
uri := fmt.Sprintf(pathUsers, c.base)
err := c.post(uri, in, out)
return out, err
}
// UserPatch updates a user account.
func (c *client) UserPatch(in *User) (*User, error) {
out := new(User)
uri := fmt.Sprintf(pathUser, c.base, in.Login)
err := c.patch(uri, in, out)
return out, err
}
// UserDel deletes a user account.
func (c *client) UserDel(login string) error {
uri := fmt.Sprintf(pathUser, c.base, login)
err := c.delete(uri)
return err
}
// UserFeed returns the user's activity feed.
func (c *client) UserFeed() ([]*Activity, error) {
out := make([]*Activity, 0)
uri := fmt.Sprintf(pathFeed, c.base)
err := c.get(uri, &out)
return out, err
}
// Repo returns a repository by name.
func (c *client) Repo(owner string, name string) (*Repo, error) {
out := new(Repo)
uri := fmt.Sprintf(pathRepo, c.base, owner, name)
err := c.get(uri, out)
return out, err
}
// RepoList returns a list of all repositories to which
// the user has explicit access in the host system.
func (c *client) RepoList() ([]*Repo, error) {
out := make([]*Repo, 0)
uri := fmt.Sprintf(pathRepos, c.base)
err := c.get(uri, &out)
return out, err
}
// RepoPost activates a repository.
func (c *client) RepoPost(owner string, name string) (*Repo, error) {
out := new(Repo)
uri := fmt.Sprintf(pathRepo, c.base, owner, name)
err := c.post(uri, nil, out)
return out, err
}
// RepoPatch updates a repository.
func (c *client) RepoPatch(in *Repo) (*Repo, error) {
out := new(Repo)
uri := fmt.Sprintf(pathRepo, c.base, in.Owner, in.Name)
err := c.patch(uri, in, out)
return out, err
}
// RepoDel deletes a repository.
func (c *client) RepoDel(owner, name string) error {
uri := fmt.Sprintf(pathRepo, c.base, owner, name)
err := c.delete(uri)
return err
}
// RepoKey returns a repository public key.
func (c *client) RepoKey(owner, name string) (*Key, error) {
out := new(Key)
uri := fmt.Sprintf(pathKey, c.base, owner, name)
rc, err := c.stream(uri, "GET", nil, nil)
if err != nil {
return nil, err
}
defer rc.Close()
raw, _ := ioutil.ReadAll(rc)
out.Public = string(raw)
return out, err
}
// Build returns a repository build by number.
func (c *client) Build(owner, name string, num int) (*Build, error) {
out := new(Build)
uri := fmt.Sprintf(pathBuild, c.base, owner, name, num)
err := c.get(uri, out)
return out, err
}
// Build returns the latest repository build by branch.
func (c *client) BuildLast(owner, name, branch string) (*Build, error) {
out := new(Build)
uri := fmt.Sprintf(pathBuild, c.base, owner, name, "latest")
if len(branch) != 0 {
uri += "?branch=" + branch
}
err := c.get(uri, out)
return out, err
}
// BuildList returns a list of recent builds for the
// the specified repository.
func (c *client) BuildList(owner, name string) ([]*Build, error) {
out := make([]*Build, 0)
uri := fmt.Sprintf(pathBuilds, c.base, owner, name)
err := c.get(uri, &out)
return out, err
}
// BuildStart re-starts a stopped build.
func (c *client) BuildStart(owner, name string, num int) (*Build, error) {
out := new(Build)
uri := fmt.Sprintf(pathBuild, c.base, owner, name, num)
err := c.post(uri, nil, out)
return out, err
}
// BuildStop cancels the running job.
func (c *client) BuildStop(owner, name string, num, job int) error {
uri := fmt.Sprintf(pathJob, c.base, owner, name, num, job)
err := c.delete(uri)
return err
}
// BuildFork re-starts a stopped build with a new build number,
// preserving the prior history.
func (c *client) BuildFork(owner, name string, num int) (*Build, error) {
out := new(Build)
uri := fmt.Sprintf(pathBuild+"?fork=true", c.base, owner, name, num)
err := c.post(uri, nil, out)
return out, err
}
// BuildLogs returns the build logs for the specified job.
func (c *client) BuildLogs(owner, name string, num, job int) (io.ReadCloser, error) {
uri := fmt.Sprintf(pathLog, c.base, owner, name, num, job)
return c.stream(uri, "GET", nil, nil)
}
// Node returns a node by id.
func (c *client) Node(id int64) (*Node, error) {
out := new(Node)
uri := fmt.Sprintf(pathNode, c.base, id)
err := c.get(uri, out)
return out, err
}
// NodeList returns a list of all registered worker nodes.
func (c *client) NodeList() ([]*Node, error) {
out := make([]*Node, 0)
uri := fmt.Sprintf(pathNodes, c.base)
err := c.get(uri, &out)
return out, err
}
// NodePost registers a new worker node.
func (c *client) NodePost(in *Node) (*Node, error) {
out := new(Node)
uri := fmt.Sprintf(pathNodes, c.base)
err := c.post(uri, in, out)
return out, err
}
// NodeDel deletes a worker node.
func (c *client) NodeDel(id int64) error {
uri := fmt.Sprintf(pathNode, c.base, id)
err := c.delete(uri)
return err
}
//
// http request helper functions
//
// helper function for making an http GET request.
func (c *client) get(rawurl string, out interface{}) error {
return c.do(rawurl, "GET", nil, out)
}
// helper function for making an http POST request.
func (c *client) post(rawurl string, in, out interface{}) error {
return c.do(rawurl, "POST", in, out)
}
// helper function for making an http PUT request.
func (c *client) put(rawurl string, in, out interface{}) error {
return c.do(rawurl, "PUT", in, out)
}
// helper function for making an http PATCH request.
func (c *client) patch(rawurl string, in, out interface{}) error {
return c.do(rawurl, "PATCH", in, out)
}
// helper function for making an http DELETE request.
func (c *client) delete(rawurl string) error {
return c.do(rawurl, "DELETE", nil, nil)
}
// helper function to make an http request
func (c *client) do(rawurl, method string, in, out interface{}) error {
// executes the http request and returns the body as
// and io.ReadCloser
body, err := c.stream(rawurl, method, in, out)
if err != nil {
return err
}
defer body.Close()
// if a json response is expected, parse and return
// the json response.
if out != nil {
return json.NewDecoder(body).Decode(out)
}
return nil
}
// helper function to stream an http request
func (c *client) stream(rawurl, method string, in, out interface{}) (io.ReadCloser, error) {
uri, err := url.Parse(rawurl)
if err != nil {
return nil, err
}
// if we are posting or putting data, we need to
// write it to the body of the request.
var buf io.ReadWriter
if in != nil {
buf = new(bytes.Buffer)
err := json.NewEncoder(buf).Encode(in)
if err != nil {
return nil, err
}
}
// creates a new http request to bitbucket.
req, err := http.NewRequest(method, uri.String(), buf)
if err != nil {
return nil, err
}
if in != nil {
req.Header.Set("Content-Type", "application/json")
}
resp, err := c.client.Do(req)
if err != nil {
return nil, err
}
if resp.StatusCode > http.StatusPartialContent {
defer resp.Body.Close()
out, _ := ioutil.ReadAll(resp.Body)
return nil, fmt.Errorf(string(out))
}
return resp.Body, nil
}
+44
View File
@@ -0,0 +1,44 @@
package drone
const (
EventPush = "push"
EventPull = "pull_request"
EventTag = "tag"
EventDeploy = "deployment"
)
const (
StatusSkipped = "skipped"
StatusPending = "pending"
StatusRunning = "running"
StatusSuccess = "success"
StatusFailure = "failure"
StatusKilled = "killed"
StatusError = "error"
)
const (
Freebsd_386 uint = iota
Freebsd_amd64
Freebsd_arm
Linux_386
Linux_amd64
Linux_arm
Linux_arm64
Solaris_amd64
Windows_386
Windows_amd64
)
var Archs = map[string]uint{
"freebsd_386": Freebsd_386,
"freebsd_amd64": Freebsd_amd64,
"freebsd_arm": Freebsd_arm,
"linux_386": Linux_386,
"linux_amd64": Linux_amd64,
"linux_arm": Linux_arm,
"linux_arm64": Linux_arm64,
"solaris_amd64": Solaris_amd64,
"windows_386": Windows_386,
"windows_amd64": Windows_amd64,
}
+81
View File
@@ -0,0 +1,81 @@
package drone
import "io"
type Client interface {
// Self returns the currently authenticated user.
Self() (*User, error)
// User returns a user by login.
User(string) (*User, error)
// UserList returns a list of all registered users.
UserList() ([]*User, error)
// UserPost creates a new user account.
UserPost(*User) (*User, error)
// UserPatch updates a user account.
UserPatch(*User) (*User, error)
// UserDel deletes a user account.
UserDel(string) error
// UserFeed returns the user's activity feed.
UserFeed() ([]*Activity, error)
// Repo returns a repository by name.
Repo(string, string) (*Repo, error)
// RepoList returns a list of all repositories to which
// the user has explicit access in the host system.
RepoList() ([]*Repo, error)
// RepoPost activates a repository.
RepoPost(string, string) (*Repo, error)
// RepoPatch updates a repository.
RepoPatch(*Repo) (*Repo, error)
// RepoDel deletes a repository.
RepoDel(string, string) error
// RepoKey returns a repository public key.
RepoKey(string, string) (*Key, error)
// Build returns a repository build by number.
Build(string, string, int) (*Build, error)
// BuildLast returns the latest repository build by branch.
// An empty branch will result in the default branch.
BuildLast(string, string, string) (*Build, error)
// BuildList returns a list of recent builds for the
// the specified repository.
BuildList(string, string) ([]*Build, error)
// BuildStart re-starts a stopped build.
BuildStart(string, string, int) (*Build, error)
// BuildStop stops the specified running job for given build.
BuildStop(string, string, int, int) error
// BuildFork re-starts a stopped build with a new build number,
// preserving the prior history.
BuildFork(string, string, int) (*Build, error)
// BuildLogs returns the build logs for the specified job.
BuildLogs(string, string, int, int) (io.ReadCloser, error)
// Node returns a node by id.
Node(int64) (*Node, error)
// NodeList returns a list of all registered worker nodes.
NodeList() ([]*Node, error)
// NodePost registers a new worker node.
NodePost(*Node) (*Node, error)
// NodeDel deletes a worker node.
NodeDel(int64) error
}
+435
View File
@@ -0,0 +1,435 @@
package mocks
import "github.com/drone/drone-go/drone"
import "github.com/stretchr/testify/mock"
import "io"
type Client struct {
mock.Mock
}
func (_m *Client) Self() (*drone.User, error) {
ret := _m.Called()
var r0 *drone.User
if rf, ok := ret.Get(0).(func() *drone.User); ok {
r0 = rf()
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*drone.User)
}
}
var r1 error
if rf, ok := ret.Get(1).(func() error); ok {
r1 = rf()
} else {
r1 = ret.Error(1)
}
return r0, r1
}
func (_m *Client) User(_a0 string) (*drone.User, error) {
ret := _m.Called(_a0)
var r0 *drone.User
if rf, ok := ret.Get(0).(func(string) *drone.User); ok {
r0 = rf(_a0)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*drone.User)
}
}
var r1 error
if rf, ok := ret.Get(1).(func(string) error); ok {
r1 = rf(_a0)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
func (_m *Client) UserList() ([]*drone.User, error) {
ret := _m.Called()
var r0 []*drone.User
if rf, ok := ret.Get(0).(func() []*drone.User); ok {
r0 = rf()
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).([]*drone.User)
}
}
var r1 error
if rf, ok := ret.Get(1).(func() error); ok {
r1 = rf()
} else {
r1 = ret.Error(1)
}
return r0, r1
}
func (_m *Client) UserPost(_a0 *drone.User) (*drone.User, error) {
ret := _m.Called(_a0)
var r0 *drone.User
if rf, ok := ret.Get(0).(func(*drone.User) *drone.User); ok {
r0 = rf(_a0)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*drone.User)
}
}
var r1 error
if rf, ok := ret.Get(1).(func(*drone.User) error); ok {
r1 = rf(_a0)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
func (_m *Client) UserPatch(_a0 *drone.User) (*drone.User, error) {
ret := _m.Called(_a0)
var r0 *drone.User
if rf, ok := ret.Get(0).(func(*drone.User) *drone.User); ok {
r0 = rf(_a0)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*drone.User)
}
}
var r1 error
if rf, ok := ret.Get(1).(func(*drone.User) error); ok {
r1 = rf(_a0)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
func (_m *Client) UserDel(_a0 string) error {
ret := _m.Called(_a0)
var r0 error
if rf, ok := ret.Get(0).(func(string) error); ok {
r0 = rf(_a0)
} else {
r0 = ret.Error(0)
}
return r0
}
func (_m *Client) UserFeed() ([]*drone.Activity, error) {
ret := _m.Called()
var r0 []*drone.Activity
if rf, ok := ret.Get(0).(func() []*drone.Activity); ok {
r0 = rf()
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).([]*drone.Activity)
}
}
var r1 error
if rf, ok := ret.Get(1).(func() error); ok {
r1 = rf()
} else {
r1 = ret.Error(1)
}
return r0, r1
}
func (_m *Client) Repo(_a0 string, _a1 string) (*drone.Repo, error) {
ret := _m.Called(_a0, _a1)
var r0 *drone.Repo
if rf, ok := ret.Get(0).(func(string, string) *drone.Repo); ok {
r0 = rf(_a0, _a1)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*drone.Repo)
}
}
var r1 error
if rf, ok := ret.Get(1).(func(string, string) error); ok {
r1 = rf(_a0, _a1)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
func (_m *Client) RepoList() ([]*drone.Repo, error) {
ret := _m.Called()
var r0 []*drone.Repo
if rf, ok := ret.Get(0).(func() []*drone.Repo); ok {
r0 = rf()
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).([]*drone.Repo)
}
}
var r1 error
if rf, ok := ret.Get(1).(func() error); ok {
r1 = rf()
} else {
r1 = ret.Error(1)
}
return r0, r1
}
func (_m *Client) RepoPost(_a0 string, _a1 string) (*drone.Repo, error) {
ret := _m.Called(_a0, _a1)
var r0 *drone.Repo
if rf, ok := ret.Get(0).(func(string, string) *drone.Repo); ok {
r0 = rf(_a0, _a1)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*drone.Repo)
}
}
var r1 error
if rf, ok := ret.Get(1).(func(string, string) error); ok {
r1 = rf(_a0, _a1)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
func (_m *Client) RepoPatch(_a0 *drone.Repo) (*drone.Repo, error) {
ret := _m.Called(_a0)
var r0 *drone.Repo
if rf, ok := ret.Get(0).(func(*drone.Repo) *drone.Repo); ok {
r0 = rf(_a0)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*drone.Repo)
}
}
var r1 error
if rf, ok := ret.Get(1).(func(*drone.Repo) error); ok {
r1 = rf(_a0)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
func (_m *Client) RepoDel(_a0 string, _a1 string) error {
ret := _m.Called(_a0, _a1)
var r0 error
if rf, ok := ret.Get(0).(func(string, string) error); ok {
r0 = rf(_a0, _a1)
} else {
r0 = ret.Error(0)
}
return r0
}
func (_m *Client) RepoKey(_a0 string, _a1 string) (*drone.Key, error) {
ret := _m.Called(_a0, _a1)
var r0 *drone.Key
if rf, ok := ret.Get(0).(func(string, string) *drone.Key); ok {
r0 = rf(_a0, _a1)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*drone.Key)
}
}
var r1 error
if rf, ok := ret.Get(1).(func(string, string) error); ok {
r1 = rf(_a0, _a1)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
func (_m *Client) Build(_a0 string, _a1 string, _a2 int) (*drone.Build, error) {
ret := _m.Called(_a0, _a1, _a2)
var r0 *drone.Build
if rf, ok := ret.Get(0).(func(string, string, int) *drone.Build); ok {
r0 = rf(_a0, _a1, _a2)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*drone.Build)
}
}
var r1 error
if rf, ok := ret.Get(1).(func(string, string, int) error); ok {
r1 = rf(_a0, _a1, _a2)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
func (_m *Client) BuildList(_a0 string, _a1 string) ([]*drone.Build, error) {
ret := _m.Called(_a0, _a1)
var r0 []*drone.Build
if rf, ok := ret.Get(0).(func(string, string) []*drone.Build); ok {
r0 = rf(_a0, _a1)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).([]*drone.Build)
}
}
var r1 error
if rf, ok := ret.Get(1).(func(string, string) error); ok {
r1 = rf(_a0, _a1)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
func (_m *Client) BuildStart(_a0 string, _a1 string, _a2 int) (*drone.Build, error) {
ret := _m.Called(_a0, _a1, _a2)
var r0 *drone.Build
if rf, ok := ret.Get(0).(func(string, string, int) *drone.Build); ok {
r0 = rf(_a0, _a1, _a2)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*drone.Build)
}
}
var r1 error
if rf, ok := ret.Get(1).(func(string, string, int) error); ok {
r1 = rf(_a0, _a1, _a2)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
func (_m *Client) BuildStop(_a0 string, _a1 string, _a2 int, _a3 int) error {
ret := _m.Called(_a0, _a1, _a2, _a3)
var r0 error
if rf, ok := ret.Get(0).(func(string, string, int, int) error); ok {
r0 = rf(_a0, _a1, _a2, _a3)
} else {
r0 = ret.Error(0)
}
return r0
}
func (_m *Client) BuildLogs(_a0 string, _a1 string, _a2 int, _a3 int) (io.ReadCloser, error) {
ret := _m.Called(_a0, _a1, _a2, _a3)
var r0 io.ReadCloser
if rf, ok := ret.Get(0).(func(string, string, int, int) io.ReadCloser); ok {
r0 = rf(_a0, _a1, _a2, _a3)
} else {
r0 = ret.Get(0).(io.ReadCloser)
}
var r1 error
if rf, ok := ret.Get(1).(func(string, string, int, int) error); ok {
r1 = rf(_a0, _a1, _a2, _a3)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
func (_m *Client) Node(_a0 int64) (*drone.Node, error) {
ret := _m.Called(_a0)
var r0 *drone.Node
if rf, ok := ret.Get(0).(func(int64) *drone.Node); ok {
r0 = rf(_a0)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*drone.Node)
}
}
var r1 error
if rf, ok := ret.Get(1).(func(int64) error); ok {
r1 = rf(_a0)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
func (_m *Client) NodeList() ([]*drone.Node, error) {
ret := _m.Called()
var r0 []*drone.Node
if rf, ok := ret.Get(0).(func() []*drone.Node); ok {
r0 = rf()
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).([]*drone.Node)
}
}
var r1 error
if rf, ok := ret.Get(1).(func() error); ok {
r1 = rf()
} else {
r1 = ret.Error(1)
}
return r0, r1
}
func (_m *Client) NodePost(_a0 *drone.Node) (*drone.Node, error) {
ret := _m.Called(_a0)
var r0 *drone.Node
if rf, ok := ret.Get(0).(func(*drone.Node) *drone.Node); ok {
r0 = rf(_a0)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*drone.Node)
}
}
var r1 error
if rf, ok := ret.Get(1).(func(*drone.Node) error); ok {
r1 = rf(_a0)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
func (_m *Client) NodeDel(_a0 int64) error {
ret := _m.Called(_a0)
var r0 error
if rf, ok := ret.Get(0).(func(int64) error); ok {
r0 = rf(_a0)
} else {
r0 = ret.Error(0)
}
return r0
}
+157
View File
@@ -0,0 +1,157 @@
package drone
// User represents a user account.
type User struct {
ID int64 `json:"id""`
Login string `json:"login"`
Email string `json:"email"`
Avatar string `json:"avatar_url"`
Active bool `json:"active"`
Admin bool `json:"admin"`
}
// Repo represents a version control repository.
type Repo struct {
ID int64 `json:"id"`
Owner string `json:"owner"`
Name string `json:"name"`
FullName string `json:"full_name"`
Avatar string `json:"avatar_url"`
Link string `json:"link_url"`
Clone string `json:"clone_url"`
Branch string `json:"default_branch"`
Timeout int64 `json:"timeout"`
IsPrivate bool `json:"private"`
IsTrusted bool `json:"trusted"`
AllowPull bool `json:"allow_pr"`
AllowPush bool `json:"allow_push"`
AllowDeploy bool `json:"allow_deploys"`
AllowTag bool `json:"allow_tags"`
}
// Build represents the process of compiling and testing a changeset,
// typically triggered by the remote system (ie GitHub).
type Build struct {
ID int64 `json:"id"`
Number int `json:"number"`
Event string `json:"event"`
Status string `json:"status"`
Enqueued int64 `json:"enqueued_at"`
Created int64 `json:"created_at"`
Started int64 `json:"started_at"`
Finished int64 `json:"finished_at"`
Commit string `json:"commit"`
Branch string `json:"branch"`
Ref string `json:"ref"`
Refspec string `json:"refspec"`
Remote string `json:"remote"`
Title string `json:"title"`
Message string `json:"message"`
Timestamp int64 `json:"timestamp"`
Author string `json:"author"`
Avatar string `json:"author_avatar"`
Email string `json:"author_email"`
Link string `json:"link_url"`
}
// Job represents a single job that is being executed as part
// of a Build.
type Job struct {
ID int64 `json:"id"`
Number int `json:"number"`
Status string `json:"status"`
ExitCode int `json:"exit_code"`
Enqueued int64 `json:"enqueued_at"`
Started int64 `json:"started_at"`
Finished int64 `json:"finished_at"`
Environment map[string]string `json:"environment"`
}
// Activity represents a build activity. It combines the
// build details with summary Repository information.
type Activity struct {
Owner string `json:"owner"`
Name string `json:"name"`
FullName string `json:"full_name"`
Number int `json:"number"`
Event string `json:"event"`
Status string `json:"status"`
Enqueued int64 `json:"enqueued_at"`
Created int64 `json:"created_at"`
Started int64 `json:"started_at"`
Finished int64 `json:"finished_at"`
Commit string `json:"commit"`
Branch string `json:"branch"`
Ref string `json:"ref"`
Refspec string `json:"refspec"`
Remote string `json:"remote"`
Title string `json:"title"`
Message string `json:"message"`
Timestamp int64 `json:"timestamp"`
Author string `json:"author"`
Avatar string `json:"author_avatar"`
Email string `json:"author_email"`
Link string `json:"link_url"`
}
// Repo represents a local or remote Docker daemon that is
// repsonsible for running jobs.
type Node struct {
ID int64 `json:"id"`
Addr string `json:"address"`
Arch string `json:"architecture"`
Cert string `json:"cert"`
Key string `json:"key"`
CA string `json:"ca"`
}
// Key represents an RSA public and private key assigned to a
// repository. It may be used to clone private repositories, or as
// a deployment key.
type Key struct {
Public string `json:"public"`
Private string `json:"private"`
}
// Netrc defines a default .netrc file that should be injected
// into the build environment. It will be used to authorize access
// to https resources, such as git+https clones.
type Netrc struct {
Machine string `json:"machine"`
Login string `json:"login"`
Password string `json:"user"`
}
type System struct {
Version string `json:"version"`
Link string `json:"link_url"`
Plugins []string `json:"plugins"`
Globals []string `json:"globals"`
}
// Workspace defines the build's workspace inside the
// container. This helps the plugin locate the source
// code directory.
type Workspace struct {
Root string `json:"root"`
Path string `json:"path"`
Netrc *Netrc `json:"netrc"`
Keys *Key `json:"keys"`
}
// Payload defines the full payload send to plugins.
type Payload struct {
Yaml string `json:"config"`
YamlEnc string `json:"secret"`
Repo *Repo `json:"repo"`
Build *Build `json:"build"`
BuildLast *Build `json:"build_last"`
Job *Job `json:"job"`
Netrc *Netrc `json:"netrc"`
Keys *Key `json:"keys"`
System *System `json:"system"`
Workspace *Workspace `json:"workspace"`
Vargs interface{} `json:"vargs"`
}
+114
View File
@@ -0,0 +1,114 @@
package drone
import (
"encoding/json"
"strconv"
)
// StringSlice representes a string or an array of strings.
type StringSlice struct {
parts []string
}
func (e *StringSlice) UnmarshalJSON(b []byte) error {
if len(b) == 0 {
return nil
}
p := make([]string, 0, 1)
if err := json.Unmarshal(b, &p); err != nil {
var s string
if err := json.Unmarshal(b, &s); err != nil {
return err
}
p = append(p, s)
}
e.parts = p
return nil
}
func (e *StringSlice) Len() int {
if e == nil {
return 0
}
return len(e.parts)
}
func (e *StringSlice) Slice() []string {
if e == nil {
return nil
}
return e.parts
}
// StringInt representes a string or an integer value.
type StringInt struct {
value string
}
func (e *StringInt) UnmarshalJSON(b []byte) error {
var num int
err := json.Unmarshal(b, &num)
if err == nil {
e.value = strconv.Itoa(num)
return nil
}
return json.Unmarshal(b, &e.value)
}
func (e StringInt) String() string {
return e.value
}
// StringMap representes a string or a map of strings.
// StringMap representes a string or a map of strings.
type StringMap struct {
parts map[string]string
}
func (e *StringMap) UnmarshalJSON(b []byte) error {
if len(b) == 0 {
return nil
}
p := map[string]string{}
if err := json.Unmarshal(b, &p); err != nil {
var s string
if err := json.Unmarshal(b, &s); err != nil {
return err
}
p[""] = s
}
e.parts = p
return nil
}
func (e *StringMap) Len() int {
if e == nil {
return 0
}
return len(e.parts)
}
func (e *StringMap) String() (str string) {
if e == nil {
return
}
for _, val := range e.parts {
return val // returns the first string value
}
return
}
func (e *StringMap) Map() map[string]string {
if e == nil {
return nil
}
return e.parts
}
func NewStringMap(parts map[string]string) StringMap {
return StringMap{parts}
}
+131
View File
@@ -0,0 +1,131 @@
package plugin
import (
"bytes"
"encoding/json"
"fmt"
"io"
"os"
)
var Stdin *ParamSet
func init() {
// defaults to stdin
Stdin = NewParamSet(os.Stdin)
// check for params after the double dash
// in the command string
for i, argv := range os.Args {
if argv == "--" {
arg := os.Args[i+1]
buf := bytes.NewBufferString(arg)
Stdin = NewParamSet(buf)
break
}
}
}
// this init function is deprecated, but I'm keeping it
// around just in case it proves useful in the future.
func deprecated_init() {
// if piping from stdin we can just exit
// and use the default Stdin value
stat, _ := os.Stdin.Stat()
if (stat.Mode() & os.ModeCharDevice) == 0 {
return
}
// check for params after the double dash
// in the command string
for i, argv := range os.Args {
if argv == "--" {
arg := os.Args[i+1]
buf := bytes.NewBufferString(arg)
Stdin = NewParamSet(buf)
return
}
}
// else use the first variable in the list
if len(os.Args) > 1 {
buf := bytes.NewBufferString(os.Args[1])
Stdin = NewParamSet(buf)
}
}
type ParamSet struct {
reader io.Reader
params map[string]interface{}
}
func NewParamSet(reader io.Reader) *ParamSet {
var p = new(ParamSet)
p.reader = reader
p.params = map[string]interface{}{}
return p
}
// Param defines a parameter with the specified name.
func (p ParamSet) Param(name string, value interface{}) {
p.params[name] = value
}
// Parse parses parameter definitions from the map.
func (p ParamSet) Parse() error {
raw := map[string]json.RawMessage{}
err := json.NewDecoder(p.reader).Decode(&raw)
if err != nil {
return err
}
for key, val := range p.params {
data, ok := raw[key]
if !ok {
continue
}
err := json.Unmarshal(data, val)
if err != nil {
return fmt.Errorf("Unable to unarmshal %s. %s", key, err)
}
}
return nil
}
// Unmarshal parses the JSON payload from the command
// arguments and unmarshal into a value pointed to by v.
func (p ParamSet) Unmarshal(v interface{}) error {
return json.NewDecoder(p.reader).Decode(v)
}
// Param defines a parameter with the specified name.
func Param(name string, value interface{}) {
Stdin.Param(name, value)
}
// Parse parses parameter definitions from the map.
func Parse() error {
return Stdin.Parse()
}
// Unmarshal parses the JSON payload from the command
// arguments and unmarshal into a value pointed to by v.
func Unmarshal(v interface{}) error {
return Stdin.Unmarshal(v)
}
// Unmarshal parses the JSON payload from the command
// arguments and unmarshal into a value pointed to by v.
func MustUnmarshal(v interface{}) error {
return Stdin.Unmarshal(v)
}
// MustParse parses parameter definitions from the map
// and panics if there is a parsing error.
func MustParse() {
err := Parse()
if err != nil {
panic(err)
}
}
+1
View File
@@ -0,0 +1 @@
package plugin
+124
View File
@@ -0,0 +1,124 @@
package template
import (
"encoding/json"
"fmt"
"io"
"strings"
"time"
"unicode"
"github.com/aymerick/raymond"
"github.com/drone/drone-go/drone"
)
func init() {
raymond.RegisterHelpers(funcs)
}
// Render parses and executes a template, returning the results
// in string format.
func Render(template string, playload *drone.Payload) (string, error) {
return raymond.Render(template, normalize(playload))
}
// 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 *drone.Payload) (string, error) {
out, err := Render(template, playload)
return strings.Trim(out, " \n"), err
}
// Write parses and executes a template, writing the results to
// writer w.
func Write(w io.Writer, template string, playload *drone.Payload) error {
out, err := Render(template, playload)
if err != nil {
return err
}
_, err = io.WriteString(w, out)
return err
}
var funcs = map[string]interface{}{
"uppercase": strings.ToUpper,
"lowercase": strings.ToLower,
"uppercasefirst": uppercaseFirst,
"duration": toDuration,
"datetime": toDatetime,
"success": isSuccess,
"failure": isFailure,
}
// uppercaseFirst is a helper function that takes a string and capitalizes
// the first letter.
func uppercaseFirst(s string) string {
a := []rune(s)
a[0] = unicode.ToUpper(a[0])
s = string(a)
return s
}
// toDuration is a helper function that calculates a duration for a start and
// and end time, and returns the duration in string format.
func toDuration(started, finished float64) string {
dur := time.Duration(int64(finished - started))
return fmt.Sprintln(dur)
}
// toDatetime is a helper function that converts a unix timestamp to a string.
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 {
fmt.Printf("Error parsing timezone, defaulting to local timezone. %s\n", err)
return time.Unix(int64(timestamp), 0).Local().Format(layout)
}
return time.Unix(int64(timestamp), 0).In(loc).Format(layout)
}
// isSuccess is a helper function that executes a block iff the status
// is success, else it executes the else block.
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()
}
}
// isFailure is a helper function that executes a block iff the status
// is a form of failure, else it executes the else block.
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()
}
}
// normalize takes a Go representation of the variable, marshals
// to json and then unmarshals to a map[string]interfacce{}. This
// is important because it let's us use the JSON variable names
// in our template
func normalize(in interface{}) map[string]interface{} {
data, _ := json.Marshal(in) // we own the types, so this should never fail
out := map[string]interface{}{}
json.Unmarshal(data, &out)
return out
}
+92
View File
@@ -0,0 +1,92 @@
package template
import (
"testing"
"github.com/drone/drone-go/drone"
)
var tests = []struct {
Payload *drone.Payload
Input string
Output string
}{
{
&drone.Payload{Build: &drone.Build{Number: 1}},
"build #{{build.number}}",
"build #1",
},
{
&drone.Payload{Build: &drone.Build{Status: drone.StatusSuccess}},
"{{uppercase build.status}}",
"SUCCESS",
},
{
&drone.Payload{Build: &drone.Build{Author: "Octocat"}},
"{{lowercase build.author}}",
"octocat",
},
{
&drone.Payload{Build: &drone.Build{Status: drone.StatusSuccess}},
"{{uppercasefirst build.status}}",
"Success",
},
{
&drone.Payload{Build: &drone.Build{
Started: 1448127131,
Finished: 1448127505},
},
"{{ duration build.started_at build.finished_at }}",
"374ns",
},
{
&drone.Payload{Build: &drone.Build{Finished: 1448127505}},
`finished at {{ datetime build.finished_at "3:04PM" "UTC" }}`,
"finished at 5:38PM",
},
// verify the success if / else block works
{
&drone.Payload{Build: &drone.Build{Status: drone.StatusSuccess}},
"{{#success build.status}}SUCCESS{{/success}}",
"SUCCESS",
},
{
&drone.Payload{Build: &drone.Build{Status: drone.StatusFailure}},
"{{#success build.status}}SUCCESS{{/success}}",
"",
},
{
&drone.Payload{Build: &drone.Build{Status: drone.StatusFailure}},
"{{#success build.status}}SUCCESS{{else}}NOT SUCCESS{{/success}}",
"NOT SUCCESS",
},
// verify the failure if / else block works
{
&drone.Payload{Build: &drone.Build{Status: drone.StatusFailure}},
"{{#failure build.status}}FAILURE{{/failure}}",
"FAILURE",
},
{
&drone.Payload{Build: &drone.Build{Status: drone.StatusSuccess}},
"{{#failure build.status}}FAILURE{{/failure}}",
"",
},
{
&drone.Payload{Build: &drone.Build{Status: drone.StatusSuccess}},
"{{#failure build.status}}FAILURE{{else}}NOT FAILURE{{/failure}}",
"NOT FAILURE",
},
}
func TestTemplate(t *testing.T) {
for _, test := range tests {
got, err := RenderTrim(test.Input, test.Payload)
if err != nil {
t.Errorf("Failed rendering template %q, got error %s.", test.Input, err)
}
if got != test.Output {
t.Errorf("Wanted rendered template %q, got %q", test.Output, got)
}
}
}