Vendoring gitlab client

This commit is contained in:
Kirill Zaitsev 2015-07-27 02:25:20 +03:00
parent da597626dd
commit 4f0267e47e
50 changed files with 2680 additions and 4 deletions

6
Godeps/Godeps.json generated
View file

@ -2,7 +2,7 @@
"ImportPath": "github.com/drone/drone",
"GoVersion": "go1.4.2",
"Packages": [
"github.com/drone/drone/..."
"github.com/drone/drone..."
],
"Deps": [
{
@ -10,6 +10,10 @@
"Comment": "null-236",
"Rev": "69e2a90ed92d03812364aeb947b7068dc42e561e"
},
{
"ImportPath": "github.com/Bugagazavr/go-gitlab-client",
"Rev": "912567bb7e65212c910733b3bfa178b11049a70e"
},
{
"ImportPath": "github.com/BurntSushi/migration",
"Rev": "c45b897f13350786ccaf2b7403b92b1c7ad85844"

View file

@ -0,0 +1,3 @@
.DS_Store
.idea
examples/config.json

View file

@ -0,0 +1,6 @@
language: go
go:
- 1.4
script:
- make deps test

View file

@ -0,0 +1,8 @@
all:deps test
deps:
go get github.com/stretchr/testify
go get ./...
test:
go test -cover -short ./...

View file

@ -0,0 +1,78 @@
go-gitlab-client
================
This is a fork of project https://github.com/plouc/go-gitlab-client
go-gitlab-client is a simple client written in golang to consume gitlab API.
[![Build Status](https://travis-ci.org/Bugagazavr/go-gitlab-client.svg?branch=master)](https://travis-ci.org/Bugagazavr/go-gitlab-client)
##features
*
###Session [gitlab api doc](http://doc.gitlab.com/ce/api/session.html)
* get session
*
###Projects [gitlab api doc](http://doc.gitlab.com/ce/api/projects.html)
* list projects
* get single project
*
###Repositories [gitlab api doc](http://doc.gitlab.com/ce/api/repositories.html)
* list repository branches
* get single repository branch
* list project repository tags
* list repository commits
* list project hooks
* add/get/edit/rm project hook
*
###Users [gitlab api doc](http://doc.gitlab.com/ce/api/users.html)
* get single user
* manage user keys
*
###Deploy Keys [gitlab api doc](http://doc.gitlab.com/ce/api/deploy_keys.html)
* list project deploy keys
* add/get/rm project deploy key
##Installation
To install go-gitlab-client, use `go get`:
go get github.com/bugagazavr/go-gitlab-client
Import the `go-gitlab-client` package into your code:
```go
package whatever
import (
"github.com/bugagazavr/go-gitlab-client"
)
```
##Update
To update `go-gitlab-client`, use `go get -u`:
go get -u github.com/bugagazavr/go-gitlab-client
##Documentation
Visit the docs at http://godoc.org/github.com/Bugagazavr/go-gitlab-client
## Examples
You can play with the examples located in the `examples` directory
* [projects](https://github.com/Bugagazavr/go-gitlab-client/tree/master/examples/projects)
* [repositories](https://github.com/Bugagazavr/go-gitlab-client/tree/master/examples/repositories)

View file

@ -0,0 +1,118 @@
package gogitlab
import (
"encoding/json"
"net/url"
)
const (
// ID
project_url_deploy_keys = "/projects/:id/keys" // Get list of project deploy keys
// PROJECT ID AND KEY ID
project_url_deploy_key = "/projects/:id/keys/:key_id" // Get single project deploy key
)
/*
Get list of project deploy keys.
GET /projects/:id/keys
Parameters:
id The ID of a project
*/
func (g *Gitlab) ProjectDeployKeys(id string) ([]*PublicKey, error) {
url, opaque := g.ResourceUrlRaw(project_url_deploy_keys, map[string]string{":id": id})
var deployKeys []*PublicKey
contents, err := g.buildAndExecRequestRaw("GET", url, opaque, nil)
if err == nil {
err = json.Unmarshal(contents, &deployKeys)
}
return deployKeys, err
}
/*
Get single project deploy key.
GET /projects/:id/keys/:key_id
Parameters:
id The ID of a project
key_id The ID of a key
*/
func (g *Gitlab) ProjectDeployKey(id, key_id string) (*PublicKey, error) {
url, opaque := g.ResourceUrlRaw(project_url_deploy_key, map[string]string{
":id": id,
":key_id": key_id,
})
var deployKey *PublicKey
contents, err := g.buildAndExecRequestRaw("GET", url, opaque, nil)
if err == nil {
err = json.Unmarshal(contents, &deployKey)
}
return deployKey, err
}
/*
Add deploy key to project.
POST /projects/:id/keys
Parameters:
id The ID of a project
title The key title
key The key value
*/
func (g *Gitlab) AddProjectDeployKey(id, title, key string) error {
var err error
path, opaque := g.ResourceUrlRaw(project_url_deploy_keys, map[string]string{":id": id})
v := url.Values{}
v.Set("title", title)
v.Set("key", key)
body := v.Encode()
_, err = g.buildAndExecRequestRaw("POST", path, opaque, []byte(body))
return err
}
/*
Remove deploy key from project
DELETE /projects/:id/keys/:key_id
Parameters:
id The ID of a project
key_id The ID of a key
*/
func (g *Gitlab) RemoveProjectDeployKey(id, key_id string) error {
url, opaque := g.ResourceUrlRaw(project_url_deploy_key, map[string]string{
":id": id,
":key_id": key_id,
})
var err error
_, err = g.buildAndExecRequestRaw("DELETE", url, opaque, nil)
return err
}

View file

@ -0,0 +1,72 @@
package gogitlab
import (
"encoding/xml"
"fmt"
"time"
)
type Person struct {
Name string `xml:"name"json:"name"`
Email string `xml:"email"json:"email"`
}
type Link struct {
Rel string `xml:"rel,attr,omitempty"json:"rel"`
Href string `xml:"href,attr"json:"href"`
}
type ActivityFeed struct {
Title string `xml:"title"json:"title"`
Id string `xml:"id"json:"id"`
Link []Link `xml:"link"json:"link"`
Updated time.Time `xml:"updated,attr"json:"updated"`
Entries []*FeedCommit `xml:"entry"json:"entries"`
}
type FeedCommit struct {
Id string `xml:"id"json:"id"`
Title string `xml:"title"json:"title"`
Link []Link `xml:"link"json:"link"`
Updated time.Time `xml:"updated"json:"updated"`
Author Person `xml:"author"json:"author"`
Summary string `xml:"summary"json:"summary"`
//<media:thumbnail width="40" height="40" url="https://secure.gravatar.com/avatar/7070eab7c6206530d3b7820362227fec?s=40&amp;d=mm"/>
}
func (g *Gitlab) Activity() (ActivityFeed, error) {
url := g.BaseUrl + dasboard_feed_path + "?private_token=" + g.Token
fmt.Println(url)
contents, err := g.buildAndExecRequest("GET", url, nil)
if err != nil {
fmt.Println("%s", err)
}
var activity ActivityFeed
err = xml.Unmarshal(contents, &activity)
if err != nil {
fmt.Println("%s", err)
}
return activity, err
}
func (g *Gitlab) RepoActivityFeed(feedPath string) ActivityFeed {
url := g.BaseUrl + g.RepoFeedPath + "?private_token=" + g.Token
contents, err := g.buildAndExecRequest("GET", url, nil)
if err != nil {
fmt.Println("%s", err)
}
var activity ActivityFeed
err = xml.Unmarshal(contents, &activity)
if err != nil {
fmt.Println("%s", err)
}
return activity
}

View file

@ -0,0 +1,5 @@
{
"host": "https://gitlab.domain.com",
"api_path": "/api/v3",
"token": "TOKEN"
}

View file

@ -0,0 +1,195 @@
package main
import (
"encoding/json"
"flag"
"fmt"
"github.com/bugagazavr/go-gitlab-client"
"io/ioutil"
"os"
"strconv"
"time"
)
type Config struct {
Host string `json:"host"`
ApiPath string `json:"api_path"`
Token string `json:"token"`
}
func main() {
help := flag.Bool("help", false, "Show usage")
file, e := ioutil.ReadFile("../config.json")
if e != nil {
fmt.Printf("Config file error: %v\n", e)
os.Exit(1)
}
var config Config
json.Unmarshal(file, &config)
fmt.Printf("Results: %+v\n", config)
var gitlab *gogitlab.Gitlab
gitlab = gogitlab.NewGitlab(config.Host, config.ApiPath, config.Token)
var method string
flag.StringVar(&method, "m", "", "Specify method to retrieve projects infos, available methods:\n"+
" > -m projects\n"+
" > -m project -id PROJECT_ID\n"+
" > -m hooks -id PROJECT_ID\n"+
" > -m branches -id PROJECT_ID\n"+
" > -m merge_requests -id PROJECT_ID\n"+
" > -m team -id PROJECT_ID")
var id string
flag.StringVar(&id, "id", "", "Specify repository id")
flag.Usage = func() {
fmt.Printf("Usage:\n")
flag.PrintDefaults()
}
flag.Parse()
if *help == true || method == "" {
flag.Usage()
return
}
startedAt := time.Now()
defer func() {
fmt.Printf("processed in %v\n", time.Now().Sub(startedAt))
}()
switch method {
case "projects":
fmt.Println("Fetching projects…")
projects, err := gitlab.Projects(1, 100)
if err != nil {
fmt.Println(err.Error())
return
}
for _, project := range projects {
fmt.Printf("> %6d | %s\n", project.Id, project.Name)
}
case "project":
fmt.Println("Fetching project…")
if id == "" {
flag.Usage()
return
}
project, err := gitlab.Project(id)
if err != nil {
fmt.Println(err.Error())
return
}
format := "> %-23s: %s\n"
fmt.Printf("%s\n", project.Name)
fmt.Printf(format, "id", strconv.Itoa(project.Id))
fmt.Printf(format, "name", project.Name)
fmt.Printf(format, "description", project.Description)
fmt.Printf(format, "default branch", project.DefaultBranch)
if project.Owner != nil {
fmt.Printf(format, "owner.name", project.Owner.Username)
}
fmt.Printf(format, "public", strconv.FormatBool(project.Public))
fmt.Printf(format, "path", project.Path)
fmt.Printf(format, "path with namespace", project.PathWithNamespace)
fmt.Printf(format, "issues enabled", strconv.FormatBool(project.IssuesEnabled))
fmt.Printf(format, "merge requests enabled", strconv.FormatBool(project.MergeRequestsEnabled))
fmt.Printf(format, "wall enabled", strconv.FormatBool(project.WallEnabled))
fmt.Printf(format, "wiki enabled", strconv.FormatBool(project.WikiEnabled))
fmt.Printf(format, "created at", project.CreatedAtRaw)
//fmt.Printf(format, "namespace", project.Namespace)
case "branches":
fmt.Println("Fetching project branches…")
if id == "" {
flag.Usage()
return
}
branches, err := gitlab.ProjectBranches(id)
if err != nil {
fmt.Println(err.Error())
return
}
for _, branch := range branches {
fmt.Printf("> %s\n", branch.Name)
}
case "merge_requests":
fmt.Println("Fetching project merge_requests…")
if id == "" {
flag.Usage()
return
}
mrs, err := gitlab.ProjectMergeRequests(id, 0, 30, "opened")
if err != nil {
fmt.Println(err.Error())
return
}
for _, mr := range mrs {
author := ""
if mr.Author != nil {
author = mr.Author.Username
}
assignee := ""
if mr.Assignee != nil {
assignee = mr.Assignee.Username
}
fmt.Printf(" %s -> %s [%s] author[%s] assignee[%s]\n",
mr.SourceBranch, mr.TargetBranch, mr.State,
author, assignee)
}
case "hooks":
fmt.Println("Fetching project hooks…")
if id == "" {
flag.Usage()
return
}
hooks, err := gitlab.ProjectHooks(id)
if err != nil {
fmt.Println(err.Error())
return
}
for _, hook := range hooks {
fmt.Printf("> [%d] %s, created on %s\n", hook.Id, hook.Url, hook.CreatedAtRaw)
}
case "team":
fmt.Println("Fetching project team members…")
if id == "" {
flag.Usage()
return
}
members, err := gitlab.ProjectMembers(id)
if err != nil {
fmt.Println(err.Error())
return
}
for _, member := range members {
fmt.Printf("> [%d] %s (%s) since %s\n", member.Id, member.Username, member.Name, member.CreatedAt)
}
}
}

View file

@ -0,0 +1,96 @@
package main
import (
"encoding/json"
"flag"
"fmt"
"github.com/bugagazavr/go-gitlab-client"
"io/ioutil"
"os"
"time"
)
type Config struct {
Host string `json:"host"`
ApiPath string `json:"api_path"`
Token string `json:"token"`
}
func main() {
help := flag.Bool("help", false, "Show usage")
file, e := ioutil.ReadFile("../config.json")
if e != nil {
fmt.Printf("Config file error: %v\n", e)
os.Exit(1)
}
var config Config
json.Unmarshal(file, &config)
fmt.Printf("Results: %+v\n", config)
gitlab := gogitlab.NewGitlab(config.Host, config.ApiPath, config.Token)
var method string
flag.StringVar(&method, "m", "", "Specify method to retrieve repositories, available methods:\n"+
" > branches\n"+
" > branch\n"+
" > tags\n"+
" > commits")
var id string
flag.StringVar(&id, "id", "", "Specify repository id")
flag.Usage = func() {
fmt.Printf("Usage:\n")
flag.PrintDefaults()
}
flag.Parse()
if *help == true || method == "" || id == "" {
flag.Usage()
return
}
startedAt := time.Now()
defer func() {
fmt.Printf("processed in %v\n", time.Now().Sub(startedAt))
}()
switch method {
case "branches":
fmt.Println("Fetching repository branches…")
branches, err := gitlab.RepoBranches(id)
if err != nil {
fmt.Println(err.Error())
}
for _, branch := range branches {
fmt.Printf("> %s\n", branch.Name)
}
case "branch":
case "tags":
fmt.Println("Fetching repository tags…")
tags, err := gitlab.RepoTags(id)
if err != nil {
fmt.Println(err.Error())
}
for _, tag := range tags {
fmt.Printf("> %s\n", tag.Name)
}
case "commits":
fmt.Println("Fetching repository commits…")
commits, err := gitlab.RepoCommits(id)
if err != nil {
fmt.Println(err.Error())
}
for _, commit := range commits {
fmt.Printf("%s > [%s] %s\n", commit.CreatedAt.Format("Mon 02 Jan 15:04"), commit.Author_Name, commit.Title)
}
}
}

View file

@ -0,0 +1,191 @@
// Package github implements a simple client to consume gitlab API.
package gogitlab
import (
"bytes"
"crypto/tls"
"flag"
"fmt"
"io/ioutil"
"net/http"
"net/url"
"strings"
)
const (
dasboard_feed_path = "/dashboard.atom"
)
type Gitlab struct {
BaseUrl string
ApiPath string
RepoFeedPath string
Token string
Bearer bool
Client *http.Client
}
const (
dateLayout = "2006-01-02T15:04:05-07:00"
)
var (
skipCertVerify = flag.Bool("gitlab.skip-cert-check", false,
`If set to true, gitlab client will skip certificate checking for https, possibly exposing your system to MITM attack.`)
)
func NewGitlab(baseUrl, apiPath, token string) *Gitlab {
return NewGitlabCert(baseUrl, apiPath, token, *skipCertVerify)
}
func NewGitlabCert(baseUrl, apiPath, token string, skipVerify bool) *Gitlab {
config := &tls.Config{InsecureSkipVerify: skipVerify}
tr := &http.Transport{
Proxy: http.ProxyFromEnvironment,
TLSClientConfig: config,
}
client := &http.Client{Transport: tr}
return &Gitlab{
BaseUrl: baseUrl,
ApiPath: apiPath,
Token: token,
Client: client,
}
}
func (g *Gitlab) ResourceUrl(url string, params map[string]string) string {
if params != nil {
for key, val := range params {
url = strings.Replace(url, key, encodeParameter(val), -1)
}
}
url = g.BaseUrl + g.ApiPath + url
if !g.Bearer {
url = url + "?private_token=" + g.Token
}
return url
}
func (g *Gitlab) buildAndExecRequest(method, url string, body []byte) ([]byte, error) {
var req *http.Request
var err error
if body != nil {
reader := bytes.NewReader(body)
req, err = http.NewRequest(method, url, reader)
} else {
req, err = http.NewRequest(method, url, nil)
}
if err != nil {
panic("Error while building gitlab request")
}
if g.Bearer {
req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", g.Token))
}
resp, err := g.Client.Do(req)
if err != nil {
return nil, fmt.Errorf("Client.Do error: %q", err)
}
defer resp.Body.Close()
contents, err := ioutil.ReadAll(resp.Body)
if err != nil {
fmt.Printf("%s", err)
}
if resp.StatusCode >= 400 {
err = fmt.Errorf("*Gitlab.buildAndExecRequest failed: <%d> %s", resp.StatusCode, req.URL)
}
return contents, err
}
func (g *Gitlab) ResourceUrlQuery(u string, params, query map[string]string) string {
if params != nil {
for key, val := range params {
u = strings.Replace(u, key, encodeParameter(val), -1)
}
}
query_params := url.Values{}
if !g.Bearer {
query_params.Add("private_token", g.Token)
}
if query != nil {
for key, val := range query {
query_params.Set(key, val)
}
}
u = g.BaseUrl + g.ApiPath + u + "?" + query_params.Encode()
return u
}
func (g *Gitlab) ResourceUrlRaw(u string, params map[string]string) (string, string) {
if params != nil {
for key, val := range params {
u = strings.Replace(u, key, encodeParameter(val), -1)
}
}
path := u
u = g.BaseUrl + g.ApiPath + path
if !g.Bearer {
u = u + "?private_token=" + g.Token
}
p, err := url.Parse(u)
if err != nil {
return u, ""
}
opaque := "//" + p.Host + p.Path
return u, opaque
}
func (g *Gitlab) buildAndExecRequestRaw(method, url, opaque string, body []byte) ([]byte, error) {
var req *http.Request
var err error
if body != nil {
reader := bytes.NewReader(body)
req, err = http.NewRequest(method, url, reader)
} else {
req, err = http.NewRequest(method, url, nil)
}
if err != nil {
panic("Error while building gitlab request")
}
if g.Bearer {
req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", g.Token))
}
if len(opaque) > 0 {
req.URL.Opaque = opaque
}
resp, err := g.Client.Do(req)
if err != nil {
return nil, fmt.Errorf("Client.Do error: %q", err)
}
defer resp.Body.Close()
contents, err := ioutil.ReadAll(resp.Body)
if err != nil {
fmt.Printf("%s", err)
}
if resp.StatusCode >= 400 {
err = fmt.Errorf("*Gitlab.buildAndExecRequestRaw failed: <%d> %s", resp.StatusCode, req.URL)
}
return contents, err
}

View file

@ -0,0 +1,13 @@
package gogitlab
import (
"github.com/stretchr/testify/assert"
"testing"
)
func TestResourceUrl(t *testing.T) {
gitlab := NewGitlab("http://base_url/", "api_path", "token")
assert.Equal(t, gitlab.ResourceUrl(projects_url, nil), "http://base_url/api_path/projects?private_token=token")
assert.Equal(t, gitlab.ResourceUrl(project_url, map[string]string{":id": "123"}), "http://base_url/api_path/projects/123?private_token=token")
}

View file

@ -0,0 +1,16 @@
package gogitlab
import (
"io/ioutil"
"net/http"
"net/http/httptest"
)
func Stub(filename string) (*httptest.Server, *Gitlab) {
stub, _ := ioutil.ReadFile(filename)
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Write([]byte(stub))
}))
gitlab := NewGitlab(ts.URL, "", "")
return ts, gitlab
}

View file

@ -0,0 +1,154 @@
package gogitlab
import (
"encoding/json"
"fmt"
"strings"
)
type HookObjAttr struct {
Id int `json:"id,omitempty"`
Title string `json:"title,omitempty"`
AssigneeId int `json:"assignee_id,omitempty"`
AuthorId int `json:"author_id,omitempty"`
ProjectId int `json:"project_id,omitempty"`
CreatedAt string `json:"created_at,omitempty"`
UpdatedAt string `json:"updated_at,omitempty"`
Position int `json:"position,omitempty"`
BranchName string `json:"branch_name,omitempty"`
Description string `json:"description,omitempty"`
MilestoneId int `json:"milestone_id,omitempty"`
State string `json:"state,omitempty"`
IId int `json:"iid,omitempty"`
TargetBranch string `json:"target_branch,omitempty"`
SourceBranch string `json:"source_branch,omitempty"`
SourceProjectId int `json:"source_project_id,omitempty"`
StCommits string `json:"st_commits,omitempty"`
StDiffs string `json:"st_diffs,omitempty"`
MergeStatus string `json:"merge_status,omitempty"`
TargetProjectId int `json:"target_project_id,omitempty"`
Source *hProject `json:"source,omitempty"`
Target *hProject `json:"target,omitempty"`
LastCommit *hCommit `json:"last_commit,omitempty"`
}
type hProject struct {
Name string `json:"name"`
SshUrl string `json:"ssh_url"`
HttpUrl string `json:"http_url"`
VisibilityLevel int `json:"visibility_level"`
Namespace string `json:"namespace"`
}
type hRepository struct {
Name string `json:"name,omitempty"`
URL string `json:"url,omitempty"`
Description string `json:"description,omitempty"`
Homepage string `json:"homepage,omitempty"`
GitHttpUrl string `json:"git_http_url,omitempty"`
GitSshUrl string `json:"git_ssh_url,omitempty"`
VisibilityLevel int `json:"visibility_level,omitempty"`
}
type hCommit struct {
Id string `json:"id,omitempty"`
Message string `json:"message,omitempty"`
Timestamp string `json:"timestamp,omitempty"`
URL string `json:"url,omitempty"`
Author *Person `json:"author,omitempty"`
}
type HookPayload struct {
Before string `json:"before,omitempty"`
After string `json:"after,omitempty"`
Ref string `json:"ref,omitempty"`
UserId int `json:"user_id,omitempty"`
UserName string `json:"user_name,omitempty"`
ProjectId int `json:"project_id,omitempty"`
Repository *hRepository `json:"repository,omitempty"`
Commits []hCommit `json:"commits,omitempty"`
TotalCommitsCount int `json:"total_commits_count,omitempty"`
ObjectKind string `json:"object_kind,omitempty"`
ObjectAttributes *HookObjAttr `json:"object_attributes,omitempty"`
}
// ParseHook parses hook payload from GitLab
func ParseHook(payload []byte) (*HookPayload, error) {
hp := HookPayload{}
if err := json.Unmarshal(payload, &hp); err != nil {
return nil, err
}
// Basic sanity check
switch {
case len(hp.ObjectKind) == 0:
// Assume this is a post-receive within repository
if len(hp.After) == 0 {
return nil, fmt.Errorf("Invalid hook received, commit hash not found.")
}
case hp.ObjectKind == "push":
if hp.Repository == nil {
return nil, fmt.Errorf("Invalid push hook received, attributes not found")
}
case hp.ObjectKind == "tag_push":
if hp.Repository == nil {
return nil, fmt.Errorf("Invalid tag push hook received, attributes not found")
}
case hp.ObjectKind == "issue":
fallthrough
case hp.ObjectKind == "merge_request":
if hp.ObjectAttributes == nil {
return nil, fmt.Errorf("Invalid hook received, attributes not found.")
}
default:
return nil, fmt.Errorf("Invalid hook received, payload format not recognized.")
}
return &hp, nil
}
// Type return current event type
// This function returns "unknown" type if event not supported
func (h *HookPayload) Type() string {
switch {
case strings.HasPrefix(h.Ref, "refs/heads/") && len(h.After) == 0:
return "branch_deleted"
case strings.HasPrefix(h.Ref, "refs/heads/") && len(h.Before) == 0:
return "branch"
case strings.HasPrefix(h.Ref, "refs/heads/"):
return "commit"
case strings.HasPrefix(h.Ref, "refs/tags/") && len(h.After) == 0:
return "tag_deleted"
case strings.HasPrefix(h.Ref, "refs/tags/"):
return "tag"
case h.ObjectKind == "issue":
return "issue"
case h.ObjectKind == "merge_request":
return "merge_request"
default:
return "unknown"
}
}
// Tag returns current tag for push event hook payload
// This function returns empty string for any other events
func (h *HookPayload) Tag() string {
return strings.TrimPrefix(h.Ref, "refs/tags/")
}
// Branch returns current branch for push event hook payload
// This function returns empty string for any other events
func (h *HookPayload) Branch() string {
return strings.TrimPrefix(h.Ref, "refs/heads/")
}
// Head returns the latest changeset for push event hook payload
func (h *HookPayload) Head() hCommit {
c := hCommit{}
for _, cm := range h.Commits {
if h.After == cm.Id {
return cm
}
}
return c
}

View file

@ -0,0 +1,45 @@
package gogitlab
import (
"github.com/stretchr/testify/assert"
"io/ioutil"
"testing"
)
func TestParsePushHook(t *testing.T) {
stub, _ := ioutil.ReadFile("stubs/hook_payloads/push.json")
p, err := ParseHook([]byte(stub))
assert.Equal(t, err, nil)
assert.Equal(t, p.ObjectKind, "push")
assert.IsType(t, new(HookPayload), p)
assert.Equal(t, p.After, "da1560886d4f094c3e6c9ef40349f7d38b5d27d7")
assert.Equal(t, p.Repository.URL, "git@example.com:mike/diasporadiaspora.git")
assert.Equal(t, p.Repository.GitHttpUrl, "http://example.com/mike/diaspora.git")
assert.Equal(t, p.Repository.GitSshUrl, "git@example.com:mike/diaspora.git")
assert.Equal(t, p.Repository.VisibilityLevel, 0)
assert.Equal(t, len(p.Commits), 2)
assert.Equal(t, p.Commits[0].Author.Email, "jordi@softcatala.org")
assert.Equal(t, p.Commits[1].Id, "da1560886d4f094c3e6c9ef40349f7d38b5d27d7")
assert.Equal(t, p.Branch(), "master")
assert.Equal(t, p.Head().Message, "fixed readme")
}
func TestParseIssueHook(t *testing.T) {
stub, _ := ioutil.ReadFile("stubs/hook_payloads/issue.json")
p, err := ParseHook([]byte(stub))
assert.Equal(t, err, nil)
assert.Equal(t, p.ObjectKind, "issue")
assert.Equal(t, p.ObjectAttributes.Id, 301)
}
func TestParseMergeRequestHook(t *testing.T) {
stub, _ := ioutil.ReadFile("stubs/hook_payloads/merge_request.json")
p, err := ParseHook([]byte(stub))
assert.Equal(t, err, nil)
assert.Equal(t, p.ObjectKind, "merge_request")
assert.Equal(t, p.ObjectAttributes.TargetBranch, "master")
assert.Equal(t, p.ObjectAttributes.SourceProjectId, p.ObjectAttributes.TargetProjectId)
}

View file

@ -0,0 +1,183 @@
package gogitlab
import (
"encoding/json"
"net/url"
)
const (
project_url_hooks = "/projects/:id/hooks" // Get list of project hooks
project_url_hook = "/projects/:id/hooks/:hook_id" // Get single project hook
)
type Hook struct {
Id int `json:"id,omitempty"`
Url string `json:"url,omitempty"`
CreatedAtRaw string `json:"created_at,omitempty"`
}
/*
Get list of project hooks.
GET /projects/:id/hooks
Parameters:
id The ID of a project
*/
func (g *Gitlab) ProjectHooks(id string) ([]*Hook, error) {
url, opaque := g.ResourceUrlRaw(project_url_hooks, map[string]string{":id": id})
var err error
var hooks []*Hook
contents, err := g.buildAndExecRequestRaw("GET", url, opaque, nil)
if err != nil {
return hooks, err
}
err = json.Unmarshal(contents, &hooks)
return hooks, err
}
/*
Get single project hook.
GET /projects/:id/hooks/:hook_id
Parameters:
id The ID of a project
hook_id The ID of a hook
*/
func (g *Gitlab) ProjectHook(id, hook_id string) (*Hook, error) {
url, opaque := g.ResourceUrlRaw(project_url_hook, map[string]string{
":id": id,
":hook_id": hook_id,
})
var err error
hook := new(Hook)
contents, err := g.buildAndExecRequestRaw("GET", url, opaque, nil)
if err != nil {
return hook, err
}
err = json.Unmarshal(contents, &hook)
return hook, err
}
/*
Add new project hook.
POST /projects/:id/hooks
Parameters:
id The ID or NAMESPACE/PROJECT_NAME of a project
hook_url The hook URL
push_events Trigger hook on push events
issues_events Trigger hook on issues events
merge_requests_events Trigger hook on merge_requests events
*/
func (g *Gitlab) AddProjectHook(id, hook_url string, push_events, issues_events, merge_requests_events bool) error {
url, opaque := g.ResourceUrlRaw(project_url_hooks, map[string]string{":id": id})
var err error
body := buildHookQuery(hook_url, push_events, issues_events, merge_requests_events)
_, err = g.buildAndExecRequestRaw("POST", url, opaque, []byte(body))
return err
}
/*
Edit existing project hook.
PUT /projects/:id/hooks/:hook_id
Parameters:
id The ID or NAMESPACE/PROJECT_NAME of a project
hook_id The ID of a project hook
hook_url The hook URL
push_events Trigger hook on push events
issues_events Trigger hook on issues events
merge_requests_events Trigger hook on merge_requests events
*/
func (g *Gitlab) EditProjectHook(id, hook_id, hook_url string, push_events, issues_events, merge_requests_events bool) error {
url, opaque := g.ResourceUrlRaw(project_url_hook, map[string]string{
":id": id,
":hook_id": hook_id,
})
var err error
body := buildHookQuery(hook_url, push_events, issues_events, merge_requests_events)
_, err = g.buildAndExecRequestRaw("PUT", url, opaque, []byte(body))
return err
}
/*
Remove hook from project.
DELETE /projects/:id/hooks/:hook_id
Parameters:
id The ID or NAMESPACE/PROJECT_NAME of a project
hook_id The ID of hook to delete
*/
func (g *Gitlab) RemoveProjectHook(id, hook_id string) error {
url, opaque := g.ResourceUrlRaw(project_url_hook, map[string]string{
":id": id,
":hook_id": hook_id,
})
var err error
_, err = g.buildAndExecRequestRaw("DELETE", url, opaque, nil)
return err
}
/*
Build HTTP query to add or edit hook
*/
func buildHookQuery(hook_url string, push_events, issues_events, merge_requests_events bool) string {
v := url.Values{}
v.Set("url", hook_url)
if push_events {
v.Set("push_events", "true")
} else {
v.Set("push_events", "false")
}
if issues_events {
v.Set("issues_events", "true")
} else {
v.Set("issues_events", "false")
}
if merge_requests_events {
v.Set("merge_requests_events", "true")
} else {
v.Set("merge_requests_events", "false")
}
return v.Encode()
}

View file

@ -0,0 +1,16 @@
package gogitlab
import (
"github.com/stretchr/testify/assert"
"testing"
)
func TestHook(t *testing.T) {
ts, gitlab := Stub("stubs/hooks/show.json")
hook, err := gitlab.ProjectHook("1", "2")
assert.Equal(t, err, nil)
assert.IsType(t, new(Hook), hook)
assert.Equal(t, hook.Url, "http://example.com/hook")
defer ts.Close()
}

View file

@ -0,0 +1,245 @@
package gogitlab
import (
"encoding/json"
"strconv"
"strings"
)
const (
projects_url = "/projects" // Get a list of projects owned by the authenticated user
projects_search_url = "/projects/search/:query" // Search for projects by name
project_url = "/projects/:id" // Get a specific project, identified by project ID or NAME
project_url_events = "/projects/:id/events" // Get project events
project_url_branches = "/projects/:id/repository/branches" // Lists all branches of a project
project_url_members = "/projects/:id/members" // List project team members
project_url_member = "/projects/:id/members/:user_id" // Get project team member
project_url_merge_requests = "/projects/:id/merge_requests" // List all merge requests of a project
)
type Member struct {
Id int
Username string
Email string
Name string
State string
CreatedAt string `json:"created_at,omitempty"`
// AccessLevel int
}
type Namespace struct {
Id int
Name string
Path string
Description string
Owner_Id int
Created_At string
Updated_At string
}
type ProjectAccess struct {
AccessLevel int `json:"access_level,omitempty"`
NotificationLevel int `json:"notification_level,omitempty"`
}
type GroupAccess struct {
AccessLevel int `json:"access_level,omitempty"`
NotificationLevel int `json:"notification_level,omitempty"`
}
type Permissions struct {
ProjectAccess *ProjectAccess `json:"project_access,omitempty"`
GroupAccess *GroupAccess `json:"group_access,omitempty"`
}
// A gitlab project
type Project struct {
Id int `json:"id,omitempty"`
Name string `json:"name,omitempty"`
Description string `json:"description,omitempty"`
DefaultBranch string `json:"default_branch,omitempty"`
Owner *Member `json:"owner,omitempty"`
Public bool `json:"public,omitempty"`
Path string `json:"path,omitempty"`
PathWithNamespace string `json:"path_with_namespace,omitempty"`
IssuesEnabled bool `json:"issues_enabled,omitempty"`
MergeRequestsEnabled bool `json:"merge_requests_enabled,omitempty"`
WallEnabled bool `json:"wall_enabled,omitempty"`
WikiEnabled bool `json:"wiki_enabled,omitempty"`
CreatedAtRaw string `json:"created_at,omitempty"`
Namespace *Namespace `json:"namespace,omitempty"`
SshRepoUrl string `json:"ssh_url_to_repo"`
HttpRepoUrl string `json:"http_url_to_repo"`
Url string `json:"web_url"`
Permissions *Permissions `json:"permissions,omitempty"`
}
type MergeRequest struct {
Id int `json:"id,omitempty"`
// IId
TargetBranch string `json:"target_branch,omitempty"`
SourceBranch string `json:"source_branch,omitempty"`
ProjectId int `json:"project_id,omitempty"`
Title string `json:"title,omitempty"`
State string `json:"state,omitempty"`
Upvotes int `json:"upvotes,omitempty"`
Downvotes int `json:"downvotes,omitempty"`
Author *Member `json:"author,omitempty"`
Assignee *Member `json:"assignee,omitempty"`
Description string `json:"description,omitempty"`
}
/*
Get a list of all projects owned by the authenticated user.
*/
func (g *Gitlab) AllProjects() ([]*Project, error) {
var per_page = 100
var projects []*Project
for i := 1; true; i++ {
contents, err := g.Projects(i, per_page)
if err != nil {
return projects, err
}
for _, value := range contents {
projects = append(projects, value)
}
if len(projects) == 0 {
break
}
if len(projects)/i < per_page {
break
}
}
return projects, nil
}
/*
Get a list of projects owned by the authenticated user.
*/
func (g *Gitlab) Projects(page int, per_page int) ([]*Project, error) {
url := g.ResourceUrlQuery(projects_url, nil, map[string]string{"page": strconv.Itoa(page), "per_page": strconv.Itoa(per_page)})
var projects []*Project
contents, err := g.buildAndExecRequest("GET", url, nil)
if err == nil {
err = json.Unmarshal(contents, &projects)
}
return projects, err
}
/*
Get a specific project, identified by project ID or NAME,
which is owned by the authentication user.
Namespaced project may be retrieved by specifying the namespace
and its project name like this:
`namespace%2Fproject-name`
*/
func (g *Gitlab) Project(id string) (*Project, error) {
url, opaque := g.ResourceUrlRaw(project_url, map[string]string{":id": id})
var project *Project
contents, err := g.buildAndExecRequestRaw("GET", url, opaque, nil)
if err == nil {
err = json.Unmarshal(contents, &project)
}
return project, err
}
/*
Lists all branches of a project.
*/
func (g *Gitlab) ProjectBranches(id string) ([]*Branch, error) {
url, opaque := g.ResourceUrlRaw(project_url_branches, map[string]string{":id": id})
var branches []*Branch
contents, err := g.buildAndExecRequestRaw("GET", url, opaque, nil)
if err == nil {
err = json.Unmarshal(contents, &branches)
}
return branches, err
}
func (g *Gitlab) ProjectMembers(id string) ([]*Member, error) {
url, opaque := g.ResourceUrlRaw(project_url_members, map[string]string{":id": id})
var members []*Member
contents, err := g.buildAndExecRequestRaw("GET", url, opaque, nil)
if err == nil {
err = json.Unmarshal(contents, &members)
}
return members, err
}
/*
Lists all merge requests of a project.
*/
func (g *Gitlab) ProjectMergeRequests(id string, page int, per_page int, state string) ([]*MergeRequest, error) {
par := map[string]string{":id": id}
qry := map[string]string{
"state": state,
"page": strconv.Itoa(page),
"per_page": strconv.Itoa(per_page)}
url := g.ResourceUrlQuery(project_url_merge_requests, par, qry)
var mr []*MergeRequest
contents, err := g.buildAndExecRequest("GET", url, nil)
if err == nil {
err = json.Unmarshal(contents, &mr)
}
return mr, err
}
/*
Get single project id.
GET /projects/search/:query
Parameters:
namespace The namespace of a project
name The id of a project
*/
func (g *Gitlab) SearchProjectId(namespace string, name string) (id int, err error) {
url, opaque := g.ResourceUrlRaw(projects_search_url, map[string]string{
":query": strings.ToLower(name),
})
var projects []*Project
contents, err := g.buildAndExecRequestRaw("GET", url, opaque, nil)
if err == nil {
err = json.Unmarshal(contents, &projects)
} else {
return id, err
}
for _, project := range projects {
if project.Namespace.Name == namespace {
id = project.Id
}
}
return id, err
}

View file

@ -0,0 +1,70 @@
package gogitlab
import (
"github.com/stretchr/testify/assert"
"testing"
)
func TestALlProjects(t *testing.T) {
ts, gitlab := Stub("stubs/projects/index.json")
projects, err := gitlab.AllProjects()
assert.Equal(t, err, nil)
assert.Equal(t, len(projects), 2)
defer ts.Close()
}
func TestProjects(t *testing.T) {
ts, gitlab := Stub("stubs/projects/index.json")
projects, err := gitlab.Projects(1, 100)
assert.Equal(t, err, nil)
assert.Equal(t, len(projects), 2)
defer ts.Close()
}
func TestProject(t *testing.T) {
ts, gitlab := Stub("stubs/projects/show.json")
project, err := gitlab.Project("1")
assert.Equal(t, err, nil)
assert.IsType(t, new(Project), project)
assert.Equal(t, project.SshRepoUrl, "git@example.com:diaspora/diaspora-project-site.git")
assert.Equal(t, project.HttpRepoUrl, "http://example.com/diaspora/diaspora-project-site.git")
defer ts.Close()
}
func TestProjectBranches(t *testing.T) {
ts, gitlab := Stub("stubs/projects/branches/index.json")
branches, err := gitlab.ProjectBranches("1")
assert.Equal(t, err, nil)
assert.Equal(t, len(branches), 2)
defer ts.Close()
}
func TestProjectMergeRequests(t *testing.T) {
ts, gitlab := Stub("stubs/projects/merge_requests/index.json")
defer ts.Close()
mr, err := gitlab.ProjectMergeRequests("1", 0, 30, "all")
assert.Equal(t, err, nil)
assert.Equal(t, len(mr), 1)
if len(mr) > 0 {
assert.Equal(t, mr[0].TargetBranch, "master")
assert.Equal(t, mr[0].SourceBranch, "test1")
}
}
func TestSearchProjectId(t *testing.T) {
ts, gitlab := Stub("stubs/projects/index.json")
namespace := "Brightbox"
name := "Puppet"
id, err := gitlab.SearchProjectId(namespace, name)
assert.Equal(t, err, nil)
assert.Equal(t, id, 6)
defer ts.Close()
}

View file

@ -0,0 +1,69 @@
package gogitlab
import (
"encoding/json"
"net/url"
)
const (
// ID
user_keys = "/user/keys" // Get current user keys
user_key = "/user/keys/:id" // Get user key by id
custom_user_keys = "/user/:id/keys" // Create key for user with :id
)
type PublicKey struct {
Id int `json:"id,omitempty"`
Title string `json:"title,omitempty"`
Key string `json:"key,omitempty"`
CreatedAtRaw string `json:"created_at,omitempty"`
}
func (g *Gitlab) UserKeys() ([]*PublicKey, error) {
url := g.ResourceUrl(user_keys, nil)
var keys []*PublicKey
contents, err := g.buildAndExecRequest("GET", url, nil)
if err == nil {
err = json.Unmarshal(contents, &keys)
}
return keys, err
}
func (g *Gitlab) UserKey(id string) (*PublicKey, error) {
url := g.ResourceUrl(user_key, map[string]string{":id": id})
var key *PublicKey
contents, err := g.buildAndExecRequest("GET", url, nil)
if err == nil {
err = json.Unmarshal(contents, &key)
}
return key, err
}
func (g *Gitlab) AddKey(title, key string) error {
path := g.ResourceUrl(user_keys, nil)
var err error
v := url.Values{}
v.Set("title", title)
v.Set("key", key)
body := v.Encode()
_, err = g.buildAndExecRequest("POST", path, []byte(body))
return err
}
func (g *Gitlab) AddUserKey(id, title, key string) error {
path := g.ResourceUrl(user_keys, map[string]string{":id": id})
var err error
v := url.Values{}
v.Set("title", title)
v.Set("key", key)
body := v.Encode()
_, err = g.buildAndExecRequest("POST", path, []byte(body))
return err
}
func (g *Gitlab) DeleteKey(id string) error {
url := g.ResourceUrl(user_key, map[string]string{":id": id})
var err error
_, err = g.buildAndExecRequest("DELETE", url, nil)
return err
}

View file

@ -0,0 +1,50 @@
package gogitlab
import (
"github.com/stretchr/testify/assert"
"testing"
)
func TestGetUserKeys(t *testing.T) {
ts, gitlab := Stub("stubs/public_keys/index.json")
keys, err := gitlab.UserKeys()
assert.Equal(t, err, nil)
assert.Equal(t, len(keys), 2)
defer ts.Close()
}
func TestGetUserKey(t *testing.T) {
ts, gitlab := Stub("stubs/public_keys/show.json")
key, err := gitlab.UserKey("1")
assert.Equal(t, err, nil)
assert.IsType(t, new(PublicKey), key)
assert.Equal(t, key.Title, "Public key")
assert.Equal(t, key.Key, "ssh-rsa AAAAB3NzaC1yc2EAAAABJQAAAIEAiPWx6WM4lhHNedGfBpPJNPpZ7yKu+dnn1SJejgt4596k6YjzGGphH2TUxwKzxcKDKKezwkpfnxPkSMkuEspGRt/aZZ9wa++Oi7Qkr8prgHc4soW6NUlfDzpvZK2H5E7eQaSeP3SAwGmQKUFHCddNaP0L+hM7zhFNzjFvpaMgJw0=")
defer ts.Close()
}
func TestAddKey(t *testing.T) {
ts, gitlab := Stub("")
err := gitlab.AddKey("Public key", "stubbed key")
assert.Equal(t, err, nil)
defer ts.Close()
}
func TestAddUserKey(t *testing.T) {
ts, gitlab := Stub("")
err := gitlab.AddUserKey("1", "Public key", "stubbed key")
assert.Equal(t, err, nil)
defer ts.Close()
}
func TestDeleteKey(t *testing.T) {
ts, gitlab := Stub("")
err := gitlab.DeleteKey("1")
assert.Equal(t, err, nil)
defer ts.Close()
}

View file

@ -0,0 +1,246 @@
package gogitlab
import (
"encoding/json"
"net/url"
"time"
)
const (
repo_url_branches = "/projects/:id/repository/branches" // List repository branches
repo_url_branch = "/projects/:id/repository/branches/:branch" // Get a specific branch of a project.
repo_url_tags = "/projects/:id/repository/tags" // List project repository tags
repo_url_commits = "/projects/:id/repository/commits" // List repository commits
repo_url_tree = "/projects/:id/repository/tree" // List repository tree
repo_url_raw_file = "/projects/:id/repository/blobs/:sha" // Get raw file content for specific commit/branch
)
type BranchCommit struct {
Id string `json:"id,omitempty"`
Tree string `json:"tree,omitempty"`
AuthoredDateRaw string `json:"authored_date,omitempty"`
CommittedDateRaw string `json:"committed_date,omitempty"`
Message string `json:"message,omitempty"`
Author *Person `json:"author,omitempty"`
Committer *Person `json:"committer,omitempty"`
/*
"parents": [
{"id": "9b0c4b08e7890337fc8111e66f809c8bbec467a9"},
{"id": "3ac634dca850cab70ab14b43ad6073d1e0a7827f"}
]
*/
}
type Branch struct {
Name string `json:"name,omitempty"`
Protected bool `json:"protected,omitempty"`
Commit *BranchCommit `json:"commit,omitempty"`
}
type Tag struct {
Name string `json:"name,omitempty"`
Protected bool `json:"protected,omitempty"`
Commit *BranchCommit `json:"commit,omitempty"`
}
type Commit struct {
Id string
Short_Id string
Title string
Author_Name string
Author_Email string
Created_At string
CreatedAt time.Time
}
type File struct {
Id string `json:"id,omitempty"`
Name string `json:"name,omitempty"`
Type string `json:"type,omitempty"`
Mode string `json:"mode,omitempty"`
Children []*File
}
/*
Get a list of repository branches from a project, sorted by name alphabetically.
GET /projects/:id/repository/branches
Parameters:
id The ID of a project
Usage:
branches, err := gitlab.RepoBranches("your_projet_id")
if err != nil {
fmt.Println(err.Error())
}
for _, branch := range branches {
fmt.Printf("%+v\n", branch)
}
*/
func (g *Gitlab) RepoBranches(id string) ([]*Branch, error) {
url, opaque := g.ResourceUrlRaw(repo_url_branches, map[string]string{":id": id})
var branches []*Branch
contents, err := g.buildAndExecRequestRaw("GET", url, opaque, nil)
if err == nil {
err = json.Unmarshal(contents, &branches)
}
return branches, err
}
/*
Get a single project repository branch.
GET /projects/:id/repository/branches/:branch
Parameters:
id The ID of a project
branch The name of the branch
*/
func (g *Gitlab) RepoBranch(id, refName string) (*Branch, error) {
url, opaque := g.ResourceUrlRaw(repo_url_branch, map[string]string{
":id": id,
":branch": refName,
})
branch := new(Branch)
contents, err := g.buildAndExecRequestRaw("GET", url, opaque, nil)
if err == nil {
err = json.Unmarshal(contents, &branch)
}
return branch, err
}
/*
Get a list of repository tags from a project, sorted by name in reverse alphabetical order.
GET /projects/:id/repository/tags
Parameters:
id The ID of a project
Usage:
tags, err := gitlab.RepoTags("your_projet_id")
if err != nil {
fmt.Println(err.Error())
}
for _, tag := range tags {
fmt.Printf("%+v\n", tag)
}
*/
func (g *Gitlab) RepoTags(id string) ([]*Tag, error) {
url, opaque := g.ResourceUrlRaw(repo_url_tags, map[string]string{":id": id})
var tags []*Tag
contents, err := g.buildAndExecRequestRaw("GET", url, opaque, nil)
if err == nil {
err = json.Unmarshal(contents, &tags)
}
return tags, err
}
/*
Get a list of repository commits in a project.
GET /projects/:id/repository/commits
Parameters:
id The ID of a project
refName The name of a repository branch or tag or if not given the default branch
Usage:
commits, err := gitlab.RepoCommits("your_projet_id")
if err != nil {
fmt.Println(err.Error())
}
for _, commit := range commits {
fmt.Printf("%+v\n", commit)
}
*/
func (g *Gitlab) RepoCommits(id string) ([]*Commit, error) {
url, opaque := g.ResourceUrlRaw(repo_url_commits, map[string]string{":id": id})
var commits []*Commit
contents, err := g.buildAndExecRequestRaw("GET", url, opaque, nil)
if err == nil {
err = json.Unmarshal(contents, &commits)
if err == nil {
for _, commit := range commits {
t, _ := time.Parse(dateLayout, commit.Created_At)
commit.CreatedAt = t
}
}
}
return commits, err
}
/*
Get Raw file content
*/
func (g *Gitlab) RepoRawFile(id, sha, filepath string) ([]byte, error) {
url_ := g.ResourceUrlQuery(repo_url_raw_file, map[string]string{
":id": id,
":sha": sha,
}, map[string]string{
"filepath": filepath,
})
p, err := url.Parse(url_)
if err != nil {
return nil, err
}
opaque := "//" + p.Host + p.Path
contents, err := g.buildAndExecRequestRaw("GET", url_, opaque, nil)
return contents, err
}
/*
Get Raw file content
*/
func (g *Gitlab) RepoTree(id, ref, path string) ([]*File, error) {
url := g.ResourceUrlQuery(repo_url_tree, map[string]string{
":id": id,
}, map[string]string{
"ref": ref,
"path": path,
})
var files []*File
contents, err := g.buildAndExecRequest("GET", url, nil)
if err == nil {
err = json.Unmarshal(contents, &files)
}
for _, f := range files {
if f.Type == "tree" {
f.Children, err = g.RepoTree(id, ref, path+"/"+f.Name)
}
}
return files, err
}

View file

@ -0,0 +1,43 @@
package gogitlab
import (
"github.com/stretchr/testify/assert"
"testing"
)
func TestRepoBranches(t *testing.T) {
ts, gitlab := Stub("stubs/branches/index.json")
branches, err := gitlab.RepoBranches("1")
assert.Equal(t, err, nil)
assert.Equal(t, len(branches), 1)
defer ts.Close()
}
func TestRepoBranch(t *testing.T) {
ts, gitlab := Stub("stubs/branches/show.json")
branch, err := gitlab.RepoBranch("1", "master")
assert.Equal(t, err, nil)
assert.IsType(t, new(Branch), branch)
assert.Equal(t, branch.Name, "master")
defer ts.Close()
}
func TestRepoTags(t *testing.T) {
ts, gitlab := Stub("stubs/tags/index.json")
tags, err := gitlab.RepoTags("1")
assert.Equal(t, err, nil)
assert.Equal(t, len(tags), 1)
defer ts.Close()
}
func TestRepoCommits(t *testing.T) {
ts, gitlab := Stub("stubs/commits/index.json")
commits, err := gitlab.RepoCommits("1")
assert.Equal(t, err, nil)
assert.Equal(t, len(commits), 2)
defer ts.Close()
}

View file

@ -0,0 +1,54 @@
package gogitlab
import (
"encoding/json"
"net/url"
)
const (
session_path = "/session"
)
type Session struct {
Id int `json:"id"`
UserName string `json:"username"`
Name string `json:"name"`
Blocked bool `json:"blocked"`
State string `json:"state"`
AvatarURL string `json:"avatar_url",omitempty`
IsAdmin bool `json:"is_admin"`
Bio string `json:"bio",omitempty`
Email string `json:"email"`
ThemeId int `json:"theme_id",omitempty`
ColorSchemeId int `json:"color_scheme_id",omitempty`
ExternUid string `json:"extern_uid",omitempty`
Provider string `json:"provider",omitempty`
CanCreateGroup bool `json:"can_create_group"`
CanCreateProject bool `json:"can_create_project"`
Skype string `json:"skype",omitempty`
Twitter string `json:"twitter",omitempty`
LinkedIn string `json:"linkedin",omitempty`
WebsiteURL string `json:"website_url",omitempty`
PrivateToken string `json:"private_token"`
}
func (g *Gitlab) GetSession(email string, password string) (*Session, error) {
session_url := g.ResourceUrl(session_path, map[string]string{})
var session *Session
v := url.Values{}
v.Set("email", email)
v.Set("password", password)
body := v.Encode()
contents, err := g.buildAndExecRequest("POST", session_url, []byte(body))
if err != nil {
return session, err
}
err = json.Unmarshal(contents, &session)
return session, err
}

View file

@ -0,0 +1,33 @@
package gogitlab
import (
"github.com/stretchr/testify/assert"
"testing"
)
func TestGetSesison(t *testing.T) {
ts, gitlab := Stub("stubs/session/index.json")
session, err := gitlab.GetSession("john@example.com", "samplepassword")
assert.Equal(t, err, nil)
assert.Equal(t, session.Id, 1)
assert.Equal(t, session.UserName, "john_smith")
assert.Equal(t, session.Name, "John Smith")
assert.Equal(t, session.State, "active")
assert.Equal(t, session.AvatarURL, "http://someurl.com/avatar.png")
assert.Equal(t, session.IsAdmin, false)
assert.Equal(t, session.Bio, "somebio")
assert.Equal(t, session.Skype, "someskype")
assert.Equal(t, session.LinkedIn, "somelinkedin")
assert.Equal(t, session.Twitter, "sometwitter")
assert.Equal(t, session.WebsiteURL, "http://example.com")
assert.Equal(t, session.Email, "john@example.com")
assert.Equal(t, session.ThemeId, 1)
assert.Equal(t, session.ColorSchemeId, 1)
assert.Equal(t, session.ExternUid, "someuid")
assert.Equal(t, session.Provider, "github.com")
assert.Equal(t, session.CanCreateGroup, true)
assert.Equal(t, session.CanCreateProject, true)
assert.Equal(t, session.PrivateToken, "dd34asd13as")
defer ts.Close()
}

View file

@ -0,0 +1,26 @@
[
{
"name": "master",
"commit": {
"id": "7b5c3cc8be40ee161ae89a06bba6229da1032a0c",
"parents": [
{
"id": "4ad91d3c1144c406e50c7b33bae684bd6837faf8"
}
],
"tree": "46e82de44b1061621357f24c05515327f2795a95",
"message": "add projects API",
"author": {
"name": "John Smith",
"email": "john@example.com"
},
"committer": {
"name": "John Smith",
"email": "john@example.com"
},
"authored_date": "2012-06-27T05:51:39-07:00",
"committed_date": "2012-06-28T03:44:20-07:00"
},
"protected": true
}
]

View file

@ -0,0 +1,24 @@
{
"name": "master",
"commit": {
"id": "7b5c3cc8be40ee161ae89a06bba6229da1032a0c",
"parents": [
{
"id": "4ad91d3c1144c406e50c7b33bae684bd6837faf8"
}
],
"tree": "46e82de44b1061621357f24c05515327f2795a95",
"message": "add projects API",
"author": {
"name": "John Smith",
"email": "john@example.com"
},
"committer": {
"name": "John Smith",
"email": "john@example.com"
},
"authored_date": "2012-06-27T05:51:39-07:00",
"committed_date": "2012-06-28T03:44:20-07:00"
},
"protected": true
}

View file

@ -0,0 +1,18 @@
[
{
"id": "ed899a2f4b50b4370feeea94676502b42383c746",
"short_id": "ed899a2f4b5",
"title": "Replace sanitize with escape once",
"author_name": "Dmitriy Zaporozhets",
"author_email": "dzaporozhets@sphereconsultinginc.com",
"created_at": "2012-09-20T11:50:22+03:00"
},
{
"id": "6104942438c14ec7bd21c6cd5bd995272b3faff6",
"short_id": "6104942438c",
"title": "Sanitize for network graph",
"author_name": "randx",
"author_email": "dmitriy.zaporozhets@gmail.com",
"created_at": "2012-09-20T09:06:12+03:00"
}
]

View file

@ -0,0 +1,18 @@
{
"object_kind": "issue",
"object_attributes": {
"id": 301,
"title": "New API: create/update/delete file",
"assignee_id": 51,
"author_id": 51,
"project_id": 14,
"created_at": "2013-12-03T17:15:43Z",
"updated_at": "2013-12-03T17:15:43Z",
"position": 0,
"branch_name": null,
"description": "Create new API for manipulations with repository",
"milestone_id": null,
"state": "opened",
"iid": 23
}
}

View file

@ -0,0 +1,22 @@
{
"object_kind": "merge_request",
"object_attributes": {
"id": 99,
"target_branch": "master",
"source_branch": "ms-viewport",
"source_project_id": 14,
"author_id": 51,
"assignee_id": 6,
"title": "MS-Viewport",
"created_at": "2013-12-03T17:23:34Z",
"updated_at": "2013-12-03T17:23:34Z",
"st_commits": null,
"st_diffs": null,
"milestone_id": null,
"state": "opened",
"merge_status": "unchecked",
"target_project_id": 14,
"iid": 1,
"description": ""
}
}

View file

@ -0,0 +1,42 @@
{
"object_kind": "push",
"before": "95790bf891e76fee5e1747ab589903a6a1f80f22",
"after": "da1560886d4f094c3e6c9ef40349f7d38b5d27d7",
"ref": "refs/heads/master",
"user_id": 4,
"user_name": "John Smith",
"user_email": "john@example.com",
"project_id": 15,
"repository": {
"name": "Diaspora",
"url": "git@example.com:mike/diasporadiaspora.git",
"description": "",
"homepage": "http://example.com/mike/diaspora",
"git_http_url":"http://example.com/mike/diaspora.git",
"git_ssh_url":"git@example.com:mike/diaspora.git",
"visibility_level":0
},
"commits": [
{
"id": "b6568db1bc1dcd7f8b4d5a946b0b91f9dacd7327",
"message": "Update Catalan translation to e38cb41.",
"timestamp": "2011-12-12T14:27:31+02:00",
"url": "http://example.com/mike/diaspora/commit/b6568db1bc1dcd7f8b4d5a946b0b91f9dacd7327",
"author": {
"name": "Jordi Mallach",
"email": "jordi@softcatala.org"
}
},
{
"id": "da1560886d4f094c3e6c9ef40349f7d38b5d27d7",
"message": "fixed readme",
"timestamp": "2012-01-03T23:36:29+02:00",
"url": "http://example.com/mike/diaspora/commit/da1560886d4f094c3e6c9ef40349f7d38b5d27d7",
"author": {
"name": "GitLab dev user",
"email": "gitlabdev@dv6700.(none)"
}
}
],
"total_commits_count": 4
}

View file

@ -0,0 +1,9 @@
{
"id": 1,
"url": "http://example.com/hook",
"project_id": 3,
"push_events": "true",
"issues_events": "true",
"merge_requests_events": "true",
"created_at": "2012-10-12T17:04:47Z"
}

View file

@ -0,0 +1,50 @@
[
{
"name": "async",
"commit": {
"id": "a2b702edecdf41f07b42653eb1abe30ce98b9fca",
"parents": [
{
"id": "3f94fc7c85061973edc9906ae170cc269b07ca55"
}
],
"tree": "c68537c6534a02cc2b176ca1549f4ffa190b58ee",
"message": "give caolan credit where it's due (up top)",
"author": {
"name": "Jeremy Ashkenas",
"email": "jashkenas@example.com"
},
"committer": {
"name": "Jeremy Ashkenas",
"email": "jashkenas@example.com"
},
"authored_date": "2010-12-08T21:28:50+00:00",
"committed_date": "2010-12-08T21:28:50+00:00"
},
"protected": false
},
{
"name": "gh-pages",
"commit": {
"id": "101c10a60019fe870d21868835f65c25d64968fc",
"parents": [
{
"id": "9c15d2e26945a665131af5d7b6d30a06ba338aaa"
}
],
"tree": "fb5cc9d45da3014b17a876ad539976a0fb9b352a",
"message": "Underscore.js 1.5.2",
"author": {
"name": "Jeremy Ashkenas",
"email": "jashkenas@example.com"
},
"committer": {
"name": "Jeremy Ashkenas",
"email": "jashkenas@example.com"
},
"authored_date": "2013-09-07T12: 58: 21+00: 00",
"committed_date": "2013-09-07T12: 58: 21+00: 00"
},
"protected": false
}
]

View file

@ -0,0 +1,72 @@
[
{
"id": 4,
"description": null,
"default_branch": "master",
"public": false,
"visibility_level": 0,
"ssh_url_to_repo": "git@example.com:diaspora/diaspora-client.git",
"http_url_to_repo": "http://example.com/diaspora/diaspora-client.git",
"web_url": "http://example.com/diaspora/diaspora-client",
"owner": {
"id": 3,
"name": "Diaspora",
"created_at": "2013-09-30T13: 46: 02Z"
},
"name": "Diaspora Client",
"name_with_namespace": "Diaspora / Diaspora Client",
"path": "diaspora-client",
"path_with_namespace": "diaspora/diaspora-client",
"issues_enabled": true,
"merge_requests_enabled": true,
"wall_enabled": false,
"wiki_enabled": true,
"snippets_enabled": false,
"created_at": "2013-09-30T13: 46: 02Z",
"last_activity_at": "2013-09-30T13: 46: 02Z",
"namespace": {
"created_at": "2013-09-30T13: 46: 02Z",
"description": "",
"id": 3,
"name": "Diaspora",
"owner_id": 1,
"path": "diaspora",
"updated_at": "2013-09-30T13: 46: 02Z"
}
},
{
"id": 6,
"description": null,
"default_branch": "master",
"public": false,
"visibility_level": 0,
"ssh_url_to_repo": "git@example.com:brightbox/puppet.git",
"http_url_to_repo": "http://example.com/brightbox/puppet.git",
"web_url": "http://example.com/brightbox/puppet",
"owner": {
"id": 4,
"name": "Brightbox",
"created_at": "2013-09-30T13:46:02Z"
},
"name": "Puppet",
"name_with_namespace": "Brightbox / Puppet",
"path": "puppet",
"path_with_namespace": "brightbox/puppet",
"issues_enabled": true,
"merge_requests_enabled": true,
"wall_enabled": false,
"wiki_enabled": true,
"snippets_enabled": false,
"created_at": "2013-09-30T13:46:02Z",
"last_activity_at": "2013-09-30T13:46:02Z",
"namespace": {
"created_at": "2013-09-30T13:46:02Z",
"description": "",
"id": 4,
"name": "Brightbox",
"owner_id": 1,
"path": "brightbox",
"updated_at": "2013-09-30T13:46:02Z"
}
}
]

View file

@ -0,0 +1,30 @@
[
{
"id": 1,
"iid": 1,
"target_branch": "master",
"source_branch": "test1",
"project_id": 3,
"title": "test1",
"state": "opened",
"upvotes": 0,
"downvotes": 0,
"author": {
"id": 1,
"username": "admin",
"email": "admin@example.com",
"name": "Administrator",
"state": "active",
"created_at": "2012-04-29T08:46:00Z"
},
"assignee": {
"id": 1,
"username": "admin",
"email": "admin@example.com",
"name": "Administrator",
"state": "active",
"created_at": "2012-04-29T08:46:00Z"
},
"description":"fixed login page css paddings"
}
]

View file

@ -0,0 +1,45 @@
{
"id": 3,
"description": null,
"default_branch": "master",
"public": false,
"visibility_level": 0,
"ssh_url_to_repo": "git@example.com:diaspora/diaspora-project-site.git",
"http_url_to_repo": "http://example.com/diaspora/diaspora-project-site.git",
"web_url": "http://example.com/diaspora/diaspora-project-site",
"owner": {
"id": 3,
"name": "Diaspora",
"created_at": "2013-09-30T13: 46: 02Z"
},
"name": "Diaspora Project Site",
"name_with_namespace": "Diaspora / Diaspora Project Site",
"path": "diaspora-project-site",
"path_with_namespace": "diaspora/diaspora-project-site",
"issues_enabled": true,
"merge_requests_enabled": true,
"wall_enabled": false,
"wiki_enabled": true,
"snippets_enabled": false,
"created_at": "2013-09-30T13: 46: 02Z",
"last_activity_at": "2013-09-30T13: 46: 02Z",
"namespace": {
"created_at": "2013-09-30T13: 46: 02Z",
"description": "",
"id": 3,
"name": "Diaspora",
"owner_id": 1,
"path": "diaspora",
"updated_at": "2013-09-30T13: 46: 02Z"
},
"permissions": {
"project_access": {
"access_level": 10,
"notification_level": 3
},
"group_access": {
"access_level": 50,
"notification_level": 3
}
}
}

View file

@ -0,0 +1,12 @@
[
{
"id": 1,
"title": "Public key",
"key": "ssh-rsa AAAAB3NzaC1yc2EAAAABJQAAAIEAiPWx6WM4lhHNedGfBpPJNPpZ7yKu+dnn1SJejgt4596k6YjzGGphH2TUxwKzxcKDKKezwkpfnxPkSMkuEspGRt/aZZ9wa++Oi7Qkr8prgHc4soW6NUlfDzpvZK2H5E7eQaSeP3SAwGmQKUFHCddNaP0L+hM7zhFNzjFvpaMgJw0="
},
{
"id": 3,
"title": "Another Public key",
"key": "ssh-rsa AAAAB3NzaC1yc2EAAAABJQAAAIEAiPWx6WM4lhHNedGfBpPJNPpZ7yKu+dnn1SJejgt4596k6YjzGGphH2TUxwKzxcKDKKezwkpfnxPkSMkuEspGRt/aZZ9wa++Oi7Qkr8prgHc4soW6NUlfDzpvZK2H5E7eQaSeP3SAwGmQKUFHCddNaP0L+hM7zhFNzjFvpaMgJw0="
}
]

View file

@ -0,0 +1,5 @@
{
"id": 1,
"title": "Public key",
"key": "ssh-rsa AAAAB3NzaC1yc2EAAAABJQAAAIEAiPWx6WM4lhHNedGfBpPJNPpZ7yKu+dnn1SJejgt4596k6YjzGGphH2TUxwKzxcKDKKezwkpfnxPkSMkuEspGRt/aZZ9wa++Oi7Qkr8prgHc4soW6NUlfDzpvZK2H5E7eQaSeP3SAwGmQKUFHCddNaP0L+hM7zhFNzjFvpaMgJw0="
}

View file

@ -0,0 +1,23 @@
{
"id": 1,
"username": "john_smith",
"email": "john@example.com",
"name": "John Smith",
"avatar_url": "http://someurl.com/avatar.png",
"state": "active",
"created_at": "2012-05-23T08:00:58Z",
"bio": "somebio",
"skype": "someskype",
"linkedin": "somelinkedin",
"twitter": "sometwitter",
"website_url": "http://example.com",
"theme_id": 1,
"color_scheme_id": 1,
"extern_uid": "someuid",
"provider": "github.com",
"is_admin": false,
"can_create_group": true,
"can_create_team": true,
"can_create_project": true,
"private_token": "dd34asd13as"
}

View file

@ -0,0 +1,22 @@
[
{
"name": "v1.0.0",
"commit": {
"id": "2695effb5807a22ff3d138d593fd856244e155e7",
"parents": [],
"tree": "38017f2f189336fe4497e9d230c5bb1bf873f08d",
"message": "Initial commit",
"author": {
"name": "John Smith",
"email": "john@example.com"
},
"committer": {
"name": "Jack Smith",
"email": "jack@example.com"
},
"authored_date": "2012-05-28T04:42:42-07:00",
"committed_date": "2012-05-28T04:42:42-07:00"
},
"protected": null
}
]

View file

@ -0,0 +1,19 @@
{
"id": 1,
"username": "john_smith",
"email": "john@example.com",
"name": "John Smith",
"private_token": "dd34asd13as",
"state": "active",
"created_at": "2012-05-23T08:00:58Z",
"bio": null,
"skype": "",
"linkedin": "",
"twitter": "",
"website_url": "",
"theme_id": 1,
"color_scheme_id": 2,
"is_admin": false,
"can_create_group": true,
"can_create_project": true
}

View file

@ -0,0 +1,41 @@
[
{
"id": 1,
"username": "john_smith",
"email": "john@example.com",
"name": "John Smith",
"state": "active",
"created_at": "2012-05-23T08:00:58Z",
"bio": null,
"skype": "",
"linkedin": "",
"twitter": "",
"website_url": "",
"extern_uid": "john.smith",
"provider": "provider_name",
"theme_id": 1,
"color_scheme_id": 2,
"is_admin": false,
"can_create_group": true
},
{
"id": 2,
"username": "jack_smith",
"email": "jack@example.com",
"name": "Jack Smith",
"state": "blocked",
"created_at": "2012-05-23T08:01:01Z",
"bio": null,
"skype": "",
"linkedin": "",
"twitter": "",
"website_url": "",
"extern_uid": "jack.smith",
"provider": "provider_name",
"theme_id": 1,
"color_scheme_id": 3,
"is_admin": false,
"can_create_group": true,
"can_create_project": true
}
]

View file

@ -0,0 +1,15 @@
{
"id": 6,
"username": "plouc",
"email": "plouc@plouc.com",
"name": "Raphaël Benitte",
"bio": null,
"skype": "",
"linkedin": "",
"twitter": "",
"theme_id": 2,
"state": "active",
"created_at": "2001-01-01T00:00:00Z",
"extern_uid": "uid=plouc",
"provider": "ldap"
}

View file

@ -0,0 +1,97 @@
package gogitlab
import (
"encoding/json"
"strconv"
)
const (
users_url = "/users" // Get users list
user_url = "/users/:id" // Get a single user.
current_user_url = "/user" // Get current user
)
type User struct {
Id int `json:"id,omitempty"`
Username string `json:"username,omitempty"`
Email string `json:"email,omitempty"`
AvatarUrl string `json:"avatar_url,omitempty"`
Name string `json:"name,omitempty"`
State string `json:"state,omitempty"`
CreatedAt string `json:"created_at,omitempty"`
Bio string `json:"bio,omitempty"`
Skype string `json:"skype,omitempty"`
LinkedIn string `json:"linkedin,omitempty"`
Twitter string `json:"twitter,omitempty"`
ExternUid string `json:"extern_uid,omitempty"`
Provider string `json:"provider,omitempty"`
ThemeId int `json:"theme_id,omitempty"`
ColorSchemeId int `json:"color_scheme_id,color_scheme_id"`
}
func (g *Gitlab) Users(page int, per_page int) ([]*User, error) {
qry := map[string]string{
"page": strconv.Itoa(page),
"per_page": strconv.Itoa(per_page)}
url := g.ResourceUrlQuery(users_url, nil, qry)
var users []*User
contents, err := g.buildAndExecRequest("GET", url, nil)
if err == nil {
err = json.Unmarshal(contents, &users)
}
return users, err
}
/*
Get a single user.
GET /users/:id
Parameters:
id The ID of a user
Usage:
user, err := gitlab.User("your_user_id")
if err != nil {
fmt.Println(err.Error())
}
fmt.Printf("%+v\n", user)
*/
func (g *Gitlab) User(id string) (*User, error) {
url := g.ResourceUrl(user_url, map[string]string{":id": id})
user := new(User)
contents, err := g.buildAndExecRequest("GET", url, nil)
if err == nil {
err = json.Unmarshal(contents, &user)
}
return user, err
}
func (g *Gitlab) DeleteUser(id string) error {
url := g.ResourceUrl(user_url, map[string]string{":id": id})
var err error
_, err = g.buildAndExecRequest("DELETE", url, nil)
return err
}
func (g *Gitlab) CurrentUser() (User, error) {
url := g.ResourceUrl(current_user_url, nil)
var user User
contents, err := g.buildAndExecRequest("GET", url, nil)
if err == nil {
err = json.Unmarshal(contents, &user)
}
return user, err
}

View file

@ -0,0 +1,53 @@
package gogitlab
import (
"github.com/stretchr/testify/assert"
"testing"
)
func TestUsers(t *testing.T) {
ts, gitlab := Stub("stubs/users/index.json")
users, err := gitlab.Users(0, 100)
assert.Equal(t, err, nil)
assert.Equal(t, len(users), 2)
defer ts.Close()
}
func TestUser(t *testing.T) {
ts, gitlab := Stub("stubs/users/show.json")
user, err := gitlab.User("plouc")
assert.Equal(t, err, nil)
assert.IsType(t, new(User), user)
assert.Equal(t, user.Id, 6)
assert.Equal(t, user.Username, "plouc")
assert.Equal(t, user.Name, "Raphaël Benitte")
assert.Equal(t, user.Bio, "")
assert.Equal(t, user.Skype, "")
assert.Equal(t, user.LinkedIn, "")
assert.Equal(t, user.Twitter, "")
assert.Equal(t, user.ThemeId, 2)
assert.Equal(t, user.State, "active")
assert.Equal(t, user.CreatedAt, "2001-01-01T00:00:00Z")
assert.Equal(t, user.ExternUid, "uid=plouc")
assert.Equal(t, user.Provider, "ldap")
defer ts.Close()
}
func TestDeleteUser(t *testing.T) {
ts, gitlab := Stub("")
err := gitlab.DeleteUser("1")
assert.Equal(t, err, nil)
defer ts.Close()
}
func TestCurrentUser(t *testing.T) {
ts, gitlab := Stub("stubs/users/current.json")
user, err := gitlab.CurrentUser()
assert.Equal(t, err, nil)
assert.Equal(t, user.Username, "john_smith")
defer ts.Close()
}

View file

@ -0,0 +1,10 @@
package gogitlab
import (
"net/url"
"strings"
)
func encodeParameter(value string) string {
return strings.Replace(url.QueryEscape(value), "/", "%2F", 0)
}

View file

@ -0,0 +1,11 @@
package gogitlab
import (
"github.com/stretchr/testify/assert"
"testing"
)
func TestParameterEncoding(t *testing.T) {
assert.Equal(t, encodeParameter("namespace/project"), "namespace%2Fproject")
assert.Equal(t, encodeParameter("14"), "14")
}

View file

@ -7,7 +7,6 @@ all: concat bindata build
deps:
go get github.com/jteeuwen/go-bindata/...
go get github.com/Bugagazavr/go-gitlab-client...
test:
go vet github.com/drone/drone/pkg/...

View file

@ -8,7 +8,7 @@ import (
"strconv"
"strings"
"github.com/Bugagazavr/go-gitlab-client"
"github.com/drone/drone/Godeps/_workspace/src/github.com/Bugagazavr/go-gitlab-client"
"github.com/drone/drone/Godeps/_workspace/src/github.com/hashicorp/golang-lru"
"github.com/drone/drone/pkg/config"
"github.com/drone/drone/pkg/oauth2"

View file

@ -4,7 +4,7 @@ import (
"fmt"
"net/url"
"github.com/Bugagazavr/go-gitlab-client"
"github.com/drone/drone/Godeps/_workspace/src/github.com/Bugagazavr/go-gitlab-client"
)
// NewClient is a helper function that returns a new GitHub