1
0
mirror of https://github.com/woodpecker-ci/woodpecker.git synced 2024-12-24 10:07:21 +02:00

feat: add gitea remote driver.

This commit is contained in:
Bo-Yi Wu 2017-05-01 18:33:06 +08:00
parent 076dc0c3b9
commit 35b1e1d386
No known key found for this signature in database
GPG Key ID: 0F84B2110C500B1F
48 changed files with 4006 additions and 0 deletions

View File

@ -225,6 +225,37 @@ var Command = cli.Command{
Name: "gogs-skip-verify",
Usage: "gogs skip ssl verification",
},
cli.BoolFlag{
EnvVar: "DRONE_GITEA",
Name: "gitea",
Usage: "gitea driver is enabled",
},
cli.StringFlag{
EnvVar: "DRONE_GITEA_URL",
Name: "gitea-server",
Usage: "gitea server address",
Value: "https://github.com",
},
cli.StringFlag{
EnvVar: "DRONE_GITEA_GIT_USERNAME",
Name: "gitea-git-username",
Usage: "gitea service account username",
},
cli.StringFlag{
EnvVar: "DRONE_GITEA_GIT_PASSWORD",
Name: "gitea-git-password",
Usage: "gitea service account password",
},
cli.BoolFlag{
EnvVar: "DRONE_GITEA_PRIVATE_MODE",
Name: "gitea-private-mode",
Usage: "gitea private mode enabled",
},
cli.BoolFlag{
EnvVar: "DRONE_GITEA_SKIP_VERIFY",
Name: "gitea-skip-verify",
Usage: "gitea skip ssl verification",
},
cli.BoolFlag{
EnvVar: "DRONE_BITBUCKET",
Name: "bitbucket",

View File

@ -0,0 +1,110 @@
package fixtures
import (
"net/http"
"github.com/gin-gonic/gin"
)
// Handler returns an http.Handler that is capable of handling a variety of mock
// Bitbucket requests and returning mock responses.
func Handler() http.Handler {
gin.SetMode(gin.TestMode)
e := gin.New()
e.GET("/api/v1/repos/:owner/:name", getRepo)
e.GET("/api/v1/repos/:owner/:name/raw/:commit/:file", getRepoFile)
e.POST("/api/v1/repos/:owner/:name/hooks", createRepoHook)
e.GET("/api/v1/user/repos", getUserRepos)
return e
}
func getRepo(c *gin.Context) {
switch c.Param("name") {
case "repo_not_found":
c.String(404, "")
default:
c.String(200, repoPayload)
}
}
func getRepoFile(c *gin.Context) {
if c.Param("file") == "file_not_found" {
c.String(404, "")
}
if c.Param("commit") == "v1.0.0" || c.Param("commit") == "9ecad50" {
c.String(200, repoFilePayload)
}
c.String(404, "")
}
func createRepoHook(c *gin.Context) {
in := struct {
Type string `json:"type"`
Conf struct {
Type string `json:"content_type"`
URL string `json:"url"`
} `json:"config"`
}{}
c.BindJSON(&in)
if in.Type != "gogs" ||
in.Conf.Type != "json" ||
in.Conf.URL != "http://localhost" {
c.String(500, "")
return
}
c.String(200, "{}")
}
func getUserRepos(c *gin.Context) {
switch c.Request.Header.Get("Authorization") {
case "token repos_not_found":
c.String(404, "")
default:
c.String(200, userRepoPayload)
}
}
const repoPayload = `
{
"owner": {
"username": "test_name",
"email": "octocat@github.com",
"avatar_url": "https:\/\/secure.gravatar.com\/avatar\/8c58a0be77ee441bb8f8595b7f1b4e87"
},
"full_name": "test_name\/repo_name",
"private": true,
"html_url": "http:\/\/localhost\/test_name\/repo_name",
"clone_url": "http:\/\/localhost\/test_name\/repo_name.git",
"permissions": {
"admin": true,
"push": true,
"pull": true
}
}
`
const repoFilePayload = `{ platform: linux/amd64 }`
const userRepoPayload = `
[
{
"owner": {
"username": "test_name",
"email": "octocat@github.com",
"avatar_url": "https:\/\/secure.gravatar.com\/avatar\/8c58a0be77ee441bb8f8595b7f1b4e87"
},
"full_name": "test_name\/repo_name",
"private": true,
"html_url": "http:\/\/localhost\/test_name\/repo_name",
"clone_url": "http:\/\/localhost\/test_name\/repo_name.git",
"permissions": {
"admin": true,
"push": true,
"pull": true
}
}
]
`

View File

@ -0,0 +1,140 @@
package fixtures
// Sample Gogs push hook
var HookPush = `
{
"ref": "refs/heads/master",
"before": "4b2626259b5a97b6b4eab5e6cca66adb986b672b",
"after": "ef98532add3b2feb7a137426bba1248724367df5",
"compare_url": "http://gogs.golang.org/gordon/hello-world/compare/4b2626259b5a97b6b4eab5e6cca66adb986b672b...ef98532add3b2feb7a137426bba1248724367df5",
"commits": [
{
"id": "ef98532add3b2feb7a137426bba1248724367df5",
"message": "bump\n",
"url": "http://gogs.golang.org/gordon/hello-world/commit/ef98532add3b2feb7a137426bba1248724367df5",
"author": {
"name": "Gordon the Gopher",
"email": "gordon@golang.org",
"username": "gordon"
}
}
],
"repository": {
"id": 1,
"name": "hello-world",
"full_name": "gordon/hello-world",
"html_url": "http://gogs.golang.org/gordon/hello-world",
"ssh_url": "git@gogs.golang.org:gordon/hello-world.git",
"clone_url": "http://gogs.golang.org/gordon/hello-world.git",
"description": "",
"website": "",
"watchers": 1,
"owner": {
"name": "gordon",
"email": "gordon@golang.org",
"username": "gordon"
},
"private": true
},
"pusher": {
"name": "gordon",
"email": "gordon@golang.org",
"username": "gordon"
},
"sender": {
"login": "gordon",
"id": 1,
"avatar_url": "http://gogs.golang.org///1.gravatar.com/avatar/8c58a0be77ee441bb8f8595b7f1b4e87"
}
}
`
// Sample Gogs tag hook
var HookPushTag = `{
"secret": "l26Un7G7HXogLAvsyf2hOA4EMARSTsR3",
"ref": "v1.0.0",
"ref_type": "tag",
"repository": {
"id": 1,
"owner": {
"id": 1,
"username": "gordon",
"full_name": "Gordon the Gopher",
"email": "gordon@golang.org",
"avatar_url": "https://secure.gravatar.com/avatar/8c58a0be77ee441bb8f8595b7f1b4e87"
},
"name": "hello-world",
"full_name": "gordon/hello-world",
"description": "",
"private": true,
"fork": false,
"html_url": "http://gogs.golang.org/gordon/hello-world",
"ssh_url": "git@gogs.golang.org:gordon/hello-world.git",
"clone_url": "http://gogs.golang.org/gordon/hello-world.git",
"default_branch": "master",
"created_at": "2015-10-22T19:32:44Z",
"updated_at": "2016-11-24T13:37:16Z"
},
"sender": {
"id": 1,
"username": "gordon",
"full_name": "Gordon the Gopher",
"email": "gordon@golang.org",
"avatar_url": "https://secure.gravatar.com/avatar/8c58a0be77ee441bb8f8595b7f1b4e87"
}
}`
// HookPullRequest is a sample pull_request webhook payload
var HookPullRequest = `{
"action": "opened",
"number": 1,
"pull_request": {
"html_url": "http://gogs.golang.org/gordon/hello-world/pull/1",
"state": "open",
"title": "Update the README with new information",
"body": "please merge",
"user": {
"id": 1,
"username": "gordon",
"full_name": "Gordon the Gopher",
"email": "gordon@golang.org",
"avatar_url": "http://gogs.golang.org///1.gravatar.com/avatar/8c58a0be77ee441bb8f8595b7f1b4e87"
},
"base_branch": "master",
"base": {
"label": "master",
"ref": "master",
"sha": "9353195a19e45482665306e466c832c46560532d"
},
"head_branch": "feature/changes",
"head": {
"label": "feature/changes",
"ref": "feature/changes",
"sha": "0d1a26e67d8f5eaf1f6ba5c57fc3c7d91ac0fd1c"
}
},
"repository": {
"id": 35129377,
"name": "hello-world",
"full_name": "gordon/hello-world",
"owner": {
"id": 1,
"username": "gordon",
"full_name": "Gordon the Gopher",
"email": "gordon@golang.org",
"avatar_url": "https://secure.gravatar.com/avatar/8c58a0be77ee441bb8f8595b7f1b4e87"
},
"private": true,
"html_url": "http://gogs.golang.org/gordon/hello-world",
"clone_url": "https://gogs.golang.org/gordon/hello-world.git",
"default_branch": "master"
},
"sender": {
"id": 1,
"login": "gordon",
"username": "gordon",
"full_name": "Gordon the Gopher",
"email": "gordon@golang.org",
"avatar_url": "https://secure.gravatar.com/avatar/8c58a0be77ee441bb8f8595b7f1b4e87"
}
}`

344
remote/gitea/gitea.go Normal file
View File

@ -0,0 +1,344 @@
package gitea
import (
"crypto/tls"
"fmt"
"net"
"net/http"
"net/url"
"strings"
"github.com/drone/drone/model"
"github.com/drone/drone/remote"
"github.com/go-gitea/go-sdk/gitea"
)
// Opts defines configuration options.
type Opts struct {
URL string // Gitea server url.
Username string // Optional machine account username.
Password string // Optional machine account password.
PrivateMode bool // Gitea is running in private mode.
SkipVerify bool // Skip ssl verification.
}
type client struct {
URL string
Machine string
Username string
Password string
PrivateMode bool
SkipVerify bool
}
const (
DescPending = "the build is pending"
DescRunning = "the buils is running"
DescSuccess = "the build was successful"
DescFailure = "the build failed"
DescCanceled = "the build canceled"
DescBlocked = "the build is pending approval"
DescDeclined = "the build was rejected"
)
// getStatus is a helper functin that converts a Drone
// status to a GitHub status.
func getStatus(status string) gitea.StatusState {
switch status {
case model.StatusPending, model.StatusBlocked:
return gitea.StatusPending
case model.StatusRunning:
return gitea.StatusPending
case model.StatusSuccess:
return gitea.StatusSuccess
case model.StatusFailure, model.StatusError:
return gitea.StatusFailure
case model.StatusKilled:
return gitea.StatusCanceled
default:
return gitea.StatusFailure
}
}
// getDesc is a helper function that generates a description
// message for the build based on the status.
func getDesc(status string) string {
switch status {
case model.StatusPending:
return DescPending
case model.StatusRunning:
return DescRunning
case model.StatusSuccess:
return DescSuccess
case model.StatusFailure, model.StatusError:
return DescFailure
case model.StatusKilled:
return DescCanceled
case model.StatusBlocked:
return DescBlocked
case model.StatusDeclined:
return DescDeclined
default:
return DescFailure
}
}
// New returns a Remote implementation that integrates with Gitea, an open
// source Git service written in Go. See https://gitea.io/
func New(opts Opts) (remote.Remote, error) {
url, err := url.Parse(opts.URL)
if err != nil {
return nil, err
}
host, _, err := net.SplitHostPort(url.Host)
if err == nil {
url.Host = host
}
return &client{
URL: opts.URL,
Machine: url.Host,
Username: opts.Username,
Password: opts.Password,
PrivateMode: opts.PrivateMode,
SkipVerify: opts.SkipVerify,
}, nil
}
// Login authenticates an account with Gitea using basic authenticaiton. The
// Gitea account details are returned when the user is successfully authenticated.
func (c *client) Login(res http.ResponseWriter, req *http.Request) (*model.User, error) {
var (
username = req.FormValue("username")
password = req.FormValue("password")
)
// if the username or password is empty we re-direct to the login screen.
if len(username) == 0 || len(password) == 0 {
http.Redirect(res, req, "/login/form", http.StatusSeeOther)
return nil, nil
}
client := c.newClient()
// try to fetch drone token if it exists
var accessToken string
tokens, err := client.ListAccessTokens(username, password)
if err == nil {
for _, token := range tokens {
if token.Name == "drone" {
accessToken = token.Sha1
break
}
}
}
// if drone token not found, create it
if accessToken == "" {
token, terr := client.CreateAccessToken(
username,
password,
gitea.CreateAccessTokenOption{Name: "drone"},
)
if terr != nil {
return nil, terr
}
accessToken = token.Sha1
}
client = c.newClientToken(accessToken)
account, err := client.GetUserInfo(username)
if err != nil {
return nil, err
}
return &model.User{
Token: accessToken,
Login: account.UserName,
Email: account.Email,
Avatar: expandAvatar(c.URL, account.AvatarURL),
}, nil
}
// Auth is not supported by the Gitea driver.
func (c *client) Auth(token, secret string) (string, error) {
return "", fmt.Errorf("Not Implemented")
}
// Teams is not supported by the Gitea driver.
func (c *client) Teams(u *model.User) ([]*model.Team, error) {
client := c.newClientToken(u.Token)
orgs, err := client.ListMyOrgs()
if err != nil {
return nil, err
}
var teams []*model.Team
for _, org := range orgs {
teams = append(teams, toTeam(org, c.URL))
}
return teams, nil
}
// TeamPerm is not supported by the Gitea driver.
func (c *client) TeamPerm(u *model.User, org string) (*model.Perm, error) {
return nil, nil
}
// Repo returns the named Gitea repository.
func (c *client) Repo(u *model.User, owner, name string) (*model.Repo, error) {
client := c.newClientToken(u.Token)
repo, err := client.GetRepo(owner, name)
if err != nil {
return nil, err
}
if c.PrivateMode {
repo.Private = true
}
return toRepo(repo), nil
}
// Repos returns a list of all repositories for the Gitea account, including
// organization repositories.
func (c *client) Repos(u *model.User) ([]*model.RepoLite, error) {
repos := []*model.RepoLite{}
client := c.newClientToken(u.Token)
all, err := client.ListMyRepos()
if err != nil {
return repos, err
}
for _, repo := range all {
repos = append(repos, toRepoLite(repo))
}
return repos, err
}
// Perm returns the user permissions for the named Gitea repository.
func (c *client) Perm(u *model.User, owner, name string) (*model.Perm, error) {
client := c.newClientToken(u.Token)
repo, err := client.GetRepo(owner, name)
if err != nil {
return nil, err
}
return toPerm(repo.Permissions), nil
}
// File fetches the file from the Gitea repository and returns its contents.
func (c *client) File(u *model.User, r *model.Repo, b *model.Build, f string) ([]byte, error) {
client := c.newClientToken(u.Token)
ref := b.Commit
// TODO gogs does not yet return a sha with the pull request
// so unfortunately we need to use the pull request branch.
if b.Event == model.EventPull {
ref = b.Branch
}
if ref == "" {
// Remove refs/tags or refs/heads, Gitea needs a short ref
ref = strings.TrimPrefix(
strings.TrimPrefix(
b.Ref,
"refs/heads/",
),
"refs/tags/",
)
}
cfg, err := client.GetFile(r.Owner, r.Name, ref, f)
return cfg, err
}
// FileRef fetches the file from the Gitea repository and returns its contents.
func (c *client) FileRef(u *model.User, r *model.Repo, ref, f string) ([]byte, error) {
return c.newClientToken(u.Token).GetFile(r.Owner, r.Name, ref, f)
}
// Status is not supported by the Gitea driver.
func (c *client) Status(u *model.User, r *model.Repo, b *model.Build, link string) error {
client := c.newClientToken(u.Token)
status := getStatus(b.Status)
desc := getDesc(b.Status)
client.CreateStatus(
r.Owner,
r.Name,
b.Commit,
gitea.CreateStatusOption{
status,
link,
desc,
"",
},
)
return nil
}
// Netrc returns a netrc file capable of authenticating Gitea requests and
// cloning Gitea repositories. The netrc will use the global machine account
// when configured.
func (c *client) Netrc(u *model.User, r *model.Repo) (*model.Netrc, error) {
if c.Password != "" {
return &model.Netrc{
Login: c.Username,
Password: c.Password,
Machine: c.Machine,
}, nil
}
return &model.Netrc{
Login: u.Token,
Password: "x-oauth-basic",
Machine: c.Machine,
}, nil
}
// Activate activates the repository by registering post-commit hooks with
// the Gitea repository.
func (c *client) Activate(u *model.User, r *model.Repo, link string) error {
config := map[string]string{
"url": link,
"secret": r.Hash,
"content_type": "json",
}
hook := gitea.CreateHookOption{
Type: "gogs",
Config: config,
Events: []string{"push", "create", "pull_request"},
Active: true,
}
client := c.newClientToken(u.Token)
_, err := client.CreateRepoHook(r.Owner, r.Name, hook)
return err
}
// Deactivate is not supported by the Gitea driver.
func (c *client) Deactivate(u *model.User, r *model.Repo, link string) error {
return nil
}
// Hook parses the incoming Gitea hook and returns the Repository and Build
// details. If the hook is unsupported nil values are returned.
func (c *client) Hook(r *http.Request) (*model.Repo, *model.Build, error) {
return parseHook(r)
}
// helper function to return the Gitea client
func (c *client) newClient() *gitea.Client {
return c.newClientToken("")
}
// helper function to return the Gitea client
func (c *client) newClientToken(token string) *gitea.Client {
client := gitea.NewClient(c.URL, token)
if c.SkipVerify {
httpClient := &http.Client{}
httpClient.Transport = &http.Transport{
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
}
client.SetHTTPClient(httpClient)
}
return client
}

191
remote/gitea/gitea_test.go Normal file
View File

@ -0,0 +1,191 @@
package gitea
import (
"net/http/httptest"
"testing"
"github.com/drone/drone/model"
"github.com/drone/drone/remote/gitea/fixtures"
"github.com/franela/goblin"
"github.com/gin-gonic/gin"
)
func Test_gogs(t *testing.T) {
gin.SetMode(gin.TestMode)
s := httptest.NewServer(fixtures.Handler())
c, _ := New(Opts{
URL: s.URL,
SkipVerify: true,
})
g := goblin.Goblin(t)
g.Describe("Gitea", func() {
g.After(func() {
s.Close()
})
g.Describe("Creating a remote", func() {
g.It("Should return client with specified options", func() {
remote, _ := New(Opts{
URL: "http://localhost:8080",
Username: "someuser",
Password: "password",
SkipVerify: true,
PrivateMode: true,
})
g.Assert(remote.(*client).URL).Equal("http://localhost:8080")
g.Assert(remote.(*client).Machine).Equal("localhost")
g.Assert(remote.(*client).Username).Equal("someuser")
g.Assert(remote.(*client).Password).Equal("password")
g.Assert(remote.(*client).SkipVerify).Equal(true)
g.Assert(remote.(*client).PrivateMode).Equal(true)
})
g.It("Should handle malformed url", func() {
_, err := New(Opts{URL: "%gh&%ij"})
g.Assert(err != nil).IsTrue()
})
})
g.Describe("Generating a netrc file", func() {
g.It("Should return a netrc with the user token", func() {
remote, _ := New(Opts{
URL: "http://gogs.com",
})
netrc, _ := remote.Netrc(fakeUser, nil)
g.Assert(netrc.Machine).Equal("gogs.com")
g.Assert(netrc.Login).Equal(fakeUser.Token)
g.Assert(netrc.Password).Equal("x-oauth-basic")
})
g.It("Should return a netrc with the machine account", func() {
remote, _ := New(Opts{
URL: "http://gogs.com",
Username: "someuser",
Password: "password",
})
netrc, _ := remote.Netrc(nil, nil)
g.Assert(netrc.Machine).Equal("gogs.com")
g.Assert(netrc.Login).Equal("someuser")
g.Assert(netrc.Password).Equal("password")
})
})
g.Describe("Requesting a repository", func() {
g.It("Should return the repository details", func() {
repo, err := c.Repo(fakeUser, fakeRepo.Owner, fakeRepo.Name)
g.Assert(err == nil).IsTrue()
g.Assert(repo.Owner).Equal(fakeRepo.Owner)
g.Assert(repo.Name).Equal(fakeRepo.Name)
g.Assert(repo.FullName).Equal(fakeRepo.Owner + "/" + fakeRepo.Name)
g.Assert(repo.IsPrivate).IsTrue()
g.Assert(repo.Clone).Equal("http://localhost/test_name/repo_name.git")
g.Assert(repo.Link).Equal("http://localhost/test_name/repo_name")
})
g.It("Should handle a not found error", func() {
_, err := c.Repo(fakeUser, fakeRepoNotFound.Owner, fakeRepoNotFound.Name)
g.Assert(err != nil).IsTrue()
})
})
g.Describe("Requesting repository permissions", func() {
g.It("Should return the permission details", func() {
perm, err := c.Perm(fakeUser, fakeRepo.Owner, fakeRepo.Name)
g.Assert(err == nil).IsTrue()
g.Assert(perm.Admin).IsTrue()
g.Assert(perm.Push).IsTrue()
g.Assert(perm.Pull).IsTrue()
})
g.It("Should handle a not found error", func() {
_, err := c.Perm(fakeUser, fakeRepoNotFound.Owner, fakeRepoNotFound.Name)
g.Assert(err != nil).IsTrue()
})
})
g.Describe("Requesting a repository list", func() {
g.It("Should return the repository list", func() {
repos, err := c.Repos(fakeUser)
g.Assert(err == nil).IsTrue()
g.Assert(repos[0].Owner).Equal(fakeRepo.Owner)
g.Assert(repos[0].Name).Equal(fakeRepo.Name)
g.Assert(repos[0].FullName).Equal(fakeRepo.Owner + "/" + fakeRepo.Name)
})
g.It("Should handle a not found error", func() {
_, err := c.Repos(fakeUserNoRepos)
g.Assert(err != nil).IsTrue()
})
})
g.It("Should register repositroy hooks", func() {
err := c.Activate(fakeUser, fakeRepo, "http://localhost")
g.Assert(err == nil).IsTrue()
})
g.It("Should return a repository file", func() {
raw, err := c.File(fakeUser, fakeRepo, fakeBuild, ".drone.yml")
g.Assert(err == nil).IsTrue()
g.Assert(string(raw)).Equal("{ platform: linux/amd64 }")
})
g.It("Should return a repository file from a ref", func() {
raw, err := c.File(fakeUser, fakeRepo, fakeBuildWithRef, ".drone.yml")
g.Assert(err == nil).IsTrue()
g.Assert(string(raw)).Equal("{ platform: linux/amd64 }")
})
g.Describe("Given an authentication request", func() {
g.It("Should redirect to login form")
g.It("Should create an access token")
g.It("Should handle an access token error")
g.It("Should return the authenticated user")
})
g.Describe("Given a repository hook", func() {
g.It("Should skip non-push events")
g.It("Should return push details")
g.It("Should handle a parsing error")
})
g.It("Should return no-op for usupporeted features", func() {
_, err1 := c.Auth("octocat", "4vyW6b49Z")
err2 := c.Status(nil, nil, nil, "")
err3 := c.Deactivate(nil, nil, "")
g.Assert(err1 != nil).IsTrue()
g.Assert(err2 == nil).IsTrue()
g.Assert(err3 == nil).IsTrue()
})
})
}
var (
fakeUser = &model.User{
Login: "someuser",
Token: "cfcd2084",
}
fakeUserNoRepos = &model.User{
Login: "someuser",
Token: "repos_not_found",
}
fakeRepo = &model.Repo{
Owner: "test_name",
Name: "repo_name",
FullName: "test_name/repo_name",
}
fakeRepoNotFound = &model.Repo{
Owner: "test_name",
Name: "repo_not_found",
FullName: "test_name/repo_not_found",
}
fakeBuild = &model.Build{
Commit: "9ecad50",
}
fakeBuildWithRef = &model.Build{
Ref: "refs/tags/v1.0.0",
}
)

221
remote/gitea/helper.go Normal file
View File

@ -0,0 +1,221 @@
package gitea
import (
"encoding/json"
"fmt"
"io"
"net/url"
"strings"
"time"
"github.com/drone/drone/model"
"github.com/go-gitea/go-sdk/gitea"
)
// helper function that converts a Gogs repository to a Drone repository.
func toRepoLite(from *gitea.Repository) *model.RepoLite {
name := strings.Split(from.FullName, "/")[1]
avatar := expandAvatar(
from.HTMLURL,
from.Owner.AvatarURL,
)
return &model.RepoLite{
Name: name,
Owner: from.Owner.UserName,
FullName: from.FullName,
Avatar: avatar,
}
}
// helper function that converts a Gogs repository to a Drone repository.
func toRepo(from *gitea.Repository) *model.Repo {
name := strings.Split(from.FullName, "/")[1]
avatar := expandAvatar(
from.HTMLURL,
from.Owner.AvatarURL,
)
return &model.Repo{
Kind: model.RepoGit,
Name: name,
Owner: from.Owner.UserName,
FullName: from.FullName,
Avatar: avatar,
Link: from.HTMLURL,
IsPrivate: from.Private,
Clone: from.CloneURL,
Branch: "master",
}
}
// helper function that converts a Gogs permission to a Drone permission.
func toPerm(from *gitea.Permission) *model.Perm {
return &model.Perm{
Pull: from.Pull,
Push: from.Push,
Admin: from.Admin,
}
}
// helper function that converts a Gogs team to a Drone team.
func toTeam(from *gitea.Organization, link string) *model.Team {
return &model.Team{
Login: from.UserName,
Avatar: expandAvatar(link, from.AvatarURL),
}
}
// helper function that extracts the Build data from a Gogs push hook
func buildFromPush(hook *pushHook) *model.Build {
avatar := expandAvatar(
hook.Repo.URL,
fixMalformedAvatar(hook.Sender.Avatar),
)
author := hook.Sender.Login
if author == "" {
author = hook.Sender.Username
}
sender := hook.Sender.Username
if sender == "" {
sender = hook.Sender.Login
}
return &model.Build{
Event: model.EventPush,
Commit: hook.After,
Ref: hook.Ref,
Link: hook.Compare,
Branch: strings.TrimPrefix(hook.Ref, "refs/heads/"),
Message: hook.Commits[0].Message,
Avatar: avatar,
Author: author,
Timestamp: time.Now().UTC().Unix(),
Sender: sender,
}
}
// helper function that extracts the Build data from a Gogs tag hook
func buildFromTag(hook *pushHook) *model.Build {
avatar := expandAvatar(
hook.Repo.URL,
fixMalformedAvatar(hook.Sender.Avatar),
)
author := hook.Sender.Login
if author == "" {
author = hook.Sender.Username
}
sender := hook.Sender.Username
if sender == "" {
sender = hook.Sender.Login
}
return &model.Build{
Event: model.EventTag,
Commit: hook.After,
Ref: fmt.Sprintf("refs/tags/%s", hook.Ref),
Link: fmt.Sprintf("%s/src/%s", hook.Repo.URL, hook.Ref),
Branch: fmt.Sprintf("refs/tags/%s", hook.Ref),
Message: fmt.Sprintf("created tag %s", hook.Ref),
Avatar: avatar,
Author: author,
Sender: sender,
Timestamp: time.Now().UTC().Unix(),
}
}
// helper function that extracts the Build data from a Gogs pull_request hook
func buildFromPullRequest(hook *pullRequestHook) *model.Build {
avatar := expandAvatar(
hook.Repo.URL,
fixMalformedAvatar(hook.PullRequest.User.Avatar),
)
sender := hook.Sender.Username
if sender == "" {
sender = hook.Sender.Login
}
build := &model.Build{
Event: model.EventPull,
Commit: hook.PullRequest.Head.Sha,
Link: hook.PullRequest.URL,
Ref: fmt.Sprintf("refs/pull/%d/head", hook.Number),
Branch: hook.PullRequest.BaseBranch,
Message: hook.PullRequest.Title,
Author: hook.PullRequest.User.Username,
Avatar: avatar,
Sender: sender,
Title: hook.PullRequest.Title,
Refspec: fmt.Sprintf("%s:%s",
hook.PullRequest.HeadBranch,
hook.PullRequest.BaseBranch,
),
}
return build
}
// helper function that extracts the Repository data from a Gogs push hook
func repoFromPush(hook *pushHook) *model.Repo {
return &model.Repo{
Name: hook.Repo.Name,
Owner: hook.Repo.Owner.Username,
FullName: hook.Repo.FullName,
Link: hook.Repo.URL,
}
}
// helper function that extracts the Repository data from a Gogs pull_request hook
func repoFromPullRequest(hook *pullRequestHook) *model.Repo {
return &model.Repo{
Name: hook.Repo.Name,
Owner: hook.Repo.Owner.Username,
FullName: hook.Repo.FullName,
Link: hook.Repo.URL,
}
}
// helper function that parses a push hook from a read closer.
func parsePush(r io.Reader) (*pushHook, error) {
push := new(pushHook)
err := json.NewDecoder(r).Decode(push)
return push, err
}
func parsePullRequest(r io.Reader) (*pullRequestHook, error) {
pr := new(pullRequestHook)
err := json.NewDecoder(r).Decode(pr)
return pr, err
}
// fixMalformedAvatar is a helper function that fixes an avatar url if malformed
// (currently a known bug with gogs)
func fixMalformedAvatar(url string) string {
index := strings.Index(url, "///")
if index != -1 {
return url[index+1:]
}
index = strings.Index(url, "//avatars/")
if index != -1 {
return strings.Replace(url, "//avatars/", "/avatars/", -1)
}
return url
}
// expandAvatar is a helper function that converts a relative avatar URL to the
// absolute url.
func expandAvatar(repo, rawurl string) string {
aurl, err := url.Parse(rawurl)
if err != nil {
return rawurl
}
if aurl.IsAbs() {
// Url is already absolute
return aurl.String()
}
// Resolve to base
burl, err := url.Parse(repo)
if err != nil {
return rawurl
}
aurl = burl.ResolveReference(aurl)
return aurl.String()
}

250
remote/gitea/helper_test.go Normal file
View File

@ -0,0 +1,250 @@
package gitea
import (
"bytes"
"testing"
"github.com/drone/drone/model"
"github.com/drone/drone/remote/gitea/fixtures"
"github.com/franela/goblin"
"github.com/go-gitea/go-sdk/gitea"
)
func Test_parse(t *testing.T) {
g := goblin.Goblin(t)
g.Describe("Gogs", func() {
g.It("Should parse push hook payload", func() {
buf := bytes.NewBufferString(fixtures.HookPush)
hook, err := parsePush(buf)
g.Assert(err == nil).IsTrue()
g.Assert(hook.Ref).Equal("refs/heads/master")
g.Assert(hook.After).Equal("ef98532add3b2feb7a137426bba1248724367df5")
g.Assert(hook.Before).Equal("4b2626259b5a97b6b4eab5e6cca66adb986b672b")
g.Assert(hook.Compare).Equal("http://gogs.golang.org/gordon/hello-world/compare/4b2626259b5a97b6b4eab5e6cca66adb986b672b...ef98532add3b2feb7a137426bba1248724367df5")
g.Assert(hook.Repo.Name).Equal("hello-world")
g.Assert(hook.Repo.URL).Equal("http://gogs.golang.org/gordon/hello-world")
g.Assert(hook.Repo.Owner.Name).Equal("gordon")
g.Assert(hook.Repo.FullName).Equal("gordon/hello-world")
g.Assert(hook.Repo.Owner.Email).Equal("gordon@golang.org")
g.Assert(hook.Repo.Owner.Username).Equal("gordon")
g.Assert(hook.Repo.Private).Equal(true)
g.Assert(hook.Pusher.Name).Equal("gordon")
g.Assert(hook.Pusher.Email).Equal("gordon@golang.org")
g.Assert(hook.Pusher.Username).Equal("gordon")
g.Assert(hook.Sender.Login).Equal("gordon")
g.Assert(hook.Sender.Avatar).Equal("http://gogs.golang.org///1.gravatar.com/avatar/8c58a0be77ee441bb8f8595b7f1b4e87")
})
g.It("Should parse tag hook payload", func() {
buf := bytes.NewBufferString(fixtures.HookPushTag)
hook, err := parsePush(buf)
g.Assert(err == nil).IsTrue()
g.Assert(hook.Ref).Equal("v1.0.0")
g.Assert(hook.Repo.Name).Equal("hello-world")
g.Assert(hook.Repo.URL).Equal("http://gogs.golang.org/gordon/hello-world")
g.Assert(hook.Repo.FullName).Equal("gordon/hello-world")
g.Assert(hook.Repo.Owner.Email).Equal("gordon@golang.org")
g.Assert(hook.Repo.Owner.Username).Equal("gordon")
g.Assert(hook.Repo.Private).Equal(true)
g.Assert(hook.Sender.Username).Equal("gordon")
g.Assert(hook.Sender.Avatar).Equal("https://secure.gravatar.com/avatar/8c58a0be77ee441bb8f8595b7f1b4e87")
})
g.It("Should parse pull_request hook payload", func() {
buf := bytes.NewBufferString(fixtures.HookPullRequest)
hook, err := parsePullRequest(buf)
g.Assert(err == nil).IsTrue()
g.Assert(hook.Action).Equal("opened")
g.Assert(hook.Number).Equal(int64(1))
g.Assert(hook.Repo.Name).Equal("hello-world")
g.Assert(hook.Repo.URL).Equal("http://gogs.golang.org/gordon/hello-world")
g.Assert(hook.Repo.FullName).Equal("gordon/hello-world")
g.Assert(hook.Repo.Owner.Email).Equal("gordon@golang.org")
g.Assert(hook.Repo.Owner.Username).Equal("gordon")
g.Assert(hook.Repo.Private).Equal(true)
g.Assert(hook.Sender.Username).Equal("gordon")
g.Assert(hook.Sender.Avatar).Equal("https://secure.gravatar.com/avatar/8c58a0be77ee441bb8f8595b7f1b4e87")
g.Assert(hook.PullRequest.Title).Equal("Update the README with new information")
g.Assert(hook.PullRequest.Body).Equal("please merge")
g.Assert(hook.PullRequest.State).Equal("open")
g.Assert(hook.PullRequest.User.Username).Equal("gordon")
g.Assert(hook.PullRequest.Base.Label).Equal("master")
g.Assert(hook.PullRequest.Base.Ref).Equal("master")
g.Assert(hook.PullRequest.Head.Label).Equal("feature/changes")
g.Assert(hook.PullRequest.Head.Ref).Equal("feature/changes")
})
g.It("Should return a Build struct from a push hook", func() {
buf := bytes.NewBufferString(fixtures.HookPush)
hook, _ := parsePush(buf)
build := buildFromPush(hook)
g.Assert(build.Event).Equal(model.EventPush)
g.Assert(build.Commit).Equal(hook.After)
g.Assert(build.Ref).Equal(hook.Ref)
g.Assert(build.Link).Equal(hook.Compare)
g.Assert(build.Branch).Equal("master")
g.Assert(build.Message).Equal(hook.Commits[0].Message)
g.Assert(build.Avatar).Equal("http://1.gravatar.com/avatar/8c58a0be77ee441bb8f8595b7f1b4e87")
g.Assert(build.Author).Equal(hook.Sender.Login)
})
g.It("Should return a Repo struct from a push hook", func() {
buf := bytes.NewBufferString(fixtures.HookPush)
hook, _ := parsePush(buf)
repo := repoFromPush(hook)
g.Assert(repo.Name).Equal(hook.Repo.Name)
g.Assert(repo.Owner).Equal(hook.Repo.Owner.Username)
g.Assert(repo.FullName).Equal("gordon/hello-world")
g.Assert(repo.Link).Equal(hook.Repo.URL)
})
g.It("Should return a Build struct from a pull_request hook", func() {
buf := bytes.NewBufferString(fixtures.HookPullRequest)
hook, _ := parsePullRequest(buf)
build := buildFromPullRequest(hook)
g.Assert(build.Event).Equal(model.EventPull)
g.Assert(build.Commit).Equal(hook.PullRequest.Head.Sha)
g.Assert(build.Ref).Equal("refs/pull/1/head")
g.Assert(build.Link).Equal(hook.PullRequest.URL)
g.Assert(build.Branch).Equal("master")
g.Assert(build.Message).Equal(hook.PullRequest.Title)
g.Assert(build.Avatar).Equal("http://1.gravatar.com/avatar/8c58a0be77ee441bb8f8595b7f1b4e87")
g.Assert(build.Author).Equal(hook.PullRequest.User.Username)
})
g.It("Should return a Repo struct from a pull_request hook", func() {
buf := bytes.NewBufferString(fixtures.HookPullRequest)
hook, _ := parsePullRequest(buf)
repo := repoFromPullRequest(hook)
g.Assert(repo.Name).Equal(hook.Repo.Name)
g.Assert(repo.Owner).Equal(hook.Repo.Owner.Username)
g.Assert(repo.FullName).Equal("gordon/hello-world")
g.Assert(repo.Link).Equal(hook.Repo.URL)
})
g.It("Should return a Perm struct from a Gogs Perm", func() {
perms := []gogs.Permission{
{true, true, true},
{true, true, false},
{true, false, false},
}
for _, from := range perms {
perm := toPerm(from)
g.Assert(perm.Pull).Equal(from.Pull)
g.Assert(perm.Push).Equal(from.Push)
g.Assert(perm.Admin).Equal(from.Admin)
}
})
g.It("Should return a Team struct from a Gogs Org", func() {
from := &gogs.Organization{
UserName: "drone",
AvatarUrl: "/avatars/1",
}
to := toTeam(from, "http://localhost:80")
g.Assert(to.Login).Equal(from.UserName)
g.Assert(to.Avatar).Equal("http://localhost:80/avatars/1")
})
g.It("Should return a Repo struct from a Gogs Repo", func() {
from := gogs.Repository{
FullName: "gophers/hello-world",
Owner: gogs.User{
UserName: "gordon",
AvatarUrl: "http://1.gravatar.com/avatar/8c58a0be77ee441bb8f8595b7f1b4e87",
},
CloneUrl: "http://gogs.golang.org/gophers/hello-world.git",
HtmlUrl: "http://gogs.golang.org/gophers/hello-world",
Private: true,
}
repo := toRepo(&from)
g.Assert(repo.FullName).Equal(from.FullName)
g.Assert(repo.Owner).Equal(from.Owner.UserName)
g.Assert(repo.Name).Equal("hello-world")
g.Assert(repo.Branch).Equal("master")
g.Assert(repo.Link).Equal(from.HtmlUrl)
g.Assert(repo.Clone).Equal(from.CloneUrl)
g.Assert(repo.Avatar).Equal(from.Owner.AvatarUrl)
g.Assert(repo.IsPrivate).Equal(from.Private)
})
g.It("Should return a RepoLite struct from a Gogs Repo", func() {
from := gogs.Repository{
FullName: "gophers/hello-world",
Owner: gogs.User{
UserName: "gordon",
AvatarUrl: "http://1.gravatar.com/avatar/8c58a0be77ee441bb8f8595b7f1b4e87",
},
}
repo := toRepoLite(&from)
g.Assert(repo.FullName).Equal(from.FullName)
g.Assert(repo.Owner).Equal(from.Owner.UserName)
g.Assert(repo.Name).Equal("hello-world")
g.Assert(repo.Avatar).Equal(from.Owner.AvatarUrl)
})
g.It("Should correct a malformed avatar url", func() {
var urls = []struct {
Before string
After string
}{
{
"http://gogs.golang.org///1.gravatar.com/avatar/8c58a0be77ee441bb8f8595b7f1b4e87",
"//1.gravatar.com/avatar/8c58a0be77ee441bb8f8595b7f1b4e87",
},
{
"//1.gravatar.com/avatar/8c58a0be77ee441bb8f8595b7f1b4e87",
"//1.gravatar.com/avatar/8c58a0be77ee441bb8f8595b7f1b4e87",
},
{
"http://gogs.golang.org/avatars/1",
"http://gogs.golang.org/avatars/1",
},
{
"http://gogs.golang.org//avatars/1",
"http://gogs.golang.org/avatars/1",
},
}
for _, url := range urls {
got := fixMalformedAvatar(url.Before)
g.Assert(got).Equal(url.After)
}
})
g.It("Should expand the avatar url", func() {
var urls = []struct {
Before string
After string
}{
{
"/avatars/1",
"http://gogs.io/avatars/1",
},
{
"//1.gravatar.com/avatar/8c58a0be77ee441bb8f8595b7f1b4e87",
"http://1.gravatar.com/avatar/8c58a0be77ee441bb8f8595b7f1b4e87",
},
{
"/gogs/avatars/2",
"http://gogs.io/gogs/avatars/2",
},
}
var repo = "http://gogs.io/foo/bar"
for _, url := range urls {
got := expandAvatar(repo, url.Before)
g.Assert(got).Equal(url.After)
}
})
})
}

107
remote/gitea/parse.go Normal file
View File

@ -0,0 +1,107 @@
package gitea
import (
"io"
"net/http"
"github.com/drone/drone/model"
)
const (
hookEvent = "X-Gogs-Event"
hookPush = "push"
hookCreated = "create"
hookPullRequest = "pull_request"
actionOpen = "opened"
actionSync = "synchronize"
stateOpen = "open"
refBranch = "branch"
refTag = "tag"
)
// parseHook parses a Bitbucket hook from an http.Request request and returns
// Repo and Build detail. If a hook type is unsupported nil values are returned.
func parseHook(r *http.Request) (*model.Repo, *model.Build, error) {
switch r.Header.Get(hookEvent) {
case hookPush:
return parsePushHook(r.Body)
case hookCreated:
return parseCreatedHook(r.Body)
case hookPullRequest:
return parsePullRequestHook(r.Body)
}
return nil, nil, nil
}
// parsePushHook parses a push hook and returns the Repo and Build details.
// If the commit type is unsupported nil values are returned.
func parsePushHook(payload io.Reader) (*model.Repo, *model.Build, error) {
var (
repo *model.Repo
build *model.Build
)
push, err := parsePush(payload)
if err != nil {
return nil, nil, err
}
// is this even needed?
if push.RefType == refBranch {
return nil, nil, nil
}
repo = repoFromPush(push)
build = buildFromPush(push)
return repo, build, err
}
// parseCreatedHook parses a push hook and returns the Repo and Build details.
// If the commit type is unsupported nil values are returned.
func parseCreatedHook(payload io.Reader) (*model.Repo, *model.Build, error) {
var (
repo *model.Repo
build *model.Build
)
push, err := parsePush(payload)
if err != nil {
return nil, nil, err
}
if push.RefType != refTag {
return nil, nil, nil
}
repo = repoFromPush(push)
build = buildFromTag(push)
return repo, build, err
}
// parsePullRequestHook parses a pull_request hook and returns the Repo and Build details.
func parsePullRequestHook(payload io.Reader) (*model.Repo, *model.Build, error) {
var (
repo *model.Repo
build *model.Build
)
pr, err := parsePullRequest(payload)
if err != nil {
return nil, nil, err
}
// Don't trigger builds for non-code changes, or if PR is not open
if pr.Action != actionOpen && pr.Action != actionSync {
return nil, nil, nil
}
if pr.PullRequest.State != stateOpen {
return nil, nil, nil
}
repo = repoFromPullRequest(pr)
build = buildFromPullRequest(pr)
return repo, build, err
}

View File

@ -0,0 +1 @@
package gitea

127
remote/gitea/types.go Normal file
View File

@ -0,0 +1,127 @@
package gitea
type pushHook struct {
Ref string `json:"ref"`
Before string `json:"before"`
After string `json:"after"`
Compare string `json:"compare_url"`
RefType string `json:"ref_type"`
Pusher struct {
Name string `json:"name"`
Email string `json:"email"`
Login string `json:"login"`
Username string `json:"username"`
} `json:"pusher"`
Repo struct {
ID int64 `json:"id"`
Name string `json:"name"`
FullName string `json:"full_name"`
URL string `json:"html_url"`
Private bool `json:"private"`
Owner struct {
Name string `json:"name"`
Email string `json:"email"`
Username string `json:"username"`
} `json:"owner"`
} `json:"repository"`
Commits []struct {
ID string `json:"id"`
Message string `json:"message"`
URL string `json:"url"`
} `json:"commits"`
Sender struct {
ID int64 `json:"id"`
Login string `json:"login"`
Username string `json:"username"`
Avatar string `json:"avatar_url"`
} `json:"sender"`
}
type pullRequestHook struct {
Action string `json:"action"`
Number int64 `json:"number"`
PullRequest struct {
ID int64 `json:"id"`
User struct {
ID int64 `json:"id"`
Username string `json:"username"`
Name string `json:"full_name"`
Email string `json:"email"`
Avatar string `json:"avatar_url"`
} `json:"user"`
Title string `json:"title"`
Body string `json:"body"`
Labels []string `json:"labels"`
State string `json:"state"`
URL string `json:"html_url"`
Mergeable bool `json:"mergeable"`
Merged bool `json:"merged"`
MergeBase string `json:"merge_base"`
BaseBranch string `json:"base_branch"`
Base struct {
Label string `json:"label"`
Ref string `json:"ref"`
Sha string `json:"sha"`
Repo struct {
ID int64 `json:"id"`
Name string `json:"name"`
FullName string `json:"full_name"`
URL string `json:"html_url"`
Private bool `json:"private"`
Owner struct {
ID int64 `json:"id"`
Username string `json:"username"`
Name string `json:"full_name"`
Email string `json:"email"`
Avatar string `json:"avatar_url"`
} `json:"owner"`
} `json:"repo"`
} `json:"base"`
HeadBranch string `json:"head_branch"`
Head struct {
Label string `json:"label"`
Ref string `json:"ref"`
Sha string `json:"sha"`
Repo struct {
ID int64 `json:"id"`
Name string `json:"name"`
FullName string `json:"full_name"`
URL string `json:"html_url"`
Private bool `json:"private"`
Owner struct {
ID int64 `json:"id"`
Username string `json:"username"`
Name string `json:"full_name"`
Email string `json:"email"`
Avatar string `json:"avatar_url"`
} `json:"owner"`
} `json:"repo"`
} `json:"head"`
} `json:"pull_request"`
Repo struct {
ID int64 `json:"id"`
Name string `json:"name"`
FullName string `json:"full_name"`
URL string `json:"html_url"`
Private bool `json:"private"`
Owner struct {
ID int64 `json:"id"`
Username string `json:"username"`
Name string `json:"full_name"`
Email string `json:"email"`
Avatar string `json:"avatar_url"`
} `json:"owner"`
} `json:"repository"`
Sender struct {
ID int64 `json:"id"`
Login string `json:"login"`
Username string `json:"username"`
Name string `json:"full_name"`
Email string `json:"email"`
Avatar string `json:"avatar_url"`
} `json:"sender"`
}

View File

@ -7,6 +7,7 @@ import (
"github.com/drone/drone/remote"
"github.com/drone/drone/remote/bitbucket"
"github.com/drone/drone/remote/bitbucketserver"
"github.com/drone/drone/remote/gitea"
"github.com/drone/drone/remote/github"
"github.com/drone/drone/remote/gitlab"
"github.com/drone/drone/remote/gogs"
@ -39,6 +40,8 @@ func setupRemote(c *cli.Context) (remote.Remote, error) {
return setupStash(c)
case c.Bool("gogs"):
return setupGogs(c)
case c.Bool("gitea"):
return setupGitea(c)
default:
return nil, fmt.Errorf("version control system not configured")
}
@ -63,6 +66,17 @@ func setupGogs(c *cli.Context) (remote.Remote, error) {
})
}
// helper function to setup the Gitea remote from the CLI arguments.
func setupGitea(c *cli.Context) (remote.Remote, error) {
return gitea.New(gitea.Opts{
URL: c.String("gitea-server"),
Username: c.String("gitea-git-username"),
Password: c.String("gitea-git-password"),
PrivateMode: c.Bool("gitea-private-mode"),
SkipVerify: c.Bool("gitea-skip-verify"),
})
}
// helper function to setup the Stash remote from the CLI arguments.
func setupStash(c *cli.Context) (remote.Remote, error) {
return bitbucketserver.New(bitbucketserver.Opts{

86
vendor/github.com/go-gitea/go-sdk/CONTRIBUTING.md generated vendored Normal file
View File

@ -0,0 +1,86 @@
# Contribution Guidelines
## Introduction
This document explains how to contribute changes to the Gitea project. It assumes you have followed the [installation instructions](https://github.com/go-gitea/docs/tree/master/en-US/installation). Sensitive security-related issues should be reported to [security@gitea.io](mailto:security@gitea.io).
## Bug reports
Please search the issues on the issue tracker with a variety of keywords to ensure your bug is not already reported.
If unique, [open an issue](https://github.com/go-gitea/gitea/issues/new) and answer the questions so we can understand and reproduce the problematic behavior.
To show us that the issue you are having is in Gitea itself, please write clear, concise instructions so we can reproduce the behavior (even if it seems obvious). The more detailed and specific you are, the faster we can fix the issue. Check out [How to Report Bugs Effectively](http://www.chiark.greenend.org.uk/~sgtatham/bugs.html).
Please be kind, remember that Gitea comes at no cost to you, and you're getting free help.
## Discuss your design
The project welcomes submissions but please let everyone know what you're working on if you want to change or add something to the Gitea repositories.
Before starting to write something new for the Gitea project, please [file an issue](https://github.com/go-gitea/gitea/issues/new). Significant changes must go through the [change proposal process](https://github.com/go-gitea/proposals) before they can be accepted.
This process gives everyone a chance to validate the design, helps prevent duplication of effort, and ensures that the idea fits inside the goals for the project and tools. It also checks that the design is sound before code is written; the code review tool is not the place for high-level discussions.
## Testing redux
Before sending code out for review, run all the tests for the whole tree to make sure the changes don't break other usage and keep the compatibility on upgrade. To make sure you are running the test suite exactly like we do, you should install the CLI for [Drone CI](https://github.com/drone/drone), as we are using the server for continous testing, following [these instructions](http://readme.drone.io/0.5/install/cli/). After that you can simply call `drone exec` within your working directory and it will try to run the test suite locally.
## Code review
Changes to Gitea must be reviewed before they are accepted, no matter who makes the change even if it is an owner or a maintainer. We use GitHub's pull request workflow to do that and we also use [LGTM](http://lgtm.co) to ensure every PR is reviewed by at least 2 maintainers.
Please try to make your pull request easy to review for us. Please read the "[How to get faster PR reviews](https://github.com/kubernetes/community/blob/master/contributors/devel/faster_reviews.md)" guide, it has lots of useful tips for any project you may want to contribute. Some of the key points:
* Make small pull requests. The smaller, the faster to review and the more likely it will be merged soon.
* Don't make changes unrelated to your PR. Maybe there are typos on some comments, maybe refactoring would be welcome on a function... but if that is not related to your PR, please make *another* PR for that.
* Split big pull requests into multiple small ones. An incremental change will be faster to review than a huge PR.
## Sign your work
The sign-off is a simple line at the end of the explanation for the patch. Your signature certifies that you wrote the patch or otherwise have the right to pass it on as an open-source patch. The rules are pretty simple: If you can certify [DCO](DCO), then you just add a line to every git commit message:
```
Signed-off-by: Joe Smith <joe.smith@email.com>
```
Please use your real name, we really dislike pseudonyms or anonymous contributions. We are in the open-source world without secrets. If you set your `user.name` and `user.email` git configs, you can sign your commit automatically with `git commit -s`.
## Maintainers
To make sure every PR is checked, we have [team maintainers](https://github.com/orgs/go-gitea/teams/maintainers). Every PR **MUST** be reviewed by at least two maintainers (or owners) before it can get merged. A maintainer should be a contributor of Gitea (or Gogs) and contributed at least 4 accepted PRs. A contributor should apply as a maintainer in the [Gitter develop channel](https://gitter.im/go-gitea/develop). The owners or the team maintainers may invite the contributor. A maintainer should spend some time on code reviews. If a maintainer has no time to do that, they should apply to leave the maintainers team and we will give them the honor of being a member of the [advisors team](https://github.com/orgs/go-gitea/teams/advisors). Of course, if an advisor has time to code review, we will gladly welcome them back to the maintainers team. If a maintainer is inactive for more than 3 months and forgets to leave the maintainers team, the owners may move him or her from the maintainers team to the advisors team.
## Owners
Since Gitea is a pure community organization without any company support, to keep the development healthy we will elect three owners every year. All contributors may vote to elect up to three candidates, one of which will be the main owner, and the other two the assistant owners. When the new owners have been elected, the old owners will give up ownership to the newly elected owners. If an owner is unable to do so, the other owners will assist in ceding ownership to the newly elected owners.
After the election, the new owners should proactively agree with our [CONTRIBUTING](CONTRIBUTING.md) requirements on the [Gitter main channel](https://gitter.im/go-gitea/gitea). Below are the words to speak:
```
I'm honored to having been elected an owner of Gitea, I agree with [CONTRIBUTING](CONTRIBUTING.md). I will spend part of my time on Gitea and lead the development of Gitea.
```
To honor the past owners, here's the history of the owners and the time they served:
* 2016-11-04 ~ 2017-12-31
* [Lunny Xiao](https://github.com/lunny) <xiaolunwen@gmail.com>
* [Thomas Boerger](https://github.com/tboerger) <thomas@webhippie.de>
* [Kim Carlbäcker](https://github.com/bkcsoft) <kim.carlbacker@gmail.com>
## Versions
Gitea has the `master` branch as a tip branch and has version branches such as `v0.9`. `v0.9` is a release branch and we will tag `v0.9.0` for binary download. If `v0.9.0` has bugs, we will accept pull requests on the `v0.9` branch and publish a `v0.9.1` tag, after bringing the bug fix also to the master branch.
Since the `master` branch is a tip version, if you wish to use Gitea in production, please download the latest release tag version. All the branches will be protected via GitHub, all the PRs to every branch must be reviewed by two maintainers and must pass the automatic tests.
## Copyright
Code that you contribute should use the standard copyright header:
```
// Copyright 2017 The Gitea Authors. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
```
Files in the repository contain copyright from the year they are added to the year they are last changed. If the copyright author is changed, just paste the header below the old one.

36
vendor/github.com/go-gitea/go-sdk/DCO generated vendored Normal file
View File

@ -0,0 +1,36 @@
Developer Certificate of Origin
Version 1.1
Copyright (C) 2004, 2006 The Linux Foundation and its contributors.
660 York Street, Suite 102,
San Francisco, CA 94110 USA
Everyone is permitted to copy and distribute verbatim copies of this
license document, but changing it is not allowed.
Developer's Certificate of Origin 1.1
By making a contribution to this project, I certify that:
(a) The contribution was created in whole or in part by me and I
have the right to submit it under the open source license
indicated in the file; or
(b) The contribution is based upon previous work that, to the best
of my knowledge, is covered under an appropriate open source
license and I have the right under that license to submit that
work with modifications, whether created in whole or in part
by me, under the same open source license (unless I am
permitted to submit under a different license), as indicated
in the file; or
(c) The contribution was provided directly to me by some other
person who certified (a), (b) or (c) and I have not modified
it.
(d) I understand and agree that this project and the contribution
are public and that a record of the contribution (including all
personal information I submit with it, including my sign-off) is
maintained indefinitely and may be redistributed consistent with
this project or the open source license(s) involved.

20
vendor/github.com/go-gitea/go-sdk/LICENSE generated vendored Normal file
View File

@ -0,0 +1,20 @@
Copyright (c) 2016 The Gitea Authors
Copyright (c) 2014 The Gogs Authors
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

15
vendor/github.com/go-gitea/go-sdk/MAINTAINERS generated vendored Normal file
View File

@ -0,0 +1,15 @@
Alexey Makhov <amakhov@avito.ru> (@makhov)
Andrey Nering <andrey.nering@gmail.com> (@andreynering)
Bo-Yi Wu <appleboy.tw@gmail.com> (@appleboy)
Ethan Koenig <ethantkoenig@gmail.com> (@ethantkoenig)
Kees de Vries <bouwko@gmail.com> (@Bwko)
Kim Carlbäcker <kim.carlbacker@gmail.com> (@bkcsoft)
LefsFlare <nobody@nobody.tld> (@LefsFlarey)
Lunny Xiao <xiaolunwen@gmail.com> (@lunny)
Matthias Loibl <mail@matthiasloibl.com> (@metalmatze)
Rachid Zarouali <nobody@nobody.tld> (@xinity)
Rémy Boulanouar <admin@dblk.org> (@DblK)
Sandro Santilli <strk@kbt.io> (@strk)
Thibault Meyer <meyer.thibault@gmail.com> (@0xbaadf00d)
Thomas Boerger <thomas@webhippie.de> (@tboerger)
Antoine Girard <sapk@sapk.fr> (@sapk)

40
vendor/github.com/go-gitea/go-sdk/Makefile generated vendored Normal file
View File

@ -0,0 +1,40 @@
IMPORT := code.gitea.io/sdk
PACKAGES ?= $(shell go list ./... | grep -v /vendor/)
GENERATE ?= code.gitea.io/sdk/gitea
.PHONY: all
all: clean test build
.PHONY: clean
clean:
go clean -i ./...
generate:
@which mockery > /dev/null; if [ $$? -ne 0 ]; then \
go get -u github.com/vektra/mockery/...; \
fi
go generate $(GENERATE)
.PHONY: fmt
fmt:
find . -name "*.go" -type f -not -path "./vendor/*" | xargs gofmt -s -w
.PHONY: vet
vet:
go vet $(PACKAGES)
.PHONY: lint
lint:
@which golint > /dev/null; if [ $$? -ne 0 ]; then \
go get -u github.com/golang/lint/golint; \
fi
for PKG in $(PACKAGES); do golint -set_exit_status $$PKG || exit 1; done;
.PHONY: test
test:
for PKG in $(PACKAGES); do go test -cover -coverprofile $$GOPATH/src/$$PKG/coverage.out $$PKG || exit 1; done;
.PHONY: build
build:
go build ./gitea

26
vendor/github.com/go-gitea/go-sdk/README.md generated vendored Normal file
View File

@ -0,0 +1,26 @@
# Gitea SDK for Go
[![Build Status](http://drone.gitea.io/api/badges/go-gitea/go-sdk/status.svg)](http://drone.gitea.io/go-gitea/go-sdk)
[![Join the chat at https://gitter.im/go-gitea/gitea](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/go-gitea/gitea?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
[![](https://images.microbadger.com/badges/image/gitea/gitea.svg)](http://microbadger.com/images/gitea/gitea "Get your own image badge on microbadger.com")
[![Coverage Status](https://coverage.gitea.io/badges/go-gitea/go-sdk/coverage.svg)](https://coverage.gitea.io/go-gitea/go-sdk)
[![Go Report Card](https://goreportcard.com/badge/code.gitea.io/sdk)](https://goreportcard.com/report/code.gitea.io/sdk)
[![GoDoc](https://godoc.org/code.gitea.io/sdk/gitea?status.svg)](https://godoc.org/code.gitea.io/sdk/gitea)
This project acts as a client SDK implementation written in Go to interact with
the Gitea API implementation. For further informations take a look at the
current [documentation](https://godoc.org/code.gitea.io/sdk/gitea).
## Contributing
Fork -> Patch -> Push -> Pull Request
## Authors
* [Maintainers](https://github.com/orgs/go-gitea/people)
* [Contributors](https://github.com/go-gitea/go-sdk/graphs/contributors)
## License
This project is under the MIT License. See the [LICENSE](LICENSE) file for the
full license text.

22
vendor/github.com/go-gitea/go-sdk/gitea/admin_org.go generated vendored Normal file
View File

@ -0,0 +1,22 @@
// Copyright 2015 The Gogs Authors. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package gitea
import (
"bytes"
"encoding/json"
"fmt"
)
// AdminCreateOrg create an organization
func (c *Client) AdminCreateOrg(user string, opt CreateOrgOption) (*Organization, error) {
body, err := json.Marshal(&opt)
if err != nil {
return nil, err
}
org := new(Organization)
return org, c.getParsedResponse("POST", fmt.Sprintf("/admin/users/%s/orgs", user),
jsonHeader, bytes.NewReader(body), org)
}

22
vendor/github.com/go-gitea/go-sdk/gitea/admin_repo.go generated vendored Normal file
View File

@ -0,0 +1,22 @@
// Copyright 2015 The Gogs Authors. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package gitea
import (
"bytes"
"encoding/json"
"fmt"
)
// AdminCreateRepo create a repo
func (c *Client) AdminCreateRepo(user string, opt CreateRepoOption) (*Repository, error) {
body, err := json.Marshal(&opt)
if err != nil {
return nil, err
}
repo := new(Repository)
return repo, c.getParsedResponse("POST", fmt.Sprintf("/admin/users/%s/repos", user),
jsonHeader, bytes.NewReader(body), repo)
}

74
vendor/github.com/go-gitea/go-sdk/gitea/admin_user.go generated vendored Normal file
View File

@ -0,0 +1,74 @@
// Copyright 2015 The Gogs Authors. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package gitea
import (
"bytes"
"encoding/json"
"fmt"
)
// CreateUserOption create user options
type CreateUserOption struct {
SourceID int64 `json:"source_id"`
LoginName string `json:"login_name"`
Username string `json:"username" binding:"Required;AlphaDashDot;MaxSize(35)"`
FullName string `json:"full_name" binding:"MaxSize(100)"`
Email string `json:"email" binding:"Required;Email;MaxSize(254)"`
Password string `json:"password" binding:"MaxSize(255)"`
SendNotify bool `json:"send_notify"`
}
// AdminCreateUser create a user
func (c *Client) AdminCreateUser(opt CreateUserOption) (*User, error) {
body, err := json.Marshal(&opt)
if err != nil {
return nil, err
}
user := new(User)
return user, c.getParsedResponse("POST", "/admin/users", jsonHeader, bytes.NewReader(body), user)
}
// EditUserOption edit user options
type EditUserOption struct {
SourceID int64 `json:"source_id"`
LoginName string `json:"login_name"`
FullName string `json:"full_name" binding:"MaxSize(100)"`
Email string `json:"email" binding:"Required;Email;MaxSize(254)"`
Password string `json:"password" binding:"MaxSize(255)"`
Website string `json:"website" binding:"MaxSize(50)"`
Location string `json:"location" binding:"MaxSize(50)"`
Active *bool `json:"active"`
Admin *bool `json:"admin"`
AllowGitHook *bool `json:"allow_git_hook"`
AllowImportLocal *bool `json:"allow_import_local"`
MaxRepoCreation *int `json:"max_repo_creation"`
}
// AdminEditUser modify user informations
func (c *Client) AdminEditUser(user string, opt EditUserOption) error {
body, err := json.Marshal(&opt)
if err != nil {
return err
}
_, err = c.getResponse("PATCH", fmt.Sprintf("/admin/users/%s", user), jsonHeader, bytes.NewReader(body))
return err
}
// AdminDeleteUser delete one user according name
func (c *Client) AdminDeleteUser(user string) error {
_, err := c.getResponse("DELETE", fmt.Sprintf("/admin/users/%s", user), nil, nil)
return err
}
// AdminCreateUserPublicKey create one user with options
func (c *Client) AdminCreateUserPublicKey(user string, opt CreateKeyOption) (*PublicKey, error) {
body, err := json.Marshal(&opt)
if err != nil {
return nil, err
}
key := new(PublicKey)
return key, c.getParsedResponse("POST", fmt.Sprintf("/admin/users/%s/keys", user), jsonHeader, bytes.NewReader(body), key)
}

5
vendor/github.com/go-gitea/go-sdk/gitea/doc.go generated vendored Normal file
View File

@ -0,0 +1,5 @@
// Copyright 2016 The Gitea Authors. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package gitea // import "code.gitea.io/sdk/gitea"

38
vendor/github.com/go-gitea/go-sdk/gitea/fork.go generated vendored Normal file
View File

@ -0,0 +1,38 @@
// Copyright 2016 The Gitea Authors. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package gitea
import (
"bytes"
"encoding/json"
"fmt"
)
// ListForks list a repository's forks
func (c *Client) ListForks(user, repo string) ([]*Repository, error) {
forks := make([]*Repository, 10)
err := c.getParsedResponse("GET",
fmt.Sprintf("/repos/%s/%s/forks", user, repo),
nil, nil, &forks)
return forks, err
}
// CreateForkOption options for creating a fork
type CreateForkOption struct {
Organization *string `json:"organization"`
}
// CreateFork create a fork of a repository
func (c *Client) CreateFork(user, repo string, form CreateForkOption) (*Repository, error) {
body, err := json.Marshal(form)
if err != nil {
return nil, err
}
fork := new(Repository)
err = c.getParsedResponse("POST",
fmt.Sprintf("/repos/%s/%s/forks", user, repo),
jsonHeader, bytes.NewReader(body), &fork)
return fork, err
}

101
vendor/github.com/go-gitea/go-sdk/gitea/gitea.go generated vendored Normal file
View File

@ -0,0 +1,101 @@
// Copyright 2014 The Gogs Authors. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package gitea
import (
"encoding/json"
"errors"
"io"
"io/ioutil"
"net/http"
"strings"
)
// Version return the library version
func Version() string {
return "0.12.3"
}
// Client represents a Gogs API client.
type Client struct {
url string
accessToken string
client *http.Client
}
// NewClient initializes and returns a API client.
func NewClient(url, token string) *Client {
return &Client{
url: strings.TrimSuffix(url, "/"),
accessToken: token,
client: &http.Client{},
}
}
// SetHTTPClient replaces default http.Client with user given one.
func (c *Client) SetHTTPClient(client *http.Client) {
c.client = client
}
func (c *Client) doRequest(method, path string, header http.Header, body io.Reader) (*http.Response, error) {
req, err := http.NewRequest(method, c.url+"/api/v1"+path, body)
if err != nil {
return nil, err
}
req.Header.Set("Authorization", "token "+c.accessToken)
for k, v := range header {
req.Header[k] = v
}
return c.client.Do(req)
}
func (c *Client) getResponse(method, path string, header http.Header, body io.Reader) ([]byte, error) {
resp, err := c.doRequest(method, path, header, body)
if err != nil {
return nil, err
}
defer resp.Body.Close()
data, err := ioutil.ReadAll(resp.Body)
if err != nil {
return nil, err
}
switch resp.StatusCode {
case 403:
return nil, errors.New("403 Forbidden")
case 404:
return nil, errors.New("404 Not Found")
}
if resp.StatusCode/100 != 2 {
errMap := make(map[string]interface{})
if err = json.Unmarshal(data, &errMap); err != nil {
return nil, err
}
return nil, errors.New(errMap["message"].(string))
}
return data, nil
}
func (c *Client) getParsedResponse(method, path string, header http.Header, body io.Reader, obj interface{}) error {
data, err := c.getResponse(method, path, header, body)
if err != nil {
return err
}
return json.Unmarshal(data, obj)
}
func (c *Client) getStatusCode(method, path string, header http.Header, body io.Reader) (int, error) {
resp, err := c.doRequest(method, path, header, body)
if err != nil {
return -1, err
}
defer resp.Body.Close()
return resp.StatusCode, nil
}

355
vendor/github.com/go-gitea/go-sdk/gitea/hook.go generated vendored Normal file
View File

@ -0,0 +1,355 @@
// Copyright 2014 The Gogs Authors. All rights reserved.
// Copyright 2017 The Gitea Authors. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package gitea
import (
"bytes"
"encoding/json"
"errors"
"fmt"
"strings"
"time"
)
var (
// ErrInvalidReceiveHook FIXME
ErrInvalidReceiveHook = errors.New("Invalid JSON payload received over webhook")
)
// Hook a hook is a web hook when one repository changed
type Hook struct {
ID int64 `json:"id"`
Type string `json:"type"`
URL string `json:"-"`
Config map[string]string `json:"config"`
Events []string `json:"events"`
Active bool `json:"active"`
Updated time.Time `json:"updated_at"`
Created time.Time `json:"created_at"`
}
// ListOrgHooks list all the hooks of one organization
func (c *Client) ListOrgHooks(org string) ([]*Hook, error) {
hooks := make([]*Hook, 0, 10)
return hooks, c.getParsedResponse("GET", fmt.Sprintf("/orgs/%s/hooks", org), nil, nil, &hooks)
}
// ListRepoHooks list all the hooks of one repository
func (c *Client) ListRepoHooks(user, repo string) ([]*Hook, error) {
hooks := make([]*Hook, 0, 10)
return hooks, c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/hooks", user, repo), nil, nil, &hooks)
}
// GetOrgHook get a hook of an organization
func (c *Client) GetOrgHook(org string, id int64) (*Hook, error) {
h := new(Hook)
return h, c.getParsedResponse("GET", fmt.Sprintf("/orgs/%s/hooks/%d", org, id), nil, nil, h)
}
// GetRepoHook get a hook of a repository
func (c *Client) GetRepoHook(user, repo string, id int64) (*Hook, error) {
h := new(Hook)
return h, c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/hooks/%d", user, repo, id), nil, nil, h)
}
// CreateHookOption options when create a hook
type CreateHookOption struct {
Type string `json:"type" binding:"Required"`
Config map[string]string `json:"config" binding:"Required"`
Events []string `json:"events"`
Active bool `json:"active"`
}
// CreateOrgHook create one hook for an organization, with options
func (c *Client) CreateOrgHook(org string, opt CreateHookOption) (*Hook, error) {
body, err := json.Marshal(&opt)
if err != nil {
return nil, err
}
h := new(Hook)
return h, c.getParsedResponse("POST", fmt.Sprintf("/orgs/%s/hooks", org), jsonHeader, bytes.NewReader(body), h)
}
// CreateRepoHook create one hook for a repository, with options
func (c *Client) CreateRepoHook(user, repo string, opt CreateHookOption) (*Hook, error) {
body, err := json.Marshal(&opt)
if err != nil {
return nil, err
}
h := new(Hook)
return h, c.getParsedResponse("POST", fmt.Sprintf("/repos/%s/%s/hooks", user, repo), jsonHeader, bytes.NewReader(body), h)
}
// EditHookOption options when modify one hook
type EditHookOption struct {
Config map[string]string `json:"config"`
Events []string `json:"events"`
Active *bool `json:"active"`
}
// EditOrgHook modify one hook of an organization, with hook id and options
func (c *Client) EditOrgHook(org string, id int64, opt EditHookOption) error {
body, err := json.Marshal(&opt)
if err != nil {
return err
}
_, err = c.getResponse("PATCH", fmt.Sprintf("/orgs/%s/hooks/%d", org, id), jsonHeader, bytes.NewReader(body))
return err
}
// EditRepoHook modify one hook of a repository, with hook id and options
func (c *Client) EditRepoHook(user, repo string, id int64, opt EditHookOption) error {
body, err := json.Marshal(&opt)
if err != nil {
return err
}
_, err = c.getResponse("PATCH", fmt.Sprintf("/repos/%s/%s/hooks/%d", user, repo, id), jsonHeader, bytes.NewReader(body))
return err
}
// DeleteOrgHook delete one hook from an organization, with hook id
func (c *Client) DeleteOrgHook(org string, id int64) error {
_, err := c.getResponse("DELETE", fmt.Sprintf("/org/%s/hooks/%d", org, id), nil, nil)
return err
}
// DeleteRepoHook delete one hook from a repository, with hook id
func (c *Client) DeleteRepoHook(user, repo string, id int64) error {
_, err := c.getResponse("DELETE", fmt.Sprintf("/repos/%s/%s/hooks/%d", user, repo, id), nil, nil)
return err
}
// Payloader payload is some part of one hook
type Payloader interface {
SetSecret(string)
JSONPayload() ([]byte, error)
}
// PayloadUser FIXME
type PayloadUser struct {
Name string `json:"name"`
Email string `json:"email"`
UserName string `json:"username"`
}
// PayloadCommit FIXME: consider use same format as API when commits API are added.
type PayloadCommit struct {
ID string `json:"id"`
Message string `json:"message"`
URL string `json:"url"`
Author *PayloadUser `json:"author"`
Committer *PayloadUser `json:"committer"`
Verification *PayloadCommitVerification `json:"verification"`
Timestamp time.Time `json:"timestamp"`
}
// PayloadCommitVerification represent the GPG verification part of a commit. FIXME: like PayloadCommit consider use same format as API when commits API are added.
type PayloadCommitVerification struct {
Verified bool `json:"verified"`
Reason string `json:"reason"`
Signature string `json:"signature"`
Payload string `json:"payload"`
}
var (
_ Payloader = &CreatePayload{}
_ Payloader = &PushPayload{}
_ Payloader = &IssuePayload{}
_ Payloader = &PullRequestPayload{}
)
// _________ __
// \_ ___ \_______ ____ _____ _/ |_ ____
// / \ \/\_ __ \_/ __ \\__ \\ __\/ __ \
// \ \____| | \/\ ___/ / __ \| | \ ___/
// \______ /|__| \___ >____ /__| \___ >
// \/ \/ \/ \/
// CreatePayload FIXME
type CreatePayload struct {
Secret string `json:"secret"`
Sha string `json:"sha"`
Ref string `json:"ref"`
RefType string `json:"ref_type"`
Repo *Repository `json:"repository"`
Sender *User `json:"sender"`
}
// SetSecret FIXME
func (p *CreatePayload) SetSecret(secret string) {
p.Secret = secret
}
// JSONPayload return payload information
func (p *CreatePayload) JSONPayload() ([]byte, error) {
return json.MarshalIndent(p, "", " ")
}
// ParseCreateHook parses create event hook content.
func ParseCreateHook(raw []byte) (*CreatePayload, error) {
hook := new(CreatePayload)
if err := json.Unmarshal(raw, hook); err != nil {
return nil, err
}
// it is possible the JSON was parsed, however,
// was not from Gogs (maybe was from Bitbucket)
// So we'll check to be sure certain key fields
// were populated
switch {
case hook.Repo == nil:
return nil, ErrInvalidReceiveHook
case len(hook.Ref) == 0:
return nil, ErrInvalidReceiveHook
}
return hook, nil
}
// __________ .__
// \______ \__ __ _____| |__
// | ___/ | \/ ___/ | \
// | | | | /\___ \| Y \
// |____| |____//____ >___| /
// \/ \/
// PushPayload represents a payload information of push event.
type PushPayload struct {
Secret string `json:"secret"`
Ref string `json:"ref"`
Before string `json:"before"`
After string `json:"after"`
CompareURL string `json:"compare_url"`
Commits []*PayloadCommit `json:"commits"`
Repo *Repository `json:"repository"`
Pusher *User `json:"pusher"`
Sender *User `json:"sender"`
}
// SetSecret FIXME
func (p *PushPayload) SetSecret(secret string) {
p.Secret = secret
}
// JSONPayload FIXME
func (p *PushPayload) JSONPayload() ([]byte, error) {
return json.MarshalIndent(p, "", " ")
}
// ParsePushHook parses push event hook content.
func ParsePushHook(raw []byte) (*PushPayload, error) {
hook := new(PushPayload)
if err := json.Unmarshal(raw, hook); err != nil {
return nil, err
}
switch {
case hook.Repo == nil:
return nil, ErrInvalidReceiveHook
case len(hook.Ref) == 0:
return nil, ErrInvalidReceiveHook
}
return hook, nil
}
// Branch returns branch name from a payload
func (p *PushPayload) Branch() string {
return strings.Replace(p.Ref, "refs/heads/", "", -1)
}
// .___
// | | ______ ________ __ ____
// | |/ ___// ___/ | \_/ __ \
// | |\___ \ \___ \| | /\ ___/
// |___/____ >____ >____/ \___ >
// \/ \/ \/
// HookIssueAction FIXME
type HookIssueAction string
const (
// HookIssueOpened opened
HookIssueOpened HookIssueAction = "opened"
// HookIssueClosed closed
HookIssueClosed HookIssueAction = "closed"
// HookIssueReOpened reopened
HookIssueReOpened HookIssueAction = "reopened"
// HookIssueEdited edited
HookIssueEdited HookIssueAction = "edited"
// HookIssueAssigned assigned
HookIssueAssigned HookIssueAction = "assigned"
// HookIssueUnassigned unassigned
HookIssueUnassigned HookIssueAction = "unassigned"
// HookIssueLabelUpdated label_updated
HookIssueLabelUpdated HookIssueAction = "label_updated"
// HookIssueLabelCleared label_cleared
HookIssueLabelCleared HookIssueAction = "label_cleared"
// HookIssueSynchronized synchronized
HookIssueSynchronized HookIssueAction = "synchronized"
// HookIssueMilestoned is an issue action for when a milestone is set on an issue.
HookIssueMilestoned HookIssueAction = "milestoned"
// HookIssueDemilestoned is an issue action for when a milestone is cleared on an issue.
HookIssueDemilestoned HookIssueAction = "demilestoned"
)
// IssuePayload represents the payload information that is sent along with an issue event.
type IssuePayload struct {
Secret string `json:"secret"`
Action HookIssueAction `json:"action"`
Index int64 `json:"number"`
Changes *ChangesPayload `json:"changes,omitempty"`
Issue *Issue `json:"issue"`
Repository *Repository `json:"repository"`
Sender *User `json:"sender"`
}
// SetSecret modifies the secret of the IssuePayload.
func (p *IssuePayload) SetSecret(secret string) {
p.Secret = secret
}
// JSONPayload encodes the IssuePayload to JSON, with an indentation of two spaces.
func (p *IssuePayload) JSONPayload() ([]byte, error) {
return json.MarshalIndent(p, "", " ")
}
// ChangesFromPayload FIXME
type ChangesFromPayload struct {
From string `json:"from"`
}
// ChangesPayload FIXME
type ChangesPayload struct {
Title *ChangesFromPayload `json:"title,omitempty"`
Body *ChangesFromPayload `json:"body,omitempty"`
}
// __________ .__ .__ __________ __
// \______ \__ __| | | | \______ \ ____ ________ __ ____ _______/ |_
// | ___/ | \ | | | | _// __ \/ ____/ | \_/ __ \ / ___/\ __\
// | | | | / |_| |__ | | \ ___< <_| | | /\ ___/ \___ \ | |
// |____| |____/|____/____/ |____|_ /\___ >__ |____/ \___ >____ > |__|
// \/ \/ |__| \/ \/
// PullRequestPayload represents a payload information of pull request event.
type PullRequestPayload struct {
Secret string `json:"secret"`
Action HookIssueAction `json:"action"`
Index int64 `json:"number"`
Changes *ChangesPayload `json:"changes,omitempty"`
PullRequest *PullRequest `json:"pull_request"`
Repository *Repository `json:"repository"`
Sender *User `json:"sender"`
}
// SetSecret modifies the secret of the PullRequestPayload.
func (p *PullRequestPayload) SetSecret(secret string) {
p.Secret = secret
}
// JSONPayload FIXME
func (p *PullRequestPayload) JSONPayload() ([]byte, error) {
return json.MarshalIndent(p, "", " ")
}

118
vendor/github.com/go-gitea/go-sdk/gitea/issue.go generated vendored Normal file
View File

@ -0,0 +1,118 @@
// Copyright 2016 The Gogs Authors. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package gitea
import (
"bytes"
"encoding/json"
"fmt"
"time"
)
// StateType issue state type
type StateType string
const (
// StateOpen pr is opend
StateOpen StateType = "open"
// StateClosed pr is closed
StateClosed StateType = "closed"
)
// PullRequestMeta PR info if an issue is a PR
type PullRequestMeta struct {
HasMerged bool `json:"merged"`
Merged *time.Time `json:"merged_at"`
}
// Issue an issue to a repository
type Issue struct {
ID int64 `json:"id"`
URL string `json:"url"`
Index int64 `json:"number"`
Poster *User `json:"user"`
Title string `json:"title"`
Body string `json:"body"`
Labels []*Label `json:"labels"`
Milestone *Milestone `json:"milestone"`
Assignee *User `json:"assignee"`
State StateType `json:"state"`
Comments int `json:"comments"`
Created time.Time `json:"created_at"`
Updated time.Time `json:"updated_at"`
PullRequest *PullRequestMeta `json:"pull_request"`
}
// ListIssueOption list issue options
type ListIssueOption struct {
Page int
State string
}
// ListIssues returns all issues assigned the authenticated user
func (c *Client) ListIssues(opt ListIssueOption) ([]*Issue, error) {
issues := make([]*Issue, 0, 10)
return issues, c.getParsedResponse("GET", fmt.Sprintf("/issues?page=%d", opt.Page), nil, nil, &issues)
}
// ListUserIssues returns all issues assigned to the authenticated user
func (c *Client) ListUserIssues(opt ListIssueOption) ([]*Issue, error) {
issues := make([]*Issue, 0, 10)
return issues, c.getParsedResponse("GET", fmt.Sprintf("/user/issues?page=%d", opt.Page), nil, nil, &issues)
}
// ListRepoIssues returns all issues for a given repository
func (c *Client) ListRepoIssues(owner, repo string, opt ListIssueOption) ([]*Issue, error) {
issues := make([]*Issue, 0, 10)
return issues, c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/issues?page=%d", owner, repo, opt.Page), nil, nil, &issues)
}
// GetIssue returns a single issue for a given repository
func (c *Client) GetIssue(owner, repo string, index int64) (*Issue, error) {
issue := new(Issue)
return issue, c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/issues/%d", owner, repo, index), nil, nil, issue)
}
// CreateIssueOption options to create one issue
type CreateIssueOption struct {
Title string `json:"title" binding:"Required"`
Body string `json:"body"`
Assignee string `json:"assignee"`
Milestone int64 `json:"milestone"`
Labels []int64 `json:"labels"`
Closed bool `json:"closed"`
}
// CreateIssue create a new issue for a given repository
func (c *Client) CreateIssue(owner, repo string, opt CreateIssueOption) (*Issue, error) {
body, err := json.Marshal(&opt)
if err != nil {
return nil, err
}
issue := new(Issue)
return issue, c.getParsedResponse("POST", fmt.Sprintf("/repos/%s/%s/issues", owner, repo),
jsonHeader, bytes.NewReader(body), issue)
}
// EditIssueOption edit issue options
type EditIssueOption struct {
Title string `json:"title"`
Body *string `json:"body"`
Assignee *string `json:"assignee"`
Milestone *int64 `json:"milestone"`
State *string `json:"state"`
}
// EditIssue modify an existing issue for a given repository
func (c *Client) EditIssue(owner, repo string, index int64, opt EditIssueOption) (*Issue, error) {
body, err := json.Marshal(&opt)
if err != nil {
return nil, err
}
issue := new(Issue)
return issue, c.getParsedResponse("PATCH", fmt.Sprintf("/repos/%s/%s/issues/%d", owner, repo, index),
jsonHeader, bytes.NewReader(body), issue)
}

View File

@ -0,0 +1,72 @@
// Copyright 2016 The Gogs Authors. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package gitea
import (
"bytes"
"encoding/json"
"fmt"
"time"
)
// Comment represents a comment in commit and issue page.
type Comment struct {
ID int64 `json:"id"`
HTMLURL string `json:"html_url"`
PRURL string `json:"pull_request_url"`
IssueURL string `json:"issue_url"`
Poster *User `json:"user"`
Body string `json:"body"`
Created time.Time `json:"created_at"`
Updated time.Time `json:"updated_at"`
}
// ListIssueComments list comments on an issue.
func (c *Client) ListIssueComments(owner, repo string, index int64) ([]*Comment, error) {
comments := make([]*Comment, 0, 10)
return comments, c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/issues/%d/comments", owner, repo, index), nil, nil, &comments)
}
// ListRepoIssueComments list comments for a given repo.
func (c *Client) ListRepoIssueComments(owner, repo string) ([]*Comment, error) {
comments := make([]*Comment, 0, 10)
return comments, c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/issues/comments", owner, repo), nil, nil, &comments)
}
// CreateIssueCommentOption is option when creating an issue comment.
type CreateIssueCommentOption struct {
Body string `json:"body" binding:"Required"`
}
// CreateIssueComment create comment on an issue.
func (c *Client) CreateIssueComment(owner, repo string, index int64, opt CreateIssueCommentOption) (*Comment, error) {
body, err := json.Marshal(&opt)
if err != nil {
return nil, err
}
comment := new(Comment)
return comment, c.getParsedResponse("POST", fmt.Sprintf("/repos/%s/%s/issues/%d/comments", owner, repo, index), jsonHeader, bytes.NewReader(body), comment)
}
// EditIssueCommentOption is option when editing an issue comment.
type EditIssueCommentOption struct {
Body string `json:"body" binding:"Required"`
}
// EditIssueComment edits an issue comment.
func (c *Client) EditIssueComment(owner, repo string, index, commentID int64, opt EditIssueCommentOption) (*Comment, error) {
body, err := json.Marshal(&opt)
if err != nil {
return nil, err
}
comment := new(Comment)
return comment, c.getParsedResponse("PATCH", fmt.Sprintf("/repos/:%s/:%s/issues/%d/comments/%d", owner, repo, index, commentID), jsonHeader, bytes.NewReader(body), comment)
}
// DeleteIssueComment deletes an issue comment.
func (c *Client) DeleteIssueComment(owner, repo string, index, commentID int64) error {
_, err := c.getResponse("DELETE", fmt.Sprintf("/repos/%s/%s/issues/%d/comments/%d", owner, repo, index, commentID), nil, nil)
return err
}

116
vendor/github.com/go-gitea/go-sdk/gitea/issue_label.go generated vendored Normal file
View File

@ -0,0 +1,116 @@
// Copyright 2016 The Gogs Authors. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package gitea
import (
"bytes"
"encoding/json"
"fmt"
)
// Label a label to an issue or a pr
type Label struct {
ID int64 `json:"id"`
Name string `json:"name"`
Color string `json:"color"`
URL string `json:"url"`
}
// ListRepoLabels list lables of one reppsitory
func (c *Client) ListRepoLabels(owner, repo string) ([]*Label, error) {
labels := make([]*Label, 0, 10)
return labels, c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/labels", owner, repo), nil, nil, &labels)
}
// GetRepoLabel get one label of repository by repo it
// TODO: maybe we need get a label by name
func (c *Client) GetRepoLabel(owner, repo string, id int64) (*Label, error) {
label := new(Label)
return label, c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/labels/%d", owner, repo, id), nil, nil, label)
}
// CreateLabelOption create options when one label of repository
type CreateLabelOption struct {
Name string `json:"name" binding:"Required"`
Color string `json:"color" binding:"Required;Size(7)"`
}
// CreateLabel create one label of repository
func (c *Client) CreateLabel(owner, repo string, opt CreateLabelOption) (*Label, error) {
body, err := json.Marshal(&opt)
if err != nil {
return nil, err
}
label := new(Label)
return label, c.getParsedResponse("POST", fmt.Sprintf("/repos/%s/%s/labels", owner, repo),
jsonHeader, bytes.NewReader(body), label)
}
// EditLabelOption edit label options
type EditLabelOption struct {
Name *string `json:"name"`
Color *string `json:"color"`
}
// EditLabel modify one label with options
func (c *Client) EditLabel(owner, repo string, id int64, opt EditLabelOption) (*Label, error) {
body, err := json.Marshal(&opt)
if err != nil {
return nil, err
}
label := new(Label)
return label, c.getParsedResponse("PATCH", fmt.Sprintf("/repos/%s/%s/labels/%d", owner, repo, id), jsonHeader, bytes.NewReader(body), label)
}
// DeleteLabel delete one label of repository by id
// TODO: maybe we need delete by name
func (c *Client) DeleteLabel(owner, repo string, id int64) error {
_, err := c.getResponse("DELETE", fmt.Sprintf("/repos/%s/%s/labels/%d", owner, repo, id), nil, nil)
return err
}
// IssueLabelsOption list one issue's labels options
type IssueLabelsOption struct {
Labels []int64 `json:"labels"`
}
// GetIssueLabels get labels of one issue via issue id
func (c *Client) GetIssueLabels(owner, repo string, index int64) ([]*Label, error) {
labels := make([]*Label, 0, 5)
return labels, c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/issues/%d/labels", owner, repo, index), nil, nil, &labels)
}
// AddIssueLabels add one or more labels to one issue
func (c *Client) AddIssueLabels(owner, repo string, index int64, opt IssueLabelsOption) ([]*Label, error) {
body, err := json.Marshal(&opt)
if err != nil {
return nil, err
}
var labels []*Label
return labels, c.getParsedResponse("POST", fmt.Sprintf("/repos/%s/%s/issues/%d/labels", owner, repo, index), jsonHeader, bytes.NewReader(body), &labels)
}
// ReplaceIssueLabels replace old labels of issue with new labels
func (c *Client) ReplaceIssueLabels(owner, repo string, index int64, opt IssueLabelsOption) ([]*Label, error) {
body, err := json.Marshal(&opt)
if err != nil {
return nil, err
}
var labels []*Label
return labels, c.getParsedResponse("PUT", fmt.Sprintf("/repos/%s/%s/issues/%d/labels", owner, repo, index), jsonHeader, bytes.NewReader(body), &labels)
}
// DeleteIssueLabel delete one label of one issue by issue id and label id
// TODO: maybe we need delete by label name and issue id
func (c *Client) DeleteIssueLabel(owner, repo string, index, label int64) error {
_, err := c.getResponse("DELETE", fmt.Sprintf("/repos/%s/%s/issues/%d/labels/%d", owner, repo, index, label), nil, nil)
return err
}
// ClearIssueLabels delete all the labels of one issue.
func (c *Client) ClearIssueLabels(owner, repo string, index int64) error {
_, err := c.getResponse("DELETE", fmt.Sprintf("/repos/%s/%s/issues/%d/labels", owner, repo, index), nil, nil)
return err
}

View File

@ -0,0 +1,77 @@
// Copyright 2016 The Gogs Authors. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package gitea
import (
"bytes"
"encoding/json"
"fmt"
"time"
)
// Milestone milestone is a collection of issues on one repository
type Milestone struct {
ID int64 `json:"id"`
Title string `json:"title"`
Description string `json:"description"`
State StateType `json:"state"`
OpenIssues int `json:"open_issues"`
ClosedIssues int `json:"closed_issues"`
Closed *time.Time `json:"closed_at"`
Deadline *time.Time `json:"due_on"`
}
// ListRepoMilestones list all the milestones of one repository
func (c *Client) ListRepoMilestones(owner, repo string) ([]*Milestone, error) {
milestones := make([]*Milestone, 0, 10)
return milestones, c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/milestones", owner, repo), nil, nil, &milestones)
}
// GetMilestone get one milestone by repo name and milestone id
func (c *Client) GetMilestone(owner, repo string, id int64) (*Milestone, error) {
milestone := new(Milestone)
return milestone, c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/milestones/%d", owner, repo, id), nil, nil, milestone)
}
// CreateMilestoneOption options when creating milestone
type CreateMilestoneOption struct {
Title string `json:"title"`
Description string `json:"description"`
Deadline *time.Time `json:"due_on"`
}
// CreateMilestone create one milestone with options
func (c *Client) CreateMilestone(owner, repo string, opt CreateMilestoneOption) (*Milestone, error) {
body, err := json.Marshal(&opt)
if err != nil {
return nil, err
}
milestone := new(Milestone)
return milestone, c.getParsedResponse("POST", fmt.Sprintf("/repos/%s/%s/milestones", owner, repo), jsonHeader, bytes.NewReader(body), milestone)
}
// EditMilestoneOption options when modify milestone
type EditMilestoneOption struct {
Title string `json:"title"`
Description *string `json:"description"`
State *string `json:"state"`
Deadline *time.Time `json:"due_on"`
}
// EditMilestone modify milestone with options
func (c *Client) EditMilestone(owner, repo string, id int64, opt EditMilestoneOption) (*Milestone, error) {
body, err := json.Marshal(&opt)
if err != nil {
return nil, err
}
milestone := new(Milestone)
return milestone, c.getParsedResponse("PATCH", fmt.Sprintf("/repos/%s/%s/milestones/%d", owner, repo, id), jsonHeader, bytes.NewReader(body), milestone)
}
// DeleteMilestone delete one milestone by milestone id
func (c *Client) DeleteMilestone(owner, repo string, id int64) error {
_, err := c.getResponse("DELETE", fmt.Sprintf("/repos/%s/%s/milestones/%d", owner, repo, id), nil, nil)
return err
}

View File

@ -0,0 +1,56 @@
// Copyright 2015 The Gogs Authors. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package gitea
// SearchResults results of search
// swagger:response SearchResults
type SearchResults struct {
OK bool `json:"ok"`
Data []*Repository `json:"data"`
}
// SearchError error of failing search
// swagger:response SearchError
type SearchError struct {
OK bool `json:"ok"`
Error string `json:"error"`
}
// MarkdownOption markdown options
// swagger:parameters renderMarkdown
type MarkdownOption struct {
// Text markdown to render
//
// in: body
Text string
// Mode to render
//
// in: body
Mode string
// Context to render
//
// in: body
Context string
// Is it a wiki page ?
//
// in: body
Wiki bool
}
// MarkdownRender is a rendered markdown document
// swagger:response MarkdownRender
type MarkdownRender string
// ServerVersion wraps the version of the server
// swagger:response ServerVersion
type ServerVersion struct {
Version string
}
// ServerVersion returns the version of the server
func (c *Client) ServerVersion() (string, error) {
v := ServerVersion{}
return v.Version, c.getParsedResponse("GET", "/api/v1/version", nil, nil, &v)
}

67
vendor/github.com/go-gitea/go-sdk/gitea/org.go generated vendored Normal file
View File

@ -0,0 +1,67 @@
// Copyright 2015 The Gogs Authors. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package gitea
import (
"bytes"
"encoding/json"
"fmt"
)
// Organization a group of some repositories, users and teams
type Organization struct {
ID int64 `json:"id"`
UserName string `json:"username"`
FullName string `json:"full_name"`
AvatarURL string `json:"avatar_url"`
Description string `json:"description"`
Website string `json:"website"`
Location string `json:"location"`
}
// ListMyOrgs list all of current user's organizations
func (c *Client) ListMyOrgs() ([]*Organization, error) {
orgs := make([]*Organization, 0, 5)
return orgs, c.getParsedResponse("GET", "/user/orgs", nil, nil, &orgs)
}
// ListUserOrgs list all of some user's organizations
func (c *Client) ListUserOrgs(user string) ([]*Organization, error) {
orgs := make([]*Organization, 0, 5)
return orgs, c.getParsedResponse("GET", fmt.Sprintf("/users/%s/orgs", user), nil, nil, &orgs)
}
// GetOrg get one organization by name
func (c *Client) GetOrg(orgname string) (*Organization, error) {
org := new(Organization)
return org, c.getParsedResponse("GET", fmt.Sprintf("/orgs/%s", orgname), nil, nil, org)
}
// CreateOrgOption create one organization options
type CreateOrgOption struct {
UserName string `json:"username" binding:"Required"`
FullName string `json:"full_name"`
Description string `json:"description"`
Website string `json:"website"`
Location string `json:"location"`
}
// EditOrgOption edit one organization options
type EditOrgOption struct {
FullName string `json:"full_name"`
Description string `json:"description"`
Website string `json:"website"`
Location string `json:"location"`
}
// EditOrg modify one organization via options
func (c *Client) EditOrg(orgname string, opt EditOrgOption) error {
body, err := json.Marshal(&opt)
if err != nil {
return err
}
_, err = c.getResponse("PATCH", fmt.Sprintf("/orgs/%s", orgname), jsonHeader, bytes.NewReader(body))
return err
}

26
vendor/github.com/go-gitea/go-sdk/gitea/org_member.go generated vendored Normal file
View File

@ -0,0 +1,26 @@
// Copyright 2016 The Gogs Authors. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package gitea
import (
"bytes"
"encoding/json"
"fmt"
)
// AddOrgMembershipOption add user to organization options
type AddOrgMembershipOption struct {
Role string `json:"role" binding:"Required"`
}
// AddOrgMembership add some one to an organization's member
func (c *Client) AddOrgMembership(org, user string, opt AddOrgMembershipOption) error {
body, err := json.Marshal(&opt)
if err != nil {
return err
}
_, err = c.getResponse("PUT", fmt.Sprintf("/orgs/%s/membership/%s", org, user), jsonHeader, bytes.NewReader(body))
return err
}

27
vendor/github.com/go-gitea/go-sdk/gitea/org_team.go generated vendored Normal file
View File

@ -0,0 +1,27 @@
// Copyright 2016 The Gogs Authors. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package gitea
// Team is a sub virtual organization of one Organization
type Team struct {
ID int64 `json:"id"`
Name string `json:"name"`
Description string `json:"description"`
Permission string `json:"permission"`
}
// CreateTeamOption options when create team
type CreateTeamOption struct {
Name string `json:"name" binding:"Required;AlphaDashDot;MaxSize(30)"`
Description string `json:"description" binding:"MaxSize(255)"`
Permission string `json:"permission"`
}
// EditTeamOption options when edit team
type EditTeamOption struct {
Name string `json:"name" binding:"Required;AlphaDashDot;MaxSize(30)"`
Description string `json:"description" binding:"MaxSize(255)"`
Permission string `json:"permission"`
}

136
vendor/github.com/go-gitea/go-sdk/gitea/pull.go generated vendored Normal file
View File

@ -0,0 +1,136 @@
// Copyright 2016 The Gogs Authors. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package gitea
import (
"bytes"
"encoding/json"
"fmt"
"time"
)
// PullRequest represents a pull request API object.
type PullRequest struct {
ID int64 `json:"id"`
URL string `json:"url"`
Index int64 `json:"number"`
Poster *User `json:"user"`
Title string `json:"title"`
Body string `json:"body"`
Labels []*Label `json:"labels"`
Milestone *Milestone `json:"milestone"`
Assignee *User `json:"assignee"`
State StateType `json:"state"`
Comments int `json:"comments"`
HTMLURL string `json:"html_url"`
DiffURL string `json:"diff_url"`
PatchURL string `json:"patch_url"`
Mergeable bool `json:"mergeable"`
HasMerged bool `json:"merged"`
Merged *time.Time `json:"merged_at"`
MergedCommitID *string `json:"merge_commit_sha"`
MergedBy *User `json:"merged_by"`
Base *PRBranchInfo `json:"base"`
Head *PRBranchInfo `json:"head"`
MergeBase string `json:"merge_base"`
Created *time.Time `json:"created_at"`
Updated *time.Time `json:"updated_at"`
}
// PRBranchInfo base branch info when send a PR
type PRBranchInfo struct {
Name string `json:"label"`
Ref string `json:"ref"`
Sha string `json:"sha"`
RepoID int64 `json:"repo_id"`
Repository *Repository `json:"repo"`
}
// ListPullRequestsOptions options when list PRs
type ListPullRequestsOptions struct {
Page int `json:"page"`
State string `json:"state"`
}
// ListRepoPullRequests list PRs of one repository
func (c *Client) ListRepoPullRequests(owner, repo string, opt ListPullRequestsOptions) ([]*PullRequest, error) {
body, err := json.Marshal(&opt)
if err != nil {
return nil, err
}
prs := make([]*PullRequest, 0, 10)
return prs, c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/pulls", owner, repo), jsonHeader, bytes.NewReader(body), &prs)
}
// GetPullRequest get information of one PR
func (c *Client) GetPullRequest(owner, repo string, index int64) (*PullRequest, error) {
pr := new(PullRequest)
return pr, c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/pulls/%d", owner, repo, index), nil, nil, pr)
}
// CreatePullRequestOption options when creating a pull request
type CreatePullRequestOption struct {
Head string `json:"head" binding:"Required"`
Base string `json:"base" binding:"Required"`
Title string `json:"title" binding:"Required"`
Body string `json:"body"`
Assignee string `json:"assignee"`
Milestone int64 `json:"milestone"`
Labels []int64 `json:"labels"`
}
// CreatePullRequest create pull request with options
func (c *Client) CreatePullRequest(owner, repo string, opt CreatePullRequestOption) (*PullRequest, error) {
body, err := json.Marshal(&opt)
if err != nil {
return nil, err
}
pr := new(PullRequest)
return pr, c.getParsedResponse("POST", fmt.Sprintf("/repos/%s/%s/pulls", owner, repo),
jsonHeader, bytes.NewReader(body), pr)
}
// EditPullRequestOption options when modify pull request
type EditPullRequestOption struct {
Title string `json:"title"`
Body string `json:"body"`
Assignee string `json:"assignee"`
Milestone int64 `json:"milestone"`
Labels []int64 `json:"labels"`
State *string `json:"state"`
}
// EditPullRequest modify pull request with PR id and options
func (c *Client) EditPullRequest(owner, repo string, index int64, opt EditPullRequestOption) (*PullRequest, error) {
body, err := json.Marshal(&opt)
if err != nil {
return nil, err
}
pr := new(PullRequest)
return pr, c.getParsedResponse("PATCH", fmt.Sprintf("/repos/%s/%s/issues/%d", owner, repo, index),
jsonHeader, bytes.NewReader(body), pr)
}
// MergePullRequest merge a PR to repository by PR id
func (c *Client) MergePullRequest(owner, repo string, index int64) error {
_, err := c.getResponse("POST", fmt.Sprintf("/repos/%s/%s/pulls/%d/merge", owner, repo, index), nil, nil)
return err
}
// IsPullRequestMerged test if one PR is merged to one repository
func (c *Client) IsPullRequestMerged(owner, repo string, index int64) (bool, error) {
statusCode, err := c.getStatusCode("GET", fmt.Sprintf("/repos/%s/%s/pulls/%d/merge", owner, repo, index), nil, nil)
if err != nil {
return false, err
}
return statusCode == 204, nil
}

101
vendor/github.com/go-gitea/go-sdk/gitea/release.go generated vendored Normal file
View File

@ -0,0 +1,101 @@
// Copyright 2016 The Gitea Authors. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package gitea
import (
"bytes"
"encoding/json"
"fmt"
"time"
)
// Release represents a repository release
type Release struct {
ID int64 `json:"id"`
TagName string `json:"tag_name"`
Target string `json:"target_commitish"`
Title string `json:"name"`
Note string `json:"body"`
URL string `json:"url"`
TarURL string `json:"tarball_url"`
ZipURL string `json:"zipball_url"`
IsDraft bool `json:"draft"`
IsPrerelease bool `json:"prerelease"`
CreatedAt time.Time `json:"created_at"`
PublishedAt time.Time `json:"published_at"`
Publisher *User `json:"author"`
}
// ListReleases list releases of a repository
func (c *Client) ListReleases(user, repo string) ([]*Release, error) {
releases := make([]*Release, 0, 10)
err := c.getParsedResponse("GET",
fmt.Sprintf("/repos/%s/%s/releases", user, repo),
nil, nil, &releases)
return releases, err
}
// GetRelease get a release of a repository
func (c *Client) GetRelease(user, repo string, id int64) (*Release, error) {
r := new(Release)
err := c.getParsedResponse("GET",
fmt.Sprintf("/repos/%s/%s/releases/%d", user, repo, id),
nil, nil, &r)
return r, err
}
// CreateReleaseOption options when creating a release
type CreateReleaseOption struct {
TagName string `json:"tag_name" binding:"Required"`
Target string `json:"target_commitish"`
Title string `json:"name"`
Note string `json:"body"`
IsDraft bool `json:"draft"`
IsPrerelease bool `json:"prerelease"`
}
// CreateRelease create a release
func (c *Client) CreateRelease(user, repo string, form CreateReleaseOption) (*Release, error) {
body, err := json.Marshal(form)
if err != nil {
return nil, err
}
r := new(Release)
err = c.getParsedResponse("POST",
fmt.Sprintf("/repos/%s/%s/releases", user, repo),
jsonHeader, bytes.NewReader(body), r)
return r, err
}
// EditReleaseOption options when editing a release
type EditReleaseOption struct {
TagName string `json:"tag_name"`
Target string `json:"target_commitish"`
Title string `json:"name"`
Note string `json:"body"`
IsDraft *bool `json:"draft"`
IsPrerelease *bool `json:"prerelease"`
}
// EditRelease edit a release
func (c *Client) EditRelease(user, repo string, id int64, form EditReleaseOption) (*Release, error) {
body, err := json.Marshal(form)
if err != nil {
return nil, err
}
r := new(Release)
err = c.getParsedResponse("PATCH",
fmt.Sprintf("/repos/%s/%s/releases/%d", user, repo, id),
jsonHeader, bytes.NewReader(body), r)
return r, err
}
// DeleteRelease delete a release from a repository
func (c *Client) DeleteRelease(user, repo string, id int64) error {
_, err := c.getResponse("DELETE",
fmt.Sprintf("/repos/%s/%s/releases/%d", user, repo, id),
nil, nil)
return err
}

158
vendor/github.com/go-gitea/go-sdk/gitea/repo.go generated vendored Normal file
View File

@ -0,0 +1,158 @@
// Copyright 2014 The Gogs Authors. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package gitea
import (
"bytes"
"encoding/json"
"fmt"
"time"
)
// Permission represents a API permission.
type Permission struct {
Admin bool `json:"admin"`
Push bool `json:"push"`
Pull bool `json:"pull"`
}
// Repository represents a API repository.
// swagger:response Repository
type Repository struct {
ID int64 `json:"id"`
Owner *User `json:"owner"`
Name string `json:"name"`
FullName string `json:"full_name"`
Description string `json:"description"`
Private bool `json:"private"`
Fork bool `json:"fork"`
Mirror bool `json:"mirror"`
HTMLURL string `json:"html_url"`
SSHURL string `json:"ssh_url"`
CloneURL string `json:"clone_url"`
Website string `json:"website"`
Stars int `json:"stars_count"`
Forks int `json:"forks_count"`
Watchers int `json:"watchers_count"`
OpenIssues int `json:"open_issues_count"`
DefaultBranch string `json:"default_branch"`
Created time.Time `json:"created_at"`
Updated time.Time `json:"updated_at"`
Permissions *Permission `json:"permissions,omitempty"`
}
// RepositoryList represents a list of API repository.
// swagger:response RepositoryList
type RepositoryList []*Repository
// ListMyRepos lists all repositories for the authenticated user that has access to.
func (c *Client) ListMyRepos() ([]*Repository, error) {
repos := make([]*Repository, 0, 10)
return repos, c.getParsedResponse("GET", "/user/repos", nil, nil, &repos)
}
// ListUserRepos list all repositories of one user by user's name
func (c *Client) ListUserRepos(user string) ([]*Repository, error) {
repos := make([]*Repository, 0, 10)
return repos, c.getParsedResponse("GET", fmt.Sprintf("/users/%s/repos", user), nil, nil, &repos)
}
// ListOrgRepos list all repositories of one organization by organization's name
func (c *Client) ListOrgRepos(org string) ([]*Repository, error) {
repos := make([]*Repository, 0, 10)
return repos, c.getParsedResponse("GET", fmt.Sprintf("/orgs/%s/repos", org), nil, nil, &repos)
}
// CreateRepoOption options when creating repository
//swagger:parameters createOrgRepo
type CreateRepoOption struct {
// Name of the repository to create
//
// in: body
// unique: true
Name string `json:"name" binding:"Required;AlphaDashDot;MaxSize(100)"`
// Description of the repository to create
//
// in: body
Description string `json:"description" binding:"MaxSize(255)"`
// Is the repository to create private ?
//
// in: body
Private bool `json:"private"`
// Init the repository to create ?
//
// in: body
AutoInit bool `json:"auto_init"`
// Gitignores to use
//
// in: body
Gitignores string `json:"gitignores"`
// License to use
//
// in: body
License string `json:"license"`
// Readme of the repository to create
//
// in: body
Readme string `json:"readme"`
}
// CreateRepo creates a repository for authenticated user.
func (c *Client) CreateRepo(opt CreateRepoOption) (*Repository, error) {
body, err := json.Marshal(&opt)
if err != nil {
return nil, err
}
repo := new(Repository)
return repo, c.getParsedResponse("POST", "/user/repos", jsonHeader, bytes.NewReader(body), repo)
}
// CreateOrgRepo creates an organization repository for authenticated user.
func (c *Client) CreateOrgRepo(org string, opt CreateRepoOption) (*Repository, error) {
body, err := json.Marshal(&opt)
if err != nil {
return nil, err
}
repo := new(Repository)
return repo, c.getParsedResponse("POST", fmt.Sprintf("/org/%s/repos", org), jsonHeader, bytes.NewReader(body), repo)
}
// GetRepo returns information of a repository of given owner.
func (c *Client) GetRepo(owner, reponame string) (*Repository, error) {
repo := new(Repository)
return repo, c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s", owner, reponame), nil, nil, repo)
}
// DeleteRepo deletes a repository of user or organization.
func (c *Client) DeleteRepo(owner, repo string) error {
_, err := c.getResponse("DELETE", fmt.Sprintf("/repos/%s/%s", owner, repo), nil, nil)
return err
}
// MigrateRepoOption options when migrate repository from an external place
type MigrateRepoOption struct {
CloneAddr string `json:"clone_addr" binding:"Required"`
AuthUsername string `json:"auth_username"`
AuthPassword string `json:"auth_password"`
UID int `json:"uid" binding:"Required"`
RepoName string `json:"repo_name" binding:"Required"`
Mirror bool `json:"mirror"`
Private bool `json:"private"`
Description string `json:"description"`
}
// MigrateRepo migrates a repository from other Git hosting sources for the
// authenticated user.
//
// To migrate a repository for a organization, the authenticated user must be a
// owner of the specified organization.
func (c *Client) MigrateRepo(opt MigrateRepoOption) (*Repository, error) {
body, err := json.Marshal(&opt)
if err != nil {
return nil, err
}
repo := new(Repository)
return repo, c.getParsedResponse("POST", "/repos/migrate", jsonHeader, bytes.NewReader(body), repo)
}

27
vendor/github.com/go-gitea/go-sdk/gitea/repo_branch.go generated vendored Normal file
View File

@ -0,0 +1,27 @@
// Copyright 2016 The Gogs Authors. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package gitea
import (
"fmt"
)
// Branch represents a repository branch.
type Branch struct {
Name string `json:"name"`
Commit *PayloadCommit `json:"commit"`
}
// ListRepoBranches list all the branches of one repository
func (c *Client) ListRepoBranches(user, repo string) ([]*Branch, error) {
branches := make([]*Branch, 0, 10)
return branches, c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/branches", user, repo), nil, nil, &branches)
}
// GetRepoBranch get one branch's information of one repository
func (c *Client) GetRepoBranch(user, repo, branch string) (*Branch, error) {
b := new(Branch)
return b, c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/branches/%s", user, repo, branch), nil, nil, &b)
}

View File

@ -0,0 +1,57 @@
// Copyright 2016 The Gogs Authors. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package gitea
import (
"bytes"
"encoding/json"
"fmt"
)
// ListCollaborators list a repository's collaborators
func (c *Client) ListCollaborators(user, repo string) ([]*User, error) {
collaborators := make([]*User, 0, 10)
err := c.getParsedResponse("GET",
fmt.Sprintf("/repos/%s/%s/collaborators", user, repo),
nil, nil, &collaborators)
return collaborators, err
}
// IsCollaborator check if a user is a collaborator of a repository
func (c *Client) IsCollaborator(user, repo, collaborator string) (bool, error) {
status, err := c.getStatusCode("GET",
fmt.Sprintf("/repos/%s/%s/collaborators/%s", user, repo, collaborator),
nil, nil)
if err != nil {
return false, err
}
if status == 204 {
return true, nil
}
return false, nil
}
// AddCollaboratorOption options when add some user as a collaborator of a repository
type AddCollaboratorOption struct {
Permission *string `json:"permission"`
}
// AddCollaborator add some user as a collaborator of a repository
func (c *Client) AddCollaborator(user, repo, collaborator string, opt AddCollaboratorOption) error {
body, err := json.Marshal(&opt)
if err != nil {
return err
}
_, err = c.getResponse("PUT", fmt.Sprintf("/repos/%s/%s/collaborators/%s", user, repo, collaborator), nil, bytes.NewReader(body))
return err
}
// DeleteCollaborator remove a collaborator from a repository
func (c *Client) DeleteCollaborator(user, repo, collaborator string) error {
_, err := c.getResponse("DELETE",
fmt.Sprintf("/repos/%s/%s/collaborators/%s", user, repo, collaborator),
nil, nil)
return err
}

15
vendor/github.com/go-gitea/go-sdk/gitea/repo_file.go generated vendored Normal file
View File

@ -0,0 +1,15 @@
// Copyright 2014 The Gogs Authors. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package gitea
import (
"fmt"
)
// GetFile downloads a file of repository, ref can be branch/tag/commit.
// e.g.: ref -> master, tree -> macaron.go(no leading slash)
func (c *Client) GetFile(user, repo, ref, tree string) ([]byte, error) {
return c.getResponse("GET", fmt.Sprintf("/repos/%s/%s/raw/%s/%s", user, repo, ref, tree), nil, nil)
}

67
vendor/github.com/go-gitea/go-sdk/gitea/repo_key.go generated vendored Normal file
View File

@ -0,0 +1,67 @@
// Copyright 2015 The Gogs Authors. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package gitea
import (
"bytes"
"encoding/json"
"fmt"
"time"
)
// DeployKey a deploy key
type DeployKey struct {
ID int64 `json:"id"`
Key string `json:"key"`
URL string `json:"url"`
Title string `json:"title"`
Created time.Time `json:"created_at"`
ReadOnly bool `json:"read_only"`
}
// ListDeployKeys list all the deploy keys of one repository
func (c *Client) ListDeployKeys(user, repo string) ([]*DeployKey, error) {
keys := make([]*DeployKey, 0, 10)
return keys, c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/keys", user, repo), nil, nil, &keys)
}
// GetDeployKey get one deploy key with key id
func (c *Client) GetDeployKey(user, repo string, keyID int64) (*DeployKey, error) {
key := new(DeployKey)
return key, c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/keys/%d", user, repo, keyID), nil, nil, &key)
}
// CreateKeyOption options when create deploy key
// swagger:parameters userCurrentPostKey
type CreateKeyOption struct {
// Title of the key to add
//
// in: body
// required: true
// unique: true
Title string `json:"title" binding:"Required"`
// An armored SSH key to add
//
// in: body
// required: true
// unique: true
Key string `json:"key" binding:"Required"`
}
// CreateDeployKey options when create one deploy key
func (c *Client) CreateDeployKey(user, repo string, opt CreateKeyOption) (*DeployKey, error) {
body, err := json.Marshal(&opt)
if err != nil {
return nil, err
}
key := new(DeployKey)
return key, c.getParsedResponse("POST", fmt.Sprintf("/repos/%s/%s/keys", user, repo), jsonHeader, bytes.NewReader(body), key)
}
// DeleteDeployKey delete deploy key with key id
func (c *Client) DeleteDeployKey(owner, repo string, keyID int64) error {
_, err := c.getResponse("DELETE", fmt.Sprintf("/repos/%s/%s/keys/%d", owner, repo, keyID), nil, nil)
return err
}

42
vendor/github.com/go-gitea/go-sdk/gitea/repo_watch.go generated vendored Normal file
View File

@ -0,0 +1,42 @@
// Copyright 2017 The Gitea Authors. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package gitea
import (
"fmt"
"net/http"
"time"
)
// WatchInfo represents a API watch status of one repository
// swagger:response WatchInfo
type WatchInfo struct {
Subscribed bool `json:"subscribed"`
Ignored bool `json:"ignored"`
Reason interface{} `json:"reason"`
CreatedAt time.Time `json:"created_at"`
URL string `json:"url"`
RepositoryURL string `json:"repository_url"`
}
// GetWatchedRepos list all the watched repos of user
func (c *Client) GetWatchedRepos(user, pass string) ([]*Repository, error) {
repos := make([]*Repository, 0, 10)
return repos, c.getParsedResponse("GET", fmt.Sprintf("/users/%s/subscriptions", user),
http.Header{"Authorization": []string{"Basic " + BasicAuthEncode(user, pass)}}, nil, &repos)
}
// WatchRepo start to watch a repository
func (c *Client) WatchRepo(user, pass, repoUser, repoName string) (*WatchInfo, error) {
i := new(WatchInfo)
return i, c.getParsedResponse("PUT", fmt.Sprintf("/repos/%s/%s/subscription", repoUser, repoName),
http.Header{"Authorization": []string{"Basic " + BasicAuthEncode(user, pass)}}, nil, i)
}
// UnWatchRepo start to watch a repository
func (c *Client) UnWatchRepo(user, pass, repoUser, repoName string) (int, error) {
return c.getStatusCode("DELETE", fmt.Sprintf("/repos/%s/%s/subscription", repoUser, repoName),
http.Header{"Authorization": []string{"Basic " + BasicAuthEncode(user, pass)}}, nil)
}

97
vendor/github.com/go-gitea/go-sdk/gitea/status.go generated vendored Normal file
View File

@ -0,0 +1,97 @@
// Copyright 2017 The Gitea Authors. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package gitea
import (
"bytes"
"encoding/json"
"fmt"
"time"
)
// StatusState holds the state of a Status
// It can be "pending", "success", "error", "failure", and "warning"
type StatusState string
const (
// StatusPending is for when the Status is Pending
StatusPending StatusState = "pending"
// StatusSuccess is for when the Status is Success
StatusSuccess StatusState = "success"
// StatusError is for when the Status is Error
StatusError StatusState = "error"
// StatusFailure is for when the Status is Failure
StatusFailure StatusState = "failure"
// StatusWarning is for when the Status is Warning
StatusWarning StatusState = "warning"
// StatusCanceled is for when the Status is Canceled
StatusCanceled StatusState = "canceled"
)
// Status holds a single Status of a single Commit
type Status struct {
ID int64 `json:"id"`
State StatusState `json:"status"`
TargetURL string `json:"target_url"`
Description string `json:"description"`
URL string `json:"url"`
Context string `json:"context"`
Creator *User `json:"creator"`
Created time.Time `json:"created_at"`
Updated time.Time `json:"updated_at"`
}
// CombinedStatus holds the combined state of several statuses for a single commit
type CombinedStatus struct {
State StatusState `json:"state"`
SHA string `json:"sha"`
TotalCount int `json:"total_count"`
Statuses []*Status `json:"statuses"`
Repository *Repository `json:"repository"`
CommitURL string `json:"commit_url"`
URL string `json:"url"`
}
// CreateStatusOption holds the information needed to create a new Status for a Commit
type CreateStatusOption struct {
State StatusState `json:"state"`
TargetURL string `json:"target_url"`
Description string `json:"description"`
Context string `json:"context"`
}
// ListStatusesOption holds pagination information
type ListStatusesOption struct {
Page int
}
// CreateStatus creates a new Status for a given Commit
//
// POST /repos/:owner/:repo/statuses/:sha
func (c *Client) CreateStatus(owner, repo, sha string, opts CreateStatusOption) (*Status, error) {
body, err := json.Marshal(&opts)
if err != nil {
return nil, err
}
status := &Status{}
return status, c.getParsedResponse("POST", fmt.Sprintf("/repos/%s/%s/statuses/%s", owner, repo, sha),
jsonHeader, bytes.NewReader(body), status)
}
// ListStatuses returns all statuses for a given Commit
//
// GET /repos/:owner/:repo/commits/:ref/statuses
func (c *Client) ListStatuses(owner, repo, sha string, opts ListStatusesOption) ([]*Status, error) {
statuses := make([]*Status, 0, 10)
return statuses, c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/commits/%s/statuses?page=%d", owner, repo, sha, opts.Page), nil, nil, &statuses)
}
// GetCombinedStatus returns the CombinedStatus for a given Commit
//
// GET /repos/:owner/:repo/commits/:ref/status
func (c *Client) GetCombinedStatus(owner, repo, sha string) (*CombinedStatus, error) {
status := &CombinedStatus{}
return status, c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/commits/%s/status", owner, repo, sha), nil, nil, status)
}

41
vendor/github.com/go-gitea/go-sdk/gitea/user.go generated vendored Normal file
View File

@ -0,0 +1,41 @@
// Copyright 2014 The Gogs Authors. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package gitea
import (
"encoding/json"
"fmt"
)
// User represents a API user.
// swagger:response User
type User struct {
ID int64 `json:"id"`
UserName string `json:"login"`
FullName string `json:"full_name"`
Email string `json:"email"`
AvatarURL string `json:"avatar_url"`
}
// UserList represents a list of API user.
// swagger:response UserList
type UserList []*User
// MarshalJSON implements the json.Marshaler interface for User, adding field(s) for backward compatibility
func (u User) MarshalJSON() ([]byte, error) {
// Re-declaring User to avoid recursion
type shadow User
return json.Marshal(struct {
shadow
CompatUserName string `json:"username"`
}{shadow(u), u.UserName})
}
// GetUserInfo get user info by user's name
func (c *Client) GetUserInfo(user string) (*User, error) {
u := new(User)
err := c.getParsedResponse("GET", fmt.Sprintf("/users/%s", user), nil, nil, u)
return u, err
}

56
vendor/github.com/go-gitea/go-sdk/gitea/user_app.go generated vendored Normal file
View File

@ -0,0 +1,56 @@
// Copyright 2014 The Gogs Authors. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package gitea
import (
"bytes"
"encoding/base64"
"encoding/json"
"fmt"
"net/http"
)
// BasicAuthEncode generate base64 of basic auth head
func BasicAuthEncode(user, pass string) string {
return base64.StdEncoding.EncodeToString([]byte(user + ":" + pass))
}
// AccessToken represents a API access token.
// swagger:response AccessToken
type AccessToken struct {
Name string `json:"name"`
Sha1 string `json:"sha1"`
}
// AccessTokenList represents a list of API access token.
// swagger:response AccessTokenList
type AccessTokenList []*AccessToken
// ListAccessTokens lista all the access tokens of user
func (c *Client) ListAccessTokens(user, pass string) ([]*AccessToken, error) {
tokens := make([]*AccessToken, 0, 10)
return tokens, c.getParsedResponse("GET", fmt.Sprintf("/users/%s/tokens", user),
http.Header{"Authorization": []string{"Basic " + BasicAuthEncode(user, pass)}}, nil, &tokens)
}
// CreateAccessTokenOption options when create access token
// swagger:parameters userCreateToken
type CreateAccessTokenOption struct {
Name string `json:"name" binding:"Required"`
}
// CreateAccessToken create one access token with options
func (c *Client) CreateAccessToken(user, pass string, opt CreateAccessTokenOption) (*AccessToken, error) {
body, err := json.Marshal(&opt)
if err != nil {
return nil, err
}
t := new(AccessToken)
return t, c.getParsedResponse("POST", fmt.Sprintf("/users/%s/tokens", user),
http.Header{
"content-type": []string{"application/json"},
"Authorization": []string{"Basic " + BasicAuthEncode(user, pass)}},
bytes.NewReader(body), t)
}

48
vendor/github.com/go-gitea/go-sdk/gitea/user_email.go generated vendored Normal file
View File

@ -0,0 +1,48 @@
// Copyright 2015 The Gogs Authors. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package gitea
import (
"bytes"
"encoding/json"
)
// Email en email information of user
type Email struct {
Email string `json:"email"`
Verified bool `json:"verified"`
Primary bool `json:"primary"`
}
// ListEmails all the email addresses of user
func (c *Client) ListEmails() ([]*Email, error) {
emails := make([]*Email, 0, 3)
return emails, c.getParsedResponse("GET", "/user/emails", nil, nil, &emails)
}
// CreateEmailOption options when create an email
type CreateEmailOption struct {
Emails []string `json:"emails"`
}
// AddEmail add one email to current user with options
func (c *Client) AddEmail(opt CreateEmailOption) ([]*Email, error) {
body, err := json.Marshal(&opt)
if err != nil {
return nil, err
}
emails := make([]*Email, 0, 3)
return emails, c.getParsedResponse("POST", "/user/emails", jsonHeader, bytes.NewReader(body), emails)
}
// DeleteEmail delete one email of current users'
func (c *Client) DeleteEmail(opt CreateEmailOption) error {
body, err := json.Marshal(&opt)
if err != nil {
return err
}
_, err = c.getResponse("DELETE", "/user/emails", jsonHeader, bytes.NewReader(body))
return err
}

55
vendor/github.com/go-gitea/go-sdk/gitea/user_follow.go generated vendored Normal file
View File

@ -0,0 +1,55 @@
// Copyright 2015 The Gogs Authors. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package gitea
import "fmt"
// ListMyFollowers list all the followers of current user
func (c *Client) ListMyFollowers(page int) ([]*User, error) {
users := make([]*User, 0, 10)
return users, c.getParsedResponse("GET", fmt.Sprintf("/user/followers?page=%d", page), nil, nil, &users)
}
// ListFollowers list all the followers of one user
func (c *Client) ListFollowers(user string, page int) ([]*User, error) {
users := make([]*User, 0, 10)
return users, c.getParsedResponse("GET", fmt.Sprintf("/users/%s/followers?page=%d", user, page), nil, nil, &users)
}
// ListMyFollowing list all the users current user followed
func (c *Client) ListMyFollowing(page int) ([]*User, error) {
users := make([]*User, 0, 10)
return users, c.getParsedResponse("GET", fmt.Sprintf("/user/following?page=%d", page), nil, nil, &users)
}
// ListFollowing list all the users the user followed
func (c *Client) ListFollowing(user string, page int) ([]*User, error) {
users := make([]*User, 0, 10)
return users, c.getParsedResponse("GET", fmt.Sprintf("/users/%s/following?page=%d", user, page), nil, nil, &users)
}
// IsFollowing if current user followed the target
func (c *Client) IsFollowing(target string) bool {
_, err := c.getResponse("GET", fmt.Sprintf("/user/following/%s", target), nil, nil)
return err == nil
}
// IsUserFollowing if the user followed the target
func (c *Client) IsUserFollowing(user, target string) bool {
_, err := c.getResponse("GET", fmt.Sprintf("/users/%s/following/%s", user, target), nil, nil)
return err == nil
}
// Follow set current user follow the target
func (c *Client) Follow(target string) error {
_, err := c.getResponse("PUT", fmt.Sprintf("/user/following/%s", target), nil, nil)
return err
}
// Unfollow set current user unfollow the target
func (c *Client) Unfollow(target string) error {
_, err := c.getResponse("DELETE", fmt.Sprintf("/user/following/%s", target), nil, nil)
return err
}

85
vendor/github.com/go-gitea/go-sdk/gitea/user_gpgkey.go generated vendored Normal file
View File

@ -0,0 +1,85 @@
// Copyright 2017 Gitea Authors. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package gitea
import (
"bytes"
"encoding/json"
"fmt"
"time"
)
// GPGKeyList represents a list of GPGKey
// swagger:response GPGKeyList
type GPGKeyList []*GPGKey
// GPGKey a user GPG key to sign commit and tag in repository
// swagger:response GPGKey
type GPGKey struct {
ID int64 `json:"id"`
PrimaryKeyID string `json:"primary_key_id"`
KeyID string `json:"key_id"`
PublicKey string `json:"public_key"`
Emails []*GPGKeyEmail `json:"emails"`
SubsKey []*GPGKey `json:"subkeys"`
CanSign bool `json:"can_sign"`
CanEncryptComms bool `json:"can_encrypt_comms"`
CanEncryptStorage bool `json:"can_encrypt_storage"`
CanCertify bool `json:"can_certify"`
Created time.Time `json:"created_at,omitempty"`
Expires time.Time `json:"expires_at,omitempty"`
}
// GPGKeyEmail a email attache to a GPGKey
// swagger:model GPGKeyEmail
type GPGKeyEmail struct {
Email string `json:"email"`
Verified bool `json:"verified"`
}
// CreateGPGKeyOption options create user GPG key
// swagger:parameters userCurrentPostGPGKey
type CreateGPGKeyOption struct {
// An armored GPG key to add
//
// in: body
// required: true
// unique: true
ArmoredKey string `json:"armored_public_key" binding:"Required"`
}
// ListGPGKeys list all the GPG keys of the user
func (c *Client) ListGPGKeys(user string) ([]*GPGKey, error) {
keys := make([]*GPGKey, 0, 10)
return keys, c.getParsedResponse("GET", fmt.Sprintf("/users/%s/gpg_keys", user), nil, nil, &keys)
}
// ListMyGPGKeys list all the GPG keys of current user
func (c *Client) ListMyGPGKeys() ([]*GPGKey, error) {
keys := make([]*GPGKey, 0, 10)
return keys, c.getParsedResponse("GET", "/user/gpg_keys", nil, nil, &keys)
}
// GetGPGKey get current user's GPG key by key id
func (c *Client) GetGPGKey(keyID int64) (*GPGKey, error) {
key := new(GPGKey)
return key, c.getParsedResponse("GET", fmt.Sprintf("/user/gpg_keys/%d", keyID), nil, nil, &key)
}
// CreateGPGKey create GPG key with options
func (c *Client) CreateGPGKey(opt CreateGPGKeyOption) (*GPGKey, error) {
body, err := json.Marshal(&opt)
if err != nil {
return nil, err
}
key := new(GPGKey)
return key, c.getParsedResponse("POST", "/user/gpg_keys", jsonHeader, bytes.NewReader(body), key)
}
// DeleteGPGKey delete GPG key with key id
func (c *Client) DeleteGPGKey(keyID int64) error {
_, err := c.getResponse("DELETE", fmt.Sprintf("/user/gpg_keys/%d", keyID), nil, nil)
return err
}

60
vendor/github.com/go-gitea/go-sdk/gitea/user_key.go generated vendored Normal file
View File

@ -0,0 +1,60 @@
// Copyright 2015 The Gogs Authors. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package gitea
import (
"bytes"
"encoding/json"
"fmt"
"time"
)
// PublicKeyList represents a list of PublicKey
// swagger:response PublicKeyList
type PublicKeyList []*PublicKey
// PublicKey publickey is a user key to push code to repository
// swagger:response PublicKey
type PublicKey struct {
ID int64 `json:"id"`
Key string `json:"key"`
URL string `json:"url,omitempty"`
Title string `json:"title,omitempty"`
Created time.Time `json:"created_at,omitempty"`
}
// ListPublicKeys list all the public keys of the user
func (c *Client) ListPublicKeys(user string) ([]*PublicKey, error) {
keys := make([]*PublicKey, 0, 10)
return keys, c.getParsedResponse("GET", fmt.Sprintf("/users/%s/keys", user), nil, nil, &keys)
}
// ListMyPublicKeys list all the public keys of current user
func (c *Client) ListMyPublicKeys() ([]*PublicKey, error) {
keys := make([]*PublicKey, 0, 10)
return keys, c.getParsedResponse("GET", "/user/keys", nil, nil, &keys)
}
// GetPublicKey get current user's public key by key id
func (c *Client) GetPublicKey(keyID int64) (*PublicKey, error) {
key := new(PublicKey)
return key, c.getParsedResponse("GET", fmt.Sprintf("/user/keys/%d", keyID), nil, nil, &key)
}
// CreatePublicKey create public key with options
func (c *Client) CreatePublicKey(opt CreateKeyOption) (*PublicKey, error) {
body, err := json.Marshal(&opt)
if err != nil {
return nil, err
}
key := new(PublicKey)
return key, c.getParsedResponse("POST", "/user/keys", jsonHeader, bytes.NewReader(body), key)
}
// DeletePublicKey delete public key with key id
func (c *Client) DeletePublicKey(keyID int64) error {
_, err := c.getResponse("DELETE", fmt.Sprintf("/user/keys/%d", keyID), nil, nil)
return err
}

26
vendor/github.com/go-gitea/go-sdk/gitea/utils.go generated vendored Normal file
View File

@ -0,0 +1,26 @@
// Copyright 2015 The Gogs Authors. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package gitea
import (
"net/http"
)
var jsonHeader = http.Header{"content-type": []string{"application/json"}}
// Bool return address of bool value
func Bool(v bool) *bool {
return &v
}
// String return address of string value
func String(v string) *string {
return &v
}
// Int64 return address of int64 value
func Int64(v int64) *int64 {
return &v
}