mirror of
https://github.com/strongdm/comply
synced 2025-12-15 10:43:47 +00:00
Compare commits
52 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d43aca58ba | ||
|
|
9e4cd2cf1a | ||
|
|
3711e0054d | ||
|
|
2e9f6cf270 | ||
|
|
c5868fa544 | ||
|
|
274986ad9c | ||
|
|
bcc9b06ac4 | ||
|
|
8f3d668789 | ||
|
|
358ac431a6 | ||
|
|
365e98222b | ||
|
|
84589a83f4 | ||
|
|
b329107079 | ||
|
|
3f5d9b4409 | ||
|
|
3df822206e | ||
|
|
007cf3dd3c | ||
|
|
97989c5cf6 | ||
|
|
ce5c4c3a4a | ||
|
|
cd89840164 | ||
|
|
e60d7285f4 | ||
|
|
c99d800397 | ||
|
|
0f1badca5b | ||
|
|
00b59ed620 | ||
|
|
749017761d | ||
|
|
f502225cde | ||
|
|
6cf6f70296 | ||
|
|
3494bdce7b | ||
|
|
924dd25744 | ||
|
|
02d3b75731 | ||
|
|
4a314c62d1 | ||
|
|
f2ef58e7bd | ||
|
|
fc1a1d9abc | ||
|
|
65dddc4332 | ||
|
|
eecfe49fbd | ||
|
|
44931ca808 | ||
|
|
06b8a2fe44 | ||
|
|
2d088cdf45 | ||
|
|
fb60f405ba | ||
|
|
3c696e6d01 | ||
|
|
4d63cf559b | ||
|
|
0ff74208cc | ||
|
|
75a80189ce | ||
|
|
f6c9f89792 | ||
|
|
25f7156ac2 | ||
|
|
2d5e6b48cb | ||
|
|
4d830789ec | ||
|
|
4969d179ec | ||
|
|
10dc0b70e0 | ||
|
|
0f68acae10 | ||
|
|
19e100801a | ||
|
|
46aaf1c663 | ||
|
|
815e7e5f61 | ||
|
|
ff626a5ee2 |
@@ -1,4 +1,9 @@
|
||||
# Authors in alphabetical order:
|
||||
|
||||
Alan Cox
|
||||
Andy Magnusson
|
||||
Anthony Oliver
|
||||
Justin Bodeutsch
|
||||
Justin McCarthy <justin@strongdm.com>
|
||||
Manisha Singh <manisha@strongdm.com>
|
||||
Manisha Singh
|
||||
Mason Hensley
|
||||
29
Gopkg.lock
generated
29
Gopkg.lock
generated
@@ -7,6 +7,12 @@
|
||||
revision = "7da180ee92d8bd8bb8c37fc560e673e6557c392f"
|
||||
version = "v0.4.7"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/andygrunwald/go-jira"
|
||||
packages = ["."]
|
||||
revision = "5cfdb85cc91c6299f75b6504a1d0ec174c21be39"
|
||||
version = "v1.3.0"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "github.com/chzyer/readline"
|
||||
@@ -79,6 +85,12 @@
|
||||
revision = "507f6050b8568533fb3f5504de8e5205fa62a114"
|
||||
version = "v1.6.0"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/fatih/structs"
|
||||
packages = ["."]
|
||||
revision = "a720dfa8df582c51dee1b36feabb906bde1588bd"
|
||||
version = "v1.0"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/fsnotify/fsnotify"
|
||||
packages = ["."]
|
||||
@@ -194,12 +206,27 @@
|
||||
packages = ["open"]
|
||||
revision = "75fb7ed4208cf72d323d7d02fd1a5964a7a9073c"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/trivago/tgo"
|
||||
packages = [
|
||||
"tcontainer",
|
||||
"treflect"
|
||||
]
|
||||
revision = "e4d1ddd28c17dd89ed26327cf69fded22060671b"
|
||||
version = "v1.0.1"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/urfave/cli"
|
||||
packages = ["."]
|
||||
revision = "cfb38830724cc34fedffe9a2a29fb54fa9169cd1"
|
||||
version = "v1.20.0"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/xanzy/go-gitlab"
|
||||
packages = ["."]
|
||||
revision = "79dad8e74fd097eb2e0fd0883f1978213e88107a"
|
||||
version = "v0.10.7"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/yosssi/ace"
|
||||
packages = ["."]
|
||||
@@ -257,6 +284,6 @@
|
||||
[solve-meta]
|
||||
analyzer-name = "dep"
|
||||
analyzer-version = 1
|
||||
inputs-digest = "4fd2ff9f9869c3f3e30601504f4b00fce69d282ae8df42583a1c60848bfd0766"
|
||||
inputs-digest = "50dc710fa4b581d4fd6907e0e3337c53c3d530e46c53aa71ef9f8e80d3a54d8b"
|
||||
solver-name = "gps-cdcl"
|
||||
solver-version = 1
|
||||
|
||||
8
Makefile
8
Makefile
@@ -19,12 +19,14 @@ dist: clean
|
||||
$(eval LDFLAGS := -ldflags='-X "github.com/strongdm/comply/internal/cli.Version=$(VERSION)"')
|
||||
mkdir dist
|
||||
echo $(VERSION)
|
||||
GOOS=darwin GOARCH=amd64 CGO_ENABLED=0 go build -gcflags=-trimpath=$(GOPATH) -asmflags=-trimpath=$(GOPATH) $(LDFLAGS) -o dist/comply-$(VERSION)-darwin-amd64 .
|
||||
GOOS=linux GOARCH=amd64 CGO_ENABLED=0 go build -gcflags=-trimpath=$(GOPATH) -asmflags=-trimpath=$(GOPATH) $(LDFLAGS) -o dist/comply-$(VERSION)-linux-amd64 .
|
||||
GOOS=darwin GOARCH=amd64 CGO_ENABLED=0 go build -gcflags=-trimpath=$(GOPATH) -asmflags=-trimpath=$(GOPATH) -ldflags '-extldflags "-static"' $(LDFLAGS) -o dist/comply-$(VERSION)-darwin-amd64 .
|
||||
GOOS=linux GOARCH=amd64 CGO_ENABLED=0 go build -gcflags=-trimpath=$(GOPATH) -asmflags=-trimpath=$(GOPATH) -ldflags '-extldflags "-static"' $(LDFLAGS) -o dist/comply-$(VERSION)-linux-amd64 .
|
||||
GOOS=windows GOARCH=amd64 CGO_ENABLED=0 go build -gcflags=-trimpath=$(GOPATH) -asmflags=-trimpath=$(GOPATH) -ldflags '-extldflags "-static"' $(LDFLAGS) -o dist/comply-$(VERSION)-windows-amd64.exe .
|
||||
cd dist && tar -czvf comply-$(VERSION)-darwin-amd64.tgz comply-$(VERSION)-darwin-amd64
|
||||
cd dist && tar -czvf comply-$(VERSION)-linux-amd64.tgz comply-$(VERSION)-linux-amd64
|
||||
cd dist && zip comply-$(VERSION)-windows-amd64.zip comply-$(VERSION)-windows-amd64.exe
|
||||
|
||||
brew: clean assets $(GO_SOURCES)
|
||||
brew: clean $(GO_SOURCES)
|
||||
$(eval VERSION := $(shell cat version))
|
||||
$(eval LDFLAGS := -ldflags='-X "github.com/strongdm/comply/internal/cli.Version=$(VERSION)"')
|
||||
mkdir bin
|
||||
|
||||
36
README.md
36
README.md
@@ -77,4 +77,40 @@ COMMANDS:
|
||||
todo list declared vs satisfied compliance controls
|
||||
help, h Shows a list of commands or help for one command
|
||||
```
|
||||
## Ticketing Integrations:
|
||||
- Jira
|
||||
- Github
|
||||
- Gitlab
|
||||
|
||||
## Configuring Jira
|
||||
When comply creates a ticket (through `proc`, for instance), it sets the following fields.
|
||||
|
||||
- assignee
|
||||
- description
|
||||
- issuetype
|
||||
- labels
|
||||
- project key
|
||||
- reporter
|
||||
- summary
|
||||
|
||||
Please make sure that the default *Create Screen* has all of those fields enabled. Additionally, make sure that there are no other required fields for the issue type you choose.
|
||||
|
||||
|
||||
|
||||
|
||||
## Forking and local development
|
||||
> Assumes installation of golang and configuration of GOPATH in .bash_profile, .zshrc, etc
|
||||
> Inspiration: http://code.openark.org/blog/development/forking-golang-repositories-on-github-and-managing-the-import-path
|
||||
|
||||
```
|
||||
$ go get github.com/strongdm/comply
|
||||
$ cd $GOPATH/src/github.com/strongdm/comply ; go get ./...
|
||||
$ make
|
||||
$ cd example
|
||||
$ mv comply.yml.example comply.yml
|
||||
$ ../comply -h
|
||||
$ ../comply sync
|
||||
$ ../comply serve
|
||||
#
|
||||
$ make # recompile as needed with in $GOPATH/src/github.com/strongdm/comply
|
||||
```
|
||||
|
||||
@@ -8,6 +8,7 @@ RUN apt-get update -y \
|
||||
&& apt-get install -y -o Acquire::Retries=10 --no-install-recommends \
|
||||
texlive-latex-base \
|
||||
texlive-xetex \
|
||||
texlive-fonts-recommended \
|
||||
latex-xcolor \
|
||||
texlive-latex-extra \
|
||||
fontconfig \
|
||||
@@ -25,4 +26,4 @@ WORKDIR /source
|
||||
|
||||
ENTRYPOINT ["/root/.cabal/bin/pandoc"]
|
||||
|
||||
CMD ["--help"]
|
||||
CMD ["--help"]
|
||||
|
||||
@@ -1,7 +1,31 @@
|
||||
name: "Acme"
|
||||
filePrefix: "Acme"
|
||||
|
||||
# The following setting is optional.
|
||||
# If you set this (to, e.g. master), and you build the policies
|
||||
# on that branch, then a section is appended to each policy that
|
||||
# describes the approval. Text will look like:
|
||||
#
|
||||
# Last edit made by John Doe (jdoe@email.com) on Wed, 15 Aug 2018 12:45:28 -0400.
|
||||
# Approved by Joan Smith (jsmith@email.com) on Wed, 15 Aug 2018 16:54:48 -0400 in commit abc123123.
|
||||
#
|
||||
# The change author gets credit for the edit.
|
||||
# The person who committed or merged to the approval branch gets credit for approval.
|
||||
approvedBranch: master
|
||||
tickets:
|
||||
github:
|
||||
token: XXX
|
||||
username: strongdm
|
||||
repo: comply
|
||||
repo: comply
|
||||
# jira:
|
||||
# username: xxxx # This is the username you log in to Jira's UI with. Probably your email address.
|
||||
# password: xxxx # If you don't have a "managed account", use your password in this field. But if your organization
|
||||
# # uses SAML or OAuth, or Jira's built-in multi-factor authentication, you need to use
|
||||
# # an API token. Learn more here: https://confluence.atlassian.com/cloud/api-tokens-938839638.html
|
||||
# project: comply
|
||||
# url: https://yourjira
|
||||
# taskType: Task # This must be an Issue, not a sub-task
|
||||
# gitlab:
|
||||
# domain: https://gitlab.example.com:443/ # or https://gitlab.com/
|
||||
# token: token-here
|
||||
# repo: full-slug/of-project
|
||||
|
||||
@@ -6,6 +6,8 @@ import (
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"math/rand"
|
||||
"net/http"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
@@ -13,11 +15,15 @@ import (
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
"unicode"
|
||||
"unicode/utf8"
|
||||
|
||||
"github.com/docker/docker/api/types"
|
||||
"github.com/docker/docker/client"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/strongdm/comply/internal/config"
|
||||
"github.com/strongdm/comply/internal/gitlab"
|
||||
"github.com/strongdm/comply/internal/jira"
|
||||
"github.com/strongdm/comply/internal/plugin/github"
|
||||
"github.com/urfave/cli"
|
||||
)
|
||||
@@ -43,18 +49,20 @@ func newApp() *cli.App {
|
||||
app.Usage = "policy compliance toolkit"
|
||||
|
||||
app.Commands = []cli.Command{
|
||||
initCommand,
|
||||
beforeCommand(initCommand, notifyVersion),
|
||||
}
|
||||
|
||||
app.Commands = append(app.Commands, beforeCommand(buildCommand, projectMustExist))
|
||||
app.Commands = append(app.Commands, beforeCommand(procedureCommand, projectMustExist))
|
||||
app.Commands = append(app.Commands, beforeCommand(schedulerCommand, projectMustExist))
|
||||
app.Commands = append(app.Commands, beforeCommand(serveCommand, projectMustExist))
|
||||
app.Commands = append(app.Commands, beforeCommand(syncCommand, projectMustExist))
|
||||
app.Commands = append(app.Commands, beforeCommand(todoCommand, projectMustExist))
|
||||
app.Commands = append(app.Commands, beforeCommand(buildCommand, projectMustExist, notifyVersion))
|
||||
app.Commands = append(app.Commands, beforeCommand(procedureCommand, projectMustExist, notifyVersion))
|
||||
app.Commands = append(app.Commands, beforeCommand(schedulerCommand, projectMustExist, notifyVersion))
|
||||
app.Commands = append(app.Commands, beforeCommand(serveCommand, projectMustExist, notifyVersion))
|
||||
app.Commands = append(app.Commands, beforeCommand(syncCommand, projectMustExist, notifyVersion))
|
||||
app.Commands = append(app.Commands, beforeCommand(todoCommand, projectMustExist, notifyVersion))
|
||||
|
||||
// Plugins
|
||||
github.Register()
|
||||
jira.Register()
|
||||
gitlab.Register()
|
||||
|
||||
return app
|
||||
}
|
||||
@@ -99,55 +107,157 @@ func ticketingMustBeConfigured(c *cli.Context) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func pandocMustExist(c *cli.Context) error {
|
||||
eitherMustExistErr := fmt.Errorf("Please install either Docker or the pandoc package and re-run `%s`", c.Command.Name)
|
||||
// notifyVersion asynchronously notifies the availability of version updates
|
||||
func notifyVersion(c *cli.Context) error {
|
||||
go func() {
|
||||
defer func() {
|
||||
recover() // suppress panic
|
||||
}()
|
||||
|
||||
r, err := http.Get("http://comply-releases.s3.amazonaws.com/channel/stable/VERSION")
|
||||
body, err := ioutil.ReadAll(r.Body)
|
||||
if err != nil {
|
||||
// fail silently
|
||||
}
|
||||
|
||||
version := strings.TrimSpace(string(body))
|
||||
|
||||
// only when numeric versions are present
|
||||
firstRune, _ := utf8.DecodeRuneInString(string(body))
|
||||
if unicode.IsDigit(firstRune) && version != Version {
|
||||
// only once every ~10 times
|
||||
if rand.Intn(10) == 0 {
|
||||
fmt.Fprintf(os.Stderr, "a new version of comply is available")
|
||||
}
|
||||
}
|
||||
}()
|
||||
return nil
|
||||
}
|
||||
|
||||
func pandocMustExist(c *cli.Context) error {
|
||||
eitherMustExistErr := fmt.Errorf("\n\nPlease install either Docker or the pandoc package and re-run `%s`. Find OS-specific pandoc installation instructions at: [TODO]", c.Command.Name)
|
||||
|
||||
pandocExistErr, found, goodVersion, pdfLatex := pandocBinaryMustExist(c)
|
||||
dockerExistErr, inPath, isRunning := dockerMustExist(c)
|
||||
|
||||
pandocExistErr := pandocBinaryMustExist(c)
|
||||
dockerExistErr := dockerMustExist(c)
|
||||
config.SetPandoc(pandocExistErr == nil, dockerExistErr == nil)
|
||||
check := func(b bool) string {
|
||||
if b {
|
||||
return "✔"
|
||||
} else {
|
||||
return "✖"
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if pandocExistErr != nil && dockerExistErr != nil {
|
||||
|
||||
fmt.Printf(`
|
||||
[%s] pandoc binary installed and in PATH
|
||||
[%s] pandoc version compatible
|
||||
[%s] pdflatex binary installed and in PATH
|
||||
[%s] docker binary installed
|
||||
[%s] docker running
|
||||
|
||||
`, check(found), check(goodVersion), check(pdfLatex), check(inPath), check(isRunning))
|
||||
|
||||
return eitherMustExistErr
|
||||
}
|
||||
|
||||
// if we don't have pandoc, but we do have docker, execute a pull
|
||||
if (pandocExistErr != nil && dockerExistErr == nil) || config.WhichPandoc() == config.UseDocker {
|
||||
dockerPull(c)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func pandocBinaryMustExist(c *cli.Context) error {
|
||||
func pandocBinaryMustExist(c *cli.Context) (e error, found, goodVersion, pdfLatex bool) {
|
||||
cmd := exec.Command("pandoc", "-v")
|
||||
outputRaw, err := cmd.Output()
|
||||
|
||||
e = nil
|
||||
found = false
|
||||
goodVersion = false
|
||||
pdfLatex = false
|
||||
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "error calling pandoc")
|
||||
e = errors.Wrap(err, "error calling pandoc")
|
||||
} else {
|
||||
found = true
|
||||
goodVersion = true
|
||||
output := strings.TrimSpace((string(outputRaw)))
|
||||
versionErr := errors.New("cannot determine pandoc version")
|
||||
if !strings.HasPrefix(output, "pandoc") {
|
||||
e = versionErr
|
||||
goodVersion = false
|
||||
} else {
|
||||
re := regexp.MustCompile(`pandoc (\d+)\.(\d+)`)
|
||||
result := re.FindStringSubmatch(output)
|
||||
if len(result) != 3 {
|
||||
e = versionErr
|
||||
goodVersion = false
|
||||
} else {
|
||||
major, err := strconv.Atoi(result[1])
|
||||
if err != nil {
|
||||
e = versionErr
|
||||
goodVersion = false
|
||||
}
|
||||
minor, err := strconv.Atoi(result[2])
|
||||
if err != nil {
|
||||
e = versionErr
|
||||
goodVersion = false
|
||||
}
|
||||
if major < 2 || minor < 1 {
|
||||
e = errors.New("pandoc 2.1 or greater required")
|
||||
goodVersion = false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
output := strings.TrimSpace((string(outputRaw)))
|
||||
versionErr := errors.New("cannot determine pandoc version")
|
||||
if !strings.HasPrefix(output, "pandoc") {
|
||||
return versionErr
|
||||
}
|
||||
|
||||
re := regexp.MustCompile(`pandoc (\d+)\.(\d+)`)
|
||||
result := re.FindStringSubmatch(output)
|
||||
if len(result) != 3 {
|
||||
return versionErr
|
||||
}
|
||||
|
||||
major, err := strconv.Atoi(result[1])
|
||||
// pdflatex must also be present
|
||||
cmd = exec.Command("pdflatex", "--version")
|
||||
outputRaw, err = cmd.Output()
|
||||
if err != nil {
|
||||
return versionErr
|
||||
}
|
||||
minor, err := strconv.Atoi(result[2])
|
||||
if err != nil {
|
||||
return versionErr
|
||||
e = errors.Wrap(err, "error calling pdflatex")
|
||||
} else if !strings.Contains(string(outputRaw), "TeX") {
|
||||
e = errors.New("pdflatex is required")
|
||||
} else {
|
||||
pdfLatex = true
|
||||
}
|
||||
|
||||
if major < 2 || minor < 1 {
|
||||
return errors.New("pandoc 2.1 or greater required")
|
||||
}
|
||||
return nil
|
||||
return e, found, goodVersion, pdfLatex
|
||||
}
|
||||
|
||||
func dockerMustExist(c *cli.Context) error {
|
||||
func dockerMustExist(c *cli.Context) (e error, inPath, isRunning bool) {
|
||||
dockerErr := fmt.Errorf("Docker must be available in order to run `%s`", c.Command.Name)
|
||||
|
||||
inPath = true
|
||||
cmd := exec.Command("docker", "--version")
|
||||
_, err := cmd.Output()
|
||||
if err != nil {
|
||||
inPath = false
|
||||
}
|
||||
|
||||
isRunning = true
|
||||
ctx := context.Background()
|
||||
cli, err := client.NewEnvClient()
|
||||
if err != nil {
|
||||
isRunning = false
|
||||
return dockerErr, inPath, isRunning
|
||||
}
|
||||
|
||||
_, err = cli.Ping(ctx)
|
||||
if err != nil {
|
||||
isRunning = false
|
||||
return dockerErr, inPath, isRunning
|
||||
}
|
||||
|
||||
return nil, inPath, isRunning
|
||||
}
|
||||
|
||||
func dockerPull(c *cli.Context) error {
|
||||
dockerErr := fmt.Errorf("Docker must be available in order to run `%s`", c.Command.Name)
|
||||
|
||||
ctx := context.Background()
|
||||
|
||||
@@ -100,7 +100,7 @@ func initAction(c *cli.Context) error {
|
||||
|
||||
chooser = promptui.Select{
|
||||
Label: "Ticket System",
|
||||
Items: []string{"GitHub", "Jira", "None"},
|
||||
Items: []string{"GitHub", "Jira", "GitLab", "None"},
|
||||
}
|
||||
|
||||
choice, _, err = chooser.Run()
|
||||
@@ -116,8 +116,9 @@ func initAction(c *cli.Context) error {
|
||||
case 0:
|
||||
ticketing = model.GitHub
|
||||
case 1:
|
||||
fmt.Println("\nHello Jira user! The Jira ticketing plugin is currently in development, please join us on Slack for a status update.")
|
||||
ticketing = model.NoTickets
|
||||
ticketing = model.Jira
|
||||
case 2:
|
||||
ticketing = model.GitLab
|
||||
default:
|
||||
ticketing = model.NoTickets
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ package cli
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/strongdm/comply/internal/config"
|
||||
"github.com/strongdm/comply/internal/model"
|
||||
"github.com/urfave/cli"
|
||||
)
|
||||
@@ -13,7 +14,7 @@ var procedureCommand = cli.Command{
|
||||
Usage: "create ticket by procedure ID",
|
||||
ArgsUsage: "procedureID",
|
||||
Action: procedureAction,
|
||||
Before: projectMustExist,
|
||||
Before: beforeAll(projectMustExist, ticketingMustBeConfigured),
|
||||
}
|
||||
|
||||
func procedureAction(c *cli.Context) error {
|
||||
@@ -28,14 +29,22 @@ func procedureAction(c *cli.Context) error {
|
||||
|
||||
procedureID := c.Args().First()
|
||||
|
||||
ts, err := config.Config().TicketSystem()
|
||||
if err != nil {
|
||||
return cli.NewExitError("error in ticket system configuration", 1)
|
||||
}
|
||||
|
||||
tp := model.GetPlugin(model.TicketSystem(ts))
|
||||
|
||||
for _, procedure := range procedures {
|
||||
if procedure.ID == procedureID {
|
||||
// TODO: don't hardcode GH
|
||||
tp := model.GetPlugin(model.GitHub)
|
||||
tp.Create(&model.Ticket{
|
||||
err = tp.Create(&model.Ticket{
|
||||
Name: procedure.Name,
|
||||
Body: fmt.Sprintf("%s\n\n\n---\nProcedure-ID: %s", procedure.Body, procedure.ID),
|
||||
}, []string{"comply", "comply-procedure"})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package cli
|
||||
|
||||
import (
|
||||
"github.com/strongdm/comply/internal/config"
|
||||
"github.com/strongdm/comply/internal/model"
|
||||
"github.com/urfave/cli"
|
||||
)
|
||||
@@ -13,8 +14,12 @@ var syncCommand = cli.Command{
|
||||
}
|
||||
|
||||
func syncAction(c *cli.Context) error {
|
||||
// TODO: unhardcode plugin
|
||||
tp := model.GetPlugin(model.GitHub)
|
||||
ts, err := config.Config().TicketSystem()
|
||||
if err != nil {
|
||||
return cli.NewExitError("error in ticket system configuration", 1)
|
||||
}
|
||||
|
||||
tp := model.GetPlugin(model.TicketSystem(ts))
|
||||
tickets, err := tp.FindByTagName("comply")
|
||||
if err != nil {
|
||||
return err
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package config
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
@@ -12,6 +13,13 @@ var projectRoot string
|
||||
|
||||
var dockerAvailable, pandocAvailable bool
|
||||
|
||||
const (
|
||||
Jira = "jira"
|
||||
GitHub = "github"
|
||||
GitLab = "gitlab"
|
||||
NoTickets = "none"
|
||||
)
|
||||
|
||||
const (
|
||||
// UseDocker invokes pandoc within Docker
|
||||
UseDocker = "docker"
|
||||
@@ -25,10 +33,11 @@ func SetProjectRoot(dir string) {
|
||||
}
|
||||
|
||||
type Project struct {
|
||||
Name string `yaml:"name"`
|
||||
Pandoc string `yaml:"pandoc,omitempty"`
|
||||
FilePrefix string `yaml:"filePrefix"`
|
||||
Tickets map[string]interface{} `yaml:"tickets"`
|
||||
Name string `yaml:"name"`
|
||||
Pandoc string `yaml:"pandoc,omitempty"`
|
||||
FilePrefix string `yaml:"filePrefix"`
|
||||
Tickets map[string]interface{} `yaml:"tickets"`
|
||||
ApprovedBranch string `yaml:"approvedBranch"`
|
||||
}
|
||||
|
||||
// SetPandoc records pandoc availability during initialization
|
||||
@@ -73,14 +82,14 @@ func Exists() bool {
|
||||
}
|
||||
|
||||
// Config is the parsed contents of ProjectRoot()/config.yml.
|
||||
func Config() Project {
|
||||
func Config() *Project {
|
||||
p := Project{}
|
||||
cfgBytes, err := ioutil.ReadFile(filepath.Join(ProjectRoot(), "comply.yml"))
|
||||
if err != nil {
|
||||
panic("unable to load config.yml: " + err.Error())
|
||||
}
|
||||
yaml.Unmarshal(cfgBytes, &p)
|
||||
return p
|
||||
return &p
|
||||
}
|
||||
|
||||
// ProjectRoot is the fully-qualified path to the root directory.
|
||||
@@ -95,3 +104,29 @@ func ProjectRoot() string {
|
||||
|
||||
return projectRoot
|
||||
}
|
||||
|
||||
// TicketSystem indicates the type of the configured ticket system
|
||||
func (p *Project) TicketSystem() (string, error) {
|
||||
if len(p.Tickets) > 1 {
|
||||
return NoTickets, errors.New("multiple ticket systems configured")
|
||||
}
|
||||
|
||||
for k := range p.Tickets {
|
||||
switch k {
|
||||
case GitHub:
|
||||
return GitHub, nil
|
||||
case Jira:
|
||||
return Jira, nil
|
||||
case GitLab:
|
||||
return GitLab, nil
|
||||
case NoTickets:
|
||||
return NoTickets, nil
|
||||
default:
|
||||
// explicit error for this case
|
||||
return "", errors.New("unrecognized ticket system configured")
|
||||
}
|
||||
}
|
||||
|
||||
// no ticket block configured
|
||||
return NoTickets, nil
|
||||
}
|
||||
|
||||
189
internal/gitlab/gitlab.go
Normal file
189
internal/gitlab/gitlab.go
Normal file
@@ -0,0 +1,189 @@
|
||||
package gitlab
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
"sync"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"github.com/strongdm/comply/internal/model"
|
||||
"github.com/xanzy/go-gitlab"
|
||||
)
|
||||
|
||||
const (
|
||||
cfgDomain = "domain"
|
||||
cfgToken = "token"
|
||||
cfgRepo = "repo"
|
||||
)
|
||||
|
||||
var prompts = map[string]string{
|
||||
cfgDomain: "Fully Qualified GitLab Domain",
|
||||
cfgToken: "GitLab Token",
|
||||
cfgRepo: "GitLab Repository",
|
||||
}
|
||||
|
||||
// Prompts are human-readable configuration element names
|
||||
func (g *gitlabPlugin) Prompts() map[string]string {
|
||||
return prompts
|
||||
}
|
||||
|
||||
// Register causes the Github plugin to register itself
|
||||
func Register() {
|
||||
model.Register(model.GitLab, &gitlabPlugin{})
|
||||
}
|
||||
|
||||
type gitlabPlugin struct {
|
||||
domain string
|
||||
token string
|
||||
reponame string
|
||||
|
||||
clientMu sync.Mutex
|
||||
client *gitlab.Client
|
||||
}
|
||||
|
||||
func (g *gitlabPlugin) api() *gitlab.Client {
|
||||
g.clientMu.Lock()
|
||||
defer g.clientMu.Unlock()
|
||||
if g.client == nil {
|
||||
// get go-gitlab client
|
||||
gl := gitlab.NewClient(nil, g.token)
|
||||
gl.SetBaseURL(g.domain)
|
||||
g.client = gl
|
||||
}
|
||||
return g.client
|
||||
}
|
||||
|
||||
func (g *gitlabPlugin) Get(ID string) (*model.Ticket, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (g *gitlabPlugin) Configured() bool {
|
||||
return g.reponame != "" && g.token != ""
|
||||
}
|
||||
|
||||
func (g *gitlabPlugin) Links() model.TicketLinks {
|
||||
links := model.TicketLinks{}
|
||||
links.AuditAll = fmt.Sprintf("%s/%s/issues?scope=all&utf8=✓&state=all&label_name[]=audit", g.domain, g.reponame)
|
||||
links.AuditOpen = fmt.Sprintf("%s/%s/issues?scope=all&utf8=✓&state=opened&label_name[]=audit", g.domain, g.reponame)
|
||||
links.ProcedureAll = fmt.Sprintf("%s/%s/issues?scope=all&utf8=✓&state=all&label_name[]=procedure", g.domain, g.reponame)
|
||||
links.ProcedureOpen = fmt.Sprintf("%s/%s/issues?scope=all&utf8=✓&state=opened&label_name[]=procedure", g.domain, g.reponame)
|
||||
return links
|
||||
}
|
||||
|
||||
func (g *gitlabPlugin) Configure(cfg map[string]interface{}) error {
|
||||
var err error
|
||||
|
||||
if g.domain, err = getCfg(cfg, cfgDomain); err != nil {
|
||||
return err
|
||||
}
|
||||
if g.token, err = getCfg(cfg, cfgToken); err != nil {
|
||||
return err
|
||||
}
|
||||
if g.reponame, err = getCfg(cfg, cfgRepo); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func getCfg(cfg map[string]interface{}, k string) (string, error) {
|
||||
v, ok := cfg[k]
|
||||
if !ok {
|
||||
return "", errors.New("Missing key: " + k)
|
||||
}
|
||||
|
||||
vS, ok := v.(string)
|
||||
if !ok {
|
||||
return "", errors.New("Malformatted key: " + k)
|
||||
}
|
||||
return vS, nil
|
||||
}
|
||||
|
||||
func (g *gitlabPlugin) FindOpen() ([]*model.Ticket, error) {
|
||||
options := &gitlab.ListProjectIssuesOptions{
|
||||
State: gitlab.String("opened"),
|
||||
}
|
||||
|
||||
issues, _, err := g.api().Issues.ListProjectIssues(g.reponame, options)
|
||||
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "error during FindOpen")
|
||||
}
|
||||
|
||||
return toTickets(issues), nil
|
||||
}
|
||||
|
||||
func (g *gitlabPlugin) FindByTag(name, value string) ([]*model.Ticket, error) {
|
||||
panic("not implemented")
|
||||
}
|
||||
|
||||
func (g *gitlabPlugin) FindByTagName(name string) ([]*model.Ticket, error) {
|
||||
options := &gitlab.ListProjectIssuesOptions{
|
||||
State: gitlab.String("all"),
|
||||
Labels: []string{name},
|
||||
}
|
||||
|
||||
issues, _, err := g.api().Issues.ListProjectIssues(g.reponame, options)
|
||||
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "error during FindOpen")
|
||||
}
|
||||
|
||||
return toTickets(issues), nil
|
||||
}
|
||||
|
||||
func (g *gitlabPlugin) LinkFor(t *model.Ticket) string {
|
||||
panic("not implemented")
|
||||
}
|
||||
|
||||
func (g *gitlabPlugin) Create(ticket *model.Ticket, labels []string) error {
|
||||
options := &gitlab.CreateIssueOptions{
|
||||
Title: gitlab.String(ticket.Name),
|
||||
Description: gitlab.String(ticket.Body),
|
||||
Labels: labels,
|
||||
}
|
||||
_, _, err := g.api().Issues.CreateIssue(g.reponame, options)
|
||||
return err
|
||||
}
|
||||
|
||||
func toTickets(issues []*gitlab.Issue) []*model.Ticket {
|
||||
var tickets []*model.Ticket
|
||||
for _, i := range issues {
|
||||
tickets = append(tickets, toTicket(i))
|
||||
}
|
||||
return tickets
|
||||
}
|
||||
|
||||
func toTicket(i *gitlab.Issue) *model.Ticket {
|
||||
t := &model.Ticket{Attributes: make(map[string]interface{})}
|
||||
t.ID = strconv.Itoa(i.ID)
|
||||
t.Name = i.Title
|
||||
t.Body = i.Description
|
||||
t.CreatedAt = i.CreatedAt
|
||||
t.State = toState(i.State)
|
||||
|
||||
for _, l := range i.Labels {
|
||||
if l == "audit" {
|
||||
t.SetBool("audit")
|
||||
}
|
||||
if l == "procedure" {
|
||||
t.SetBool("procedure")
|
||||
}
|
||||
}
|
||||
return t
|
||||
}
|
||||
|
||||
func toState(state string) model.TicketState {
|
||||
switch state {
|
||||
case "closed":
|
||||
return model.Closed
|
||||
}
|
||||
return model.Open
|
||||
}
|
||||
|
||||
func ss(s *string) string {
|
||||
if s == nil {
|
||||
return ""
|
||||
}
|
||||
return *s
|
||||
}
|
||||
9
internal/gitlab/gitlab_test.go
Normal file
9
internal/gitlab/gitlab_test.go
Normal file
@@ -0,0 +1,9 @@
|
||||
package gitlab
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestGitlab(t *testing.T) {
|
||||
createOne()
|
||||
}
|
||||
193
internal/jira/jira.go
Normal file
193
internal/jira/jira.go
Normal file
@@ -0,0 +1,193 @@
|
||||
package jira
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"github.com/strongdm/comply/internal/model"
|
||||
|
||||
jira "github.com/andygrunwald/go-jira"
|
||||
)
|
||||
|
||||
const (
|
||||
cfgUsername = "username"
|
||||
cfgPassword = "password"
|
||||
cfgURL = "url"
|
||||
cfgProject = "project"
|
||||
cfgTaskType = "taskType"
|
||||
)
|
||||
|
||||
var prompts = map[string]string{
|
||||
cfgUsername: "Jira Username",
|
||||
cfgPassword: "Jira Password",
|
||||
cfgURL: "Jira URL",
|
||||
cfgProject: "Jira Project Code",
|
||||
cfgTaskType: "Jira Task Type",
|
||||
}
|
||||
|
||||
// Prompts are human-readable configuration element names
|
||||
func (j *jiraPlugin) Prompts() map[string]string {
|
||||
return prompts
|
||||
}
|
||||
|
||||
// Register causes the Github plugin to register itself
|
||||
func Register() {
|
||||
model.Register(model.Jira, &jiraPlugin{})
|
||||
}
|
||||
|
||||
type jiraPlugin struct {
|
||||
username string
|
||||
password string
|
||||
url string
|
||||
project string
|
||||
taskType string
|
||||
|
||||
clientMu sync.Mutex
|
||||
client *jira.Client
|
||||
}
|
||||
|
||||
func (j *jiraPlugin) api() *jira.Client {
|
||||
j.clientMu.Lock()
|
||||
defer j.clientMu.Unlock()
|
||||
|
||||
if j.client == nil {
|
||||
tp := jira.BasicAuthTransport{
|
||||
Username: j.username,
|
||||
Password: j.password,
|
||||
}
|
||||
|
||||
client, _ := jira.NewClient(tp.Client(), j.url)
|
||||
j.client = client
|
||||
}
|
||||
return j.client
|
||||
}
|
||||
|
||||
func (j *jiraPlugin) Get(ID string) (*model.Ticket, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (j *jiraPlugin) Configured() bool {
|
||||
return j.username != "" && j.password != "" && j.url != "" && j.project != "" && j.taskType != ""
|
||||
}
|
||||
|
||||
func (j *jiraPlugin) Links() model.TicketLinks {
|
||||
links := model.TicketLinks{}
|
||||
links.ProcedureAll = fmt.Sprintf("%s/issues/?jql=labels+=+comply-procedure", j.url)
|
||||
links.ProcedureOpen = fmt.Sprintf("%s/issues/?jql=labels+=+comply-procedure+AND+resolution+=+Unresolved", j.url)
|
||||
// links.AuditAll = fmt.Sprintf("%s/issues?q=is%3Aissue+is%3Aopen+label%3Acomply+label%3Aaudit", j.url)
|
||||
// links.AuditOpen = fmt.Sprintf("%s/issues?q=is%3Aissue+is%3Aopen+label%3Acomply+label%3Aaudit", j.url)
|
||||
return links
|
||||
}
|
||||
|
||||
func (j *jiraPlugin) Configure(cfg map[string]interface{}) error {
|
||||
var err error
|
||||
|
||||
if j.username, err = getCfg(cfg, cfgUsername); err != nil {
|
||||
return err
|
||||
}
|
||||
if j.password, err = getCfg(cfg, cfgPassword); err != nil {
|
||||
return err
|
||||
}
|
||||
if j.url, err = getCfg(cfg, cfgURL); err != nil {
|
||||
return err
|
||||
}
|
||||
if j.project, err = getCfg(cfg, cfgProject); err != nil {
|
||||
return err
|
||||
}
|
||||
if j.taskType, err = getCfg(cfg, cfgTaskType); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func getCfg(cfg map[string]interface{}, k string) (string, error) {
|
||||
v, ok := cfg[k]
|
||||
if !ok {
|
||||
return "", errors.New("Missing key: " + k)
|
||||
}
|
||||
|
||||
vS, ok := v.(string)
|
||||
if !ok {
|
||||
return "", errors.New("Malformatted key: " + k)
|
||||
}
|
||||
return vS, nil
|
||||
}
|
||||
|
||||
func (j *jiraPlugin) FindOpen() ([]*model.Ticket, error) {
|
||||
panic("not implemented")
|
||||
}
|
||||
|
||||
func (j *jiraPlugin) FindByTag(name, value string) ([]*model.Ticket, error) {
|
||||
panic("not implemented")
|
||||
}
|
||||
|
||||
func (j *jiraPlugin) FindByTagName(name string) ([]*model.Ticket, error) {
|
||||
issues, _, err := j.api().Issue.Search("labels=comply", &jira.SearchOptions{MaxResults: 1000})
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "unable to fetch Jira issues")
|
||||
}
|
||||
return toTickets(issues), nil
|
||||
}
|
||||
|
||||
func (j *jiraPlugin) LinkFor(t *model.Ticket) string {
|
||||
panic("not implemented")
|
||||
}
|
||||
|
||||
func (j *jiraPlugin) Create(ticket *model.Ticket, labels []string) error {
|
||||
i := jira.Issue{
|
||||
Fields: &jira.IssueFields{
|
||||
Type: jira.IssueType{
|
||||
Name: j.taskType,
|
||||
},
|
||||
Project: jira.Project{
|
||||
Key: j.project,
|
||||
},
|
||||
Summary: ticket.Name,
|
||||
Description: ticket.Body,
|
||||
Labels: labels,
|
||||
},
|
||||
}
|
||||
|
||||
_, _, err := j.api().Issue.Create(&i)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "unable to create ticket")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func toTickets(issues []jira.Issue) []*model.Ticket {
|
||||
var tickets []*model.Ticket
|
||||
for _, i := range issues {
|
||||
tickets = append(tickets, toTicket(&i))
|
||||
}
|
||||
return tickets
|
||||
}
|
||||
|
||||
func toTicket(i *jira.Issue) *model.Ticket {
|
||||
t := &model.Ticket{Attributes: make(map[string]interface{})}
|
||||
t.ID = i.ID
|
||||
t.Name = i.Fields.Description
|
||||
t.Body = i.Fields.Summary
|
||||
createdAt := time.Time(i.Fields.Created)
|
||||
t.CreatedAt = &createdAt
|
||||
t.State = toState(i.Fields.Resolution)
|
||||
|
||||
for _, l := range i.Fields.Labels {
|
||||
t.SetBool(l)
|
||||
}
|
||||
return t
|
||||
}
|
||||
|
||||
func toState(status *jira.Resolution) model.TicketState {
|
||||
if status == nil {
|
||||
return model.Open
|
||||
}
|
||||
switch status.Name {
|
||||
case "Done":
|
||||
return model.Closed
|
||||
}
|
||||
return model.Open
|
||||
}
|
||||
9
internal/jira/jira_test.go
Normal file
9
internal/jira/jira_test.go
Normal file
@@ -0,0 +1,9 @@
|
||||
package jira
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestJira(t *testing.T) {
|
||||
createOne()
|
||||
}
|
||||
@@ -2,7 +2,7 @@ package model
|
||||
|
||||
import "time"
|
||||
|
||||
type Policy struct {
|
||||
type Document struct {
|
||||
Name string `yaml:"name"`
|
||||
Acronym string `yaml:"acronym"`
|
||||
|
||||
@@ -91,8 +91,8 @@ func ReadStandards() ([]*Standard, error) {
|
||||
}
|
||||
|
||||
// ReadNarratives loads narrative descriptions from the filesystem.
|
||||
func ReadNarratives() ([]*Narrative, error) {
|
||||
var narratives []*Narrative
|
||||
func ReadNarratives() ([]*Document, error) {
|
||||
var narratives []*Document
|
||||
|
||||
files, err := path.Narratives()
|
||||
if err != nil {
|
||||
@@ -100,7 +100,7 @@ func ReadNarratives() ([]*Narrative, error) {
|
||||
}
|
||||
|
||||
for _, f := range files {
|
||||
n := &Narrative{}
|
||||
n := &Document{}
|
||||
mdmd := loadMDMD(f.FullPath)
|
||||
err = yaml.Unmarshal([]byte(mdmd.yaml), &n)
|
||||
if err != nil {
|
||||
@@ -141,8 +141,8 @@ func ReadProcedures() ([]*Procedure, error) {
|
||||
}
|
||||
|
||||
// ReadPolicies loads policy documents from the filesystem.
|
||||
func ReadPolicies() ([]*Policy, error) {
|
||||
var policies []*Policy
|
||||
func ReadPolicies() ([]*Document, error) {
|
||||
var policies []*Document
|
||||
|
||||
files, err := path.Policies()
|
||||
if err != nil {
|
||||
@@ -150,7 +150,7 @@ func ReadPolicies() ([]*Policy, error) {
|
||||
}
|
||||
|
||||
for _, f := range files {
|
||||
p := &Policy{}
|
||||
p := &Document{}
|
||||
mdmd := loadMDMD(f.FullPath)
|
||||
err = yaml.Unmarshal([]byte(mdmd.yaml), &p)
|
||||
if err != nil {
|
||||
|
||||
@@ -2,8 +2,8 @@ package model
|
||||
|
||||
type Data struct {
|
||||
Standards []*Standard
|
||||
Narratives []*Narrative
|
||||
Policies []*Policy
|
||||
Narratives []*Document
|
||||
Policies []*Document
|
||||
Procedures []*Procedure
|
||||
Tickets []*Ticket
|
||||
Audits []*Audit
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
package model
|
||||
|
||||
import "time"
|
||||
|
||||
type Narrative struct {
|
||||
Name string `yaml:"name"`
|
||||
Acronym string `yaml:"acronym"`
|
||||
|
||||
Revisions []Revision `yaml:"majorRevisions"`
|
||||
Satisfies Satisfaction `yaml:"satisfies"`
|
||||
FullPath string
|
||||
OutputFilename string
|
||||
ModifiedAt time.Time
|
||||
Body string
|
||||
}
|
||||
@@ -17,11 +17,13 @@ type TicketSystem string
|
||||
|
||||
const (
|
||||
// Jira from Atlassian.
|
||||
Jira = TicketSystem("jira")
|
||||
Jira = TicketSystem(config.Jira)
|
||||
// GitHub from GitHub.
|
||||
GitHub = TicketSystem("github")
|
||||
GitHub = TicketSystem(config.GitHub)
|
||||
// GitLab from GitLab.
|
||||
GitLab = TicketSystem(config.GitLab)
|
||||
// NoTickets indicates no ticketing system integration.
|
||||
NoTickets = TicketSystem("none")
|
||||
NoTickets = TicketSystem(config.NoTickets)
|
||||
)
|
||||
|
||||
type TicketLinks struct {
|
||||
@@ -50,6 +52,10 @@ func GetPlugin(ts TicketSystem) TicketPlugin {
|
||||
tsPluginsMu.Lock()
|
||||
defer tsPluginsMu.Unlock()
|
||||
|
||||
if ts == NoTickets {
|
||||
return &noopTicketSystem{}
|
||||
}
|
||||
|
||||
tp, ok := tsPlugins[ts]
|
||||
if !ok {
|
||||
panic("Unknown ticket system: " + ts)
|
||||
@@ -81,7 +87,10 @@ func GetPlugin(ts TicketSystem) TicketPlugin {
|
||||
}
|
||||
cfgStringed[kS] = v
|
||||
}
|
||||
tp.Configure(cfgStringed)
|
||||
err := tp.Configure(cfgStringed)
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("Configuration error `%s` in project YAML", err))
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -100,3 +109,36 @@ func Register(ts TicketSystem, plugin TicketPlugin) {
|
||||
|
||||
tsPlugins[ts] = plugin
|
||||
}
|
||||
|
||||
type noopTicketSystem struct{}
|
||||
|
||||
func (*noopTicketSystem) Get(ID string) (*Ticket, error) {
|
||||
return nil, nil
|
||||
}
|
||||
func (*noopTicketSystem) FindOpen() ([]*Ticket, error) {
|
||||
return []*Ticket{}, nil
|
||||
}
|
||||
func (*noopTicketSystem) FindByTag(name, value string) ([]*Ticket, error) {
|
||||
return []*Ticket{}, nil
|
||||
}
|
||||
func (*noopTicketSystem) FindByTagName(name string) ([]*Ticket, error) {
|
||||
return []*Ticket{}, nil
|
||||
}
|
||||
func (*noopTicketSystem) Create(ticket *Ticket, labels []string) error {
|
||||
return nil
|
||||
}
|
||||
func (*noopTicketSystem) Configure(map[string]interface{}) error {
|
||||
return nil
|
||||
}
|
||||
func (*noopTicketSystem) Prompts() map[string]string {
|
||||
return make(map[string]string)
|
||||
}
|
||||
func (*noopTicketSystem) Links() TicketLinks {
|
||||
return TicketLinks{}
|
||||
}
|
||||
func (*noopTicketSystem) LinkFor(ticket *Ticket) string {
|
||||
return ""
|
||||
}
|
||||
func (*noopTicketSystem) Configured() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
@@ -69,10 +69,10 @@ func (g *githubPlugin) Configured() bool {
|
||||
|
||||
func (g *githubPlugin) Links() model.TicketLinks {
|
||||
links := model.TicketLinks{}
|
||||
links.AuditAll = fmt.Sprintf("https://github.com/%s/%s/issues?q=is%3Aissue+is%3Aopen+label%3Acomply+label%3Aaudit", g.username, g.reponame)
|
||||
links.AuditOpen = fmt.Sprintf("https://github.com/%s/%s/issues?q=is%3Aissue+is%3Aopen+label%3Acomply+label%3Aaudit", g.username, g.reponame)
|
||||
links.ProcedureAll = fmt.Sprintf("https://github.com/%s/%s/issues?q=is%3Aissue+label%3Acomply+label%3Aprocedure", g.username, g.reponame)
|
||||
links.ProcedureOpen = fmt.Sprintf("https://github.com/%s/%s/issues?q=is%3Aissue+is%3Aopen+label%3Acomply+label%3Aprocedure", g.username, g.reponame)
|
||||
links.AuditAll = fmt.Sprintf("https://github.com/%s/%s/issues?q=is%%3Aissue+is%%3Aopen+label%%3Acomply+label%%3Aaudit", g.username, g.reponame)
|
||||
links.AuditOpen = fmt.Sprintf("https://github.com/%s/%s/issues?q=is%%3Aissue+is%%3Aopen+label%%3Acomply+label%%3Aaudit", g.username, g.reponame)
|
||||
links.ProcedureAll = fmt.Sprintf("https://github.com/%s/%s/issues?q=is%%3Aissue+label%%3Acomply+label%%3Acomply-procedure", g.username, g.reponame)
|
||||
links.ProcedureOpen = fmt.Sprintf("https://github.com/%s/%s/issues?q=is%%3Aissue+is%%3Aopen+label%%3Acomply+label%%3Acomply-procedure", g.username, g.reponame)
|
||||
return links
|
||||
}
|
||||
|
||||
@@ -135,7 +135,8 @@ func (g *githubPlugin) FindByTagName(name string) ([]*model.Ticket, error) {
|
||||
}
|
||||
|
||||
func (g *githubPlugin) LinkFor(t *model.Ticket) string {
|
||||
return fmt.Sprintf("https://github.com/strongdm/comply/issues/%s", t.ID)
|
||||
// return fmt.Sprintf("https://github.com/strongdm/comply/issues/%s", t.ID)
|
||||
panic("not implemented")
|
||||
}
|
||||
|
||||
func (g *githubPlugin) Create(ticket *model.Ticket, labels []string) error {
|
||||
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
"sort"
|
||||
"time"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"github.com/strongdm/comply/internal/config"
|
||||
"github.com/strongdm/comply/internal/model"
|
||||
)
|
||||
@@ -32,8 +33,8 @@ type renderData struct {
|
||||
Name string
|
||||
Project *project
|
||||
Stats *stats
|
||||
Narratives []*model.Narrative
|
||||
Policies []*model.Policy
|
||||
Narratives []*model.Document
|
||||
Policies []*model.Document
|
||||
Procedures []*model.Procedure
|
||||
Standards []*model.Standard
|
||||
Tickets []*model.Ticket
|
||||
@@ -93,8 +94,12 @@ func load() (*model.Data, *renderData, error) {
|
||||
rd.Name = project.OrganizationName
|
||||
rd.Controls = controls
|
||||
|
||||
// TODO: unhardcode plugin
|
||||
tp := model.GetPlugin(model.GitHub)
|
||||
ts, err := config.Config().TicketSystem()
|
||||
if err != nil {
|
||||
return nil, nil, errors.Wrap(err, "error in ticket system configuration")
|
||||
}
|
||||
|
||||
tp := model.GetPlugin(model.TicketSystem(ts))
|
||||
if tp.Configured() {
|
||||
links := tp.Links()
|
||||
rd.Links = &links
|
||||
@@ -133,7 +138,7 @@ func addStats(modelData *model.Data, renderData *renderData) {
|
||||
}
|
||||
|
||||
if t.State == model.Open {
|
||||
if t.Bool("procedure") {
|
||||
if t.Bool("comply-procedure") {
|
||||
stats.ProcedureOpen++
|
||||
if t.CreatedAt != nil {
|
||||
age := int(time.Since(*t.CreatedAt).Hours() / float64(24))
|
||||
|
||||
@@ -11,26 +11,28 @@ import (
|
||||
"text/template"
|
||||
"time"
|
||||
|
||||
"os/exec"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"github.com/strongdm/comply/internal/config"
|
||||
"github.com/strongdm/comply/internal/model"
|
||||
)
|
||||
|
||||
// TODO: refactor and eliminate duplication among narrative, policy renderers
|
||||
func renderPolicyToDisk(wg *sync.WaitGroup, errOutputCh chan error, data *renderData, policy *model.Policy, live bool) {
|
||||
func renderToFilesystem(wg *sync.WaitGroup, errOutputCh chan error, data *renderData, doc *model.Document, live bool) {
|
||||
// only files that have been touched
|
||||
if !isNewer(policy.FullPath, policy.ModifiedAt) {
|
||||
if !isNewer(doc.FullPath, doc.ModifiedAt) {
|
||||
return
|
||||
}
|
||||
recordModified(policy.FullPath, policy.ModifiedAt)
|
||||
recordModified(doc.FullPath, doc.ModifiedAt)
|
||||
|
||||
wg.Add(1)
|
||||
go func(p *model.Policy) {
|
||||
go func(p *model.Document) {
|
||||
defer wg.Done()
|
||||
|
||||
outputFilename := p.OutputFilename
|
||||
// save preprocessed markdown
|
||||
err := preprocessPolicy(data, p, filepath.Join(".", "output", outputFilename+".md"))
|
||||
err := preprocessDoc(data, p, filepath.Join(".", "output", outputFilename+".md"))
|
||||
if err != nil {
|
||||
errOutputCh <- errors.Wrap(err, "unable to preprocess")
|
||||
return
|
||||
@@ -50,10 +52,44 @@ func renderPolicyToDisk(wg *sync.WaitGroup, errOutputCh chan error, data *render
|
||||
rel = p.FullPath
|
||||
}
|
||||
fmt.Printf("%s -> %s\n", rel, filepath.Join("output", p.OutputFilename))
|
||||
}(policy)
|
||||
}(doc)
|
||||
}
|
||||
|
||||
func preprocessPolicy(data *renderData, pol *model.Policy, fullPath string) error {
|
||||
func getGitApprovalInfo(pol *model.Document) (string, error) {
|
||||
cfg := config.Config()
|
||||
|
||||
// if no approved branch specified in config.yaml, then nothing gets added to the document
|
||||
if cfg.ApprovedBranch == "" {
|
||||
return "", nil
|
||||
}
|
||||
|
||||
// Decide whether we are on the git branch that contains the approved policies
|
||||
gitBranchArgs := []string{"rev-parse", "--abbrev-ref", "HEAD"}
|
||||
gitBranchCmd := exec.Command("git", gitBranchArgs...)
|
||||
gitBranchInfo, err := gitBranchCmd.CombinedOutput()
|
||||
if err != nil {
|
||||
fmt.Println(string(gitBranchInfo))
|
||||
return "", errors.Wrap(err, "error looking up git branch")
|
||||
}
|
||||
|
||||
// if on a different branch than the approved branch, then nothing gets added to the document
|
||||
if strings.Compare(strings.TrimSpace(fmt.Sprintf("%s", gitBranchInfo)), cfg.ApprovedBranch) != 0 {
|
||||
return "", nil
|
||||
}
|
||||
|
||||
// Grab information related to commit, so that we can put approval information in the document
|
||||
gitArgs := []string{"log", "-n", "1", "--pretty=format:Last edit made by %an (%aE) on %aD.\n\nApproved by %cn (%cE) on %cD in commit %H.", "--", pol.FullPath}
|
||||
cmd := exec.Command("git", gitArgs...)
|
||||
gitApprovalInfo, err := cmd.CombinedOutput()
|
||||
if err != nil {
|
||||
fmt.Println(string(gitApprovalInfo))
|
||||
return "", errors.Wrap(err, "error looking up git committer and author data")
|
||||
}
|
||||
|
||||
return fmt.Sprintf("%s\n%s", "# Authorship and Approval", gitApprovalInfo), nil
|
||||
}
|
||||
|
||||
func preprocessDoc(data *renderData, pol *model.Document, fullPath string) error {
|
||||
cfg := config.Config()
|
||||
|
||||
var w bytes.Buffer
|
||||
@@ -89,6 +125,11 @@ func preprocessPolicy(data *renderData, pol *model.Policy, fullPath string) erro
|
||||
revisionTable = fmt.Sprintf("|Date|Comment|\n|---+--------------------------------------------|\n%s\nTable: Document history\n", rows)
|
||||
}
|
||||
|
||||
gitApprovalInfo, err := getGitApprovalInfo(pol)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
doc := fmt.Sprintf(`%% %s
|
||||
%% %s
|
||||
%% %s
|
||||
@@ -104,6 +145,8 @@ foot-content: "%s confidential %d"
|
||||
%s
|
||||
|
||||
\newpage
|
||||
%s
|
||||
|
||||
%s`,
|
||||
pol.Name,
|
||||
cfg.Name,
|
||||
@@ -114,6 +157,7 @@ foot-content: "%s confidential %d"
|
||||
satisfiesTable,
|
||||
revisionTable,
|
||||
body,
|
||||
gitApprovalInfo,
|
||||
)
|
||||
err = ioutil.WriteFile(fullPath, []byte(doc), os.FileMode(0644))
|
||||
if err != nil {
|
||||
@@ -82,7 +82,7 @@ func html(output string, live bool, errCh chan error, wg *sync.WaitGroup) {
|
||||
if live {
|
||||
if !opened {
|
||||
opened = true
|
||||
open.Run("output/index.html")
|
||||
open.Run(filepath.Join(".", "output", "index.html"))
|
||||
}
|
||||
} else {
|
||||
wg.Done()
|
||||
|
||||
@@ -1,124 +0,0 @@
|
||||
package render
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"sync"
|
||||
"text/template"
|
||||
"time"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"github.com/strongdm/comply/internal/config"
|
||||
"github.com/strongdm/comply/internal/model"
|
||||
)
|
||||
|
||||
// TODO: refactor and eliminate duplication among narrative, policy renderers
|
||||
func renderNarrativeToDisk(wg *sync.WaitGroup, errOutputCh chan error, data *renderData, narrative *model.Narrative, live bool) {
|
||||
// only files that have been touched
|
||||
if !isNewer(narrative.FullPath, narrative.ModifiedAt) {
|
||||
return
|
||||
}
|
||||
recordModified(narrative.FullPath, narrative.ModifiedAt)
|
||||
|
||||
wg.Add(1)
|
||||
go func(p *model.Narrative) {
|
||||
defer wg.Done()
|
||||
|
||||
outputFilename := p.OutputFilename
|
||||
// save preprocessed markdown
|
||||
err := preprocessNarrative(data, p, filepath.Join(".", "output", outputFilename+".md"))
|
||||
if err != nil {
|
||||
errOutputCh <- errors.Wrap(err, "unable to preprocess")
|
||||
return
|
||||
}
|
||||
|
||||
pandoc(outputFilename, errOutputCh)
|
||||
|
||||
// remove preprocessed markdown
|
||||
err = os.Remove(filepath.Join(".", "output", outputFilename+".md"))
|
||||
if err != nil {
|
||||
errOutputCh <- err
|
||||
return
|
||||
}
|
||||
|
||||
rel, err := filepath.Rel(config.ProjectRoot(), p.FullPath)
|
||||
if err != nil {
|
||||
rel = p.FullPath
|
||||
}
|
||||
fmt.Printf("%s -> %s\n", rel, filepath.Join("output", p.OutputFilename))
|
||||
|
||||
}(narrative)
|
||||
}
|
||||
|
||||
func preprocessNarrative(data *renderData, pol *model.Narrative, fullPath string) error {
|
||||
cfg := config.Config()
|
||||
|
||||
var w bytes.Buffer
|
||||
bodyTemplate, err := template.New("body").Parse(pol.Body)
|
||||
if err != nil {
|
||||
w.WriteString(fmt.Sprintf("# Error processing template:\n\n%s\n", err.Error()))
|
||||
} else {
|
||||
bodyTemplate.Execute(&w, data)
|
||||
}
|
||||
body := w.String()
|
||||
|
||||
revisionTable := ""
|
||||
satisfiesTable := ""
|
||||
|
||||
// ||Date|Comment|
|
||||
// |---+------|
|
||||
// | 4 Jan 2018 | Initial Version |
|
||||
// Table: Document history
|
||||
|
||||
if len(pol.Satisfies) > 0 {
|
||||
rows := ""
|
||||
for standard, keys := range pol.Satisfies {
|
||||
rows += fmt.Sprintf("| %s | %s |\n", standard, strings.Join(keys, ", "))
|
||||
}
|
||||
satisfiesTable = fmt.Sprintf("|Standard|Controls Satisfied|\n|-------+--------------------------------------------|\n%s\nTable: Control satisfaction\n", rows)
|
||||
}
|
||||
|
||||
if len(pol.Revisions) > 0 {
|
||||
rows := ""
|
||||
for _, rev := range pol.Revisions {
|
||||
rows += fmt.Sprintf("| %s | %s |\n", rev.Date, rev.Comment)
|
||||
}
|
||||
revisionTable = fmt.Sprintf("|Date|Comment|\n|---+--------------------------------------------|\n%s\nTable: Document history\n", rows)
|
||||
}
|
||||
|
||||
doc := fmt.Sprintf(`%% %s
|
||||
%% %s
|
||||
%% %s
|
||||
|
||||
---
|
||||
header-includes: yes
|
||||
head-content: "%s"
|
||||
foot-content: "%s confidential %d"
|
||||
---
|
||||
|
||||
%s
|
||||
|
||||
%s
|
||||
|
||||
\newpage
|
||||
%s`,
|
||||
pol.Name,
|
||||
cfg.Name,
|
||||
fmt.Sprintf("%s %d", pol.ModifiedAt.Month().String(), pol.ModifiedAt.Year()),
|
||||
pol.Name,
|
||||
cfg.Name,
|
||||
time.Now().Year(),
|
||||
satisfiesTable,
|
||||
revisionTable,
|
||||
body,
|
||||
)
|
||||
err = ioutil.WriteFile(fullPath, []byte(doc), os.FileMode(0644))
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "unable to write preprocessed narrative to disk")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -14,6 +14,8 @@ import (
|
||||
"github.com/strongdm/comply/internal/config"
|
||||
)
|
||||
|
||||
var pandocArgs = []string{"-f", "markdown+smart", "--toc", "-N", "--template", "templates/default.latex", "-o"}
|
||||
|
||||
func pandoc(outputFilename string, errOutputCh chan error) {
|
||||
if config.WhichPandoc() == config.UsePandoc {
|
||||
err := pandocPandoc(outputFilename)
|
||||
@@ -26,12 +28,7 @@ func pandoc(outputFilename string, errOutputCh chan error) {
|
||||
}
|
||||
|
||||
func dockerPandoc(outputFilename string, errOutputCh chan error) {
|
||||
// TODO: switch to new args once docker image is updated
|
||||
// cmd21 := []string{"-f", "markdown+smart", "--toc", "-N", "--template", "templates/default.latex", "-o", fmt.Sprintf("output/%s", outputFilename), fmt.Sprintf("output/%s.md", outputFilename)}
|
||||
cmd19 := []string{"--smart", "--toc", "-N", "--template=/source/templates/default.latex", "-o",
|
||||
fmt.Sprintf("/source/output/%s", outputFilename),
|
||||
fmt.Sprintf("/source/output/%s.md", outputFilename)}
|
||||
|
||||
pandocCmd := append(pandocArgs, fmt.Sprintf("/source/output/%s", outputFilename), fmt.Sprintf("/source/output/%s.md", outputFilename))
|
||||
ctx := context.Background()
|
||||
cli, err := client.NewEnvClient()
|
||||
if err != nil {
|
||||
@@ -51,7 +48,7 @@ func dockerPandoc(outputFilename string, errOutputCh chan error) {
|
||||
|
||||
resp, err := cli.ContainerCreate(ctx, &container.Config{
|
||||
Image: "strongdm/pandoc",
|
||||
Cmd: cmd19},
|
||||
Cmd: pandocCmd},
|
||||
hc, nil, "")
|
||||
|
||||
if err != nil {
|
||||
@@ -85,12 +82,16 @@ func dockerPandoc(outputFilename string, errOutputCh chan error) {
|
||||
errOutputCh <- errors.Wrap(err, "error reading Docker container logs")
|
||||
return
|
||||
}
|
||||
|
||||
if _, err = os.Stat(fmt.Sprintf("output/%s", outputFilename)); err != nil && os.IsNotExist(err) {
|
||||
errOutputCh <- errors.Wrap(err, "output not generated; verify your Docker image is up to date")
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// 🐼
|
||||
func pandocPandoc(outputFilename string) error {
|
||||
// -f markdown+smart --toc -N --template=templates/default.latex -o output/%s output/%s.md
|
||||
cmd := exec.Command("pandoc", "-f", "markdown+smart", "--toc", "-N", "--template", "templates/default.latex", "-o", fmt.Sprintf("output/%s", outputFilename), fmt.Sprintf("output/%s.md", outputFilename))
|
||||
cmd := exec.Command("pandoc", append(pandocArgs, fmt.Sprintf("output/%s", outputFilename), fmt.Sprintf("output/%s.md", outputFilename))...)
|
||||
outputRaw, err := cmd.CombinedOutput()
|
||||
if err != nil {
|
||||
fmt.Println(string(outputRaw))
|
||||
|
||||
@@ -25,7 +25,7 @@ func pdf(output string, live bool, errCh chan error, wg *sync.WaitGroup) {
|
||||
return
|
||||
}
|
||||
for _, policy := range policies {
|
||||
renderPolicyToDisk(&pdfWG, errOutputCh, data, policy, live)
|
||||
renderToFilesystem(&pdfWG, errOutputCh, data, policy, live)
|
||||
}
|
||||
|
||||
narratives, err := model.ReadNarratives()
|
||||
@@ -35,7 +35,7 @@ func pdf(output string, live bool, errCh chan error, wg *sync.WaitGroup) {
|
||||
}
|
||||
|
||||
for _, narrative := range narratives {
|
||||
renderNarrativeToDisk(&pdfWG, errOutputCh, data, narrative, live)
|
||||
renderToFilesystem(&pdfWG, errOutputCh, data, narrative, live)
|
||||
}
|
||||
|
||||
pdfWG.Wait()
|
||||
|
||||
@@ -137,7 +137,7 @@ func complyBlankReadmeMd() (*asset, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
info := bindataFileInfo{name: "comply-blank/README.md", size: 1965, mode: os.FileMode(420), modTime: time.Unix(1527121005, 0)}
|
||||
info := bindataFileInfo{name: "comply-blank/README.md", size: 1965, mode: os.FileMode(420), modTime: time.Unix(1535582995, 0)}
|
||||
a := &asset{bytes: bytes, info: info}
|
||||
return a, nil
|
||||
}
|
||||
@@ -157,7 +157,7 @@ func complyBlankTodoMd() (*asset, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
info := bindataFileInfo{name: "comply-blank/TODO.md", size: 1429, mode: os.FileMode(420), modTime: time.Unix(1527121005, 0)}
|
||||
info := bindataFileInfo{name: "comply-blank/TODO.md", size: 1429, mode: os.FileMode(420), modTime: time.Unix(1535582995, 0)}
|
||||
a := &asset{bytes: bytes, info: info}
|
||||
return a, nil
|
||||
}
|
||||
@@ -277,7 +277,7 @@ func complyBlankTemplatesDefaultLatex() (*asset, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
info := bindataFileInfo{name: "comply-blank/templates/default.latex", size: 7649, mode: os.FileMode(420), modTime: time.Unix(1527121005, 0)}
|
||||
info := bindataFileInfo{name: "comply-blank/templates/default.latex", size: 7649, mode: os.FileMode(420), modTime: time.Unix(1535582995, 0)}
|
||||
a := &asset{bytes: bytes, info: info}
|
||||
return a, nil
|
||||
}
|
||||
@@ -297,7 +297,7 @@ func complyBlankTemplatesIndexAce() (*asset, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
info := bindataFileInfo{name: "comply-blank/templates/index.ace", size: 7596, mode: os.FileMode(420), modTime: time.Unix(1527121005, 0)}
|
||||
info := bindataFileInfo{name: "comply-blank/templates/index.ace", size: 7596, mode: os.FileMode(420), modTime: time.Unix(1535582995, 0)}
|
||||
a := &asset{bytes: bytes, info: info}
|
||||
return a, nil
|
||||
}
|
||||
@@ -317,7 +317,7 @@ func complySoc2ReadmeMd() (*asset, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
info := bindataFileInfo{name: "comply-soc2/README.md", size: 1965, mode: os.FileMode(420), modTime: time.Unix(1527121005, 0)}
|
||||
info := bindataFileInfo{name: "comply-soc2/README.md", size: 1965, mode: os.FileMode(420), modTime: time.Unix(1535582995, 0)}
|
||||
a := &asset{bytes: bytes, info: info}
|
||||
return a, nil
|
||||
}
|
||||
@@ -337,7 +337,7 @@ func complySoc2TodoMd() (*asset, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
info := bindataFileInfo{name: "comply-soc2/TODO.md", size: 1429, mode: os.FileMode(420), modTime: time.Unix(1527121005, 0)}
|
||||
info := bindataFileInfo{name: "comply-soc2/TODO.md", size: 1429, mode: os.FileMode(420), modTime: time.Unix(1535582995, 0)}
|
||||
a := &asset{bytes: bytes, info: info}
|
||||
return a, nil
|
||||
}
|
||||
@@ -357,7 +357,7 @@ func complySoc2NarrativesReadmeMd() (*asset, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
info := bindataFileInfo{name: "comply-soc2/narratives/README.md", size: 96, mode: os.FileMode(420), modTime: time.Unix(1527121005, 0)}
|
||||
info := bindataFileInfo{name: "comply-soc2/narratives/README.md", size: 96, mode: os.FileMode(420), modTime: time.Unix(1535582995, 0)}
|
||||
a := &asset{bytes: bytes, info: info}
|
||||
return a, nil
|
||||
}
|
||||
@@ -377,7 +377,7 @@ func complySoc2NarrativesControlMd() (*asset, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
info := bindataFileInfo{name: "comply-soc2/narratives/control.md", size: 387, mode: os.FileMode(420), modTime: time.Unix(1527121005, 0)}
|
||||
info := bindataFileInfo{name: "comply-soc2/narratives/control.md", size: 387, mode: os.FileMode(420), modTime: time.Unix(1535582995, 0)}
|
||||
a := &asset{bytes: bytes, info: info}
|
||||
return a, nil
|
||||
}
|
||||
@@ -397,7 +397,7 @@ func complySoc2NarrativesOrganizationalMd() (*asset, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
info := bindataFileInfo{name: "comply-soc2/narratives/organizational.md", size: 2378, mode: os.FileMode(420), modTime: time.Unix(1527121005, 0)}
|
||||
info := bindataFileInfo{name: "comply-soc2/narratives/organizational.md", size: 2378, mode: os.FileMode(420), modTime: time.Unix(1535582995, 0)}
|
||||
a := &asset{bytes: bytes, info: info}
|
||||
return a, nil
|
||||
}
|
||||
@@ -417,7 +417,7 @@ func complySoc2NarrativesProductsMd() (*asset, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
info := bindataFileInfo{name: "comply-soc2/narratives/products.md", size: 232, mode: os.FileMode(420), modTime: time.Unix(1527121005, 0)}
|
||||
info := bindataFileInfo{name: "comply-soc2/narratives/products.md", size: 232, mode: os.FileMode(420), modTime: time.Unix(1535582995, 0)}
|
||||
a := &asset{bytes: bytes, info: info}
|
||||
return a, nil
|
||||
}
|
||||
@@ -437,7 +437,7 @@ func complySoc2NarrativesSecurityMd() (*asset, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
info := bindataFileInfo{name: "comply-soc2/narratives/security.md", size: 327, mode: os.FileMode(420), modTime: time.Unix(1527121005, 0)}
|
||||
info := bindataFileInfo{name: "comply-soc2/narratives/security.md", size: 327, mode: os.FileMode(420), modTime: time.Unix(1535582995, 0)}
|
||||
a := &asset{bytes: bytes, info: info}
|
||||
return a, nil
|
||||
}
|
||||
@@ -457,7 +457,7 @@ func complySoc2NarrativesSystemMd() (*asset, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
info := bindataFileInfo{name: "comply-soc2/narratives/system.md", size: 257, mode: os.FileMode(420), modTime: time.Unix(1527121005, 0)}
|
||||
info := bindataFileInfo{name: "comply-soc2/narratives/system.md", size: 257, mode: os.FileMode(420), modTime: time.Unix(1535582995, 0)}
|
||||
a := &asset{bytes: bytes, info: info}
|
||||
return a, nil
|
||||
}
|
||||
@@ -477,7 +477,7 @@ func complySoc2PoliciesReadmeMd() (*asset, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
info := bindataFileInfo{name: "comply-soc2/policies/README.md", size: 71, mode: os.FileMode(420), modTime: time.Unix(1527121005, 0)}
|
||||
info := bindataFileInfo{name: "comply-soc2/policies/README.md", size: 71, mode: os.FileMode(420), modTime: time.Unix(1535582995, 0)}
|
||||
a := &asset{bytes: bytes, info: info}
|
||||
return a, nil
|
||||
}
|
||||
@@ -497,7 +497,7 @@ func complySoc2PoliciesAccessMd() (*asset, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
info := bindataFileInfo{name: "comply-soc2/policies/access.md", size: 2175, mode: os.FileMode(420), modTime: time.Unix(1527121005, 0)}
|
||||
info := bindataFileInfo{name: "comply-soc2/policies/access.md", size: 2175, mode: os.FileMode(420), modTime: time.Unix(1535582995, 0)}
|
||||
a := &asset{bytes: bytes, info: info}
|
||||
return a, nil
|
||||
}
|
||||
@@ -517,7 +517,7 @@ func complySoc2PoliciesApplicationMd() (*asset, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
info := bindataFileInfo{name: "comply-soc2/policies/application.md", size: 8377, mode: os.FileMode(420), modTime: time.Unix(1527121005, 0)}
|
||||
info := bindataFileInfo{name: "comply-soc2/policies/application.md", size: 8377, mode: os.FileMode(420), modTime: time.Unix(1535582995, 0)}
|
||||
a := &asset{bytes: bytes, info: info}
|
||||
return a, nil
|
||||
}
|
||||
@@ -537,7 +537,7 @@ func complySoc2PoliciesAvailabilityMd() (*asset, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
info := bindataFileInfo{name: "comply-soc2/policies/availability.md", size: 7019, mode: os.FileMode(420), modTime: time.Unix(1527121005, 0)}
|
||||
info := bindataFileInfo{name: "comply-soc2/policies/availability.md", size: 7019, mode: os.FileMode(420), modTime: time.Unix(1535582995, 0)}
|
||||
a := &asset{bytes: bytes, info: info}
|
||||
return a, nil
|
||||
}
|
||||
@@ -557,7 +557,7 @@ func complySoc2PoliciesChangeMd() (*asset, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
info := bindataFileInfo{name: "comply-soc2/policies/change.md", size: 2793, mode: os.FileMode(420), modTime: time.Unix(1527121005, 0)}
|
||||
info := bindataFileInfo{name: "comply-soc2/policies/change.md", size: 2793, mode: os.FileMode(420), modTime: time.Unix(1535582995, 0)}
|
||||
a := &asset{bytes: bytes, info: info}
|
||||
return a, nil
|
||||
}
|
||||
@@ -577,7 +577,7 @@ func complySoc2PoliciesClassificationMd() (*asset, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
info := bindataFileInfo{name: "comply-soc2/policies/classification.md", size: 14376, mode: os.FileMode(420), modTime: time.Unix(1527121005, 0)}
|
||||
info := bindataFileInfo{name: "comply-soc2/policies/classification.md", size: 14376, mode: os.FileMode(420), modTime: time.Unix(1535582995, 0)}
|
||||
a := &asset{bytes: bytes, info: info}
|
||||
return a, nil
|
||||
}
|
||||
@@ -597,7 +597,7 @@ func complySoc2PoliciesConductMd() (*asset, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
info := bindataFileInfo{name: "comply-soc2/policies/conduct.md", size: 4492, mode: os.FileMode(420), modTime: time.Unix(1527121005, 0)}
|
||||
info := bindataFileInfo{name: "comply-soc2/policies/conduct.md", size: 4492, mode: os.FileMode(420), modTime: time.Unix(1535582995, 0)}
|
||||
a := &asset{bytes: bytes, info: info}
|
||||
return a, nil
|
||||
}
|
||||
@@ -617,7 +617,7 @@ func complySoc2PoliciesConfidentialityMd() (*asset, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
info := bindataFileInfo{name: "comply-soc2/policies/confidentiality.md", size: 3653, mode: os.FileMode(420), modTime: time.Unix(1527121005, 0)}
|
||||
info := bindataFileInfo{name: "comply-soc2/policies/confidentiality.md", size: 3653, mode: os.FileMode(420), modTime: time.Unix(1535582995, 0)}
|
||||
a := &asset{bytes: bytes, info: info}
|
||||
return a, nil
|
||||
}
|
||||
@@ -637,7 +637,7 @@ func complySoc2PoliciesContinuityMd() (*asset, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
info := bindataFileInfo{name: "comply-soc2/policies/continuity.md", size: 5043, mode: os.FileMode(420), modTime: time.Unix(1527121005, 0)}
|
||||
info := bindataFileInfo{name: "comply-soc2/policies/continuity.md", size: 5043, mode: os.FileMode(420), modTime: time.Unix(1535582995, 0)}
|
||||
a := &asset{bytes: bytes, info: info}
|
||||
return a, nil
|
||||
}
|
||||
@@ -657,7 +657,7 @@ func complySoc2PoliciesCyberMd() (*asset, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
info := bindataFileInfo{name: "comply-soc2/policies/cyber.md", size: 4805, mode: os.FileMode(420), modTime: time.Unix(1527121005, 0)}
|
||||
info := bindataFileInfo{name: "comply-soc2/policies/cyber.md", size: 4805, mode: os.FileMode(420), modTime: time.Unix(1535582995, 0)}
|
||||
a := &asset{bytes: bytes, info: info}
|
||||
return a, nil
|
||||
}
|
||||
@@ -677,7 +677,7 @@ func complySoc2PoliciesDatacenterMd() (*asset, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
info := bindataFileInfo{name: "comply-soc2/policies/datacenter.md", size: 3014, mode: os.FileMode(420), modTime: time.Unix(1527121005, 0)}
|
||||
info := bindataFileInfo{name: "comply-soc2/policies/datacenter.md", size: 3014, mode: os.FileMode(420), modTime: time.Unix(1535582995, 0)}
|
||||
a := &asset{bytes: bytes, info: info}
|
||||
return a, nil
|
||||
}
|
||||
@@ -697,7 +697,7 @@ func complySoc2PoliciesDevelopmentMd() (*asset, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
info := bindataFileInfo{name: "comply-soc2/policies/development.md", size: 8933, mode: os.FileMode(420), modTime: time.Unix(1527121005, 0)}
|
||||
info := bindataFileInfo{name: "comply-soc2/policies/development.md", size: 8933, mode: os.FileMode(420), modTime: time.Unix(1535582995, 0)}
|
||||
a := &asset{bytes: bytes, info: info}
|
||||
return a, nil
|
||||
}
|
||||
@@ -717,7 +717,7 @@ func complySoc2PoliciesDisasterMd() (*asset, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
info := bindataFileInfo{name: "comply-soc2/policies/disaster.md", size: 10315, mode: os.FileMode(420), modTime: time.Unix(1527121005, 0)}
|
||||
info := bindataFileInfo{name: "comply-soc2/policies/disaster.md", size: 10315, mode: os.FileMode(420), modTime: time.Unix(1535582995, 0)}
|
||||
a := &asset{bytes: bytes, info: info}
|
||||
return a, nil
|
||||
}
|
||||
@@ -737,7 +737,7 @@ func complySoc2PoliciesEncryptionMd() (*asset, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
info := bindataFileInfo{name: "comply-soc2/policies/encryption.md", size: 5381, mode: os.FileMode(420), modTime: time.Unix(1527121005, 0)}
|
||||
info := bindataFileInfo{name: "comply-soc2/policies/encryption.md", size: 5381, mode: os.FileMode(420), modTime: time.Unix(1535582995, 0)}
|
||||
a := &asset{bytes: bytes, info: info}
|
||||
return a, nil
|
||||
}
|
||||
@@ -757,7 +757,7 @@ func complySoc2PoliciesIncidentMd() (*asset, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
info := bindataFileInfo{name: "comply-soc2/policies/incident.md", size: 8552, mode: os.FileMode(420), modTime: time.Unix(1527121005, 0)}
|
||||
info := bindataFileInfo{name: "comply-soc2/policies/incident.md", size: 8552, mode: os.FileMode(420), modTime: time.Unix(1535582995, 0)}
|
||||
a := &asset{bytes: bytes, info: info}
|
||||
return a, nil
|
||||
}
|
||||
@@ -777,7 +777,7 @@ func complySoc2PoliciesInformationMd() (*asset, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
info := bindataFileInfo{name: "comply-soc2/policies/information.md", size: 5359, mode: os.FileMode(420), modTime: time.Unix(1527121005, 0)}
|
||||
info := bindataFileInfo{name: "comply-soc2/policies/information.md", size: 5359, mode: os.FileMode(420), modTime: time.Unix(1535582995, 0)}
|
||||
a := &asset{bytes: bytes, info: info}
|
||||
return a, nil
|
||||
}
|
||||
@@ -797,7 +797,7 @@ func complySoc2PoliciesLogMd() (*asset, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
info := bindataFileInfo{name: "comply-soc2/policies/log.md", size: 4307, mode: os.FileMode(420), modTime: time.Unix(1527121005, 0)}
|
||||
info := bindataFileInfo{name: "comply-soc2/policies/log.md", size: 4307, mode: os.FileMode(420), modTime: time.Unix(1535582995, 0)}
|
||||
a := &asset{bytes: bytes, info: info}
|
||||
return a, nil
|
||||
}
|
||||
@@ -817,7 +817,7 @@ func complySoc2PoliciesMediaMd() (*asset, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
info := bindataFileInfo{name: "comply-soc2/policies/media.md", size: 8819, mode: os.FileMode(420), modTime: time.Unix(1527121005, 0)}
|
||||
info := bindataFileInfo{name: "comply-soc2/policies/media.md", size: 8819, mode: os.FileMode(420), modTime: time.Unix(1535582995, 0)}
|
||||
a := &asset{bytes: bytes, info: info}
|
||||
return a, nil
|
||||
}
|
||||
@@ -837,7 +837,7 @@ func complySoc2PoliciesOfficeMd() (*asset, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
info := bindataFileInfo{name: "comply-soc2/policies/office.md", size: 3927, mode: os.FileMode(420), modTime: time.Unix(1527121005, 0)}
|
||||
info := bindataFileInfo{name: "comply-soc2/policies/office.md", size: 3927, mode: os.FileMode(420), modTime: time.Unix(1535582995, 0)}
|
||||
a := &asset{bytes: bytes, info: info}
|
||||
return a, nil
|
||||
}
|
||||
@@ -857,7 +857,7 @@ func complySoc2PoliciesPasswordMd() (*asset, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
info := bindataFileInfo{name: "comply-soc2/policies/password.md", size: 1796, mode: os.FileMode(420), modTime: time.Unix(1527121005, 0)}
|
||||
info := bindataFileInfo{name: "comply-soc2/policies/password.md", size: 1796, mode: os.FileMode(420), modTime: time.Unix(1535582995, 0)}
|
||||
a := &asset{bytes: bytes, info: info}
|
||||
return a, nil
|
||||
}
|
||||
@@ -877,7 +877,7 @@ func complySoc2PoliciesPolicyMd() (*asset, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
info := bindataFileInfo{name: "comply-soc2/policies/policy.md", size: 892, mode: os.FileMode(420), modTime: time.Unix(1527121005, 0)}
|
||||
info := bindataFileInfo{name: "comply-soc2/policies/policy.md", size: 892, mode: os.FileMode(420), modTime: time.Unix(1535582995, 0)}
|
||||
a := &asset{bytes: bytes, info: info}
|
||||
return a, nil
|
||||
}
|
||||
@@ -897,7 +897,7 @@ func complySoc2PoliciesPrivacyMd() (*asset, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
info := bindataFileInfo{name: "comply-soc2/policies/privacy.md", size: 346, mode: os.FileMode(420), modTime: time.Unix(1527121005, 0)}
|
||||
info := bindataFileInfo{name: "comply-soc2/policies/privacy.md", size: 346, mode: os.FileMode(420), modTime: time.Unix(1535582995, 0)}
|
||||
a := &asset{bytes: bytes, info: info}
|
||||
return a, nil
|
||||
}
|
||||
@@ -917,7 +917,7 @@ func complySoc2PoliciesProcessingMd() (*asset, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
info := bindataFileInfo{name: "comply-soc2/policies/processing.md", size: 210, mode: os.FileMode(420), modTime: time.Unix(1527121005, 0)}
|
||||
info := bindataFileInfo{name: "comply-soc2/policies/processing.md", size: 210, mode: os.FileMode(420), modTime: time.Unix(1535582995, 0)}
|
||||
a := &asset{bytes: bytes, info: info}
|
||||
return a, nil
|
||||
}
|
||||
@@ -937,7 +937,7 @@ func complySoc2PoliciesRemoteMd() (*asset, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
info := bindataFileInfo{name: "comply-soc2/policies/remote.md", size: 4119, mode: os.FileMode(420), modTime: time.Unix(1527121005, 0)}
|
||||
info := bindataFileInfo{name: "comply-soc2/policies/remote.md", size: 4119, mode: os.FileMode(420), modTime: time.Unix(1535582995, 0)}
|
||||
a := &asset{bytes: bytes, info: info}
|
||||
return a, nil
|
||||
}
|
||||
@@ -957,7 +957,7 @@ func complySoc2PoliciesRetentionMd() (*asset, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
info := bindataFileInfo{name: "comply-soc2/policies/retention.md", size: 6811, mode: os.FileMode(420), modTime: time.Unix(1527121005, 0)}
|
||||
info := bindataFileInfo{name: "comply-soc2/policies/retention.md", size: 6811, mode: os.FileMode(420), modTime: time.Unix(1535582995, 0)}
|
||||
a := &asset{bytes: bytes, info: info}
|
||||
return a, nil
|
||||
}
|
||||
@@ -977,7 +977,7 @@ func complySoc2PoliciesRiskMd() (*asset, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
info := bindataFileInfo{name: "comply-soc2/policies/risk.md", size: 10486, mode: os.FileMode(420), modTime: time.Unix(1527121005, 0)}
|
||||
info := bindataFileInfo{name: "comply-soc2/policies/risk.md", size: 10486, mode: os.FileMode(420), modTime: time.Unix(1535582995, 0)}
|
||||
a := &asset{bytes: bytes, info: info}
|
||||
return a, nil
|
||||
}
|
||||
@@ -997,7 +997,7 @@ func complySoc2PoliciesVendorMd() (*asset, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
info := bindataFileInfo{name: "comply-soc2/policies/vendor.md", size: 3139, mode: os.FileMode(420), modTime: time.Unix(1527121005, 0)}
|
||||
info := bindataFileInfo{name: "comply-soc2/policies/vendor.md", size: 3139, mode: os.FileMode(420), modTime: time.Unix(1535582995, 0)}
|
||||
a := &asset{bytes: bytes, info: info}
|
||||
return a, nil
|
||||
}
|
||||
@@ -1017,7 +1017,7 @@ func complySoc2PoliciesWorkstationMd() (*asset, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
info := bindataFileInfo{name: "comply-soc2/policies/workstation.md", size: 1791, mode: os.FileMode(420), modTime: time.Unix(1527121005, 0)}
|
||||
info := bindataFileInfo{name: "comply-soc2/policies/workstation.md", size: 1791, mode: os.FileMode(420), modTime: time.Unix(1535582995, 0)}
|
||||
a := &asset{bytes: bytes, info: info}
|
||||
return a, nil
|
||||
}
|
||||
@@ -1037,7 +1037,7 @@ func complySoc2ProceduresReadmeMd() (*asset, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
info := bindataFileInfo{name: "comply-soc2/procedures/README.md", size: 92, mode: os.FileMode(420), modTime: time.Unix(1527121005, 0)}
|
||||
info := bindataFileInfo{name: "comply-soc2/procedures/README.md", size: 92, mode: os.FileMode(420), modTime: time.Unix(1535582995, 0)}
|
||||
a := &asset{bytes: bytes, info: info}
|
||||
return a, nil
|
||||
}
|
||||
@@ -1057,7 +1057,7 @@ func complySoc2ProceduresOffboardingMd() (*asset, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
info := bindataFileInfo{name: "comply-soc2/procedures/offboarding.md", size: 358, mode: os.FileMode(420), modTime: time.Unix(1527121005, 0)}
|
||||
info := bindataFileInfo{name: "comply-soc2/procedures/offboarding.md", size: 358, mode: os.FileMode(420), modTime: time.Unix(1535582995, 0)}
|
||||
a := &asset{bytes: bytes, info: info}
|
||||
return a, nil
|
||||
}
|
||||
@@ -1077,7 +1077,7 @@ func complySoc2ProceduresOnboardingMd() (*asset, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
info := bindataFileInfo{name: "comply-soc2/procedures/onboarding.md", size: 495, mode: os.FileMode(420), modTime: time.Unix(1527121005, 0)}
|
||||
info := bindataFileInfo{name: "comply-soc2/procedures/onboarding.md", size: 495, mode: os.FileMode(420), modTime: time.Unix(1535582995, 0)}
|
||||
a := &asset{bytes: bytes, info: info}
|
||||
return a, nil
|
||||
}
|
||||
@@ -1097,7 +1097,7 @@ func complySoc2ProceduresPatchMd() (*asset, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
info := bindataFileInfo{name: "comply-soc2/procedures/patch.md", size: 380, mode: os.FileMode(420), modTime: time.Unix(1527121005, 0)}
|
||||
info := bindataFileInfo{name: "comply-soc2/procedures/patch.md", size: 380, mode: os.FileMode(420), modTime: time.Unix(1535582995, 0)}
|
||||
a := &asset{bytes: bytes, info: info}
|
||||
return a, nil
|
||||
}
|
||||
@@ -1117,7 +1117,7 @@ func complySoc2ProceduresWorkstationMd() (*asset, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
info := bindataFileInfo{name: "comply-soc2/procedures/workstation.md", size: 1081, mode: os.FileMode(420), modTime: time.Unix(1527121005, 0)}
|
||||
info := bindataFileInfo{name: "comply-soc2/procedures/workstation.md", size: 1081, mode: os.FileMode(420), modTime: time.Unix(1535582995, 0)}
|
||||
a := &asset{bytes: bytes, info: info}
|
||||
return a, nil
|
||||
}
|
||||
@@ -1137,7 +1137,7 @@ func complySoc2StandardsReadmeMd() (*asset, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
info := bindataFileInfo{name: "comply-soc2/standards/README.md", size: 282, mode: os.FileMode(420), modTime: time.Unix(1527121005, 0)}
|
||||
info := bindataFileInfo{name: "comply-soc2/standards/README.md", size: 282, mode: os.FileMode(420), modTime: time.Unix(1535582995, 0)}
|
||||
a := &asset{bytes: bytes, info: info}
|
||||
return a, nil
|
||||
}
|
||||
@@ -1157,7 +1157,7 @@ func complySoc2StandardsTsc2017Yml() (*asset, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
info := bindataFileInfo{name: "comply-soc2/standards/TSC-2017.yml", size: 16305, mode: os.FileMode(420), modTime: time.Unix(1527121005, 0)}
|
||||
info := bindataFileInfo{name: "comply-soc2/standards/TSC-2017.yml", size: 16305, mode: os.FileMode(420), modTime: time.Unix(1535582995, 0)}
|
||||
a := &asset{bytes: bytes, info: info}
|
||||
return a, nil
|
||||
}
|
||||
@@ -1177,7 +1177,7 @@ func complySoc2TemplatesDefaultLatex() (*asset, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
info := bindataFileInfo{name: "comply-soc2/templates/default.latex", size: 7649, mode: os.FileMode(420), modTime: time.Unix(1527121005, 0)}
|
||||
info := bindataFileInfo{name: "comply-soc2/templates/default.latex", size: 7649, mode: os.FileMode(420), modTime: time.Unix(1535582995, 0)}
|
||||
a := &asset{bytes: bytes, info: info}
|
||||
return a, nil
|
||||
}
|
||||
@@ -1197,7 +1197,7 @@ func complySoc2TemplatesIndexAce() (*asset, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
info := bindataFileInfo{name: "comply-soc2/templates/index.ace", size: 7596, mode: os.FileMode(420), modTime: time.Unix(1527121005, 0)}
|
||||
info := bindataFileInfo{name: "comply-soc2/templates/index.ace", size: 7596, mode: os.FileMode(420), modTime: time.Unix(1535582995, 0)}
|
||||
a := &asset{bytes: bytes, info: info}
|
||||
return a, nil
|
||||
}
|
||||
|
||||
@@ -5,7 +5,9 @@ import (
|
||||
"sort"
|
||||
"time"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"github.com/robfig/cron"
|
||||
"github.com/strongdm/comply/internal/config"
|
||||
"github.com/strongdm/comply/internal/model"
|
||||
)
|
||||
|
||||
@@ -68,7 +70,10 @@ func TriggerScheduled() error {
|
||||
// in the future, nothing to do
|
||||
continue
|
||||
}
|
||||
trigger(procedure)
|
||||
err = trigger(procedure)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
// don't go back further than 13 months
|
||||
tooOld := time.Now().Add(-1 * time.Hour * 24 * (365 + 30))
|
||||
@@ -88,7 +93,10 @@ func TriggerScheduled() error {
|
||||
}
|
||||
|
||||
// is in the past? then trigger.
|
||||
trigger(procedure)
|
||||
err = trigger(procedure)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
break SEARCH
|
||||
}
|
||||
}
|
||||
@@ -97,13 +105,18 @@ func TriggerScheduled() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func trigger(procedure *model.Procedure) {
|
||||
func trigger(procedure *model.Procedure) error {
|
||||
fmt.Printf("triggering procedure %s (cron expression: %s)\n", procedure.Name, procedure.Cron)
|
||||
|
||||
// TODO: don't hardcode GH
|
||||
tp := model.GetPlugin(model.GitHub)
|
||||
tp.Create(&model.Ticket{
|
||||
ts, err := config.Config().TicketSystem()
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "error in ticket system configuration")
|
||||
}
|
||||
|
||||
tp := model.GetPlugin(model.TicketSystem(ts))
|
||||
err = tp.Create(&model.Ticket{
|
||||
Name: procedure.Name,
|
||||
Body: fmt.Sprintf("%s\n\n\n---\nProcedure-ID: %s", procedure.Body, procedure.ID),
|
||||
}, []string{"comply", "comply-procedure"})
|
||||
return err
|
||||
}
|
||||
|
||||
29
vendor/github.com/andygrunwald/go-jira/.gitignore
generated
vendored
Normal file
29
vendor/github.com/andygrunwald/go-jira/.gitignore
generated
vendored
Normal file
@@ -0,0 +1,29 @@
|
||||
# Compiled Object files, Static and Dynamic libs (Shared Objects)
|
||||
*.o
|
||||
*.a
|
||||
*.so
|
||||
|
||||
# Don't check in vendor
|
||||
vendor/
|
||||
|
||||
# Folders
|
||||
_obj
|
||||
_test
|
||||
|
||||
# Architecture specific extensions/prefixes
|
||||
*.[568vq]
|
||||
[568vq].out
|
||||
|
||||
*.cgo1.go
|
||||
*.cgo2.c
|
||||
_cgo_defun.c
|
||||
_cgo_gotypes.go
|
||||
_cgo_export.*
|
||||
|
||||
_testmain.go
|
||||
|
||||
*.exe
|
||||
*.test
|
||||
*.prof
|
||||
*.iml
|
||||
.idea
|
||||
17
vendor/github.com/andygrunwald/go-jira/.travis.yml
generated
vendored
Normal file
17
vendor/github.com/andygrunwald/go-jira/.travis.yml
generated
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
language: go
|
||||
|
||||
sudo: false
|
||||
|
||||
go:
|
||||
- 1.4
|
||||
- 1.5
|
||||
- 1.6
|
||||
- 1.7
|
||||
- 1.8
|
||||
- 1.9
|
||||
|
||||
before_install:
|
||||
- go get -t ./...
|
||||
|
||||
script:
|
||||
- GOMAXPROCS=4 GORACE="halt_on_error=1" go test -race -v ./...
|
||||
36
vendor/github.com/andygrunwald/go-jira/Gopkg.lock
generated
vendored
Normal file
36
vendor/github.com/andygrunwald/go-jira/Gopkg.lock
generated
vendored
Normal file
@@ -0,0 +1,36 @@
|
||||
# This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'.
|
||||
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/fatih/structs"
|
||||
packages = ["."]
|
||||
revision = "a720dfa8df582c51dee1b36feabb906bde1588bd"
|
||||
version = "v1.0"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "github.com/google/go-querystring"
|
||||
packages = ["query"]
|
||||
revision = "53e6ce116135b80d037921a7fdd5138cf32d7a8a"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/pkg/errors"
|
||||
packages = ["."]
|
||||
revision = "645ef00459ed84a119197bfb8d8205042c6df63d"
|
||||
version = "v0.8.0"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/trivago/tgo"
|
||||
packages = [
|
||||
"tcontainer",
|
||||
"treflect"
|
||||
]
|
||||
revision = "e4d1ddd28c17dd89ed26327cf69fded22060671b"
|
||||
version = "v1.0.1"
|
||||
|
||||
[solve-meta]
|
||||
analyzer-name = "dep"
|
||||
analyzer-version = 1
|
||||
inputs-digest = "e84ca9eea6d233e0947b0d760913db2983fd4cbf6fd0d8690c737a71affb635c"
|
||||
solver-name = "gps-cdcl"
|
||||
solver-version = 1
|
||||
46
vendor/github.com/andygrunwald/go-jira/Gopkg.toml
generated
vendored
Normal file
46
vendor/github.com/andygrunwald/go-jira/Gopkg.toml
generated
vendored
Normal file
@@ -0,0 +1,46 @@
|
||||
# Gopkg.toml example
|
||||
#
|
||||
# Refer to https://github.com/golang/dep/blob/master/docs/Gopkg.toml.md
|
||||
# for detailed Gopkg.toml documentation.
|
||||
#
|
||||
# required = ["github.com/user/thing/cmd/thing"]
|
||||
# ignored = ["github.com/user/project/pkgX", "bitbucket.org/user/project/pkgA/pkgY"]
|
||||
#
|
||||
# [[constraint]]
|
||||
# name = "github.com/user/project"
|
||||
# version = "1.0.0"
|
||||
#
|
||||
# [[constraint]]
|
||||
# name = "github.com/user/project2"
|
||||
# branch = "dev"
|
||||
# source = "github.com/myfork/project2"
|
||||
#
|
||||
# [[override]]
|
||||
# name = "github.com/x/y"
|
||||
# version = "2.4.0"
|
||||
#
|
||||
# [prune]
|
||||
# non-go = false
|
||||
# go-tests = true
|
||||
# unused-packages = true
|
||||
|
||||
|
||||
[[constraint]]
|
||||
name = "github.com/fatih/structs"
|
||||
version = "1.0.0"
|
||||
|
||||
[[constraint]]
|
||||
branch = "master"
|
||||
name = "github.com/google/go-querystring"
|
||||
|
||||
[[constraint]]
|
||||
name = "github.com/pkg/errors"
|
||||
version = "0.8.0"
|
||||
|
||||
[[constraint]]
|
||||
name = "github.com/trivago/tgo"
|
||||
version = "1.0.1"
|
||||
|
||||
[prune]
|
||||
go-tests = true
|
||||
unused-packages = true
|
||||
22
vendor/github.com/andygrunwald/go-jira/LICENSE
generated
vendored
Normal file
22
vendor/github.com/andygrunwald/go-jira/LICENSE
generated
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015 Andy Grunwald
|
||||
|
||||
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.
|
||||
|
||||
2
vendor/github.com/andygrunwald/go-jira/Makefile
generated
vendored
Normal file
2
vendor/github.com/andygrunwald/go-jira/Makefile
generated
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
test:
|
||||
go test -v ./...
|
||||
271
vendor/github.com/andygrunwald/go-jira/README.md
generated
vendored
Normal file
271
vendor/github.com/andygrunwald/go-jira/README.md
generated
vendored
Normal file
@@ -0,0 +1,271 @@
|
||||
# go-jira
|
||||
|
||||
[](https://godoc.org/github.com/andygrunwald/go-jira)
|
||||
[](https://travis-ci.org/andygrunwald/go-jira)
|
||||
[](https://goreportcard.com/report/github.com/andygrunwald/go-jira)
|
||||
|
||||
[Go](https://golang.org/) client library for [Atlassian JIRA](https://www.atlassian.com/software/jira).
|
||||
|
||||

|
||||
|
||||
## Features
|
||||
|
||||
* Authentication (HTTP Basic, OAuth, Session Cookie)
|
||||
* Create and retrieve issues
|
||||
* Create and retrieve issue transitions (status updates)
|
||||
* Call every API endpoint of the JIRA, even if it is not directly implemented in this library
|
||||
|
||||
This package is not JIRA API complete (yet), but you can call every API endpoint you want. See [Call a not implemented API endpoint](#call-a-not-implemented-api-endpoint) how to do this. For all possible API endpoints of JIRA have a look at [latest JIRA REST API documentation](https://docs.atlassian.com/jira/REST/latest/).
|
||||
|
||||
## Compatible JIRA versions
|
||||
|
||||
This package was tested against JIRA v6.3.4 and v7.1.2.
|
||||
|
||||
## Installation
|
||||
|
||||
It is go gettable
|
||||
|
||||
$ go get github.com/andygrunwald/go-jira
|
||||
|
||||
For stable versions you can use one of our tags with [gopkg.in](http://labix.org/gopkg.in). E.g.
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
jira "gopkg.in/andygrunwald/go-jira.v1"
|
||||
)
|
||||
...
|
||||
```
|
||||
|
||||
(optional) to run unit / example tests:
|
||||
|
||||
$ cd $GOPATH/src/github.com/andygrunwald/go-jira
|
||||
$ go test -v ./...
|
||||
|
||||
## API
|
||||
|
||||
Please have a look at the [GoDoc documentation](https://godoc.org/github.com/andygrunwald/go-jira) for a detailed API description.
|
||||
|
||||
The [latest JIRA REST API documentation](https://docs.atlassian.com/jira/REST/latest/) was the base document for this package.
|
||||
|
||||
## Examples
|
||||
|
||||
Further a few examples how the API can be used.
|
||||
A few more examples are available in the [GoDoc examples section](https://godoc.org/github.com/andygrunwald/go-jira#pkg-examples).
|
||||
|
||||
### Get a single issue
|
||||
|
||||
Lets retrieve [MESOS-3325](https://issues.apache.org/jira/browse/MESOS-3325) from the [Apache Mesos](http://mesos.apache.org/) project.
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/andygrunwald/go-jira"
|
||||
)
|
||||
|
||||
func main() {
|
||||
jiraClient, _ := jira.NewClient(nil, "https://issues.apache.org/jira/")
|
||||
issue, _, _ := jiraClient.Issue.Get("MESOS-3325", nil)
|
||||
|
||||
fmt.Printf("%s: %+v\n", issue.Key, issue.Fields.Summary)
|
||||
fmt.Printf("Type: %s\n", issue.Fields.Type.Name)
|
||||
fmt.Printf("Priority: %s\n", issue.Fields.Priority.Name)
|
||||
|
||||
// MESOS-3325: Running mesos-slave@0.23 in a container causes slave to be lost after a restart
|
||||
// Type: Bug
|
||||
// Priority: Critical
|
||||
}
|
||||
```
|
||||
|
||||
### Authentication
|
||||
|
||||
The `go-jira` library does not handle most authentication directly. Instead, authentication should be handled within
|
||||
an `http.Client`. That client can then be passed into the `NewClient` function when creating a jira client.
|
||||
|
||||
For convenience, capability for basic and cookie-based authentication is included in the main library.
|
||||
|
||||
#### Basic auth example
|
||||
|
||||
A more thorough, [runnable example](examples/basicauth/main.go) is provided in the examples directory.
|
||||
|
||||
```go
|
||||
func main() {
|
||||
tp := jira.BasicAuthTransport{
|
||||
Username: "username",
|
||||
Password: "password",
|
||||
}
|
||||
|
||||
client, err := jira.NewClient(tp.Client(), "https://my.jira.com")
|
||||
|
||||
u, _, err := client.User.Get("some_user")
|
||||
|
||||
fmt.Printf("\nEmail: %v\nSuccess!\n", u.EmailAddress)
|
||||
}
|
||||
```
|
||||
|
||||
#### Authenticate with session cookie
|
||||
|
||||
A more thorough, [runnable example](examples/cookieauth/main.go) is provided in the examples directory.
|
||||
|
||||
Note: The `AuthURL` is almost always going to have the path `/rest/auth/1/session`
|
||||
|
||||
```go
|
||||
tp := jira.CookieAuthTransport{
|
||||
Username: "username",
|
||||
Password: "password",
|
||||
AuthURL: "https://my.jira.com/rest/auth/1/session",
|
||||
}
|
||||
|
||||
client, err := jira.NewClient(tp.Client(), "https://my.jira.com")
|
||||
u, _, err := client.User.Get("admin")
|
||||
|
||||
fmt.Printf("\nEmail: %v\nSuccess!\n", u.EmailAddress)
|
||||
}
|
||||
```
|
||||
|
||||
#### Authenticate with OAuth
|
||||
|
||||
If you want to connect via OAuth to your JIRA Cloud instance checkout the [example of using OAuth authentication with JIRA in Go](https://gist.github.com/Lupus/edafe9a7c5c6b13407293d795442fe67) by [@Lupus](https://github.com/Lupus).
|
||||
|
||||
For more details have a look at the [issue #56](https://github.com/andygrunwald/go-jira/issues/56).
|
||||
|
||||
### Create an issue
|
||||
|
||||
Example how to create an issue.
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/andygrunwald/go-jira"
|
||||
)
|
||||
|
||||
func main() {
|
||||
base := "https://my.jira.com"
|
||||
tp := jira.CookieAuthTransport{
|
||||
Username: "username",
|
||||
Password: "password",
|
||||
AuthURL: fmt.Sprintf("%s/rest/auth/1/session", base),
|
||||
}
|
||||
|
||||
jiraClient, err := jira.NewClient(tp.Client(), base)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
i := jira.Issue{
|
||||
Fields: &jira.IssueFields{
|
||||
Assignee: &jira.User{
|
||||
Name: "myuser",
|
||||
},
|
||||
Reporter: &jira.User{
|
||||
Name: "youruser",
|
||||
},
|
||||
Description: "Test Issue",
|
||||
Type: jira.IssueType{
|
||||
Name: "Bug",
|
||||
},
|
||||
Project: jira.Project{
|
||||
Key: "PROJ1",
|
||||
},
|
||||
Summary: "Just a demo issue",
|
||||
},
|
||||
}
|
||||
issue, _, err := jiraClient.Issue.Create(&i)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
fmt.Printf("%s: %+v\n", issue.Key, issue.Fields.Summary)
|
||||
}
|
||||
```
|
||||
|
||||
### Call a not implemented API endpoint
|
||||
|
||||
Not all API endpoints of the JIRA API are implemented into *go-jira*.
|
||||
But you can call them anyway:
|
||||
Lets get all public projects of [Atlassian`s JIRA instance](https://jira.atlassian.com/).
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/andygrunwald/go-jira"
|
||||
)
|
||||
|
||||
func main() {
|
||||
base := "https://my.jira.com"
|
||||
tp := jira.CookieAuthTransport{
|
||||
Username: "username",
|
||||
Password: "password",
|
||||
AuthURL: fmt.Sprintf("%s/rest/auth/1/session", base),
|
||||
}
|
||||
|
||||
jiraClient, err := jira.NewClient(tp.Client(), base)
|
||||
req, _ := jiraClient.NewRequest("GET", "/rest/api/2/project", nil)
|
||||
|
||||
projects := new([]jira.Project)
|
||||
_, err := jiraClient.Do(req, projects)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
for _, project := range *projects {
|
||||
fmt.Printf("%s: %s\n", project.Key, project.Name)
|
||||
}
|
||||
|
||||
// ...
|
||||
// BAM: Bamboo
|
||||
// BAMJ: Bamboo JIRA Plugin
|
||||
// CLOV: Clover
|
||||
// CONF: Confluence
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
## Implementations
|
||||
|
||||
* [andygrunwald/jitic](https://github.com/andygrunwald/jitic) - The JIRA Ticket Checker
|
||||
|
||||
## Code structure
|
||||
|
||||
The code structure of this package was inspired by [google/go-github](https://github.com/google/go-github).
|
||||
|
||||
There is one main part (the client).
|
||||
Based on this main client the other endpoints, like Issues or Authentication are extracted in services. E.g. `IssueService` or `AuthenticationService`.
|
||||
These services own a responsibility of the single endpoints / usecases of JIRA.
|
||||
|
||||
## Contribution
|
||||
|
||||
Contribution, in any kind of way, is highly welcome!
|
||||
It doesn't matter if you are not able to write code.
|
||||
Creating issues or holding talks and help other people to use [go-jira](https://github.com/andygrunwald/go-jira) is contribution, too!
|
||||
A few examples:
|
||||
|
||||
* Correct typos in the README / documentation
|
||||
* Reporting bugs
|
||||
* Implement a new feature or endpoint
|
||||
* Sharing the love if [go-jira](https://github.com/andygrunwald/go-jira) and help people to get use to it
|
||||
|
||||
If you are new to pull requests, checkout [Collaborating on projects using issues and pull requests / Creating a pull request](https://help.github.com/articles/creating-a-pull-request/).
|
||||
|
||||
### Dependency management
|
||||
|
||||
`go-jira` uses `dep` for dependency management. After cloning the repo, it's easy to make sure you have the correct dependencies by running `dep ensure`.
|
||||
|
||||
For adding new dependencies, updating dependencies, and other operations, the [Daily Dep](https://golang.github.io/dep/docs/daily-dep.html) is a good place to start.
|
||||
|
||||
### Sandbox environment for testing
|
||||
|
||||
Jira offers sandbox test environments at http://go.atlassian.com/cloud-dev.
|
||||
|
||||
You can read more about them at https://developer.atlassian.com/blog/2016/04/cloud-ecosystem-dev-env/.
|
||||
|
||||
## License
|
||||
|
||||
This project is released under the terms of the [MIT license](http://en.wikipedia.org/wiki/MIT_License).
|
||||
187
vendor/github.com/andygrunwald/go-jira/authentication.go
generated
vendored
Normal file
187
vendor/github.com/andygrunwald/go-jira/authentication.go
generated
vendored
Normal file
@@ -0,0 +1,187 @@
|
||||
package jira
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
const (
|
||||
// HTTP Basic Authentication
|
||||
authTypeBasic = 1
|
||||
// HTTP Session Authentication
|
||||
authTypeSession = 2
|
||||
)
|
||||
|
||||
// AuthenticationService handles authentication for the JIRA instance / API.
|
||||
//
|
||||
// JIRA API docs: https://docs.atlassian.com/jira/REST/latest/#authentication
|
||||
type AuthenticationService struct {
|
||||
client *Client
|
||||
|
||||
// Authentication type
|
||||
authType int
|
||||
|
||||
// Basic auth username
|
||||
username string
|
||||
|
||||
// Basic auth password
|
||||
password string
|
||||
}
|
||||
|
||||
// Session represents a Session JSON response by the JIRA API.
|
||||
type Session struct {
|
||||
Self string `json:"self,omitempty"`
|
||||
Name string `json:"name,omitempty"`
|
||||
Session struct {
|
||||
Name string `json:"name"`
|
||||
Value string `json:"value"`
|
||||
} `json:"session,omitempty"`
|
||||
LoginInfo struct {
|
||||
FailedLoginCount int `json:"failedLoginCount"`
|
||||
LoginCount int `json:"loginCount"`
|
||||
LastFailedLoginTime string `json:"lastFailedLoginTime"`
|
||||
PreviousLoginTime string `json:"previousLoginTime"`
|
||||
} `json:"loginInfo"`
|
||||
Cookies []*http.Cookie
|
||||
}
|
||||
|
||||
// AcquireSessionCookie creates a new session for a user in JIRA.
|
||||
// Once a session has been successfully created it can be used to access any of JIRA's remote APIs and also the web UI by passing the appropriate HTTP Cookie header.
|
||||
// The header will by automatically applied to every API request.
|
||||
// Note that it is generally preferrable to use HTTP BASIC authentication with the REST API.
|
||||
// However, this resource may be used to mimic the behaviour of JIRA's log-in page (e.g. to display log-in errors to a user).
|
||||
//
|
||||
// JIRA API docs: https://docs.atlassian.com/jira/REST/latest/#auth/1/session
|
||||
//
|
||||
// Deprecated: Use CookieAuthTransport instead
|
||||
func (s *AuthenticationService) AcquireSessionCookie(username, password string) (bool, error) {
|
||||
apiEndpoint := "rest/auth/1/session"
|
||||
body := struct {
|
||||
Username string `json:"username"`
|
||||
Password string `json:"password"`
|
||||
}{
|
||||
username,
|
||||
password,
|
||||
}
|
||||
|
||||
req, err := s.client.NewRequest("POST", apiEndpoint, body)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
session := new(Session)
|
||||
resp, err := s.client.Do(req, session)
|
||||
|
||||
if resp != nil {
|
||||
session.Cookies = resp.Cookies()
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return false, fmt.Errorf("Auth at JIRA instance failed (HTTP(S) request). %s", err)
|
||||
}
|
||||
if resp != nil && resp.StatusCode != 200 {
|
||||
return false, fmt.Errorf("Auth at JIRA instance failed (HTTP(S) request). Status code: %d", resp.StatusCode)
|
||||
}
|
||||
|
||||
s.client.session = session
|
||||
s.authType = authTypeSession
|
||||
|
||||
return true, nil
|
||||
}
|
||||
|
||||
// SetBasicAuth sets username and password for the basic auth against the JIRA instance.
|
||||
//
|
||||
// Deprecated: Use BasicAuthTransport instead
|
||||
func (s *AuthenticationService) SetBasicAuth(username, password string) {
|
||||
s.username = username
|
||||
s.password = password
|
||||
s.authType = authTypeBasic
|
||||
}
|
||||
|
||||
// Authenticated reports if the current Client has authentication details for JIRA
|
||||
func (s *AuthenticationService) Authenticated() bool {
|
||||
if s != nil {
|
||||
if s.authType == authTypeSession {
|
||||
return s.client.session != nil
|
||||
} else if s.authType == authTypeBasic {
|
||||
return s.username != ""
|
||||
}
|
||||
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// Logout logs out the current user that has been authenticated and the session in the client is destroyed.
|
||||
//
|
||||
// JIRA API docs: https://docs.atlassian.com/jira/REST/latest/#auth/1/session
|
||||
//
|
||||
// Deprecated: Use CookieAuthTransport to create base client. Logging out is as simple as not using the
|
||||
// client anymore
|
||||
func (s *AuthenticationService) Logout() error {
|
||||
if s.authType != authTypeSession || s.client.session == nil {
|
||||
return fmt.Errorf("no user is authenticated")
|
||||
}
|
||||
|
||||
apiEndpoint := "rest/auth/1/session"
|
||||
req, err := s.client.NewRequest("DELETE", apiEndpoint, nil)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Creating the request to log the user out failed : %s", err)
|
||||
}
|
||||
|
||||
resp, err := s.client.Do(req, nil)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Error sending the logout request: %s", err)
|
||||
}
|
||||
if resp.StatusCode != 204 {
|
||||
return fmt.Errorf("The logout was unsuccessful with status %d", resp.StatusCode)
|
||||
}
|
||||
|
||||
// If logout successful, delete session
|
||||
s.client.session = nil
|
||||
|
||||
return nil
|
||||
|
||||
}
|
||||
|
||||
// GetCurrentUser gets the details of the current user.
|
||||
//
|
||||
// JIRA API docs: https://docs.atlassian.com/jira/REST/latest/#auth/1/session
|
||||
func (s *AuthenticationService) GetCurrentUser() (*Session, error) {
|
||||
if s == nil {
|
||||
return nil, fmt.Errorf("AUthenticaiton Service is not instantiated")
|
||||
}
|
||||
if s.authType != authTypeSession || s.client.session == nil {
|
||||
return nil, fmt.Errorf("No user is authenticated yet")
|
||||
}
|
||||
|
||||
apiEndpoint := "rest/auth/1/session"
|
||||
req, err := s.client.NewRequest("GET", apiEndpoint, nil)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Could not create request for getting user info : %s", err)
|
||||
}
|
||||
|
||||
resp, err := s.client.Do(req, nil)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Error sending request to get user info : %s", err)
|
||||
}
|
||||
if resp.StatusCode != 200 {
|
||||
return nil, fmt.Errorf("Getting user info failed with status : %d", resp.StatusCode)
|
||||
}
|
||||
|
||||
defer resp.Body.Close()
|
||||
ret := new(Session)
|
||||
data, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Couldn't read body from the response : %s", err)
|
||||
}
|
||||
|
||||
err = json.Unmarshal(data, &ret)
|
||||
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Could not unmarshall received user info : %s", err)
|
||||
}
|
||||
|
||||
return ret, nil
|
||||
}
|
||||
166
vendor/github.com/andygrunwald/go-jira/board.go
generated
vendored
Normal file
166
vendor/github.com/andygrunwald/go-jira/board.go
generated
vendored
Normal file
@@ -0,0 +1,166 @@
|
||||
package jira
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
)
|
||||
|
||||
// BoardService handles Agile Boards for the JIRA instance / API.
|
||||
//
|
||||
// JIRA API docs: https://docs.atlassian.com/jira-software/REST/server/
|
||||
type BoardService struct {
|
||||
client *Client
|
||||
}
|
||||
|
||||
// BoardsList reflects a list of agile boards
|
||||
type BoardsList struct {
|
||||
MaxResults int `json:"maxResults" structs:"maxResults"`
|
||||
StartAt int `json:"startAt" structs:"startAt"`
|
||||
Total int `json:"total" structs:"total"`
|
||||
IsLast bool `json:"isLast" structs:"isLast"`
|
||||
Values []Board `json:"values" structs:"values"`
|
||||
}
|
||||
|
||||
// Board represents a JIRA agile board
|
||||
type Board struct {
|
||||
ID int `json:"id,omitempty" structs:"id,omitempty"`
|
||||
Self string `json:"self,omitempty" structs:"self,omitempty"`
|
||||
Name string `json:"name,omitempty" structs:"name,omitemtpy"`
|
||||
Type string `json:"type,omitempty" structs:"type,omitempty"`
|
||||
FilterID int `json:"filterId,omitempty" structs:"filterId,omitempty"`
|
||||
}
|
||||
|
||||
// BoardListOptions specifies the optional parameters to the BoardService.GetList
|
||||
type BoardListOptions struct {
|
||||
// BoardType filters results to boards of the specified type.
|
||||
// Valid values: scrum, kanban.
|
||||
BoardType string `url:"boardType,omitempty"`
|
||||
// Name filters results to boards that match or partially match the specified name.
|
||||
Name string `url:"name,omitempty"`
|
||||
// ProjectKeyOrID filters results to boards that are relevant to a project.
|
||||
// Relevance meaning that the JQL filter defined in board contains a reference to a project.
|
||||
ProjectKeyOrID string `url:"projectKeyOrId,omitempty"`
|
||||
|
||||
SearchOptions
|
||||
}
|
||||
|
||||
// Wrapper struct for search result
|
||||
type sprintsResult struct {
|
||||
Sprints []Sprint `json:"values" structs:"values"`
|
||||
}
|
||||
|
||||
// Sprint represents a sprint on JIRA agile board
|
||||
type Sprint struct {
|
||||
ID int `json:"id" structs:"id"`
|
||||
Name string `json:"name" structs:"name"`
|
||||
CompleteDate *time.Time `json:"completeDate" structs:"completeDate"`
|
||||
EndDate *time.Time `json:"endDate" structs:"endDate"`
|
||||
StartDate *time.Time `json:"startDate" structs:"startDate"`
|
||||
OriginBoardID int `json:"originBoardId" structs:"originBoardId"`
|
||||
Self string `json:"self" structs:"self"`
|
||||
State string `json:"state" structs:"state"`
|
||||
}
|
||||
|
||||
// GetAllBoards will returns all boards. This only includes boards that the user has permission to view.
|
||||
//
|
||||
// JIRA API docs: https://docs.atlassian.com/jira-software/REST/cloud/#agile/1.0/board-getAllBoards
|
||||
func (s *BoardService) GetAllBoards(opt *BoardListOptions) (*BoardsList, *Response, error) {
|
||||
apiEndpoint := "rest/agile/1.0/board"
|
||||
url, err := addOptions(apiEndpoint, opt)
|
||||
req, err := s.client.NewRequest("GET", url, nil)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
boards := new(BoardsList)
|
||||
resp, err := s.client.Do(req, boards)
|
||||
if err != nil {
|
||||
jerr := NewJiraError(resp, err)
|
||||
return nil, resp, jerr
|
||||
}
|
||||
|
||||
return boards, resp, err
|
||||
}
|
||||
|
||||
// GetBoard will returns the board for the given boardID.
|
||||
// This board will only be returned if the user has permission to view it.
|
||||
//
|
||||
// JIRA API docs: https://docs.atlassian.com/jira-software/REST/cloud/#agile/1.0/board-getBoard
|
||||
func (s *BoardService) GetBoard(boardID int) (*Board, *Response, error) {
|
||||
apiEndpoint := fmt.Sprintf("rest/agile/1.0/board/%v", boardID)
|
||||
req, err := s.client.NewRequest("GET", apiEndpoint, nil)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
board := new(Board)
|
||||
resp, err := s.client.Do(req, board)
|
||||
if err != nil {
|
||||
jerr := NewJiraError(resp, err)
|
||||
return nil, resp, jerr
|
||||
}
|
||||
|
||||
return board, resp, nil
|
||||
}
|
||||
|
||||
// CreateBoard creates a new board. Board name, type and filter Id is required.
|
||||
// name - Must be less than 255 characters.
|
||||
// type - Valid values: scrum, kanban
|
||||
// filterId - Id of a filter that the user has permissions to view.
|
||||
// Note, if the user does not have the 'Create shared objects' permission and tries to create a shared board, a private
|
||||
// board will be created instead (remember that board sharing depends on the filter sharing).
|
||||
//
|
||||
// JIRA API docs: https://docs.atlassian.com/jira-software/REST/cloud/#agile/1.0/board-createBoard
|
||||
func (s *BoardService) CreateBoard(board *Board) (*Board, *Response, error) {
|
||||
apiEndpoint := "rest/agile/1.0/board"
|
||||
req, err := s.client.NewRequest("POST", apiEndpoint, board)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
responseBoard := new(Board)
|
||||
resp, err := s.client.Do(req, responseBoard)
|
||||
if err != nil {
|
||||
jerr := NewJiraError(resp, err)
|
||||
return nil, resp, jerr
|
||||
}
|
||||
|
||||
return responseBoard, resp, nil
|
||||
}
|
||||
|
||||
// DeleteBoard will delete an agile board.
|
||||
//
|
||||
// JIRA API docs: https://docs.atlassian.com/jira-software/REST/cloud/#agile/1.0/board-deleteBoard
|
||||
func (s *BoardService) DeleteBoard(boardID int) (*Board, *Response, error) {
|
||||
apiEndpoint := fmt.Sprintf("rest/agile/1.0/board/%v", boardID)
|
||||
req, err := s.client.NewRequest("DELETE", apiEndpoint, nil)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
resp, err := s.client.Do(req, nil)
|
||||
if err != nil {
|
||||
err = NewJiraError(resp, err)
|
||||
}
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
// GetAllSprints will returns all sprints from a board, for a given board Id.
|
||||
// This only includes sprints that the user has permission to view.
|
||||
//
|
||||
// JIRA API docs: https://docs.atlassian.com/jira-software/REST/cloud/#agile/1.0/board/{boardId}/sprint
|
||||
func (s *BoardService) GetAllSprints(boardID string) ([]Sprint, *Response, error) {
|
||||
apiEndpoint := fmt.Sprintf("rest/agile/1.0/board/%s/sprint", boardID)
|
||||
req, err := s.client.NewRequest("GET", apiEndpoint, nil)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
result := new(sprintsResult)
|
||||
resp, err := s.client.Do(req, result)
|
||||
if err != nil {
|
||||
err = NewJiraError(resp, err)
|
||||
}
|
||||
|
||||
return result.Sprints, resp, err
|
||||
}
|
||||
82
vendor/github.com/andygrunwald/go-jira/error.go
generated
vendored
Normal file
82
vendor/github.com/andygrunwald/go-jira/error.go
generated
vendored
Normal file
@@ -0,0 +1,82 @@
|
||||
package jira
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
// Error message from JIRA
|
||||
// See https://docs.atlassian.com/jira/REST/cloud/#error-responses
|
||||
type Error struct {
|
||||
HTTPError error
|
||||
ErrorMessages []string `json:"errorMessages"`
|
||||
Errors map[string]string `json:"errors"`
|
||||
}
|
||||
|
||||
// NewJiraError creates a new jira Error
|
||||
func NewJiraError(resp *Response, httpError error) error {
|
||||
if resp == nil {
|
||||
return errors.Wrap(httpError, "No response returned")
|
||||
}
|
||||
|
||||
defer resp.Body.Close()
|
||||
body, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, httpError.Error())
|
||||
}
|
||||
|
||||
jerr := Error{HTTPError: httpError}
|
||||
err = json.Unmarshal(body, &jerr)
|
||||
if err != nil {
|
||||
httpError = errors.Wrap(errors.New("Could not parse JSON"), httpError.Error())
|
||||
return errors.Wrap(err, httpError.Error())
|
||||
}
|
||||
|
||||
return &jerr
|
||||
}
|
||||
|
||||
// Error is a short string representing the error
|
||||
func (e *Error) Error() string {
|
||||
if len(e.ErrorMessages) > 0 {
|
||||
// return fmt.Sprintf("%v", e.HTTPError)
|
||||
return fmt.Sprintf("%s: %v", e.ErrorMessages[0], e.HTTPError)
|
||||
}
|
||||
if len(e.Errors) > 0 {
|
||||
for key, value := range e.Errors {
|
||||
return fmt.Sprintf("%s - %s: %v", key, value, e.HTTPError)
|
||||
}
|
||||
}
|
||||
return e.HTTPError.Error()
|
||||
}
|
||||
|
||||
// LongError is a full representation of the error as a string
|
||||
func (e *Error) LongError() string {
|
||||
var msg bytes.Buffer
|
||||
if e.HTTPError != nil {
|
||||
msg.WriteString("Original:\n")
|
||||
msg.WriteString(e.HTTPError.Error())
|
||||
msg.WriteString("\n")
|
||||
}
|
||||
if len(e.ErrorMessages) > 0 {
|
||||
msg.WriteString("Messages:\n")
|
||||
for _, v := range e.ErrorMessages {
|
||||
msg.WriteString(" - ")
|
||||
msg.WriteString(v)
|
||||
msg.WriteString("\n")
|
||||
}
|
||||
}
|
||||
if len(e.Errors) > 0 {
|
||||
for key, value := range e.Errors {
|
||||
msg.WriteString(" - ")
|
||||
msg.WriteString(key)
|
||||
msg.WriteString(" - ")
|
||||
msg.WriteString(value)
|
||||
msg.WriteString("\n")
|
||||
}
|
||||
}
|
||||
return msg.String()
|
||||
}
|
||||
153
vendor/github.com/andygrunwald/go-jira/group.go
generated
vendored
Normal file
153
vendor/github.com/andygrunwald/go-jira/group.go
generated
vendored
Normal file
@@ -0,0 +1,153 @@
|
||||
package jira
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/url"
|
||||
)
|
||||
|
||||
// GroupService handles Groups for the JIRA instance / API.
|
||||
//
|
||||
// JIRA API docs: https://docs.atlassian.com/jira/REST/server/#api/2/group
|
||||
type GroupService struct {
|
||||
client *Client
|
||||
}
|
||||
|
||||
// groupMembersResult is only a small wrapper around the Group* methods
|
||||
// to be able to parse the results
|
||||
type groupMembersResult struct {
|
||||
StartAt int `json:"startAt"`
|
||||
MaxResults int `json:"maxResults"`
|
||||
Total int `json:"total"`
|
||||
Members []GroupMember `json:"values"`
|
||||
}
|
||||
|
||||
// Group represents a JIRA group
|
||||
type Group struct {
|
||||
ID string `json:"id"`
|
||||
Title string `json:"title"`
|
||||
Type string `json:"type"`
|
||||
Properties groupProperties `json:"properties"`
|
||||
AdditionalProperties bool `json:"additionalProperties"`
|
||||
}
|
||||
|
||||
type groupProperties struct {
|
||||
Name groupPropertiesName `json:"name"`
|
||||
}
|
||||
|
||||
type groupPropertiesName struct {
|
||||
Type string `json:"type"`
|
||||
}
|
||||
|
||||
// GroupMember reflects a single member of a group
|
||||
type GroupMember struct {
|
||||
Self string `json:"self,omitempty"`
|
||||
Name string `json:"name,omitempty"`
|
||||
Key string `json:"key,omitempty"`
|
||||
EmailAddress string `json:"emailAddress,omitempty"`
|
||||
DisplayName string `json:"displayName,omitempty"`
|
||||
Active bool `json:"active,omitempty"`
|
||||
TimeZone string `json:"timeZone,omitempty"`
|
||||
}
|
||||
|
||||
type GroupSearchOptions struct {
|
||||
StartAt int
|
||||
MaxResults int
|
||||
IncludeInactiveUsers bool
|
||||
}
|
||||
|
||||
// Get returns a paginated list of users who are members of the specified group and its subgroups.
|
||||
// Users in the page are ordered by user names.
|
||||
// User of this resource is required to have sysadmin or admin permissions.
|
||||
//
|
||||
// JIRA API docs: https://docs.atlassian.com/jira/REST/server/#api/2/group-getUsersFromGroup
|
||||
//
|
||||
// WARNING: This API only returns the first page of group members
|
||||
func (s *GroupService) Get(name string) ([]GroupMember, *Response, error) {
|
||||
apiEndpoint := fmt.Sprintf("/rest/api/2/group/member?groupname=%s", url.QueryEscape(name))
|
||||
req, err := s.client.NewRequest("GET", apiEndpoint, nil)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
group := new(groupMembersResult)
|
||||
resp, err := s.client.Do(req, group)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return group.Members, resp, nil
|
||||
}
|
||||
|
||||
// Get returns a paginated list of members of the specified group and its subgroups.
|
||||
// Users in the page are ordered by user names.
|
||||
// User of this resource is required to have sysadmin or admin permissions.
|
||||
//
|
||||
// JIRA API docs: https://docs.atlassian.com/jira/REST/server/#api/2/group-getUsersFromGroup
|
||||
func (s *GroupService) GetWithOptions(name string, options *GroupSearchOptions) ([]GroupMember, *Response, error) {
|
||||
var apiEndpoint string
|
||||
if options == nil {
|
||||
apiEndpoint = fmt.Sprintf("/rest/api/2/group/member?groupname=%s", url.QueryEscape(name))
|
||||
} else {
|
||||
apiEndpoint = fmt.Sprintf(
|
||||
"/rest/api/2/group/member?groupname=%s&startAt=%d&maxResults=%d&includeInactiveUsers=%t",
|
||||
url.QueryEscape(name),
|
||||
options.StartAt,
|
||||
options.MaxResults,
|
||||
options.IncludeInactiveUsers,
|
||||
)
|
||||
}
|
||||
req, err := s.client.NewRequest("GET", apiEndpoint, nil)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
group := new(groupMembersResult)
|
||||
resp, err := s.client.Do(req, group)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
return group.Members, resp, nil
|
||||
}
|
||||
|
||||
// Add adds user to group
|
||||
//
|
||||
// JIRA API docs: https://docs.atlassian.com/jira/REST/cloud/#api/2/group-addUserToGroup
|
||||
func (s *GroupService) Add(groupname string, username string) (*Group, *Response, error) {
|
||||
apiEndpoint := fmt.Sprintf("/rest/api/2/group/user?groupname=%s", groupname)
|
||||
var user struct {
|
||||
Name string `json:"name"`
|
||||
}
|
||||
user.Name = username
|
||||
req, err := s.client.NewRequest("POST", apiEndpoint, &user)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
responseGroup := new(Group)
|
||||
resp, err := s.client.Do(req, responseGroup)
|
||||
if err != nil {
|
||||
jerr := NewJiraError(resp, err)
|
||||
return nil, resp, jerr
|
||||
}
|
||||
|
||||
return responseGroup, resp, nil
|
||||
}
|
||||
|
||||
// Remove removes user from group
|
||||
//
|
||||
// JIRA API docs: https://docs.atlassian.com/jira/REST/cloud/#api/2/group-removeUserFromGroup
|
||||
func (s *GroupService) Remove(groupname string, username string) (*Response, error) {
|
||||
apiEndpoint := fmt.Sprintf("/rest/api/2/group/user?groupname=%s&username=%s", groupname, username)
|
||||
req, err := s.client.NewRequest("DELETE", apiEndpoint, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
resp, err := s.client.Do(req, nil)
|
||||
if err != nil {
|
||||
jerr := NewJiraError(resp, err)
|
||||
return resp, jerr
|
||||
}
|
||||
|
||||
return resp, nil
|
||||
}
|
||||
1100
vendor/github.com/andygrunwald/go-jira/issue.go
generated
vendored
Normal file
1100
vendor/github.com/andygrunwald/go-jira/issue.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
432
vendor/github.com/andygrunwald/go-jira/jira.go
generated
vendored
Normal file
432
vendor/github.com/andygrunwald/go-jira/jira.go
generated
vendored
Normal file
@@ -0,0 +1,432 @@
|
||||
package jira
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"reflect"
|
||||
"time"
|
||||
|
||||
"github.com/google/go-querystring/query"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
// A Client manages communication with the JIRA API.
|
||||
type Client struct {
|
||||
// HTTP client used to communicate with the API.
|
||||
client *http.Client
|
||||
|
||||
// Base URL for API requests.
|
||||
baseURL *url.URL
|
||||
|
||||
// Session storage if the user authentificate with a Session cookie
|
||||
session *Session
|
||||
|
||||
// Services used for talking to different parts of the JIRA API.
|
||||
Authentication *AuthenticationService
|
||||
Issue *IssueService
|
||||
Project *ProjectService
|
||||
Board *BoardService
|
||||
Sprint *SprintService
|
||||
User *UserService
|
||||
Group *GroupService
|
||||
Version *VersionService
|
||||
}
|
||||
|
||||
// NewClient returns a new JIRA API client.
|
||||
// If a nil httpClient is provided, http.DefaultClient will be used.
|
||||
// To use API methods which require authentication you can follow the preferred solution and
|
||||
// provide an http.Client that will perform the authentication for you with OAuth and HTTP Basic (such as that provided by the golang.org/x/oauth2 library).
|
||||
// As an alternative you can use Session Cookie based authentication provided by this package as well.
|
||||
// See https://docs.atlassian.com/jira/REST/latest/#authentication
|
||||
// baseURL is the HTTP endpoint of your JIRA instance and should always be specified with a trailing slash.
|
||||
func NewClient(httpClient *http.Client, baseURL string) (*Client, error) {
|
||||
if httpClient == nil {
|
||||
httpClient = http.DefaultClient
|
||||
}
|
||||
|
||||
parsedBaseURL, err := url.Parse(baseURL)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
c := &Client{
|
||||
client: httpClient,
|
||||
baseURL: parsedBaseURL,
|
||||
}
|
||||
c.Authentication = &AuthenticationService{client: c}
|
||||
c.Issue = &IssueService{client: c}
|
||||
c.Project = &ProjectService{client: c}
|
||||
c.Board = &BoardService{client: c}
|
||||
c.Sprint = &SprintService{client: c}
|
||||
c.User = &UserService{client: c}
|
||||
c.Group = &GroupService{client: c}
|
||||
c.Version = &VersionService{client: c}
|
||||
|
||||
return c, nil
|
||||
}
|
||||
|
||||
// NewRawRequest creates an API request.
|
||||
// A relative URL can be provided in urlStr, in which case it is resolved relative to the baseURL of the Client.
|
||||
// Relative URLs should always be specified without a preceding slash.
|
||||
// Allows using an optional native io.Reader for sourcing the request body.
|
||||
func (c *Client) NewRawRequest(method, urlStr string, body io.Reader) (*http.Request, error) {
|
||||
rel, err := url.Parse(urlStr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
u := c.baseURL.ResolveReference(rel)
|
||||
|
||||
req, err := http.NewRequest(method, u.String(), body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
req.Header.Set("Content-Type", "application/json")
|
||||
|
||||
// Set authentication information
|
||||
if c.Authentication.authType == authTypeSession {
|
||||
// Set session cookie if there is one
|
||||
if c.session != nil {
|
||||
for _, cookie := range c.session.Cookies {
|
||||
req.AddCookie(cookie)
|
||||
}
|
||||
}
|
||||
} else if c.Authentication.authType == authTypeBasic {
|
||||
// Set basic auth information
|
||||
if c.Authentication.username != "" {
|
||||
req.SetBasicAuth(c.Authentication.username, c.Authentication.password)
|
||||
}
|
||||
}
|
||||
|
||||
return req, nil
|
||||
}
|
||||
|
||||
// NewRequest creates an API request.
|
||||
// A relative URL can be provided in urlStr, in which case it is resolved relative to the baseURL of the Client.
|
||||
// Relative URLs should always be specified without a preceding slash.
|
||||
// If specified, the value pointed to by body is JSON encoded and included as the request body.
|
||||
func (c *Client) NewRequest(method, urlStr string, body interface{}) (*http.Request, error) {
|
||||
rel, err := url.Parse(urlStr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
u := c.baseURL.ResolveReference(rel)
|
||||
|
||||
var buf io.ReadWriter
|
||||
if body != nil {
|
||||
buf = new(bytes.Buffer)
|
||||
err = json.NewEncoder(buf).Encode(body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
req, err := http.NewRequest(method, u.String(), buf)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
req.Header.Set("Content-Type", "application/json")
|
||||
|
||||
// Set authentication information
|
||||
if c.Authentication.authType == authTypeSession {
|
||||
// Set session cookie if there is one
|
||||
if c.session != nil {
|
||||
for _, cookie := range c.session.Cookies {
|
||||
req.AddCookie(cookie)
|
||||
}
|
||||
}
|
||||
} else if c.Authentication.authType == authTypeBasic {
|
||||
// Set basic auth information
|
||||
if c.Authentication.username != "" {
|
||||
req.SetBasicAuth(c.Authentication.username, c.Authentication.password)
|
||||
}
|
||||
}
|
||||
|
||||
return req, nil
|
||||
}
|
||||
|
||||
// addOptions adds the parameters in opt as URL query parameters to s. opt
|
||||
// must be a struct whose fields may contain "url" tags.
|
||||
func addOptions(s string, opt interface{}) (string, error) {
|
||||
v := reflect.ValueOf(opt)
|
||||
if v.Kind() == reflect.Ptr && v.IsNil() {
|
||||
return s, nil
|
||||
}
|
||||
|
||||
u, err := url.Parse(s)
|
||||
if err != nil {
|
||||
return s, err
|
||||
}
|
||||
|
||||
qs, err := query.Values(opt)
|
||||
if err != nil {
|
||||
return s, err
|
||||
}
|
||||
|
||||
u.RawQuery = qs.Encode()
|
||||
return u.String(), nil
|
||||
}
|
||||
|
||||
// NewMultiPartRequest creates an API request including a multi-part file.
|
||||
// A relative URL can be provided in urlStr, in which case it is resolved relative to the baseURL of the Client.
|
||||
// Relative URLs should always be specified without a preceding slash.
|
||||
// If specified, the value pointed to by buf is a multipart form.
|
||||
func (c *Client) NewMultiPartRequest(method, urlStr string, buf *bytes.Buffer) (*http.Request, error) {
|
||||
rel, err := url.Parse(urlStr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
u := c.baseURL.ResolveReference(rel)
|
||||
|
||||
req, err := http.NewRequest(method, u.String(), buf)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Set required headers
|
||||
req.Header.Set("X-Atlassian-Token", "nocheck")
|
||||
|
||||
// Set authentication information
|
||||
if c.Authentication.authType == authTypeSession {
|
||||
// Set session cookie if there is one
|
||||
if c.session != nil {
|
||||
for _, cookie := range c.session.Cookies {
|
||||
req.AddCookie(cookie)
|
||||
}
|
||||
}
|
||||
} else if c.Authentication.authType == authTypeBasic {
|
||||
// Set basic auth information
|
||||
if c.Authentication.username != "" {
|
||||
req.SetBasicAuth(c.Authentication.username, c.Authentication.password)
|
||||
}
|
||||
}
|
||||
|
||||
return req, nil
|
||||
}
|
||||
|
||||
// Do sends an API request and returns the API response.
|
||||
// The API response is JSON decoded and stored in the value pointed to by v, or returned as an error if an API error has occurred.
|
||||
func (c *Client) Do(req *http.Request, v interface{}) (*Response, error) {
|
||||
httpResp, err := c.client.Do(req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = CheckResponse(httpResp)
|
||||
if err != nil {
|
||||
// Even though there was an error, we still return the response
|
||||
// in case the caller wants to inspect it further
|
||||
return newResponse(httpResp, nil), err
|
||||
}
|
||||
|
||||
if v != nil {
|
||||
// Open a NewDecoder and defer closing the reader only if there is a provided interface to decode to
|
||||
defer httpResp.Body.Close()
|
||||
err = json.NewDecoder(httpResp.Body).Decode(v)
|
||||
}
|
||||
|
||||
resp := newResponse(httpResp, v)
|
||||
return resp, err
|
||||
}
|
||||
|
||||
// CheckResponse checks the API response for errors, and returns them if present.
|
||||
// A response is considered an error if it has a status code outside the 200 range.
|
||||
// The caller is responsible to analyze the response body.
|
||||
// The body can contain JSON (if the error is intended) or xml (sometimes JIRA just failes).
|
||||
func CheckResponse(r *http.Response) error {
|
||||
if c := r.StatusCode; 200 <= c && c <= 299 {
|
||||
return nil
|
||||
}
|
||||
|
||||
err := fmt.Errorf("Request failed. Please analyze the request body for more details. Status code: %d", r.StatusCode)
|
||||
return err
|
||||
}
|
||||
|
||||
// GetBaseURL will return you the Base URL.
|
||||
// This is the same URL as in the NewClient constructor
|
||||
func (c *Client) GetBaseURL() url.URL {
|
||||
return *c.baseURL
|
||||
}
|
||||
|
||||
// Response represents JIRA API response. It wraps http.Response returned from
|
||||
// API and provides information about paging.
|
||||
type Response struct {
|
||||
*http.Response
|
||||
|
||||
StartAt int
|
||||
MaxResults int
|
||||
Total int
|
||||
}
|
||||
|
||||
func newResponse(r *http.Response, v interface{}) *Response {
|
||||
resp := &Response{Response: r}
|
||||
resp.populatePageValues(v)
|
||||
return resp
|
||||
}
|
||||
|
||||
// Sets paging values if response json was parsed to searchResult type
|
||||
// (can be extended with other types if they also need paging info)
|
||||
func (r *Response) populatePageValues(v interface{}) {
|
||||
switch value := v.(type) {
|
||||
case *searchResult:
|
||||
r.StartAt = value.StartAt
|
||||
r.MaxResults = value.MaxResults
|
||||
r.Total = value.Total
|
||||
case *groupMembersResult:
|
||||
r.StartAt = value.StartAt
|
||||
r.MaxResults = value.MaxResults
|
||||
r.Total = value.Total
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// BasicAuthTransport is an http.RoundTripper that authenticates all requests
|
||||
// using HTTP Basic Authentication with the provided username and password.
|
||||
type BasicAuthTransport struct {
|
||||
Username string
|
||||
Password string
|
||||
|
||||
// Transport is the underlying HTTP transport to use when making requests.
|
||||
// It will default to http.DefaultTransport if nil.
|
||||
Transport http.RoundTripper
|
||||
}
|
||||
|
||||
// RoundTrip implements the RoundTripper interface. We just add the
|
||||
// basic auth and return the RoundTripper for this transport type.
|
||||
func (t *BasicAuthTransport) RoundTrip(req *http.Request) (*http.Response, error) {
|
||||
req2 := cloneRequest(req) // per RoundTripper contract
|
||||
|
||||
req2.SetBasicAuth(t.Username, t.Password)
|
||||
return t.transport().RoundTrip(req2)
|
||||
}
|
||||
|
||||
// Client returns an *http.Client that makes requests that are authenticated
|
||||
// using HTTP Basic Authentication. This is a nice little bit of sugar
|
||||
// so we can just get the client instead of creating the client in the calling code.
|
||||
// If it's necessary to send more information on client init, the calling code can
|
||||
// always skip this and set the transport itself.
|
||||
func (t *BasicAuthTransport) Client() *http.Client {
|
||||
return &http.Client{Transport: t}
|
||||
}
|
||||
|
||||
func (t *BasicAuthTransport) transport() http.RoundTripper {
|
||||
if t.Transport != nil {
|
||||
return t.Transport
|
||||
}
|
||||
return http.DefaultTransport
|
||||
}
|
||||
|
||||
// CookieAuthTransport is an http.RoundTripper that authenticates all requests
|
||||
// using Jira's cookie-based authentication.
|
||||
//
|
||||
// Note that it is generally preferrable to use HTTP BASIC authentication with the REST API.
|
||||
// However, this resource may be used to mimic the behaviour of JIRA's log-in page (e.g. to display log-in errors to a user).
|
||||
//
|
||||
// JIRA API docs: https://docs.atlassian.com/jira/REST/latest/#auth/1/session
|
||||
type CookieAuthTransport struct {
|
||||
Username string
|
||||
Password string
|
||||
AuthURL string
|
||||
|
||||
// SessionObject is the authenticated cookie string.s
|
||||
// It's passed in each call to prove the client is authenticated.
|
||||
SessionObject []*http.Cookie
|
||||
|
||||
// Transport is the underlying HTTP transport to use when making requests.
|
||||
// It will default to http.DefaultTransport if nil.
|
||||
Transport http.RoundTripper
|
||||
}
|
||||
|
||||
// RoundTrip adds the session object to the request.
|
||||
func (t *CookieAuthTransport) RoundTrip(req *http.Request) (*http.Response, error) {
|
||||
if t.SessionObject == nil {
|
||||
err := t.setSessionObject()
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "cookieauth: no session object has been set")
|
||||
}
|
||||
}
|
||||
|
||||
req2 := cloneRequest(req) // per RoundTripper contract
|
||||
for _, cookie := range t.SessionObject {
|
||||
req2.AddCookie(cookie)
|
||||
}
|
||||
|
||||
return t.transport().RoundTrip(req2)
|
||||
}
|
||||
|
||||
// Client returns an *http.Client that makes requests that are authenticated
|
||||
// using cookie authentication
|
||||
func (t *CookieAuthTransport) Client() *http.Client {
|
||||
return &http.Client{Transport: t}
|
||||
}
|
||||
|
||||
// setSessionObject attempts to authenticate the user and set
|
||||
// the session object (e.g. cookie)
|
||||
func (t *CookieAuthTransport) setSessionObject() error {
|
||||
req, err := t.buildAuthRequest()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var authClient = &http.Client{
|
||||
Timeout: time.Second * 60,
|
||||
}
|
||||
resp, err := authClient.Do(req)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
t.SessionObject = resp.Cookies()
|
||||
return nil
|
||||
}
|
||||
|
||||
// getAuthRequest assembles the request to get the authenticated cookie
|
||||
func (t *CookieAuthTransport) buildAuthRequest() (*http.Request, error) {
|
||||
body := struct {
|
||||
Username string `json:"username"`
|
||||
Password string `json:"password"`
|
||||
}{
|
||||
t.Username,
|
||||
t.Password,
|
||||
}
|
||||
|
||||
b := new(bytes.Buffer)
|
||||
json.NewEncoder(b).Encode(body)
|
||||
|
||||
req, err := http.NewRequest("POST", t.AuthURL, b)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
req.Header.Set("Content-Type", "application/json")
|
||||
return req, nil
|
||||
}
|
||||
|
||||
func (t *CookieAuthTransport) transport() http.RoundTripper {
|
||||
if t.Transport != nil {
|
||||
return t.Transport
|
||||
}
|
||||
return http.DefaultTransport
|
||||
}
|
||||
|
||||
// cloneRequest returns a clone of the provided *http.Request.
|
||||
// The clone is a shallow copy of the struct and its Header map.
|
||||
func cloneRequest(r *http.Request) *http.Request {
|
||||
// shallow copy of the struct
|
||||
r2 := new(http.Request)
|
||||
*r2 = *r
|
||||
// deep copy of the Header
|
||||
r2.Header = make(http.Header, len(r.Header))
|
||||
for k, s := range r.Header {
|
||||
r2.Header[k] = append([]string(nil), s...)
|
||||
}
|
||||
return r2
|
||||
}
|
||||
194
vendor/github.com/andygrunwald/go-jira/metaissue.go
generated
vendored
Normal file
194
vendor/github.com/andygrunwald/go-jira/metaissue.go
generated
vendored
Normal file
@@ -0,0 +1,194 @@
|
||||
package jira
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/google/go-querystring/query"
|
||||
"github.com/trivago/tgo/tcontainer"
|
||||
)
|
||||
|
||||
// CreateMetaInfo contains information about fields and their attributed to create a ticket.
|
||||
type CreateMetaInfo struct {
|
||||
Expand string `json:"expand,omitempty"`
|
||||
Projects []*MetaProject `json:"projects,omitempty"`
|
||||
}
|
||||
|
||||
// MetaProject is the meta information about a project returned from createmeta api
|
||||
type MetaProject struct {
|
||||
Expand string `json:"expand,omitempty"`
|
||||
Self string `json:"self,omitempty"`
|
||||
Id string `json:"id,omitempty"`
|
||||
Key string `json:"key,omitempty"`
|
||||
Name string `json:"name,omitempty"`
|
||||
// omitted avatarUrls
|
||||
IssueTypes []*MetaIssueType `json:"issuetypes,omitempty"`
|
||||
}
|
||||
|
||||
// MetaIssueType represents the different issue types a project has.
|
||||
//
|
||||
// Note: Fields is interface because this is an object which can
|
||||
// have arbitraty keys related to customfields. It is not possible to
|
||||
// expect these for a general way. This will be returning a map.
|
||||
// Further processing must be done depending on what is required.
|
||||
type MetaIssueType struct {
|
||||
Self string `json:"self,omitempty"`
|
||||
Id string `json:"id,omitempty"`
|
||||
Description string `json:"description,omitempty"`
|
||||
IconUrl string `json:"iconurl,omitempty"`
|
||||
Name string `json:"name,omitempty"`
|
||||
Subtasks bool `json:"subtask,omitempty"`
|
||||
Expand string `json:"expand,omitempty"`
|
||||
Fields tcontainer.MarshalMap `json:"fields,omitempty"`
|
||||
}
|
||||
|
||||
// GetCreateMeta makes the api call to get the meta information required to create a ticket
|
||||
func (s *IssueService) GetCreateMeta(projectkeys string) (*CreateMetaInfo, *Response, error) {
|
||||
return s.GetCreateMetaWithOptions(&GetQueryOptions{ProjectKeys: projectkeys, Expand: "projects.issuetypes.fields"})
|
||||
}
|
||||
|
||||
// GetCreateMetaWithOptions makes the api call to get the meta information without requiring to have a projectKey
|
||||
func (s *IssueService) GetCreateMetaWithOptions(options *GetQueryOptions) (*CreateMetaInfo, *Response, error) {
|
||||
apiEndpoint := "rest/api/2/issue/createmeta"
|
||||
|
||||
req, err := s.client.NewRequest("GET", apiEndpoint, nil)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
if options != nil {
|
||||
q, err := query.Values(options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
req.URL.RawQuery = q.Encode()
|
||||
}
|
||||
|
||||
meta := new(CreateMetaInfo)
|
||||
resp, err := s.client.Do(req, meta)
|
||||
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return meta, resp, nil
|
||||
}
|
||||
|
||||
// GetProjectWithName returns a project with "name" from the meta information received. If not found, this returns nil.
|
||||
// The comparison of the name is case insensitive.
|
||||
func (m *CreateMetaInfo) GetProjectWithName(name string) *MetaProject {
|
||||
for _, m := range m.Projects {
|
||||
if strings.ToLower(m.Name) == strings.ToLower(name) {
|
||||
return m
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetProjectWithKey returns a project with "name" from the meta information received. If not found, this returns nil.
|
||||
// The comparison of the name is case insensitive.
|
||||
func (m *CreateMetaInfo) GetProjectWithKey(key string) *MetaProject {
|
||||
for _, m := range m.Projects {
|
||||
if strings.ToLower(m.Key) == strings.ToLower(key) {
|
||||
return m
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetIssueTypeWithName returns an IssueType with name from a given MetaProject. If not found, this returns nil.
|
||||
// The comparison of the name is case insensitive
|
||||
func (p *MetaProject) GetIssueTypeWithName(name string) *MetaIssueType {
|
||||
for _, m := range p.IssueTypes {
|
||||
if strings.ToLower(m.Name) == strings.ToLower(name) {
|
||||
return m
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetMandatoryFields returns a map of all the required fields from the MetaIssueTypes.
|
||||
// if a field returned by the api was:
|
||||
// "customfield_10806": {
|
||||
// "required": true,
|
||||
// "schema": {
|
||||
// "type": "any",
|
||||
// "custom": "com.pyxis.greenhopper.jira:gh-epic-link",
|
||||
// "customId": 10806
|
||||
// },
|
||||
// "name": "Epic Link",
|
||||
// "hasDefaultValue": false,
|
||||
// "operations": [
|
||||
// "set"
|
||||
// ]
|
||||
// }
|
||||
// the returned map would have "Epic Link" as the key and "customfield_10806" as value.
|
||||
// This choice has been made so that the it is easier to generate the create api request later.
|
||||
func (t *MetaIssueType) GetMandatoryFields() (map[string]string, error) {
|
||||
ret := make(map[string]string)
|
||||
for key := range t.Fields {
|
||||
required, err := t.Fields.Bool(key + "/required")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if required {
|
||||
name, err := t.Fields.String(key + "/name")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ret[name] = key
|
||||
}
|
||||
}
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
// GetAllFields returns a map of all the fields for an IssueType. This includes all required and not required.
|
||||
// The key of the returned map is what you see in the form and the value is how it is representated in the jira schema.
|
||||
func (t *MetaIssueType) GetAllFields() (map[string]string, error) {
|
||||
ret := make(map[string]string)
|
||||
for key := range t.Fields {
|
||||
|
||||
name, err := t.Fields.String(key + "/name")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ret[name] = key
|
||||
}
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
// CheckCompleteAndAvailable checks if the given fields satisfies the mandatory field required to create a issue for the given type
|
||||
// And also if the given fields are available.
|
||||
func (t *MetaIssueType) CheckCompleteAndAvailable(config map[string]string) (bool, error) {
|
||||
mandatory, err := t.GetMandatoryFields()
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
all, err := t.GetAllFields()
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
// check templateconfig against mandatory fields
|
||||
for key := range mandatory {
|
||||
if _, okay := config[key]; !okay {
|
||||
var requiredFields []string
|
||||
for name := range mandatory {
|
||||
requiredFields = append(requiredFields, name)
|
||||
}
|
||||
return false, fmt.Errorf("Required field not found in provided jira.fields. Required are: %#v", requiredFields)
|
||||
}
|
||||
}
|
||||
|
||||
// check templateConfig against all fields to verify they are available
|
||||
for key := range config {
|
||||
if _, okay := all[key]; !okay {
|
||||
var availableFields []string
|
||||
for name := range all {
|
||||
availableFields = append(availableFields, name)
|
||||
}
|
||||
return false, fmt.Errorf("Fields in jira.fields are not available in jira. Available are: %#v", availableFields)
|
||||
}
|
||||
}
|
||||
|
||||
return true, nil
|
||||
}
|
||||
162
vendor/github.com/andygrunwald/go-jira/project.go
generated
vendored
Normal file
162
vendor/github.com/andygrunwald/go-jira/project.go
generated
vendored
Normal file
@@ -0,0 +1,162 @@
|
||||
package jira
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/google/go-querystring/query"
|
||||
)
|
||||
|
||||
// ProjectService handles projects for the JIRA instance / API.
|
||||
//
|
||||
// JIRA API docs: https://docs.atlassian.com/jira/REST/latest/#api/2/project
|
||||
type ProjectService struct {
|
||||
client *Client
|
||||
}
|
||||
|
||||
// ProjectList represent a list of Projects
|
||||
type ProjectList []struct {
|
||||
Expand string `json:"expand" structs:"expand"`
|
||||
Self string `json:"self" structs:"self"`
|
||||
ID string `json:"id" structs:"id"`
|
||||
Key string `json:"key" structs:"key"`
|
||||
Name string `json:"name" structs:"name"`
|
||||
AvatarUrls AvatarUrls `json:"avatarUrls" structs:"avatarUrls"`
|
||||
ProjectTypeKey string `json:"projectTypeKey" structs:"projectTypeKey"`
|
||||
ProjectCategory ProjectCategory `json:"projectCategory,omitempty" structs:"projectsCategory,omitempty"`
|
||||
IssueTypes []IssueType `json:"issueTypes,omitempty" structs:"issueTypes,omitempty"`
|
||||
}
|
||||
|
||||
// ProjectCategory represents a single project category
|
||||
type ProjectCategory struct {
|
||||
Self string `json:"self" structs:"self,omitempty"`
|
||||
ID string `json:"id" structs:"id,omitempty"`
|
||||
Name string `json:"name" structs:"name,omitempty"`
|
||||
Description string `json:"description" structs:"description,omitempty"`
|
||||
}
|
||||
|
||||
// Project represents a JIRA Project.
|
||||
type Project struct {
|
||||
Expand string `json:"expand,omitempty" structs:"expand,omitempty"`
|
||||
Self string `json:"self,omitempty" structs:"self,omitempty"`
|
||||
ID string `json:"id,omitempty" structs:"id,omitempty"`
|
||||
Key string `json:"key,omitempty" structs:"key,omitempty"`
|
||||
Description string `json:"description,omitempty" structs:"description,omitempty"`
|
||||
Lead User `json:"lead,omitempty" structs:"lead,omitempty"`
|
||||
Components []ProjectComponent `json:"components,omitempty" structs:"components,omitempty"`
|
||||
IssueTypes []IssueType `json:"issueTypes,omitempty" structs:"issueTypes,omitempty"`
|
||||
URL string `json:"url,omitempty" structs:"url,omitempty"`
|
||||
Email string `json:"email,omitempty" structs:"email,omitempty"`
|
||||
AssigneeType string `json:"assigneeType,omitempty" structs:"assigneeType,omitempty"`
|
||||
Versions []Version `json:"versions,omitempty" structs:"versions,omitempty"`
|
||||
Name string `json:"name,omitempty" structs:"name,omitempty"`
|
||||
Roles struct {
|
||||
Developers string `json:"Developers,omitempty" structs:"Developers,omitempty"`
|
||||
} `json:"roles,omitempty" structs:"roles,omitempty"`
|
||||
AvatarUrls AvatarUrls `json:"avatarUrls,omitempty" structs:"avatarUrls,omitempty"`
|
||||
ProjectCategory ProjectCategory `json:"projectCategory,omitempty" structs:"projectCategory,omitempty"`
|
||||
}
|
||||
|
||||
// ProjectComponent represents a single component of a project
|
||||
type ProjectComponent struct {
|
||||
Self string `json:"self" structs:"self,omitempty"`
|
||||
ID string `json:"id" structs:"id,omitempty"`
|
||||
Name string `json:"name" structs:"name,omitempty"`
|
||||
Description string `json:"description" structs:"description,omitempty"`
|
||||
Lead User `json:"lead,omitempty" structs:"lead,omitempty"`
|
||||
AssigneeType string `json:"assigneeType" structs:"assigneeType,omitempty"`
|
||||
Assignee User `json:"assignee" structs:"assignee,omitempty"`
|
||||
RealAssigneeType string `json:"realAssigneeType" structs:"realAssigneeType,omitempty"`
|
||||
RealAssignee User `json:"realAssignee" structs:"realAssignee,omitempty"`
|
||||
IsAssigneeTypeValid bool `json:"isAssigneeTypeValid" structs:"isAssigneeTypeValid,omitempty"`
|
||||
Project string `json:"project" structs:"project,omitempty"`
|
||||
ProjectID int `json:"projectId" structs:"projectId,omitempty"`
|
||||
}
|
||||
|
||||
// PermissionScheme represents the permission scheme for the project
|
||||
type PermissionScheme struct {
|
||||
Expand string `json:"expand" structs:"expand,omitempty"`
|
||||
Self string `json:"self" structs:"self,omitempty"`
|
||||
ID int `json:"id" structs:"id,omitempty"`
|
||||
Name string `json:"name" structs:"name,omitempty"`
|
||||
Description string `json:"description" structs:"description,omitempty"`
|
||||
}
|
||||
|
||||
// GetList gets all projects form JIRA
|
||||
//
|
||||
// JIRA API docs: https://docs.atlassian.com/jira/REST/latest/#api/2/project-getAllProjects
|
||||
func (s *ProjectService) GetList() (*ProjectList, *Response, error) {
|
||||
return s.ListWithOptions(&GetQueryOptions{})
|
||||
}
|
||||
|
||||
// ListWithOptions gets all projects form JIRA with optional query params, like &GetQueryOptions{Expand: "issueTypes"} to get
|
||||
// a list of all projects and their supported issuetypes
|
||||
//
|
||||
// JIRA API docs: https://docs.atlassian.com/jira/REST/latest/#api/2/project-getAllProjects
|
||||
func (s *ProjectService) ListWithOptions(options *GetQueryOptions) (*ProjectList, *Response, error) {
|
||||
apiEndpoint := "rest/api/2/project"
|
||||
req, err := s.client.NewRequest("GET", apiEndpoint, nil)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
if options != nil {
|
||||
q, err := query.Values(options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
req.URL.RawQuery = q.Encode()
|
||||
}
|
||||
|
||||
projectList := new(ProjectList)
|
||||
resp, err := s.client.Do(req, projectList)
|
||||
if err != nil {
|
||||
jerr := NewJiraError(resp, err)
|
||||
return nil, resp, jerr
|
||||
}
|
||||
|
||||
return projectList, resp, nil
|
||||
}
|
||||
|
||||
// Get returns a full representation of the project for the given issue key.
|
||||
// JIRA will attempt to identify the project by the projectIdOrKey path parameter.
|
||||
// This can be an project id, or an project key.
|
||||
//
|
||||
// JIRA API docs: https://docs.atlassian.com/jira/REST/latest/#api/2/project-getProject
|
||||
func (s *ProjectService) Get(projectID string) (*Project, *Response, error) {
|
||||
apiEndpoint := fmt.Sprintf("rest/api/2/project/%s", projectID)
|
||||
req, err := s.client.NewRequest("GET", apiEndpoint, nil)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
project := new(Project)
|
||||
resp, err := s.client.Do(req, project)
|
||||
if err != nil {
|
||||
jerr := NewJiraError(resp, err)
|
||||
return nil, resp, jerr
|
||||
}
|
||||
|
||||
return project, resp, nil
|
||||
}
|
||||
|
||||
// GetPermissionScheme returns a full representation of the permission scheme for the project
|
||||
// JIRA will attempt to identify the project by the projectIdOrKey path parameter.
|
||||
// This can be an project id, or an project key.
|
||||
//
|
||||
// JIRA API docs: https://docs.atlassian.com/jira/REST/latest/#api/2/project-getProject
|
||||
func (s *ProjectService) GetPermissionScheme(projectID string) (*PermissionScheme, *Response, error) {
|
||||
apiEndpoint := fmt.Sprintf("/rest/api/2/project/%s/permissionscheme", projectID)
|
||||
req, err := s.client.NewRequest("GET", apiEndpoint, nil)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
ps := new(PermissionScheme)
|
||||
resp, err := s.client.Do(req, ps)
|
||||
if err != nil {
|
||||
jerr := NewJiraError(resp, err)
|
||||
return nil, resp, jerr
|
||||
}
|
||||
|
||||
return ps, resp, nil
|
||||
}
|
||||
106
vendor/github.com/andygrunwald/go-jira/sprint.go
generated
vendored
Normal file
106
vendor/github.com/andygrunwald/go-jira/sprint.go
generated
vendored
Normal file
@@ -0,0 +1,106 @@
|
||||
package jira
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/google/go-querystring/query"
|
||||
)
|
||||
|
||||
// SprintService handles sprints in JIRA Agile API.
|
||||
// See https://docs.atlassian.com/jira-software/REST/cloud/
|
||||
type SprintService struct {
|
||||
client *Client
|
||||
}
|
||||
|
||||
// IssuesWrapper represents a wrapper struct for moving issues to sprint
|
||||
type IssuesWrapper struct {
|
||||
Issues []string `json:"issues"`
|
||||
}
|
||||
|
||||
// IssuesInSprintResult represents a wrapper struct for search result
|
||||
type IssuesInSprintResult struct {
|
||||
Issues []Issue `json:"issues"`
|
||||
}
|
||||
|
||||
// MoveIssuesToSprint moves issues to a sprint, for a given sprint Id.
|
||||
// Issues can only be moved to open or active sprints.
|
||||
// The maximum number of issues that can be moved in one operation is 50.
|
||||
//
|
||||
// JIRA API docs: https://docs.atlassian.com/jira-software/REST/cloud/#agile/1.0/sprint-moveIssuesToSprint
|
||||
func (s *SprintService) MoveIssuesToSprint(sprintID int, issueIDs []string) (*Response, error) {
|
||||
apiEndpoint := fmt.Sprintf("rest/agile/1.0/sprint/%d/issue", sprintID)
|
||||
|
||||
payload := IssuesWrapper{Issues: issueIDs}
|
||||
|
||||
req, err := s.client.NewRequest("POST", apiEndpoint, payload)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
resp, err := s.client.Do(req, nil)
|
||||
if err != nil {
|
||||
err = NewJiraError(resp, err)
|
||||
}
|
||||
return resp, err
|
||||
}
|
||||
|
||||
// GetIssuesForSprint returns all issues in a sprint, for a given sprint Id.
|
||||
// This only includes issues that the user has permission to view.
|
||||
// By default, the returned issues are ordered by rank.
|
||||
//
|
||||
// JIRA API Docs: https://docs.atlassian.com/jira-software/REST/cloud/#agile/1.0/sprint-getIssuesForSprint
|
||||
func (s *SprintService) GetIssuesForSprint(sprintID int) ([]Issue, *Response, error) {
|
||||
apiEndpoint := fmt.Sprintf("rest/agile/1.0/sprint/%d/issue", sprintID)
|
||||
|
||||
req, err := s.client.NewRequest("GET", apiEndpoint, nil)
|
||||
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
result := new(IssuesInSprintResult)
|
||||
resp, err := s.client.Do(req, result)
|
||||
if err != nil {
|
||||
err = NewJiraError(resp, err)
|
||||
}
|
||||
|
||||
return result.Issues, resp, err
|
||||
}
|
||||
|
||||
// Get returns a full representation of the issue for the given issue key.
|
||||
// JIRA will attempt to identify the issue by the issueIdOrKey path parameter.
|
||||
// This can be an issue id, or an issue key.
|
||||
// If the issue cannot be found via an exact match, JIRA will also look for the issue in a case-insensitive way, or by looking to see if the issue was moved.
|
||||
//
|
||||
// The given options will be appended to the query string
|
||||
//
|
||||
// JIRA API docs: https://docs.atlassian.com/jira-software/REST/7.3.1/#agile/1.0/issue-getIssue
|
||||
//
|
||||
// TODO: create agile service for holding all agile apis' implementation
|
||||
func (s *SprintService) GetIssue(issueID string, options *GetQueryOptions) (*Issue, *Response, error) {
|
||||
apiEndpoint := fmt.Sprintf("rest/agile/1.0/issue/%s", issueID)
|
||||
|
||||
req, err := s.client.NewRequest("GET", apiEndpoint, nil)
|
||||
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
if options != nil {
|
||||
q, err := query.Values(options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
req.URL.RawQuery = q.Encode()
|
||||
}
|
||||
|
||||
issue := new(Issue)
|
||||
resp, err := s.client.Do(req, issue)
|
||||
|
||||
if err != nil {
|
||||
jerr := NewJiraError(resp, err)
|
||||
return nil, resp, jerr
|
||||
}
|
||||
|
||||
return issue, resp, nil
|
||||
}
|
||||
119
vendor/github.com/andygrunwald/go-jira/user.go
generated
vendored
Normal file
119
vendor/github.com/andygrunwald/go-jira/user.go
generated
vendored
Normal file
@@ -0,0 +1,119 @@
|
||||
package jira
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
)
|
||||
|
||||
// UserService handles users for the JIRA instance / API.
|
||||
//
|
||||
// JIRA API docs: https://docs.atlassian.com/jira/REST/cloud/#api/2/user
|
||||
type UserService struct {
|
||||
client *Client
|
||||
}
|
||||
|
||||
// User represents a JIRA user.
|
||||
type User struct {
|
||||
Self string `json:"self,omitempty" structs:"self,omitempty"`
|
||||
Name string `json:"name,omitempty" structs:"name,omitempty"`
|
||||
Password string `json:"-"`
|
||||
Key string `json:"key,omitempty" structs:"key,omitempty"`
|
||||
EmailAddress string `json:"emailAddress,omitempty" structs:"emailAddress,omitempty"`
|
||||
AvatarUrls AvatarUrls `json:"avatarUrls,omitempty" structs:"avatarUrls,omitempty"`
|
||||
DisplayName string `json:"displayName,omitempty" structs:"displayName,omitempty"`
|
||||
Active bool `json:"active,omitempty" structs:"active,omitempty"`
|
||||
TimeZone string `json:"timeZone,omitempty" structs:"timeZone,omitempty"`
|
||||
ApplicationKeys []string `json:"applicationKeys,omitempty" structs:"applicationKeys,omitempty"`
|
||||
}
|
||||
|
||||
// UserGroup represents the group list
|
||||
type UserGroup struct {
|
||||
Self string `json:"self,omitempty" structs:"self,omitempty"`
|
||||
Name string `json:"name,omitempty" structs:"name,omitempty"`
|
||||
}
|
||||
|
||||
// Get gets user info from JIRA
|
||||
//
|
||||
// JIRA API docs: https://docs.atlassian.com/jira/REST/cloud/#api/2/user-getUser
|
||||
func (s *UserService) Get(username string) (*User, *Response, error) {
|
||||
apiEndpoint := fmt.Sprintf("/rest/api/2/user?username=%s", username)
|
||||
req, err := s.client.NewRequest("GET", apiEndpoint, nil)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
user := new(User)
|
||||
resp, err := s.client.Do(req, user)
|
||||
if err != nil {
|
||||
return nil, resp, NewJiraError(resp, err)
|
||||
}
|
||||
return user, resp, nil
|
||||
}
|
||||
|
||||
// Create creates an user in JIRA.
|
||||
//
|
||||
// JIRA API docs: https://docs.atlassian.com/jira/REST/cloud/#api/2/user-createUser
|
||||
func (s *UserService) Create(user *User) (*User, *Response, error) {
|
||||
apiEndpoint := "/rest/api/2/user"
|
||||
req, err := s.client.NewRequest("POST", apiEndpoint, user)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
resp, err := s.client.Do(req, nil)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
responseUser := new(User)
|
||||
defer resp.Body.Close()
|
||||
data, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
e := fmt.Errorf("Could not read the returned data")
|
||||
return nil, resp, NewJiraError(resp, e)
|
||||
}
|
||||
err = json.Unmarshal(data, responseUser)
|
||||
if err != nil {
|
||||
e := fmt.Errorf("Could not unmarshall the data into struct")
|
||||
return nil, resp, NewJiraError(resp, e)
|
||||
}
|
||||
return responseUser, resp, nil
|
||||
}
|
||||
|
||||
// GetGroups returns the groups which the user belongs to
|
||||
//
|
||||
// JIRA API docs: https://docs.atlassian.com/jira/REST/cloud/#api/2/user-getUserGroups
|
||||
func (s *UserService) GetGroups(username string) (*[]UserGroup, *Response, error) {
|
||||
apiEndpoint := fmt.Sprintf("/rest/api/2/user/groups?username=%s", username)
|
||||
req, err := s.client.NewRequest("GET", apiEndpoint, nil)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
userGroups := new([]UserGroup)
|
||||
resp, err := s.client.Do(req, userGroups)
|
||||
if err != nil {
|
||||
return nil, resp, NewJiraError(resp, err)
|
||||
}
|
||||
return userGroups, resp, nil
|
||||
}
|
||||
|
||||
// Find searches for user info from JIRA:
|
||||
// It can find users by email, username or name
|
||||
//
|
||||
// JIRA API docs: https://docs.atlassian.com/jira/REST/cloud/#api/2/user-findUsers
|
||||
func (s *UserService) Find(property string) ([]User, *Response, error) {
|
||||
apiEndpoint := fmt.Sprintf("/rest/api/2/user/search?username=%s", property)
|
||||
req, err := s.client.NewRequest("GET", apiEndpoint, nil)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
users := []User{}
|
||||
resp, err := s.client.Do(req, &users)
|
||||
if err != nil {
|
||||
return nil, resp, NewJiraError(resp, err)
|
||||
}
|
||||
return users, resp, nil
|
||||
}
|
||||
96
vendor/github.com/andygrunwald/go-jira/version.go
generated
vendored
Normal file
96
vendor/github.com/andygrunwald/go-jira/version.go
generated
vendored
Normal file
@@ -0,0 +1,96 @@
|
||||
package jira
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
)
|
||||
|
||||
// VersionService handles Versions for the JIRA instance / API.
|
||||
//
|
||||
// JIRA API docs: https://docs.atlassian.com/jira/REST/latest/#api/2/version
|
||||
type VersionService struct {
|
||||
client *Client
|
||||
}
|
||||
|
||||
// Version represents a single release version of a project
|
||||
type Version struct {
|
||||
Self string `json:"self,omitempty" structs:"self,omitempty"`
|
||||
ID string `json:"id,omitempty" structs:"id,omitempty"`
|
||||
Name string `json:"name,omitempty" structs:"name,omitempty"`
|
||||
Description string `json:"description,omitempty" structs:"name,omitempty"`
|
||||
Archived bool `json:"archived,omitempty" structs:"archived,omitempty"`
|
||||
Released bool `json:"released,omitempty" structs:"released,omitempty"`
|
||||
ReleaseDate string `json:"releaseDate,omitempty" structs:"releaseDate,omitempty"`
|
||||
UserReleaseDate string `json:"userReleaseDate,omitempty" structs:"userReleaseDate,omitempty"`
|
||||
ProjectID int `json:"projectId,omitempty" structs:"projectId,omitempty"` // Unlike other IDs, this is returned as a number
|
||||
}
|
||||
|
||||
// Get gets version info from JIRA
|
||||
//
|
||||
// JIRA API docs: https://developer.atlassian.com/cloud/jira/platform/rest/#api-api-2-version-id-get
|
||||
func (s *VersionService) Get(versionID int) (*Version, *Response, error) {
|
||||
apiEndpoint := fmt.Sprintf("/rest/api/2/version/%v", versionID)
|
||||
req, err := s.client.NewRequest("GET", apiEndpoint, nil)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
version := new(Version)
|
||||
resp, err := s.client.Do(req, version)
|
||||
if err != nil {
|
||||
return nil, resp, NewJiraError(resp, err)
|
||||
}
|
||||
return version, resp, nil
|
||||
}
|
||||
|
||||
// Create creates a version in JIRA.
|
||||
//
|
||||
// JIRA API docs: https://developer.atlassian.com/cloud/jira/platform/rest/#api-api-2-version-post
|
||||
func (s *VersionService) Create(version *Version) (*Version, *Response, error) {
|
||||
apiEndpoint := "/rest/api/2/version"
|
||||
req, err := s.client.NewRequest("POST", apiEndpoint, version)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
resp, err := s.client.Do(req, nil)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
responseVersion := new(Version)
|
||||
defer resp.Body.Close()
|
||||
data, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
e := fmt.Errorf("Could not read the returned data")
|
||||
return nil, resp, NewJiraError(resp, e)
|
||||
}
|
||||
err = json.Unmarshal(data, responseVersion)
|
||||
if err != nil {
|
||||
e := fmt.Errorf("Could not unmarshall the data into struct")
|
||||
return nil, resp, NewJiraError(resp, e)
|
||||
}
|
||||
return responseVersion, resp, nil
|
||||
}
|
||||
|
||||
// Update updates a version from a JSON representation.
|
||||
//
|
||||
// JIRA API docs: https://developer.atlassian.com/cloud/jira/platform/rest/#api-api-2-version-id-put
|
||||
func (s *VersionService) Update(version *Version) (*Version, *Response, error) {
|
||||
apiEndpoint := fmt.Sprintf("rest/api/2/version/%v", version.ID)
|
||||
req, err := s.client.NewRequest("PUT", apiEndpoint, version)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
resp, err := s.client.Do(req, nil)
|
||||
if err != nil {
|
||||
jerr := NewJiraError(resp, err)
|
||||
return nil, resp, jerr
|
||||
}
|
||||
|
||||
// This is just to follow the rest of the API's convention of returning a version.
|
||||
// Returning the same pointer here is pointless, so we return a copy instead.
|
||||
ret := *version
|
||||
return &ret, resp, nil
|
||||
}
|
||||
23
vendor/github.com/fatih/structs/.gitignore
generated
vendored
Normal file
23
vendor/github.com/fatih/structs/.gitignore
generated
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
# Compiled Object files, Static and Dynamic libs (Shared Objects)
|
||||
*.o
|
||||
*.a
|
||||
*.so
|
||||
|
||||
# Folders
|
||||
_obj
|
||||
_test
|
||||
|
||||
# Architecture specific extensions/prefixes
|
||||
*.[568vq]
|
||||
[568vq].out
|
||||
|
||||
*.cgo1.go
|
||||
*.cgo2.c
|
||||
_cgo_defun.c
|
||||
_cgo_gotypes.go
|
||||
_cgo_export.*
|
||||
|
||||
_testmain.go
|
||||
|
||||
*.exe
|
||||
*.test
|
||||
11
vendor/github.com/fatih/structs/.travis.yml
generated
vendored
Normal file
11
vendor/github.com/fatih/structs/.travis.yml
generated
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
language: go
|
||||
go:
|
||||
- 1.7.x
|
||||
- tip
|
||||
sudo: false
|
||||
before_install:
|
||||
- go get github.com/axw/gocov/gocov
|
||||
- go get github.com/mattn/goveralls
|
||||
- if ! go get github.com/golang/tools/cmd/cover; then go get golang.org/x/tools/cmd/cover; fi
|
||||
script:
|
||||
- $HOME/gopath/bin/goveralls -service=travis-ci
|
||||
21
vendor/github.com/fatih/structs/LICENSE
generated
vendored
Normal file
21
vendor/github.com/fatih/structs/LICENSE
generated
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2014 Fatih Arslan
|
||||
|
||||
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.
|
||||
163
vendor/github.com/fatih/structs/README.md
generated
vendored
Normal file
163
vendor/github.com/fatih/structs/README.md
generated
vendored
Normal file
@@ -0,0 +1,163 @@
|
||||
# Structs [](http://godoc.org/github.com/fatih/structs) [](https://travis-ci.org/fatih/structs) [](https://coveralls.io/r/fatih/structs)
|
||||
|
||||
Structs contains various utilities to work with Go (Golang) structs. It was
|
||||
initially used by me to convert a struct into a `map[string]interface{}`. With
|
||||
time I've added other utilities for structs. It's basically a high level
|
||||
package based on primitives from the reflect package. Feel free to add new
|
||||
functions or improve the existing code.
|
||||
|
||||
## Install
|
||||
|
||||
```bash
|
||||
go get github.com/fatih/structs
|
||||
```
|
||||
|
||||
## Usage and Examples
|
||||
|
||||
Just like the standard lib `strings`, `bytes` and co packages, `structs` has
|
||||
many global functions to manipulate or organize your struct data. Lets define
|
||||
and declare a struct:
|
||||
|
||||
```go
|
||||
type Server struct {
|
||||
Name string `json:"name,omitempty"`
|
||||
ID int
|
||||
Enabled bool
|
||||
users []string // not exported
|
||||
http.Server // embedded
|
||||
}
|
||||
|
||||
server := &Server{
|
||||
Name: "gopher",
|
||||
ID: 123456,
|
||||
Enabled: true,
|
||||
}
|
||||
```
|
||||
|
||||
```go
|
||||
// Convert a struct to a map[string]interface{}
|
||||
// => {"Name":"gopher", "ID":123456, "Enabled":true}
|
||||
m := structs.Map(server)
|
||||
|
||||
// Convert the values of a struct to a []interface{}
|
||||
// => ["gopher", 123456, true]
|
||||
v := structs.Values(server)
|
||||
|
||||
// Convert the names of a struct to a []string
|
||||
// (see "Names methods" for more info about fields)
|
||||
n := structs.Names(server)
|
||||
|
||||
// Convert the values of a struct to a []*Field
|
||||
// (see "Field methods" for more info about fields)
|
||||
f := structs.Fields(server)
|
||||
|
||||
// Return the struct name => "Server"
|
||||
n := structs.Name(server)
|
||||
|
||||
// Check if any field of a struct is initialized or not.
|
||||
h := structs.HasZero(server)
|
||||
|
||||
// Check if all fields of a struct is initialized or not.
|
||||
z := structs.IsZero(server)
|
||||
|
||||
// Check if server is a struct or a pointer to struct
|
||||
i := structs.IsStruct(server)
|
||||
```
|
||||
|
||||
### Struct methods
|
||||
|
||||
The structs functions can be also used as independent methods by creating a new
|
||||
`*structs.Struct`. This is handy if you want to have more control over the
|
||||
structs (such as retrieving a single Field).
|
||||
|
||||
```go
|
||||
// Create a new struct type:
|
||||
s := structs.New(server)
|
||||
|
||||
m := s.Map() // Get a map[string]interface{}
|
||||
v := s.Values() // Get a []interface{}
|
||||
f := s.Fields() // Get a []*Field
|
||||
n := s.Names() // Get a []string
|
||||
f := s.Field(name) // Get a *Field based on the given field name
|
||||
f, ok := s.FieldOk(name) // Get a *Field based on the given field name
|
||||
n := s.Name() // Get the struct name
|
||||
h := s.HasZero() // Check if any field is initialized
|
||||
z := s.IsZero() // Check if all fields are initialized
|
||||
```
|
||||
|
||||
### Field methods
|
||||
|
||||
We can easily examine a single Field for more detail. Below you can see how we
|
||||
get and interact with various field methods:
|
||||
|
||||
|
||||
```go
|
||||
s := structs.New(server)
|
||||
|
||||
// Get the Field struct for the "Name" field
|
||||
name := s.Field("Name")
|
||||
|
||||
// Get the underlying value, value => "gopher"
|
||||
value := name.Value().(string)
|
||||
|
||||
// Set the field's value
|
||||
name.Set("another gopher")
|
||||
|
||||
// Get the field's kind, kind => "string"
|
||||
name.Kind()
|
||||
|
||||
// Check if the field is exported or not
|
||||
if name.IsExported() {
|
||||
fmt.Println("Name field is exported")
|
||||
}
|
||||
|
||||
// Check if the value is a zero value, such as "" for string, 0 for int
|
||||
if !name.IsZero() {
|
||||
fmt.Println("Name is initialized")
|
||||
}
|
||||
|
||||
// Check if the field is an anonymous (embedded) field
|
||||
if !name.IsEmbedded() {
|
||||
fmt.Println("Name is not an embedded field")
|
||||
}
|
||||
|
||||
// Get the Field's tag value for tag name "json", tag value => "name,omitempty"
|
||||
tagValue := name.Tag("json")
|
||||
```
|
||||
|
||||
Nested structs are supported too:
|
||||
|
||||
```go
|
||||
addrField := s.Field("Server").Field("Addr")
|
||||
|
||||
// Get the value for addr
|
||||
a := addrField.Value().(string)
|
||||
|
||||
// Or get all fields
|
||||
httpServer := s.Field("Server").Fields()
|
||||
```
|
||||
|
||||
We can also get a slice of Fields from the Struct type to iterate over all
|
||||
fields. This is handy if you wish to examine all fields:
|
||||
|
||||
```go
|
||||
s := structs.New(server)
|
||||
|
||||
for _, f := range s.Fields() {
|
||||
fmt.Printf("field name: %+v\n", f.Name())
|
||||
|
||||
if f.IsExported() {
|
||||
fmt.Printf("value : %+v\n", f.Value())
|
||||
fmt.Printf("is zero : %+v\n", f.IsZero())
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Credits
|
||||
|
||||
* [Fatih Arslan](https://github.com/fatih)
|
||||
* [Cihangir Savas](https://github.com/cihangir)
|
||||
|
||||
## License
|
||||
|
||||
The MIT License (MIT) - see LICENSE.md for more details
|
||||
141
vendor/github.com/fatih/structs/field.go
generated
vendored
Normal file
141
vendor/github.com/fatih/structs/field.go
generated
vendored
Normal file
@@ -0,0 +1,141 @@
|
||||
package structs
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"reflect"
|
||||
)
|
||||
|
||||
var (
|
||||
errNotExported = errors.New("field is not exported")
|
||||
errNotSettable = errors.New("field is not settable")
|
||||
)
|
||||
|
||||
// Field represents a single struct field that encapsulates high level
|
||||
// functions around the field.
|
||||
type Field struct {
|
||||
value reflect.Value
|
||||
field reflect.StructField
|
||||
defaultTag string
|
||||
}
|
||||
|
||||
// Tag returns the value associated with key in the tag string. If there is no
|
||||
// such key in the tag, Tag returns the empty string.
|
||||
func (f *Field) Tag(key string) string {
|
||||
return f.field.Tag.Get(key)
|
||||
}
|
||||
|
||||
// Value returns the underlying value of the field. It panics if the field
|
||||
// is not exported.
|
||||
func (f *Field) Value() interface{} {
|
||||
return f.value.Interface()
|
||||
}
|
||||
|
||||
// IsEmbedded returns true if the given field is an anonymous field (embedded)
|
||||
func (f *Field) IsEmbedded() bool {
|
||||
return f.field.Anonymous
|
||||
}
|
||||
|
||||
// IsExported returns true if the given field is exported.
|
||||
func (f *Field) IsExported() bool {
|
||||
return f.field.PkgPath == ""
|
||||
}
|
||||
|
||||
// IsZero returns true if the given field is not initialized (has a zero value).
|
||||
// It panics if the field is not exported.
|
||||
func (f *Field) IsZero() bool {
|
||||
zero := reflect.Zero(f.value.Type()).Interface()
|
||||
current := f.Value()
|
||||
|
||||
return reflect.DeepEqual(current, zero)
|
||||
}
|
||||
|
||||
// Name returns the name of the given field
|
||||
func (f *Field) Name() string {
|
||||
return f.field.Name
|
||||
}
|
||||
|
||||
// Kind returns the fields kind, such as "string", "map", "bool", etc ..
|
||||
func (f *Field) Kind() reflect.Kind {
|
||||
return f.value.Kind()
|
||||
}
|
||||
|
||||
// Set sets the field to given value v. It returns an error if the field is not
|
||||
// settable (not addressable or not exported) or if the given value's type
|
||||
// doesn't match the fields type.
|
||||
func (f *Field) Set(val interface{}) error {
|
||||
// we can't set unexported fields, so be sure this field is exported
|
||||
if !f.IsExported() {
|
||||
return errNotExported
|
||||
}
|
||||
|
||||
// do we get here? not sure...
|
||||
if !f.value.CanSet() {
|
||||
return errNotSettable
|
||||
}
|
||||
|
||||
given := reflect.ValueOf(val)
|
||||
|
||||
if f.value.Kind() != given.Kind() {
|
||||
return fmt.Errorf("wrong kind. got: %s want: %s", given.Kind(), f.value.Kind())
|
||||
}
|
||||
|
||||
f.value.Set(given)
|
||||
return nil
|
||||
}
|
||||
|
||||
// Zero sets the field to its zero value. It returns an error if the field is not
|
||||
// settable (not addressable or not exported).
|
||||
func (f *Field) Zero() error {
|
||||
zero := reflect.Zero(f.value.Type()).Interface()
|
||||
return f.Set(zero)
|
||||
}
|
||||
|
||||
// Fields returns a slice of Fields. This is particular handy to get the fields
|
||||
// of a nested struct . A struct tag with the content of "-" ignores the
|
||||
// checking of that particular field. Example:
|
||||
//
|
||||
// // Field is ignored by this package.
|
||||
// Field *http.Request `structs:"-"`
|
||||
//
|
||||
// It panics if field is not exported or if field's kind is not struct
|
||||
func (f *Field) Fields() []*Field {
|
||||
return getFields(f.value, f.defaultTag)
|
||||
}
|
||||
|
||||
// Field returns the field from a nested struct. It panics if the nested struct
|
||||
// is not exported or if the field was not found.
|
||||
func (f *Field) Field(name string) *Field {
|
||||
field, ok := f.FieldOk(name)
|
||||
if !ok {
|
||||
panic("field not found")
|
||||
}
|
||||
|
||||
return field
|
||||
}
|
||||
|
||||
// FieldOk returns the field from a nested struct. The boolean returns whether
|
||||
// the field was found (true) or not (false).
|
||||
func (f *Field) FieldOk(name string) (*Field, bool) {
|
||||
value := &f.value
|
||||
// value must be settable so we need to make sure it holds the address of the
|
||||
// variable and not a copy, so we can pass the pointer to strctVal instead of a
|
||||
// copy (which is not assigned to any variable, hence not settable).
|
||||
// see "https://blog.golang.org/laws-of-reflection#TOC_8."
|
||||
if f.value.Kind() != reflect.Ptr {
|
||||
a := f.value.Addr()
|
||||
value = &a
|
||||
}
|
||||
v := strctVal(value.Interface())
|
||||
t := v.Type()
|
||||
|
||||
field, ok := t.FieldByName(name)
|
||||
if !ok {
|
||||
return nil, false
|
||||
}
|
||||
|
||||
return &Field{
|
||||
field: field,
|
||||
value: v.FieldByName(name),
|
||||
}, true
|
||||
}
|
||||
586
vendor/github.com/fatih/structs/structs.go
generated
vendored
Normal file
586
vendor/github.com/fatih/structs/structs.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
32
vendor/github.com/fatih/structs/tags.go
generated
vendored
Normal file
32
vendor/github.com/fatih/structs/tags.go
generated
vendored
Normal file
@@ -0,0 +1,32 @@
|
||||
package structs
|
||||
|
||||
import "strings"
|
||||
|
||||
// tagOptions contains a slice of tag options
|
||||
type tagOptions []string
|
||||
|
||||
// Has returns true if the given optiton is available in tagOptions
|
||||
func (t tagOptions) Has(opt string) bool {
|
||||
for _, tagOpt := range t {
|
||||
if tagOpt == opt {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
// parseTag splits a struct field's tag into its name and a list of options
|
||||
// which comes after a name. A tag is in the form of: "name,option1,option2".
|
||||
// The name can be neglectected.
|
||||
func parseTag(tag string) (string, tagOptions) {
|
||||
// tag is one of followings:
|
||||
// ""
|
||||
// "name"
|
||||
// "name,opt"
|
||||
// "name,opt,opt2"
|
||||
// ",opt"
|
||||
|
||||
res := strings.Split(tag, ",")
|
||||
return res[0], res[1:]
|
||||
}
|
||||
202
vendor/github.com/trivago/tgo/LICENSE
generated
vendored
Normal file
202
vendor/github.com/trivago/tgo/LICENSE
generated
vendored
Normal file
@@ -0,0 +1,202 @@
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "{}"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright {yyyy} {name of copyright owner}
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
113
vendor/github.com/trivago/tgo/tcontainer/arrays.go
generated
vendored
Normal file
113
vendor/github.com/trivago/tgo/tcontainer/arrays.go
generated
vendored
Normal file
@@ -0,0 +1,113 @@
|
||||
// Copyright 2015-2016 trivago GmbH
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package tcontainer
|
||||
|
||||
import "sort"
|
||||
|
||||
// Int64Slice is a typedef to allow sortable int64 slices
|
||||
type Int64Slice []int64
|
||||
|
||||
func (s Int64Slice) Len() int {
|
||||
return len(s)
|
||||
}
|
||||
|
||||
func (s Int64Slice) Less(i, j int) bool {
|
||||
return s[i] < s[j]
|
||||
}
|
||||
|
||||
func (s Int64Slice) Swap(i, j int) {
|
||||
s[i], s[j] = s[j], s[i]
|
||||
}
|
||||
|
||||
// Sort is a shortcut for sort.Sort(s)
|
||||
func (s Int64Slice) Sort() {
|
||||
sort.Sort(s)
|
||||
}
|
||||
|
||||
// IsSorted is a shortcut for sort.IsSorted(s)
|
||||
func (s Int64Slice) IsSorted() bool {
|
||||
return sort.IsSorted(s)
|
||||
}
|
||||
|
||||
// Set sets all values in this slice to the given value
|
||||
func (s Int64Slice) Set(v int64) {
|
||||
for i := range s {
|
||||
s[i] = v
|
||||
}
|
||||
}
|
||||
|
||||
// Uint64Slice is a typedef to allow sortable uint64 slices
|
||||
type Uint64Slice []uint64
|
||||
|
||||
func (s Uint64Slice) Len() int {
|
||||
return len(s)
|
||||
}
|
||||
|
||||
func (s Uint64Slice) Less(i, j int) bool {
|
||||
return s[i] < s[j]
|
||||
}
|
||||
|
||||
func (s Uint64Slice) Swap(i, j int) {
|
||||
s[i], s[j] = s[j], s[i]
|
||||
}
|
||||
|
||||
// Sort is a shortcut for sort.Sort(s)
|
||||
func (s Uint64Slice) Sort() {
|
||||
sort.Sort(s)
|
||||
}
|
||||
|
||||
// IsSorted is a shortcut for sort.IsSorted(s)
|
||||
func (s Uint64Slice) IsSorted() bool {
|
||||
return sort.IsSorted(s)
|
||||
}
|
||||
|
||||
// Set sets all values in this slice to the given value
|
||||
func (s Uint64Slice) Set(v uint64) {
|
||||
for i := range s {
|
||||
s[i] = v
|
||||
}
|
||||
}
|
||||
|
||||
// Float32Slice is a typedef to allow sortable float32 slices
|
||||
type Float32Slice []float32
|
||||
|
||||
func (s Float32Slice) Len() int {
|
||||
return len(s)
|
||||
}
|
||||
|
||||
func (s Float32Slice) Less(i, j int) bool {
|
||||
return s[i] < s[j]
|
||||
}
|
||||
|
||||
func (s Float32Slice) Swap(i, j int) {
|
||||
s[i], s[j] = s[j], s[i]
|
||||
}
|
||||
|
||||
// Sort is a shortcut for sort.Sort(s)
|
||||
func (s Float32Slice) Sort() {
|
||||
sort.Sort(s)
|
||||
}
|
||||
|
||||
// IsSorted is a shortcut for sort.IsSorted(s)
|
||||
func (s Float32Slice) IsSorted() bool {
|
||||
return sort.IsSorted(s)
|
||||
}
|
||||
|
||||
// Set sets all values in this slice to the given value
|
||||
func (s Float32Slice) Set(v float32) {
|
||||
for i := range s {
|
||||
s[i] = v
|
||||
}
|
||||
}
|
||||
157
vendor/github.com/trivago/tgo/tcontainer/bytepool.go
generated
vendored
Normal file
157
vendor/github.com/trivago/tgo/tcontainer/bytepool.go
generated
vendored
Normal file
@@ -0,0 +1,157 @@
|
||||
// Copyright 2015-2016 trivago GmbH
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package tcontainer
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"runtime"
|
||||
"sync/atomic"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
const (
|
||||
tiny = 64
|
||||
small = 512
|
||||
medium = 1024
|
||||
large = 1024 * 10
|
||||
huge = 1024 * 100
|
||||
|
||||
tinyCount = 16384 // 1 MB
|
||||
smallCount = 2048 // 1 MB
|
||||
mediumCount = 1024 // 1 MB
|
||||
largeCount = 102 // ~1 MB
|
||||
hugeCount = 10 // ~1 MB
|
||||
)
|
||||
|
||||
type byteSlab struct {
|
||||
buffer []byte
|
||||
bufferSize uintptr
|
||||
stride uintptr
|
||||
basePtr *uintptr
|
||||
nextPtr *uintptr
|
||||
}
|
||||
|
||||
// BytePool is a fragmentation friendly way to allocated byte slices.
|
||||
type BytePool struct {
|
||||
tinySlab byteSlab
|
||||
smallSlab byteSlab
|
||||
mediumSlab byteSlab
|
||||
largeSlab byteSlab
|
||||
hugeSlab byteSlab
|
||||
}
|
||||
|
||||
func newByteSlab(size, count int) byteSlab {
|
||||
bufferSize := count * size
|
||||
buffer := make([]byte, bufferSize)
|
||||
basePtr := (*reflect.SliceHeader)(unsafe.Pointer(&buffer)).Data
|
||||
nextPtr := basePtr + uintptr(bufferSize)
|
||||
|
||||
return byteSlab{
|
||||
buffer: buffer,
|
||||
bufferSize: uintptr(bufferSize),
|
||||
stride: uintptr(size),
|
||||
basePtr: &basePtr,
|
||||
nextPtr: &nextPtr,
|
||||
}
|
||||
}
|
||||
|
||||
func (slab *byteSlab) getSlice(size int) (chunk []byte) {
|
||||
chunkHeader := (*reflect.SliceHeader)(unsafe.Pointer(&chunk))
|
||||
chunkHeader.Len = size
|
||||
chunkHeader.Cap = int(slab.stride)
|
||||
|
||||
for {
|
||||
// WARNING: The following two lines are order sensitive
|
||||
basePtr := atomic.LoadUintptr(slab.basePtr)
|
||||
nextPtr := atomic.AddUintptr(slab.nextPtr, -slab.stride)
|
||||
lastPtr := basePtr + slab.bufferSize
|
||||
|
||||
switch {
|
||||
case nextPtr < basePtr || nextPtr >= lastPtr:
|
||||
// out of range either means alloc while realloc or race between
|
||||
// base and next during realloc. In the latter case we lose a chunk.
|
||||
runtime.Gosched()
|
||||
|
||||
case nextPtr == basePtr:
|
||||
// Last item: realloc
|
||||
slab.buffer = make([]byte, slab.bufferSize)
|
||||
dataPtr := (*reflect.SliceHeader)(unsafe.Pointer(&slab.buffer)).Data
|
||||
|
||||
// WARNING: The following two lines are order sensitive
|
||||
atomic.StoreUintptr(slab.nextPtr, dataPtr+slab.bufferSize)
|
||||
atomic.StoreUintptr(slab.basePtr, dataPtr)
|
||||
fallthrough
|
||||
|
||||
default:
|
||||
chunkHeader.Data = nextPtr
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// NewBytePool creates a new BytePool with each slab using 1 MB of storage.
|
||||
// The pool contains 5 slabs of different sizes: 64B, 512B, 1KB, 10KB and 100KB.
|
||||
// Allocations above 100KB will be allocated directly.
|
||||
func NewBytePool() BytePool {
|
||||
return BytePool{
|
||||
tinySlab: newByteSlab(tiny, tinyCount),
|
||||
smallSlab: newByteSlab(small, smallCount),
|
||||
mediumSlab: newByteSlab(medium, mediumCount),
|
||||
largeSlab: newByteSlab(large, largeCount),
|
||||
hugeSlab: newByteSlab(huge, hugeCount),
|
||||
}
|
||||
}
|
||||
|
||||
// NewBytePoolWithSize creates a new BytePool with each slab size using n MB of
|
||||
// storage. See NewBytePool() for slab size details.
|
||||
func NewBytePoolWithSize(n int) BytePool {
|
||||
if n <= 0 {
|
||||
n = 1
|
||||
}
|
||||
return BytePool{
|
||||
tinySlab: newByteSlab(tiny, tinyCount*n),
|
||||
smallSlab: newByteSlab(small, smallCount*n),
|
||||
mediumSlab: newByteSlab(medium, mediumCount*n),
|
||||
largeSlab: newByteSlab(large, largeCount*n),
|
||||
hugeSlab: newByteSlab(huge, hugeCount*n),
|
||||
}
|
||||
}
|
||||
|
||||
// Get returns a slice allocated to a normalized size.
|
||||
// Sizes are organized in evenly sized buckets so that fragmentation is kept low.
|
||||
func (b *BytePool) Get(size int) []byte {
|
||||
switch {
|
||||
case size == 0:
|
||||
return []byte{}
|
||||
|
||||
case size <= tiny:
|
||||
return b.tinySlab.getSlice(size)
|
||||
|
||||
case size <= small:
|
||||
return b.smallSlab.getSlice(size)
|
||||
|
||||
case size <= medium:
|
||||
return b.mediumSlab.getSlice(size)
|
||||
|
||||
case size <= large:
|
||||
return b.largeSlab.getSlice(size)
|
||||
|
||||
case size <= huge:
|
||||
return b.hugeSlab.getSlice(size)
|
||||
|
||||
default:
|
||||
return make([]byte, size)
|
||||
}
|
||||
}
|
||||
464
vendor/github.com/trivago/tgo/tcontainer/marshalmap.go
generated
vendored
Normal file
464
vendor/github.com/trivago/tgo/tcontainer/marshalmap.go
generated
vendored
Normal file
@@ -0,0 +1,464 @@
|
||||
// Copyright 2015-2016 trivago GmbH
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package tcontainer
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/trivago/tgo/treflect"
|
||||
"reflect"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
// MarshalMap is a wrapper type to attach converter methods to maps normally
|
||||
// returned by marshalling methods, i.e. key/value parsers.
|
||||
// All methods that do a conversion will return an error if the value stored
|
||||
// behind key is not of the expected type or if the key is not existing in the
|
||||
// map.
|
||||
type MarshalMap map[string]interface{}
|
||||
|
||||
const (
|
||||
// MarshalMapSeparator defines the rune used for path separation
|
||||
MarshalMapSeparator = '/'
|
||||
// MarshalMapArrayBegin defines the rune starting array index notation
|
||||
MarshalMapArrayBegin = '['
|
||||
// MarshalMapArrayEnd defines the rune ending array index notation
|
||||
MarshalMapArrayEnd = ']'
|
||||
)
|
||||
|
||||
// NewMarshalMap creates a new marshal map (string -> interface{})
|
||||
func NewMarshalMap() MarshalMap {
|
||||
return make(map[string]interface{})
|
||||
}
|
||||
|
||||
// TryConvertToMarshalMap converts collections to MarshalMap if possible.
|
||||
// This is a deep conversion, i.e. each element in the collection will be
|
||||
// traversed. You can pass a formatKey function that will be applied to all
|
||||
// string keys that are detected.
|
||||
func TryConvertToMarshalMap(value interface{}, formatKey func(string) string) interface{} {
|
||||
valueMeta := reflect.ValueOf(value)
|
||||
switch valueMeta.Kind() {
|
||||
default:
|
||||
return value
|
||||
|
||||
case reflect.Array, reflect.Slice:
|
||||
arrayLen := valueMeta.Len()
|
||||
converted := make([]interface{}, arrayLen)
|
||||
for i := 0; i < arrayLen; i++ {
|
||||
converted[i] = TryConvertToMarshalMap(valueMeta.Index(i).Interface(), formatKey)
|
||||
}
|
||||
return converted
|
||||
|
||||
case reflect.Map:
|
||||
converted := NewMarshalMap()
|
||||
keys := valueMeta.MapKeys()
|
||||
|
||||
for _, keyMeta := range keys {
|
||||
strKey, isString := keyMeta.Interface().(string)
|
||||
if !isString {
|
||||
continue
|
||||
}
|
||||
if formatKey != nil {
|
||||
strKey = formatKey(strKey)
|
||||
}
|
||||
val := valueMeta.MapIndex(keyMeta).Interface()
|
||||
converted[strKey] = TryConvertToMarshalMap(val, formatKey)
|
||||
}
|
||||
return converted // ### return, converted MarshalMap ###
|
||||
}
|
||||
}
|
||||
|
||||
// ConvertToMarshalMap tries to convert a compatible map type to a marshal map.
|
||||
// Compatible types are map[interface{}]interface{}, map[string]interface{} and of
|
||||
// course MarshalMap. The same rules as for ConvertValueToMarshalMap apply.
|
||||
func ConvertToMarshalMap(value interface{}, formatKey func(string) string) (MarshalMap, error) {
|
||||
converted := TryConvertToMarshalMap(value, formatKey)
|
||||
if result, isMap := converted.(MarshalMap); isMap {
|
||||
return result, nil
|
||||
}
|
||||
return nil, fmt.Errorf("Root value cannot be converted to MarshalMap")
|
||||
}
|
||||
|
||||
// Bool returns a value at key that is expected to be a boolean
|
||||
func (mmap MarshalMap) Bool(key string) (bool, error) {
|
||||
val, exists := mmap.Value(key)
|
||||
if !exists {
|
||||
return false, fmt.Errorf(`"%s" is not set`, key)
|
||||
}
|
||||
|
||||
boolValue, isBool := val.(bool)
|
||||
if !isBool {
|
||||
return false, fmt.Errorf(`"%s" is expected to be a boolean`, key)
|
||||
}
|
||||
return boolValue, nil
|
||||
}
|
||||
|
||||
// Uint returns a value at key that is expected to be an uint64 or compatible
|
||||
// integer value.
|
||||
func (mmap MarshalMap) Uint(key string) (uint64, error) {
|
||||
val, exists := mmap.Value(key)
|
||||
if !exists {
|
||||
return 0, fmt.Errorf(`"%s" is not set`, key)
|
||||
}
|
||||
|
||||
if intVal, isNumber := treflect.Uint64(val); isNumber {
|
||||
return intVal, nil
|
||||
}
|
||||
|
||||
return 0, fmt.Errorf(`"%s" is expected to be an unsigned number type`, key)
|
||||
}
|
||||
|
||||
// Int returns a value at key that is expected to be an int64 or compatible
|
||||
// integer value.
|
||||
func (mmap MarshalMap) Int(key string) (int64, error) {
|
||||
val, exists := mmap.Value(key)
|
||||
if !exists {
|
||||
return 0, fmt.Errorf(`"%s" is not set`, key)
|
||||
}
|
||||
|
||||
if intVal, isNumber := treflect.Int64(val); isNumber {
|
||||
return intVal, nil
|
||||
}
|
||||
|
||||
return 0, fmt.Errorf(`"%s" is expected to be a signed number type`, key)
|
||||
}
|
||||
|
||||
// Float returns a value at key that is expected to be a float64 or compatible
|
||||
// float value.
|
||||
func (mmap MarshalMap) Float(key string) (float64, error) {
|
||||
val, exists := mmap.Value(key)
|
||||
if !exists {
|
||||
return 0, fmt.Errorf(`"%s" is not set`, key)
|
||||
}
|
||||
|
||||
if floatVal, isNumber := treflect.Float64(val); isNumber {
|
||||
return floatVal, nil
|
||||
}
|
||||
|
||||
return 0, fmt.Errorf(`"%s" is expected to be a signed number type`, key)
|
||||
}
|
||||
|
||||
// Duration returns a value at key that is expected to be a string
|
||||
func (mmap MarshalMap) Duration(key string) (time.Duration, error) {
|
||||
val, exists := mmap.Value(key)
|
||||
if !exists {
|
||||
return time.Duration(0), fmt.Errorf(`"%s" is not set`, key)
|
||||
}
|
||||
|
||||
switch val.(type) {
|
||||
case time.Duration:
|
||||
return val.(time.Duration), nil
|
||||
case string:
|
||||
return time.ParseDuration(val.(string))
|
||||
}
|
||||
|
||||
return time.Duration(0), fmt.Errorf(`"%s" is expected to be a duration or string`, key)
|
||||
}
|
||||
|
||||
// String returns a value at key that is expected to be a string
|
||||
func (mmap MarshalMap) String(key string) (string, error) {
|
||||
val, exists := mmap.Value(key)
|
||||
if !exists {
|
||||
return "", fmt.Errorf(`"%s" is not set`, key)
|
||||
}
|
||||
|
||||
strValue, isString := val.(string)
|
||||
if !isString {
|
||||
return "", fmt.Errorf(`"%s" is expected to be a string`, key)
|
||||
}
|
||||
return strValue, nil
|
||||
}
|
||||
|
||||
// Array returns a value at key that is expected to be a []interface{}
|
||||
func (mmap MarshalMap) Array(key string) ([]interface{}, error) {
|
||||
val, exists := mmap.Value(key)
|
||||
if !exists {
|
||||
return nil, fmt.Errorf(`"%s" is not set`, key)
|
||||
}
|
||||
|
||||
arrayValue, isArray := val.([]interface{})
|
||||
if !isArray {
|
||||
return nil, fmt.Errorf(`"%s" is expected to be an array`, key)
|
||||
}
|
||||
return arrayValue, nil
|
||||
}
|
||||
|
||||
// Map returns a value at key that is expected to be a
|
||||
// map[interface{}]interface{}.
|
||||
func (mmap MarshalMap) Map(key string) (map[interface{}]interface{}, error) {
|
||||
val, exists := mmap.Value(key)
|
||||
if !exists {
|
||||
return nil, fmt.Errorf(`"%s" is not set`, key)
|
||||
}
|
||||
|
||||
mapValue, isMap := val.(map[interface{}]interface{})
|
||||
if !isMap {
|
||||
return nil, fmt.Errorf(`"%s" is expected to be a map`, key)
|
||||
}
|
||||
return mapValue, nil
|
||||
}
|
||||
|
||||
func castToStringArray(key string, value interface{}) ([]string, error) {
|
||||
switch value.(type) {
|
||||
case string:
|
||||
return []string{value.(string)}, nil
|
||||
|
||||
case []interface{}:
|
||||
arrayVal := value.([]interface{})
|
||||
stringArray := make([]string, 0, len(arrayVal))
|
||||
|
||||
for _, val := range arrayVal {
|
||||
strValue, isString := val.(string)
|
||||
if !isString {
|
||||
return nil, fmt.Errorf(`"%s" does not contain string keys`, key)
|
||||
}
|
||||
stringArray = append(stringArray, strValue)
|
||||
}
|
||||
return stringArray, nil
|
||||
|
||||
case []string:
|
||||
return value.([]string), nil
|
||||
|
||||
default:
|
||||
return nil, fmt.Errorf(`"%s" is not a valid string array type`, key)
|
||||
}
|
||||
}
|
||||
|
||||
// StringArray returns a value at key that is expected to be a []string
|
||||
// This function supports conversion (by copy) from
|
||||
// * []interface{}
|
||||
func (mmap MarshalMap) StringArray(key string) ([]string, error) {
|
||||
val, exists := mmap.Value(key)
|
||||
if !exists {
|
||||
return nil, fmt.Errorf(`"%s" is not set`, key)
|
||||
}
|
||||
|
||||
return castToStringArray(key, val)
|
||||
}
|
||||
|
||||
func castToInt64Array(key string, value interface{}) ([]int64, error) {
|
||||
switch value.(type) {
|
||||
case int:
|
||||
return []int64{value.(int64)}, nil
|
||||
|
||||
case []interface{}:
|
||||
arrayVal := value.([]interface{})
|
||||
intArray := make([]int64, 0, len(arrayVal))
|
||||
|
||||
for _, val := range arrayVal {
|
||||
intValue, isInt := val.(int64)
|
||||
if !isInt {
|
||||
return nil, fmt.Errorf(`"%s" does not contain int keys`, key)
|
||||
}
|
||||
intArray = append(intArray, intValue)
|
||||
}
|
||||
return intArray, nil
|
||||
|
||||
case []int64:
|
||||
return value.([]int64), nil
|
||||
|
||||
default:
|
||||
return nil, fmt.Errorf(`"%s" is not a valid string array type`, key)
|
||||
}
|
||||
}
|
||||
|
||||
// IntArray returns a value at key that is expected to be a []int64
|
||||
// This function supports conversion (by copy) from
|
||||
// * []interface{}
|
||||
func (mmap MarshalMap) Int64Array(key string) ([]int64, error) {
|
||||
val, exists := mmap.Value(key)
|
||||
if !exists {
|
||||
return nil, fmt.Errorf(`"%s" is not set`, key)
|
||||
}
|
||||
|
||||
return castToInt64Array(key, val)
|
||||
}
|
||||
|
||||
// StringMap returns a value at key that is expected to be a map[string]string.
|
||||
// This function supports conversion (by copy) from
|
||||
// * map[interface{}]interface{}
|
||||
// * map[string]interface{}
|
||||
func (mmap MarshalMap) StringMap(key string) (map[string]string, error) {
|
||||
val, exists := mmap.Value(key)
|
||||
if !exists {
|
||||
return nil, fmt.Errorf(`"%s" is not set`, key)
|
||||
}
|
||||
|
||||
switch val.(type) {
|
||||
case map[string]string:
|
||||
return val.(map[string]string), nil
|
||||
|
||||
default:
|
||||
valueMeta := reflect.ValueOf(val)
|
||||
if valueMeta.Kind() != reflect.Map {
|
||||
return nil, fmt.Errorf(`"%s" is expected to be a map[string]string but is %T`, key, val)
|
||||
}
|
||||
|
||||
result := make(map[string]string)
|
||||
for _, keyMeta := range valueMeta.MapKeys() {
|
||||
strKey, isString := keyMeta.Interface().(string)
|
||||
if !isString {
|
||||
return nil, fmt.Errorf(`"%s" is expected to be a map[string]string. Key is not a string`, key)
|
||||
}
|
||||
|
||||
value := valueMeta.MapIndex(keyMeta)
|
||||
strValue, isString := value.Interface().(string)
|
||||
if !isString {
|
||||
return nil, fmt.Errorf(`"%s" is expected to be a map[string]string. Value is not a string`, key)
|
||||
}
|
||||
|
||||
result[strKey] = strValue
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
}
|
||||
|
||||
// StringArrayMap returns a value at key that is expected to be a
|
||||
// map[string][]string. This function supports conversion (by copy) from
|
||||
// * map[interface{}][]interface{}
|
||||
// * map[interface{}]interface{}
|
||||
// * map[string]interface{}
|
||||
func (mmap MarshalMap) StringArrayMap(key string) (map[string][]string, error) {
|
||||
val, exists := mmap.Value(key)
|
||||
if !exists {
|
||||
return nil, fmt.Errorf(`"%s" is not set`, key)
|
||||
}
|
||||
|
||||
switch val.(type) {
|
||||
case map[string][]string:
|
||||
return val.(map[string][]string), nil
|
||||
|
||||
default:
|
||||
valueMeta := reflect.ValueOf(val)
|
||||
if valueMeta.Kind() != reflect.Map {
|
||||
return nil, fmt.Errorf(`"%s" is expected to be a map[string][]string but is %T`, key, val)
|
||||
}
|
||||
|
||||
result := make(map[string][]string)
|
||||
for _, keyMeta := range valueMeta.MapKeys() {
|
||||
strKey, isString := keyMeta.Interface().(string)
|
||||
if !isString {
|
||||
return nil, fmt.Errorf(`"%s" is expected to be a map[string][]string. Key is not a string`, key)
|
||||
}
|
||||
|
||||
value := valueMeta.MapIndex(keyMeta)
|
||||
arrayValue, err := castToStringArray(strKey, value.Interface())
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf(`"%s" is expected to be a map[string][]string. Value is not a []string`, key)
|
||||
}
|
||||
|
||||
result[strKey] = arrayValue
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
}
|
||||
|
||||
// MarshalMap returns a value at key that is expected to be another MarshalMap
|
||||
// This function supports conversion (by copy) from
|
||||
// * map[interface{}]interface{}
|
||||
func (mmap MarshalMap) MarshalMap(key string) (MarshalMap, error) {
|
||||
val, exists := mmap.Value(key)
|
||||
if !exists {
|
||||
return nil, fmt.Errorf(`"%s" is not set`, key)
|
||||
}
|
||||
|
||||
return ConvertToMarshalMap(val, nil)
|
||||
}
|
||||
|
||||
// Value returns a value from a given value path.
|
||||
// Fields can be accessed by their name. Nested fields can be accessed by using
|
||||
// "/" as a separator. Arrays can be addressed using the standard array
|
||||
// notation "[<index>]".
|
||||
// Examples:
|
||||
// "key" -> mmap["key"] single value
|
||||
// "key1/key2" -> mmap["key1"]["key2"] nested map
|
||||
// "key1[0]" -> mmap["key1"][0] nested array
|
||||
// "key1[0]key2" -> mmap["key1"][0]["key2"] nested array, nested map
|
||||
func (mmap MarshalMap) Value(key string) (interface{}, bool) {
|
||||
return mmap.resolvePath(key, mmap)
|
||||
}
|
||||
|
||||
func (mmap MarshalMap) resolvePathKey(key string) (int, int) {
|
||||
keyEnd := len(key)
|
||||
nextKeyStart := keyEnd
|
||||
pathIdx := strings.IndexRune(key, MarshalMapSeparator)
|
||||
arrayIdx := strings.IndexRune(key, MarshalMapArrayBegin)
|
||||
|
||||
if pathIdx > -1 && pathIdx < keyEnd {
|
||||
keyEnd = pathIdx
|
||||
nextKeyStart = pathIdx + 1 // don't include slash
|
||||
}
|
||||
if arrayIdx > -1 && arrayIdx < keyEnd {
|
||||
keyEnd = arrayIdx
|
||||
nextKeyStart = arrayIdx // include bracket because of multidimensional arrays
|
||||
}
|
||||
|
||||
// a -> key: "a", remain: "" -- value
|
||||
// a/b/c -> key: "a", remain: "b/c" -- nested map
|
||||
// a[1]b/c -> key: "a", remain: "[1]b/c" -- nested array
|
||||
|
||||
return keyEnd, nextKeyStart
|
||||
}
|
||||
|
||||
func (mmap MarshalMap) resolvePath(key string, value interface{}) (interface{}, bool) {
|
||||
if len(key) == 0 {
|
||||
return value, true // ### return, found requested value ###
|
||||
}
|
||||
|
||||
valueMeta := reflect.ValueOf(value)
|
||||
switch valueMeta.Kind() {
|
||||
case reflect.Array, reflect.Slice:
|
||||
startIdx := strings.IndexRune(key, MarshalMapArrayBegin) // Must be first char, otherwise malformed
|
||||
endIdx := strings.IndexRune(key, MarshalMapArrayEnd) // Must be > startIdx, otherwise malformed
|
||||
|
||||
if startIdx == -1 || endIdx == -1 {
|
||||
return nil, false
|
||||
}
|
||||
|
||||
if startIdx == 0 && endIdx > startIdx {
|
||||
index, err := strconv.Atoi(key[startIdx+1 : endIdx])
|
||||
|
||||
// [1] -> index: "1", remain: "" -- value
|
||||
// [1]a/b -> index: "1", remain: "a/b" -- nested map
|
||||
// [1][2] -> index: "1", remain: "[2]" -- nested array
|
||||
|
||||
if err == nil && index < valueMeta.Len() {
|
||||
item := valueMeta.Index(index).Interface()
|
||||
key := key[endIdx+1:]
|
||||
return mmap.resolvePath(key, item) // ### return, nested array ###
|
||||
}
|
||||
}
|
||||
|
||||
case reflect.Map:
|
||||
keyMeta := reflect.ValueOf(key)
|
||||
if storedValue := valueMeta.MapIndex(keyMeta); storedValue.IsValid() {
|
||||
return storedValue.Interface(), true
|
||||
}
|
||||
|
||||
keyEnd, nextKeyStart := mmap.resolvePathKey(key)
|
||||
pathKey := key[:keyEnd]
|
||||
keyMeta = reflect.ValueOf(pathKey)
|
||||
|
||||
if storedValue := valueMeta.MapIndex(keyMeta); storedValue.IsValid() {
|
||||
remain := key[nextKeyStart:]
|
||||
return mmap.resolvePath(remain, storedValue.Interface()) // ### return, nested map ###
|
||||
}
|
||||
}
|
||||
|
||||
return nil, false
|
||||
}
|
||||
227
vendor/github.com/trivago/tgo/tcontainer/trie.go
generated
vendored
Normal file
227
vendor/github.com/trivago/tgo/tcontainer/trie.go
generated
vendored
Normal file
@@ -0,0 +1,227 @@
|
||||
// Copyright 2015-2016 trivago GmbH
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package tcontainer
|
||||
|
||||
// TrieNode represents a single node inside a trie.
|
||||
// Each node can contain a payload which can be retrieved after a successfull
|
||||
// match. In addition to that PathLen will contain the length of the match.
|
||||
type TrieNode struct {
|
||||
suffix []byte
|
||||
children []*TrieNode
|
||||
longestPath int
|
||||
PathLen int
|
||||
Payload interface{}
|
||||
}
|
||||
|
||||
// NewTrie creates a new root TrieNode
|
||||
func NewTrie(data []byte, payload interface{}) *TrieNode {
|
||||
return &TrieNode{
|
||||
suffix: data,
|
||||
children: []*TrieNode{},
|
||||
longestPath: len(data),
|
||||
PathLen: len(data),
|
||||
Payload: payload,
|
||||
}
|
||||
}
|
||||
|
||||
func (node *TrieNode) addNewChild(data []byte, payload interface{}, pathLen int) {
|
||||
if node.longestPath < pathLen {
|
||||
node.longestPath = pathLen
|
||||
}
|
||||
|
||||
idx := len(node.children)
|
||||
node.children = append(node.children, nil)
|
||||
|
||||
for idx > 0 {
|
||||
nextIdx := idx - 1
|
||||
if node.children[nextIdx].longestPath > pathLen {
|
||||
break
|
||||
}
|
||||
node.children[idx] = node.children[nextIdx]
|
||||
idx = nextIdx
|
||||
}
|
||||
|
||||
node.children[idx] = &TrieNode{
|
||||
suffix: data,
|
||||
children: []*TrieNode{},
|
||||
longestPath: pathLen,
|
||||
PathLen: pathLen,
|
||||
Payload: payload,
|
||||
}
|
||||
}
|
||||
|
||||
func (node *TrieNode) replace(oldChild *TrieNode, newChild *TrieNode) {
|
||||
for i, child := range node.children {
|
||||
if child == oldChild {
|
||||
node.children[i] = newChild
|
||||
return // ### return, replaced ###
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ForEach applies a function to each node in the tree including and below the
|
||||
// passed node.
|
||||
func (node *TrieNode) ForEach(callback func(*TrieNode)) {
|
||||
callback(node)
|
||||
for _, child := range node.children {
|
||||
child.ForEach(callback)
|
||||
}
|
||||
}
|
||||
|
||||
// Add adds a new data path to the trie.
|
||||
// The TrieNode returned is the (new) root node so you should always reassign
|
||||
// the root with the return value of Add.
|
||||
func (node *TrieNode) Add(data []byte, payload interface{}) *TrieNode {
|
||||
return node.addPath(data, payload, len(data), nil)
|
||||
}
|
||||
|
||||
func (node *TrieNode) addPath(data []byte, payload interface{}, pathLen int, parent *TrieNode) *TrieNode {
|
||||
dataLen := len(data)
|
||||
suffixLen := len(node.suffix)
|
||||
testLen := suffixLen
|
||||
if dataLen < suffixLen {
|
||||
testLen = dataLen
|
||||
}
|
||||
|
||||
var splitIdx int
|
||||
for splitIdx = 0; splitIdx < testLen; splitIdx++ {
|
||||
if data[splitIdx] != node.suffix[splitIdx] {
|
||||
break // ### break, split found ###
|
||||
}
|
||||
}
|
||||
|
||||
if splitIdx == suffixLen {
|
||||
// Continue down or stop here (full suffix match)
|
||||
|
||||
if splitIdx == dataLen {
|
||||
node.Payload = payload // may overwrite
|
||||
return node // ### return, path already stored ###
|
||||
}
|
||||
|
||||
data = data[splitIdx:]
|
||||
if suffixLen > 0 {
|
||||
for _, child := range node.children {
|
||||
if child.suffix[0] == data[0] {
|
||||
child.addPath(data, payload, pathLen, node)
|
||||
return node // ### return, continue on path ###
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
node.addNewChild(data, payload, pathLen)
|
||||
return node // ### return, new leaf ###
|
||||
}
|
||||
|
||||
if splitIdx == dataLen {
|
||||
// Make current node a subpath of new data node (full data match)
|
||||
// This case implies that dataLen < suffixLen as splitIdx == suffixLen
|
||||
// did not match.
|
||||
|
||||
node.suffix = node.suffix[splitIdx:]
|
||||
|
||||
newParent := NewTrie(data, payload)
|
||||
newParent.PathLen = pathLen
|
||||
newParent.longestPath = node.longestPath
|
||||
newParent.children = []*TrieNode{node}
|
||||
|
||||
if parent != nil {
|
||||
parent.replace(node, newParent)
|
||||
}
|
||||
return newParent // ### return, rotation ###
|
||||
}
|
||||
|
||||
// New parent required with both nodes as children (partial match)
|
||||
|
||||
node.suffix = node.suffix[splitIdx:]
|
||||
|
||||
newParent := NewTrie(data[:splitIdx], nil)
|
||||
newParent.PathLen = 0
|
||||
newParent.longestPath = node.longestPath
|
||||
newParent.children = []*TrieNode{node}
|
||||
newParent.addNewChild(data[splitIdx:], payload, pathLen)
|
||||
|
||||
if parent != nil {
|
||||
parent.replace(node, newParent)
|
||||
}
|
||||
return newParent // ### return, new parent ###
|
||||
}
|
||||
|
||||
// Match compares the trie to the given data stream.
|
||||
// Match returns true if data can be completely matched to the trie.
|
||||
func (node *TrieNode) Match(data []byte) *TrieNode {
|
||||
dataLen := len(data)
|
||||
suffixLen := len(node.suffix)
|
||||
if dataLen < suffixLen {
|
||||
return nil // ### return, cannot be fully matched ###
|
||||
}
|
||||
|
||||
for i := 0; i < suffixLen; i++ {
|
||||
if data[i] != node.suffix[i] {
|
||||
return nil // ### return, no match ###
|
||||
}
|
||||
}
|
||||
|
||||
if dataLen == suffixLen {
|
||||
if node.PathLen > 0 {
|
||||
return node // ### return, full match ###
|
||||
}
|
||||
return nil // ### return, invalid match ###
|
||||
}
|
||||
|
||||
data = data[suffixLen:]
|
||||
numChildren := len(node.children)
|
||||
for i := 0; i < numChildren; i++ {
|
||||
matchedNode := node.children[i].Match(data)
|
||||
if matchedNode != nil {
|
||||
return matchedNode // ### return, match found ###
|
||||
}
|
||||
}
|
||||
|
||||
return nil // ### return, no valid path ###
|
||||
}
|
||||
|
||||
// MatchStart compares the trie to the beginning of the given data stream.
|
||||
// MatchStart returns true if the beginning of data can be matched to the trie.
|
||||
func (node *TrieNode) MatchStart(data []byte) *TrieNode {
|
||||
dataLen := len(data)
|
||||
suffixLen := len(node.suffix)
|
||||
if dataLen < suffixLen {
|
||||
return nil // ### return, cannot be fully matched ###
|
||||
}
|
||||
|
||||
for i := 0; i < suffixLen; i++ {
|
||||
if data[i] != node.suffix[i] {
|
||||
return nil // ### return, no match ###
|
||||
}
|
||||
}
|
||||
|
||||
// Match longest path first
|
||||
|
||||
data = data[suffixLen:]
|
||||
numChildren := len(node.children)
|
||||
for i := 0; i < numChildren; i++ {
|
||||
matchedNode := node.children[i].MatchStart(data)
|
||||
if matchedNode != nil {
|
||||
return matchedNode // ### return, match found ###
|
||||
}
|
||||
}
|
||||
|
||||
// May be only a part of data but we have a valid match
|
||||
|
||||
if node.PathLen > 0 {
|
||||
return node // ### return, full match ###
|
||||
}
|
||||
return nil // ### return, no valid path ###
|
||||
}
|
||||
373
vendor/github.com/trivago/tgo/treflect/reflection.go
generated
vendored
Normal file
373
vendor/github.com/trivago/tgo/treflect/reflection.go
generated
vendored
Normal file
@@ -0,0 +1,373 @@
|
||||
// Copyright 2015-2016 trivago GmbH
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package treflect
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
// GetMissingMethods checks if a given object implements all methods of a
|
||||
// given interface. It returns the interface coverage [0..1] as well as an array
|
||||
// of error messages. If the interface is correctly implemented the coverage is
|
||||
// 1 and the error message array is empty.
|
||||
func GetMissingMethods(objType reflect.Type, ifaceType reflect.Type) (float32, []string) {
|
||||
missing := []string{}
|
||||
if objType.Implements(ifaceType) {
|
||||
return 1.0, missing
|
||||
}
|
||||
|
||||
methodCount := ifaceType.NumMethod()
|
||||
for mIdx := 0; mIdx < methodCount; mIdx++ {
|
||||
ifaceMethod := ifaceType.Method(mIdx)
|
||||
objMethod, exists := objType.MethodByName(ifaceMethod.Name)
|
||||
signatureMismatch := false
|
||||
|
||||
switch {
|
||||
case !exists:
|
||||
missing = append(missing, fmt.Sprintf("Missing: \"%s\" %v", ifaceMethod.Name, ifaceMethod.Type))
|
||||
continue // ### continue, error found ###
|
||||
|
||||
case ifaceMethod.Type.NumOut() != objMethod.Type.NumOut():
|
||||
signatureMismatch = true
|
||||
|
||||
case ifaceMethod.Type.NumIn()+1 != objMethod.Type.NumIn():
|
||||
signatureMismatch = true
|
||||
|
||||
default:
|
||||
for oIdx := 0; !signatureMismatch && oIdx < ifaceMethod.Type.NumOut(); oIdx++ {
|
||||
signatureMismatch = ifaceMethod.Type.Out(oIdx) != objMethod.Type.Out(oIdx)
|
||||
}
|
||||
for iIdx := 0; !signatureMismatch && iIdx < ifaceMethod.Type.NumIn(); iIdx++ {
|
||||
signatureMismatch = ifaceMethod.Type.In(iIdx) != objMethod.Type.In(iIdx+1)
|
||||
}
|
||||
}
|
||||
|
||||
if signatureMismatch {
|
||||
missing = append(missing, fmt.Sprintf("Invalid: \"%s\" %v is not %v", ifaceMethod.Name, objMethod.Type, ifaceMethod.Type))
|
||||
}
|
||||
}
|
||||
|
||||
return float32(methodCount-len(missing)) / float32(methodCount), missing
|
||||
}
|
||||
|
||||
// Int64 converts any signed number type to an int64.
|
||||
// The second parameter is returned as false if a non-number type was given.
|
||||
func Int64(v interface{}) (int64, bool) {
|
||||
|
||||
switch reflect.TypeOf(v).Kind() {
|
||||
case reflect.Int:
|
||||
return int64(v.(int)), true
|
||||
case reflect.Int8:
|
||||
return int64(v.(int8)), true
|
||||
case reflect.Int16:
|
||||
return int64(v.(int16)), true
|
||||
case reflect.Int32:
|
||||
return int64(v.(int32)), true
|
||||
case reflect.Int64:
|
||||
return v.(int64), true
|
||||
case reflect.Float32:
|
||||
return int64(v.(float32)), true
|
||||
case reflect.Float64:
|
||||
return int64(v.(float64)), true
|
||||
}
|
||||
|
||||
fmt.Printf("%t\n%#v\n%#v\n", v, v, reflect.TypeOf(v).Kind())
|
||||
|
||||
return 0, false
|
||||
}
|
||||
|
||||
// Uint64 converts any unsigned number type to an uint64.
|
||||
// The second parameter is returned as false if a non-number type was given.
|
||||
func Uint64(v interface{}) (uint64, bool) {
|
||||
|
||||
switch reflect.TypeOf(v).Kind() {
|
||||
case reflect.Uint:
|
||||
return uint64(v.(uint)), true
|
||||
case reflect.Uint8:
|
||||
return uint64(v.(uint8)), true
|
||||
case reflect.Uint16:
|
||||
return uint64(v.(uint16)), true
|
||||
case reflect.Uint32:
|
||||
return uint64(v.(uint32)), true
|
||||
case reflect.Uint64:
|
||||
return v.(uint64), true
|
||||
}
|
||||
|
||||
return 0, false
|
||||
}
|
||||
|
||||
// Float32 converts any number type to an float32.
|
||||
// The second parameter is returned as false if a non-number type was given.
|
||||
func Float32(v interface{}) (float32, bool) {
|
||||
|
||||
switch reflect.TypeOf(v).Kind() {
|
||||
case reflect.Int:
|
||||
return float32(v.(int)), true
|
||||
case reflect.Uint:
|
||||
return float32(v.(uint)), true
|
||||
case reflect.Int8:
|
||||
return float32(v.(int8)), true
|
||||
case reflect.Uint8:
|
||||
return float32(v.(uint8)), true
|
||||
case reflect.Int16:
|
||||
return float32(v.(int16)), true
|
||||
case reflect.Uint16:
|
||||
return float32(v.(uint16)), true
|
||||
case reflect.Int32:
|
||||
return float32(v.(int32)), true
|
||||
case reflect.Uint32:
|
||||
return float32(v.(uint32)), true
|
||||
case reflect.Int64:
|
||||
return float32(v.(int64)), true
|
||||
case reflect.Uint64:
|
||||
return float32(v.(uint64)), true
|
||||
case reflect.Float32:
|
||||
return v.(float32), true
|
||||
case reflect.Float64:
|
||||
return float32(v.(float64)), true
|
||||
}
|
||||
|
||||
return 0, false
|
||||
}
|
||||
|
||||
// Float64 converts any number type to an float64.
|
||||
// The second parameter is returned as false if a non-number type was given.
|
||||
func Float64(v interface{}) (float64, bool) {
|
||||
|
||||
switch reflect.TypeOf(v).Kind() {
|
||||
case reflect.Int:
|
||||
return float64(v.(int)), true
|
||||
case reflect.Uint:
|
||||
return float64(v.(uint)), true
|
||||
case reflect.Int8:
|
||||
return float64(v.(int8)), true
|
||||
case reflect.Uint8:
|
||||
return float64(v.(uint8)), true
|
||||
case reflect.Int16:
|
||||
return float64(v.(int16)), true
|
||||
case reflect.Uint16:
|
||||
return float64(v.(uint16)), true
|
||||
case reflect.Int32:
|
||||
return float64(v.(int32)), true
|
||||
case reflect.Uint32:
|
||||
return float64(v.(uint32)), true
|
||||
case reflect.Int64:
|
||||
return float64(v.(int64)), true
|
||||
case reflect.Uint64:
|
||||
return float64(v.(uint64)), true
|
||||
case reflect.Float32:
|
||||
return float64(v.(float32)), true
|
||||
case reflect.Float64:
|
||||
return v.(float64), true
|
||||
}
|
||||
|
||||
return 0, false
|
||||
}
|
||||
|
||||
// RemovePtrFromType will return the type of t and strips away any pointer(s)
|
||||
// in front of the actual type.
|
||||
func RemovePtrFromType(t interface{}) reflect.Type {
|
||||
var v reflect.Type
|
||||
if rt, isType := t.(reflect.Type); isType {
|
||||
v = rt
|
||||
} else {
|
||||
v = reflect.TypeOf(t)
|
||||
}
|
||||
for v.Kind() == reflect.Ptr {
|
||||
v = v.Elem()
|
||||
}
|
||||
return v
|
||||
}
|
||||
|
||||
// RemovePtrFromValue will return the value of t and strips away any pointer(s)
|
||||
// in front of the actual type.
|
||||
func RemovePtrFromValue(t interface{}) reflect.Value {
|
||||
var v reflect.Value
|
||||
if rv, isValue := t.(reflect.Value); isValue {
|
||||
v = rv
|
||||
} else {
|
||||
v = reflect.ValueOf(t)
|
||||
}
|
||||
for v.Type().Kind() == reflect.Ptr {
|
||||
v = v.Elem()
|
||||
}
|
||||
return v
|
||||
}
|
||||
|
||||
// UnsafeCopy will copy data from src to dst while ignoring type information.
|
||||
// Both types need to be of the same size and dst and src have to be pointers.
|
||||
// UnsafeCopy will panic if these requirements are not met.
|
||||
func UnsafeCopy(dst, src interface{}) {
|
||||
dstValue := reflect.ValueOf(dst)
|
||||
srcValue := reflect.ValueOf(src)
|
||||
UnsafeCopyValue(dstValue, srcValue)
|
||||
}
|
||||
|
||||
// UnsafeCopyValue will copy data from src to dst while ignoring type
|
||||
// information. Both types need to be of the same size or this function will
|
||||
// panic. Also both types must support dereferencing via reflect.Elem()
|
||||
func UnsafeCopyValue(dstValue reflect.Value, srcValue reflect.Value) {
|
||||
dstType := dstValue.Elem().Type()
|
||||
srcType := srcValue.Type()
|
||||
|
||||
var srcPtr uintptr
|
||||
if srcValue.Kind() != reflect.Ptr {
|
||||
// If we don't get a pointer to our source data we need to forcefully
|
||||
// retrieve it by accessing the interface pointer. This is ok as we
|
||||
// only read from it.
|
||||
iface := srcValue.Interface()
|
||||
srcPtr = reflect.ValueOf(&iface).Elem().InterfaceData()[1] // Pointer to data
|
||||
} else {
|
||||
srcType = srcValue.Elem().Type()
|
||||
srcPtr = srcValue.Pointer()
|
||||
}
|
||||
|
||||
if dstType.Size() != srcType.Size() {
|
||||
panic("Type size mismatch between " + dstType.String() + " and " + srcType.String())
|
||||
}
|
||||
|
||||
dstAsSlice := *(*[]byte)(unsafe.Pointer(&reflect.SliceHeader{
|
||||
Data: dstValue.Pointer(),
|
||||
Len: int(dstType.Size()),
|
||||
Cap: int(dstType.Size()),
|
||||
}))
|
||||
|
||||
srcAsSlice := *(*[]byte)(unsafe.Pointer(&reflect.SliceHeader{
|
||||
Data: srcPtr,
|
||||
Len: int(srcType.Size()),
|
||||
Cap: int(srcType.Size()),
|
||||
}))
|
||||
|
||||
copy(dstAsSlice, srcAsSlice)
|
||||
}
|
||||
|
||||
// SetMemberByName sets member name of the given pointer-to-struct to the data
|
||||
// passed to this function. The member may be private, too.
|
||||
func SetMemberByName(ptrToStruct interface{}, name string, data interface{}) {
|
||||
structVal := reflect.Indirect(reflect.ValueOf(ptrToStruct))
|
||||
member := structVal.FieldByName(name)
|
||||
|
||||
SetValue(member, data)
|
||||
}
|
||||
|
||||
// SetMemberByIndex sets member idx of the given pointer-to-struct to the data
|
||||
// passed to this function. The member may be private, too.
|
||||
func SetMemberByIndex(ptrToStruct interface{}, idx int, data interface{}) {
|
||||
structVal := reflect.Indirect(reflect.ValueOf(ptrToStruct))
|
||||
member := structVal.Field(idx)
|
||||
|
||||
SetValue(member, data)
|
||||
}
|
||||
|
||||
// SetValue sets an addressable value to the data passed to this function.
|
||||
// In contrast to golangs reflect package this will also work with private
|
||||
// variables. Please note that this function may not support all types, yet.
|
||||
func SetValue(member reflect.Value, data interface{}) {
|
||||
if member.CanSet() {
|
||||
member.Set(reflect.ValueOf(data).Convert(member.Type()))
|
||||
return // ### return, easy way ###
|
||||
}
|
||||
|
||||
if !member.CanAddr() {
|
||||
panic("SetValue requires addressable member type")
|
||||
}
|
||||
|
||||
ptrToMember := unsafe.Pointer(member.UnsafeAddr())
|
||||
dataValue := reflect.ValueOf(data)
|
||||
|
||||
switch member.Kind() {
|
||||
case reflect.Bool:
|
||||
*(*bool)(ptrToMember) = dataValue.Bool()
|
||||
|
||||
case reflect.Uint:
|
||||
*(*uint)(ptrToMember) = uint(dataValue.Uint())
|
||||
|
||||
case reflect.Uint8:
|
||||
*(*uint8)(ptrToMember) = uint8(dataValue.Uint())
|
||||
|
||||
case reflect.Uint16:
|
||||
*(*uint16)(ptrToMember) = uint16(dataValue.Uint())
|
||||
|
||||
case reflect.Uint32:
|
||||
*(*uint32)(ptrToMember) = uint32(dataValue.Uint())
|
||||
|
||||
case reflect.Uint64:
|
||||
*(*uint64)(ptrToMember) = dataValue.Uint()
|
||||
|
||||
case reflect.Int:
|
||||
*(*int)(ptrToMember) = int(dataValue.Int())
|
||||
|
||||
case reflect.Int8:
|
||||
*(*int8)(ptrToMember) = int8(dataValue.Int())
|
||||
|
||||
case reflect.Int16:
|
||||
*(*int16)(ptrToMember) = int16(dataValue.Int())
|
||||
|
||||
case reflect.Int32:
|
||||
*(*int32)(ptrToMember) = int32(dataValue.Int())
|
||||
|
||||
case reflect.Int64:
|
||||
*(*int64)(ptrToMember) = dataValue.Int()
|
||||
|
||||
case reflect.Float32:
|
||||
*(*float32)(ptrToMember) = float32(dataValue.Float())
|
||||
|
||||
case reflect.Float64:
|
||||
*(*float64)(ptrToMember) = dataValue.Float()
|
||||
|
||||
case reflect.Complex64:
|
||||
*(*complex64)(ptrToMember) = complex64(dataValue.Complex())
|
||||
|
||||
case reflect.Complex128:
|
||||
*(*complex128)(ptrToMember) = dataValue.Complex()
|
||||
|
||||
case reflect.String:
|
||||
*(*string)(ptrToMember) = dataValue.String()
|
||||
|
||||
case reflect.Map, reflect.Chan:
|
||||
// Exploit the fact that "map" is actually "*runtime.hmap" and force
|
||||
// overwrite that pointer in the passed struct.
|
||||
// Same foes for "chan" which is actually "*runtime.hchan".
|
||||
|
||||
// Note: Assigning a map or channel to another variable does NOT copy
|
||||
// the contents so copying the pointer follows go's standard behavior.
|
||||
dataAsPtr := unsafe.Pointer(dataValue.Pointer())
|
||||
*(**uintptr)(ptrToMember) = (*uintptr)(dataAsPtr)
|
||||
|
||||
case reflect.Interface:
|
||||
// Interfaces are basically two pointers, see runtime.iface.
|
||||
// We want to modify exactly that data, which is returned by
|
||||
// the InterfaceData() method.
|
||||
|
||||
if dataValue.Kind() != reflect.Interface {
|
||||
// A type reference was passed. In order to overwrite the memory
|
||||
// Representation of an interface we need to generate it first.
|
||||
// Reflect does not allow us to do that unless we use the
|
||||
// InterfaceData method which exposes the internal representation
|
||||
// of an interface.
|
||||
interfaceData := reflect.ValueOf(&data).Elem().InterfaceData()
|
||||
dataValue = reflect.ValueOf(interfaceData)
|
||||
}
|
||||
fallthrough
|
||||
|
||||
default:
|
||||
// Complex types are assigned memcpy style.
|
||||
// Note: This should not break the garbage collector although we cannot
|
||||
// be 100% sure on this.
|
||||
UnsafeCopyValue(member.Addr(), dataValue)
|
||||
}
|
||||
}
|
||||
97
vendor/github.com/trivago/tgo/treflect/typeregistry.go
generated
vendored
Normal file
97
vendor/github.com/trivago/tgo/treflect/typeregistry.go
generated
vendored
Normal file
@@ -0,0 +1,97 @@
|
||||
// Copyright 2015-2016 trivago GmbH
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package treflect
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// TypeRegistry is a name to type registry used to create objects by name.
|
||||
type TypeRegistry struct {
|
||||
namedType map[string]reflect.Type
|
||||
}
|
||||
|
||||
// NewTypeRegistry creates a new TypeRegistry. Note that there is a global type
|
||||
// registry available in the main tgo package (tgo.TypeRegistry).
|
||||
func NewTypeRegistry() TypeRegistry {
|
||||
return TypeRegistry{
|
||||
namedType: make(map[string]reflect.Type),
|
||||
}
|
||||
}
|
||||
|
||||
// Register a plugin to the TypeRegistry by passing an uninitialized object.
|
||||
func (registry TypeRegistry) Register(typeInstance interface{}) {
|
||||
registry.RegisterWithDepth(typeInstance, 1)
|
||||
}
|
||||
|
||||
// RegisterWithDepth to register a plugin to the TypeRegistry by passing an uninitialized object.
|
||||
func (registry TypeRegistry) RegisterWithDepth(typeInstance interface{}, depth int) {
|
||||
structType := reflect.TypeOf(typeInstance)
|
||||
packageName := structType.PkgPath()
|
||||
typeName := structType.Name()
|
||||
|
||||
pathTokens := strings.Split(packageName, "/")
|
||||
maxDepth := 3
|
||||
if len(pathTokens) < maxDepth {
|
||||
maxDepth = len(pathTokens)
|
||||
}
|
||||
|
||||
for n := depth; n <= maxDepth; n++ {
|
||||
shortTypeName := strings.Join(pathTokens[len(pathTokens)-n:], ".") + "." + typeName
|
||||
registry.namedType[shortTypeName] = structType
|
||||
}
|
||||
}
|
||||
|
||||
// New creates an uninitialized object by class name.
|
||||
// The class name has to be "package.class" or "package/subpackage.class".
|
||||
// The gollum package is omitted from the package path.
|
||||
func (registry TypeRegistry) New(typeName string) (interface{}, error) {
|
||||
structType, exists := registry.namedType[typeName]
|
||||
if exists {
|
||||
return reflect.New(structType).Interface(), nil
|
||||
}
|
||||
return nil, fmt.Errorf("Unknown class: %s", typeName)
|
||||
}
|
||||
|
||||
// GetTypeOf returns only the type asscociated with the given name.
|
||||
// If the name is not registered, nil is returned.
|
||||
// The type returned will be a pointer type.
|
||||
func (registry TypeRegistry) GetTypeOf(typeName string) reflect.Type {
|
||||
if structType, exists := registry.namedType[typeName]; exists {
|
||||
return reflect.PtrTo(structType)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// IsTypeRegistered returns true if a type is registered to this registry.
|
||||
// Note that GetTypeOf can do the same thing by checking for nil but also
|
||||
// returns the type, so in many cases you will want to call this function.
|
||||
func (registry TypeRegistry) IsTypeRegistered(typeName string) bool {
|
||||
_, exists := registry.namedType[typeName]
|
||||
return exists
|
||||
}
|
||||
|
||||
// GetRegistered returns the names of all registered types for a given package
|
||||
func (registry TypeRegistry) GetRegistered(packageName string) []string {
|
||||
var result []string
|
||||
for key := range registry.namedType {
|
||||
if strings.HasPrefix(key, packageName) {
|
||||
result = append(result, key)
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
24
vendor/github.com/xanzy/go-gitlab/.gitignore
generated
vendored
Normal file
24
vendor/github.com/xanzy/go-gitlab/.gitignore
generated
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
# Compiled Object files, Static and Dynamic libs (Shared Objects)
|
||||
*.o
|
||||
*.a
|
||||
*.so
|
||||
|
||||
# Folders
|
||||
_obj
|
||||
_test
|
||||
|
||||
# Architecture specific extensions/prefixes
|
||||
*.[568vq]
|
||||
[568vq].out
|
||||
|
||||
*.cgo1.go
|
||||
*.cgo2.c
|
||||
_cgo_defun.c
|
||||
_cgo_gotypes.go
|
||||
_cgo_export.*
|
||||
|
||||
_testmain.go
|
||||
|
||||
*.exe
|
||||
*.test
|
||||
*.prof
|
||||
27
vendor/github.com/xanzy/go-gitlab/.travis.yml
generated
vendored
Normal file
27
vendor/github.com/xanzy/go-gitlab/.travis.yml
generated
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
language: go
|
||||
|
||||
go:
|
||||
- 1.8.x
|
||||
- 1.9.x
|
||||
- 1.10.x
|
||||
- master
|
||||
|
||||
stages:
|
||||
- lint
|
||||
- test
|
||||
|
||||
jobs:
|
||||
include:
|
||||
- stage: lint
|
||||
script:
|
||||
- go get github.com/golang/lint/golint
|
||||
- golint -set_exit_status
|
||||
- go vet -v
|
||||
- stage: test
|
||||
script:
|
||||
- go test -v
|
||||
|
||||
matrix:
|
||||
allow_failures:
|
||||
- go: master
|
||||
fast_finish: true
|
||||
27
vendor/github.com/xanzy/go-gitlab/CHANGELOG.md
generated
vendored
Normal file
27
vendor/github.com/xanzy/go-gitlab/CHANGELOG.md
generated
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
go-github CHANGELOG
|
||||
===================
|
||||
|
||||
0.6.0
|
||||
-----
|
||||
- Add support for the V4 Gitlab API. This means the older V3 API is no longer fully supported
|
||||
with this version. If you still need that version, please use the `f-api-v3` branch.
|
||||
|
||||
0.4.0
|
||||
-----
|
||||
- Add support to use [`sudo`](https://docs.gitlab.com/ce/api/README.html#sudo) for all API calls.
|
||||
- Add support for the Notification Settings API.
|
||||
- Add support for the Time Tracking API.
|
||||
- Make sure that the error response correctly outputs any returned errors.
|
||||
- And a reasonable number of smaller enhanchements and bugfixes.
|
||||
|
||||
0.3.0
|
||||
-----
|
||||
- Moved the tags related API calls to their own service, following the Gitlab API structure.
|
||||
|
||||
0.2.0
|
||||
-----
|
||||
- Convert all Option structs to use pointers for their fields.
|
||||
|
||||
0.1.0
|
||||
-----
|
||||
- Initial release.
|
||||
202
vendor/github.com/xanzy/go-gitlab/LICENSE
generated
vendored
Normal file
202
vendor/github.com/xanzy/go-gitlab/LICENSE
generated
vendored
Normal file
@@ -0,0 +1,202 @@
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "{}"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright {yyyy} {name of copyright owner}
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
171
vendor/github.com/xanzy/go-gitlab/README.md
generated
vendored
Normal file
171
vendor/github.com/xanzy/go-gitlab/README.md
generated
vendored
Normal file
@@ -0,0 +1,171 @@
|
||||
# go-gitlab
|
||||
|
||||
A GitLab API client enabling Go programs to interact with GitLab in a simple and uniform way
|
||||
|
||||
[](https://travis-ci.org/xanzy/go-gitlab)
|
||||
[](https://github.com/xanzy/go-gitlab/blob/master/LICENSE)
|
||||
[](https://sourcegraph.com/github.com/xanzy/go-gitlab?badge)
|
||||
[](https://godoc.org/github.com/xanzy/go-gitlab)
|
||||
[](https://goreportcard.com/report/github.com/xanzy/go-gitlab)
|
||||
[](https://github.com/xanzy/go-gitlab/issues)
|
||||
|
||||
## NOTE
|
||||
|
||||
Release v0.6.0 (released on 25-08-2017) no longer supports the older V3 Gitlab API. If
|
||||
you need V3 support, please use the `f-api-v3` branch. This release contains some backwards
|
||||
incompatible changes that were needed to fully support the V4 Gitlab API.
|
||||
|
||||
## Coverage
|
||||
|
||||
This API client package covers most of the existing Gitlab API calls and is updated regularly
|
||||
to add new and/or missing endpoints. Currently the following services are supported:
|
||||
|
||||
- [x] Award Emojis
|
||||
- [x] Branches
|
||||
- [x] Broadcast Messages
|
||||
- [ ] Project-level Variables
|
||||
- [ ] Group-level Variables
|
||||
- [x] Commits
|
||||
- [ ] Custom Attributes
|
||||
- [x] Deployments
|
||||
- [x] Deploy Keys
|
||||
- [x] Environments
|
||||
- [ ] Epics
|
||||
- [ ] Epic Issues
|
||||
- [x] Events
|
||||
- [x] Feature flags
|
||||
- [ ] Geo Nodes
|
||||
- [x] Gitignores templates
|
||||
- [ ] GitLab CI Config templates
|
||||
- [x] Groups
|
||||
- [ ] Group Access Requests
|
||||
- [x] Group Members
|
||||
- [x] Issues
|
||||
- [x] Issue Boards
|
||||
- [x] Jobs
|
||||
- [ ] Keys
|
||||
- [x] Labels
|
||||
- [ ] License
|
||||
- [x] Merge Requests
|
||||
- [x] Merge Request Approvals
|
||||
- [x] Project Milestones
|
||||
- [ ] Group Milestones
|
||||
- [x] Namespaces
|
||||
- [x] Notes (comments)
|
||||
- [ ] Discussions (threaded comments)
|
||||
- [x] Notification settings
|
||||
- [ ] Open source license templates
|
||||
- [x] Pages Domains
|
||||
- [x] Pipelines
|
||||
- [x] Pipeline Triggers
|
||||
- [x] Pipeline Schedules
|
||||
- [x] Projects (including setting Webhooks)
|
||||
- [ ] Project Access Requests
|
||||
- [ ] Project badges
|
||||
- [ ] Project import/export
|
||||
- [x] Project Members
|
||||
- [x] Project Snippets
|
||||
- [x] Protected Branches
|
||||
- [x] Repositories
|
||||
- [x] Repository Files
|
||||
- [x] Runners
|
||||
- [ ] Search
|
||||
- [x] Services
|
||||
- [x] Settings
|
||||
- [x] Sidekiq metrics
|
||||
- [x] Session
|
||||
- [x] System Hooks
|
||||
- [x] Tags
|
||||
- [x] Todos
|
||||
- [x] Users
|
||||
- [x] Validate CI configuration
|
||||
- [x] Version
|
||||
- [x] Wikis
|
||||
|
||||
## Usage
|
||||
|
||||
```go
|
||||
import "github.com/xanzy/go-gitlab"
|
||||
```
|
||||
|
||||
Construct a new GitLab client, then use the various services on the client to
|
||||
access different parts of the GitLab API. For example, to list all
|
||||
users:
|
||||
|
||||
```go
|
||||
git := gitlab.NewClient(nil, "yourtokengoeshere")
|
||||
//git.SetBaseURL("https://git.mydomain.com/api/v3")
|
||||
users, _, err := git.Users.ListUsers()
|
||||
```
|
||||
|
||||
Some API methods have optional parameters that can be passed. For example,
|
||||
to list all projects for user "svanharmelen":
|
||||
|
||||
```go
|
||||
git := gitlab.NewClient(nil)
|
||||
opt := &ListProjectsOptions{Search: gitlab.String("svanharmelen")}
|
||||
projects, _, err := git.Projects.ListProjects(opt)
|
||||
```
|
||||
|
||||
### Examples
|
||||
|
||||
The [examples](https://github.com/xanzy/go-gitlab/tree/master/examples) directory
|
||||
contains a couple for clear examples, of which one is partially listed here as well:
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"log"
|
||||
|
||||
"github.com/xanzy/go-gitlab"
|
||||
)
|
||||
|
||||
func main() {
|
||||
git := gitlab.NewClient(nil, "yourtokengoeshere")
|
||||
|
||||
// Create new project
|
||||
p := &gitlab.CreateProjectOptions{
|
||||
Name: gitlab.String("My Project"),
|
||||
Description: gitlab.String("Just a test project to play with"),
|
||||
MergeRequestsEnabled: gitlab.Bool(true),
|
||||
SnippetsEnabled: gitlab.Bool(true),
|
||||
Visibility: gitlab.Visibility(gitlab.PublicVisibility),
|
||||
}
|
||||
project, _, err := git.Projects.CreateProject(p)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
// Add a new snippet
|
||||
s := &gitlab.CreateProjectSnippetOptions{
|
||||
Title: gitlab.String("Dummy Snippet"),
|
||||
FileName: gitlab.String("snippet.go"),
|
||||
Code: gitlab.String("package main...."),
|
||||
Visibility: gitlab.Visibility(gitlab.PublicVisibility),
|
||||
}
|
||||
_, _, err = git.ProjectSnippets.CreateSnippet(project.ID, s)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
For complete usage of go-gitlab, see the full [package docs](https://godoc.org/github.com/xanzy/go-gitlab).
|
||||
|
||||
## ToDo
|
||||
|
||||
- The biggest thing this package still needs is tests :disappointed:
|
||||
|
||||
## Issues
|
||||
|
||||
- If you have an issue: report it on the [issue tracker](https://github.com/xanzy/go-gitlab/issues)
|
||||
|
||||
## Author
|
||||
|
||||
Sander van Harmelen (<sander@xanzy.io>)
|
||||
|
||||
## License
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at <http://www.apache.org/licenses/LICENSE-2.0>
|
||||
468
vendor/github.com/xanzy/go-gitlab/award_emojis.go
generated
vendored
Normal file
468
vendor/github.com/xanzy/go-gitlab/award_emojis.go
generated
vendored
Normal file
@@ -0,0 +1,468 @@
|
||||
//
|
||||
// Copyright 2017, Arkbriar
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
package gitlab
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/url"
|
||||
"time"
|
||||
)
|
||||
|
||||
// AwardEmojiService handles communication with the emoji awards related methods
|
||||
// of the GitLab API.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/award_emoji.html
|
||||
type AwardEmojiService struct {
|
||||
client *Client
|
||||
}
|
||||
|
||||
// AwardEmoji represents a GitLab Award Emoji.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/award_emoji.html
|
||||
type AwardEmoji struct {
|
||||
ID int `json:"id"`
|
||||
Name string `json:"name"`
|
||||
User struct {
|
||||
Name string `json:"name"`
|
||||
Username string `json:"username"`
|
||||
ID int `json:"id"`
|
||||
State string `json:"state"`
|
||||
AvatarURL string `json:"avatar_url"`
|
||||
WebURL string `json:"web_url"`
|
||||
} `json:"user"`
|
||||
CreatedAt *time.Time `json:"created_at"`
|
||||
UpdatedAt *time.Time `json:"updated_at"`
|
||||
AwardableID int `json:"awardable_id"`
|
||||
AwardableType string `json:"awardable_type"`
|
||||
}
|
||||
|
||||
const (
|
||||
awardMergeRequest = "merge_requests"
|
||||
awardIssue = "issues"
|
||||
awardSnippets = "snippets"
|
||||
)
|
||||
|
||||
// ListAwardEmojiOptions represents the available options for listing emoji
|
||||
// for each resources
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/award_emoji.html
|
||||
type ListAwardEmojiOptions ListOptions
|
||||
|
||||
// ListMergeRequestAwardEmoji gets a list of all award emoji on the merge request.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/award_emoji.html#list-an-awardable-39-s-award-emoji
|
||||
func (s *AwardEmojiService) ListMergeRequestAwardEmoji(pid interface{}, mergeRequestIID int, opt *ListAwardEmojiOptions, options ...OptionFunc) ([]*AwardEmoji, *Response, error) {
|
||||
return s.listAwardEmoji(pid, awardMergeRequest, mergeRequestIID, opt, options...)
|
||||
}
|
||||
|
||||
// ListIssueAwardEmoji gets a list of all award emoji on the issue.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/award_emoji.html#list-an-awardable-39-s-award-emoji
|
||||
func (s *AwardEmojiService) ListIssueAwardEmoji(pid interface{}, issueIID int, opt *ListAwardEmojiOptions, options ...OptionFunc) ([]*AwardEmoji, *Response, error) {
|
||||
return s.listAwardEmoji(pid, awardIssue, issueIID, opt, options...)
|
||||
}
|
||||
|
||||
// ListSnippetAwardEmoji gets a list of all award emoji on the snippet.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/award_emoji.html#list-an-awardable-39-s-award-emoji
|
||||
func (s *AwardEmojiService) ListSnippetAwardEmoji(pid interface{}, snippetID int, opt *ListAwardEmojiOptions, options ...OptionFunc) ([]*AwardEmoji, *Response, error) {
|
||||
return s.listAwardEmoji(pid, awardSnippets, snippetID, opt, options...)
|
||||
}
|
||||
|
||||
func (s *AwardEmojiService) listAwardEmoji(pid interface{}, resource string, resourceID int, opt *ListAwardEmojiOptions, options ...OptionFunc) ([]*AwardEmoji, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/%s/%d/award_emoji",
|
||||
url.QueryEscape(project),
|
||||
resource,
|
||||
resourceID,
|
||||
)
|
||||
|
||||
req, err := s.client.NewRequest("GET", u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
var as []*AwardEmoji
|
||||
resp, err := s.client.Do(req, &as)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return as, resp, err
|
||||
}
|
||||
|
||||
// GetMergeRequestAwardEmoji get an award emoji from merge request.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/award_emoji.html#list-an-awardable-39-s-award-emoji
|
||||
func (s *AwardEmojiService) GetMergeRequestAwardEmoji(pid interface{}, mergeRequestIID, awardID int, options ...OptionFunc) (*AwardEmoji, *Response, error) {
|
||||
return s.getAwardEmoji(pid, awardMergeRequest, mergeRequestIID, awardID, options...)
|
||||
}
|
||||
|
||||
// GetIssueAwardEmoji get an award emoji from issue.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/award_emoji.html#list-an-awardable-39-s-award-emoji
|
||||
func (s *AwardEmojiService) GetIssueAwardEmoji(pid interface{}, issueIID, awardID int, options ...OptionFunc) (*AwardEmoji, *Response, error) {
|
||||
return s.getAwardEmoji(pid, awardIssue, issueIID, awardID, options...)
|
||||
}
|
||||
|
||||
// GetSnippetAwardEmoji get an award emoji from snippet.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/award_emoji.html#list-an-awardable-39-s-award-emoji
|
||||
func (s *AwardEmojiService) GetSnippetAwardEmoji(pid interface{}, snippetID, awardID int, options ...OptionFunc) (*AwardEmoji, *Response, error) {
|
||||
return s.getAwardEmoji(pid, awardSnippets, snippetID, awardID, options...)
|
||||
}
|
||||
|
||||
func (s *AwardEmojiService) getAwardEmoji(pid interface{}, resource string, resourceID, awardID int, options ...OptionFunc) (*AwardEmoji, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/%s/%d/award_emoji/%d",
|
||||
url.QueryEscape(project),
|
||||
resource,
|
||||
resourceID,
|
||||
awardID,
|
||||
)
|
||||
|
||||
req, err := s.client.NewRequest("GET", u, nil, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
a := new(AwardEmoji)
|
||||
resp, err := s.client.Do(req, &a)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return a, resp, err
|
||||
}
|
||||
|
||||
// CreateAwardEmojiOptions represents the available options for awarding emoji
|
||||
// for a resource
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/award_emoji.html#award-a-new-emoji
|
||||
type CreateAwardEmojiOptions struct {
|
||||
Name string `json:"name"`
|
||||
}
|
||||
|
||||
// CreateMergeRequestAwardEmoji get an award emoji from merge request.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/award_emoji.html#award-a-new-emoji
|
||||
func (s *AwardEmojiService) CreateMergeRequestAwardEmoji(pid interface{}, mergeRequestIID int, opt *CreateAwardEmojiOptions, options ...OptionFunc) (*AwardEmoji, *Response, error) {
|
||||
return s.createAwardEmoji(pid, awardMergeRequest, mergeRequestIID, opt, options...)
|
||||
}
|
||||
|
||||
// CreateIssueAwardEmoji get an award emoji from issue.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/award_emoji.html#award-a-new-emoji
|
||||
func (s *AwardEmojiService) CreateIssueAwardEmoji(pid interface{}, issueIID int, opt *CreateAwardEmojiOptions, options ...OptionFunc) (*AwardEmoji, *Response, error) {
|
||||
return s.createAwardEmoji(pid, awardIssue, issueIID, opt, options...)
|
||||
}
|
||||
|
||||
// CreateSnippetAwardEmoji get an award emoji from snippet.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/award_emoji.html#award-a-new-emoji
|
||||
func (s *AwardEmojiService) CreateSnippetAwardEmoji(pid interface{}, snippetID int, opt *CreateAwardEmojiOptions, options ...OptionFunc) (*AwardEmoji, *Response, error) {
|
||||
return s.createAwardEmoji(pid, awardSnippets, snippetID, opt, options...)
|
||||
}
|
||||
|
||||
func (s *AwardEmojiService) createAwardEmoji(pid interface{}, resource string, resourceID int, opt *CreateAwardEmojiOptions, options ...OptionFunc) (*AwardEmoji, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/%s/%d/award_emoji",
|
||||
url.QueryEscape(project),
|
||||
resource,
|
||||
resourceID,
|
||||
)
|
||||
|
||||
req, err := s.client.NewRequest("POST", u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
a := new(AwardEmoji)
|
||||
resp, err := s.client.Do(req, &a)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return a, resp, err
|
||||
}
|
||||
|
||||
// DeleteIssueAwardEmoji delete award emoji on an issue.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/award_emoji.html#award-a-new-emoji-on-a-note
|
||||
func (s *AwardEmojiService) DeleteIssueAwardEmoji(pid interface{}, issueIID, awardID int, options ...OptionFunc) (*Response, error) {
|
||||
return s.deleteAwardEmoji(pid, awardMergeRequest, issueIID, awardID, options...)
|
||||
}
|
||||
|
||||
// DeleteMergeRequestAwardEmoji delete award emoji on a merge request.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/award_emoji.html#award-a-new-emoji-on-a-note
|
||||
func (s *AwardEmojiService) DeleteMergeRequestAwardEmoji(pid interface{}, mergeRequestIID, awardID int, options ...OptionFunc) (*Response, error) {
|
||||
return s.deleteAwardEmoji(pid, awardMergeRequest, mergeRequestIID, awardID, options...)
|
||||
}
|
||||
|
||||
// DeleteSnippetAwardEmoji delete award emoji on a snippet.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/award_emoji.html#award-a-new-emoji-on-a-note
|
||||
func (s *AwardEmojiService) DeleteSnippetAwardEmoji(pid interface{}, snippetID, awardID int, options ...OptionFunc) (*Response, error) {
|
||||
return s.deleteAwardEmoji(pid, awardMergeRequest, snippetID, awardID, options...)
|
||||
}
|
||||
|
||||
// DeleteAwardEmoji Delete an award emoji on the specified resource.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/award_emoji.html#delete-an-award-emoji
|
||||
func (s *AwardEmojiService) deleteAwardEmoji(pid interface{}, resource string, resourceID, awardID int, options ...OptionFunc) (*Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/%s/%d/award_emoji/%d", url.QueryEscape(project), resource,
|
||||
resourceID, awardID)
|
||||
|
||||
req, err := s.client.NewRequest("DELETE", u, nil, options)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return s.client.Do(req, nil)
|
||||
}
|
||||
|
||||
// ListIssuesAwardEmojiOnNote gets a list of all award emoji on a note from the
|
||||
// issue.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/award_emoji.html#award-emoji-on-notes
|
||||
func (s *AwardEmojiService) ListIssuesAwardEmojiOnNote(pid interface{}, issueID, noteID int, opt *ListAwardEmojiOptions, options ...OptionFunc) ([]*AwardEmoji, *Response, error) {
|
||||
return s.listAwardEmojiOnNote(pid, awardIssue, issueID, noteID, opt, options...)
|
||||
}
|
||||
|
||||
// ListMergeRequestAwardEmojiOnNote gets a list of all award emoji on a note
|
||||
// from the merge request.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/award_emoji.html#award-emoji-on-notes
|
||||
func (s *AwardEmojiService) ListMergeRequestAwardEmojiOnNote(pid interface{}, mergeRequestIID, noteID int, opt *ListAwardEmojiOptions, options ...OptionFunc) ([]*AwardEmoji, *Response, error) {
|
||||
return s.listAwardEmojiOnNote(pid, awardMergeRequest, mergeRequestIID, noteID, opt, options...)
|
||||
}
|
||||
|
||||
// ListSnippetAwardEmojiOnNote gets a list of all award emoji on a note from the
|
||||
// snippet.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/award_emoji.html#award-emoji-on-notes
|
||||
func (s *AwardEmojiService) ListSnippetAwardEmojiOnNote(pid interface{}, snippetIID, noteID int, opt *ListAwardEmojiOptions, options ...OptionFunc) ([]*AwardEmoji, *Response, error) {
|
||||
return s.listAwardEmojiOnNote(pid, awardSnippets, snippetIID, noteID, opt, options...)
|
||||
}
|
||||
|
||||
func (s *AwardEmojiService) listAwardEmojiOnNote(pid interface{}, resources string, ressourceID, noteID int, opt *ListAwardEmojiOptions, options ...OptionFunc) ([]*AwardEmoji, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/%s/%d/notes/%d/award_emoji", url.QueryEscape(project), resources,
|
||||
ressourceID, noteID)
|
||||
|
||||
req, err := s.client.NewRequest("GET", u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
var as []*AwardEmoji
|
||||
resp, err := s.client.Do(req, &as)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return as, resp, err
|
||||
}
|
||||
|
||||
// GetIssuesAwardEmojiOnNote gets an award emoji on a note from an issue.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/award_emoji.html#award-emoji-on-notes
|
||||
func (s *AwardEmojiService) GetIssuesAwardEmojiOnNote(pid interface{}, issueID, noteID, awardID int, options ...OptionFunc) (*AwardEmoji, *Response, error) {
|
||||
return s.getSingleNoteAwardEmoji(pid, awardIssue, issueID, noteID, awardID, options...)
|
||||
}
|
||||
|
||||
// GetMergeRequestAwardEmojiOnNote gets an award emoji on a note from a
|
||||
// merge request.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/award_emoji.html#award-emoji-on-notes
|
||||
func (s *AwardEmojiService) GetMergeRequestAwardEmojiOnNote(pid interface{}, mergeRequestIID, noteID, awardID int, options ...OptionFunc) (*AwardEmoji, *Response, error) {
|
||||
return s.getSingleNoteAwardEmoji(pid, awardMergeRequest, mergeRequestIID, noteID, awardID,
|
||||
options...)
|
||||
}
|
||||
|
||||
// GetSnippetAwardEmojiOnNote gets an award emoji on a note from a snippet.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/award_emoji.html#award-emoji-on-notes
|
||||
func (s *AwardEmojiService) GetSnippetAwardEmojiOnNote(pid interface{}, snippetIID, noteID, awardID int, options ...OptionFunc) (*AwardEmoji, *Response, error) {
|
||||
return s.getSingleNoteAwardEmoji(pid, awardSnippets, snippetIID, noteID, awardID, options...)
|
||||
}
|
||||
|
||||
func (s *AwardEmojiService) getSingleNoteAwardEmoji(pid interface{}, ressource string, resourceID, noteID, awardID int, options ...OptionFunc) (*AwardEmoji, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/%s/%d/notes/%d/award_emoji/%d",
|
||||
url.QueryEscape(project),
|
||||
ressource,
|
||||
resourceID,
|
||||
noteID,
|
||||
awardID,
|
||||
)
|
||||
|
||||
req, err := s.client.NewRequest("GET", u, nil, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
a := new(AwardEmoji)
|
||||
resp, err := s.client.Do(req, &a)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return a, resp, err
|
||||
}
|
||||
|
||||
// CreateIssuesAwardEmojiOnNote gets an award emoji on a note from an issue.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/award_emoji.html#award-emoji-on-notes
|
||||
func (s *AwardEmojiService) CreateIssuesAwardEmojiOnNote(pid interface{}, issueID, noteID int, opt *CreateAwardEmojiOptions, options ...OptionFunc) (*AwardEmoji, *Response, error) {
|
||||
return s.createAwardEmojiOnNote(pid, awardIssue, issueID, noteID, opt, options...)
|
||||
}
|
||||
|
||||
// CreateMergeRequestAwardEmojiOnNote gets an award emoji on a note from a
|
||||
// merge request.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/award_emoji.html#award-emoji-on-notes
|
||||
func (s *AwardEmojiService) CreateMergeRequestAwardEmojiOnNote(pid interface{}, mergeRequestIID, noteID int, opt *CreateAwardEmojiOptions, options ...OptionFunc) (*AwardEmoji, *Response, error) {
|
||||
return s.createAwardEmojiOnNote(pid, awardMergeRequest, mergeRequestIID, noteID, opt, options...)
|
||||
}
|
||||
|
||||
// CreateSnippetAwardEmojiOnNote gets an award emoji on a note from a snippet.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/award_emoji.html#award-emoji-on-notes
|
||||
func (s *AwardEmojiService) CreateSnippetAwardEmojiOnNote(pid interface{}, snippetIID, noteID int, opt *CreateAwardEmojiOptions, options ...OptionFunc) (*AwardEmoji, *Response, error) {
|
||||
return s.createAwardEmojiOnNote(pid, awardSnippets, snippetIID, noteID, opt, options...)
|
||||
}
|
||||
|
||||
// CreateAwardEmojiOnNote award emoji on a note.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/award_emoji.html#award-a-new-emoji-on-a-note
|
||||
func (s *AwardEmojiService) createAwardEmojiOnNote(pid interface{}, resource string, resourceID, noteID int, opt *CreateAwardEmojiOptions, options ...OptionFunc) (*AwardEmoji, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/%s/%d/notes/%d/award_emoji",
|
||||
url.QueryEscape(project),
|
||||
resource,
|
||||
resourceID,
|
||||
noteID,
|
||||
)
|
||||
|
||||
req, err := s.client.NewRequest("POST", u, nil, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
a := new(AwardEmoji)
|
||||
resp, err := s.client.Do(req, &a)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return a, resp, err
|
||||
}
|
||||
|
||||
// DeleteIssuesAwardEmojiOnNote deletes an award emoji on a note from an issue.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/award_emoji.html#award-emoji-on-notes
|
||||
func (s *AwardEmojiService) DeleteIssuesAwardEmojiOnNote(pid interface{}, issueID, noteID, awardID int, options ...OptionFunc) (*Response, error) {
|
||||
return s.deleteAwardEmojiOnNote(pid, awardIssue, issueID, noteID, awardID, options...)
|
||||
}
|
||||
|
||||
// DeleteMergeRequestAwardEmojiOnNote deletes an award emoji on a note from a
|
||||
// merge request.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/award_emoji.html#award-emoji-on-notes
|
||||
func (s *AwardEmojiService) DeleteMergeRequestAwardEmojiOnNote(pid interface{}, mergeRequestIID, noteID, awardID int, options ...OptionFunc) (*Response, error) {
|
||||
return s.deleteAwardEmojiOnNote(pid, awardMergeRequest, mergeRequestIID, noteID, awardID,
|
||||
options...)
|
||||
}
|
||||
|
||||
// DeleteSnippetAwardEmojiOnNote deletes an award emoji on a note from a snippet.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/award_emoji.html#award-emoji-on-notes
|
||||
func (s *AwardEmojiService) DeleteSnippetAwardEmojiOnNote(pid interface{}, snippetIID, noteID, awardID int, options ...OptionFunc) (*Response, error) {
|
||||
return s.deleteAwardEmojiOnNote(pid, awardSnippets, snippetIID, noteID, awardID, options...)
|
||||
}
|
||||
|
||||
func (s *AwardEmojiService) deleteAwardEmojiOnNote(pid interface{}, resource string, resourceID, noteID, awardID int, options ...OptionFunc) (*Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/%s/%d/notes/%d/award_emoji/%d",
|
||||
url.QueryEscape(project),
|
||||
resource,
|
||||
resourceID,
|
||||
noteID,
|
||||
awardID,
|
||||
)
|
||||
|
||||
req, err := s.client.NewRequest("DELETE", u, nil, options)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return s.client.Do(req, nil)
|
||||
}
|
||||
261
vendor/github.com/xanzy/go-gitlab/boards.go
generated
vendored
Normal file
261
vendor/github.com/xanzy/go-gitlab/boards.go
generated
vendored
Normal file
@@ -0,0 +1,261 @@
|
||||
//
|
||||
// Copyright 2015, Sander van Harmelen
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
package gitlab
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/url"
|
||||
)
|
||||
|
||||
// IssueBoardsService handles communication with the issue board related
|
||||
// methods of the GitLab API.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/boards.html
|
||||
type IssueBoardsService struct {
|
||||
client *Client
|
||||
}
|
||||
|
||||
// IssueBoard represents a GitLab issue board.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/boards.html
|
||||
type IssueBoard struct {
|
||||
ID int `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Project *Project `json:"project"`
|
||||
Milestone *Milestone `json:"milestone"`
|
||||
Lists []*BoardList `json:"lists"`
|
||||
}
|
||||
|
||||
func (b IssueBoard) String() string {
|
||||
return Stringify(b)
|
||||
}
|
||||
|
||||
// BoardList represents a GitLab board list.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/boards.html
|
||||
type BoardList struct {
|
||||
ID int `json:"id"`
|
||||
Labels []*Label `json:"labels"`
|
||||
Position int `json:"position"`
|
||||
}
|
||||
|
||||
func (b BoardList) String() string {
|
||||
return Stringify(b)
|
||||
}
|
||||
|
||||
// ListIssueBoardsOptions represents the available ListIssueBoards() options.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/boards.html#project-board
|
||||
type ListIssueBoardsOptions ListOptions
|
||||
|
||||
// ListIssueBoards gets a list of all issue boards in a project.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/boards.html#project-board
|
||||
func (s *IssueBoardsService) ListIssueBoards(pid interface{}, opt *ListIssueBoardsOptions, options ...OptionFunc) ([]*IssueBoard, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/boards", url.QueryEscape(project))
|
||||
|
||||
req, err := s.client.NewRequest("GET", u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
var is []*IssueBoard
|
||||
resp, err := s.client.Do(req, &is)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return is, resp, err
|
||||
}
|
||||
|
||||
// GetIssueBoard gets a single issue board of a project.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/boards.html#single-board
|
||||
func (s *IssueBoardsService) GetIssueBoard(pid interface{}, board int, options ...OptionFunc) (*IssueBoard, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/boards/%d", url.QueryEscape(project), board)
|
||||
|
||||
req, err := s.client.NewRequest("GET", u, nil, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
ib := new(IssueBoard)
|
||||
resp, err := s.client.Do(req, ib)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return ib, resp, err
|
||||
}
|
||||
|
||||
// GetIssueBoardListsOptions represents the available GetIssueBoardLists() options.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/boards.html#list-board-lists
|
||||
type GetIssueBoardListsOptions ListOptions
|
||||
|
||||
// GetIssueBoardLists gets a list of the issue board's lists. Does not include
|
||||
// backlog and closed lists.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/boards.html#list-board-lists
|
||||
func (s *IssueBoardsService) GetIssueBoardLists(pid interface{}, board int, opt *GetIssueBoardListsOptions, options ...OptionFunc) ([]*BoardList, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/boards/%d/lists", url.QueryEscape(project), board)
|
||||
|
||||
req, err := s.client.NewRequest("GET", u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
var bl []*BoardList
|
||||
resp, err := s.client.Do(req, &bl)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return bl, resp, err
|
||||
}
|
||||
|
||||
// GetIssueBoardList gets a single issue board list.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/boards.html#single-board-list
|
||||
func (s *IssueBoardsService) GetIssueBoardList(pid interface{}, board, list int, options ...OptionFunc) (*BoardList, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/boards/%d/lists/%d",
|
||||
url.QueryEscape(project),
|
||||
board,
|
||||
list,
|
||||
)
|
||||
|
||||
req, err := s.client.NewRequest("GET", u, nil, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
bl := new(BoardList)
|
||||
resp, err := s.client.Do(req, bl)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return bl, resp, err
|
||||
}
|
||||
|
||||
// CreateIssueBoardListOptions represents the available CreateIssueBoardList()
|
||||
// options.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/boards.html#new-board-list
|
||||
type CreateIssueBoardListOptions struct {
|
||||
LabelID *int `url:"label_id" json:"label_id"`
|
||||
}
|
||||
|
||||
// CreateIssueBoardList creates a new issue board list.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/boards.html#new-board-list
|
||||
func (s *IssueBoardsService) CreateIssueBoardList(pid interface{}, board int, opt *CreateIssueBoardListOptions, options ...OptionFunc) (*BoardList, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/boards/%d/lists", url.QueryEscape(project), board)
|
||||
|
||||
req, err := s.client.NewRequest("POST", u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
bl := new(BoardList)
|
||||
resp, err := s.client.Do(req, bl)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return bl, resp, err
|
||||
}
|
||||
|
||||
// UpdateIssueBoardListOptions represents the available UpdateIssueBoardList()
|
||||
// options.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/boards.html#edit-board-list
|
||||
type UpdateIssueBoardListOptions struct {
|
||||
Position *int `url:"position" json:"position"`
|
||||
}
|
||||
|
||||
// UpdateIssueBoardList updates the position of an existing issue board list.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/boards.html#edit-board-list
|
||||
func (s *IssueBoardsService) UpdateIssueBoardList(pid interface{}, board, list int, opt *UpdateIssueBoardListOptions, options ...OptionFunc) (*BoardList, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/boards/%d/lists/%d",
|
||||
url.QueryEscape(project),
|
||||
board,
|
||||
list,
|
||||
)
|
||||
|
||||
req, err := s.client.NewRequest("PUT", u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
bl := new(BoardList)
|
||||
resp, err := s.client.Do(req, bl)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return bl, resp, err
|
||||
}
|
||||
|
||||
// DeleteIssueBoardList soft deletes an issue board list. Only for admins and
|
||||
// project owners.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/boards.html#delete-a-board-list
|
||||
func (s *IssueBoardsService) DeleteIssueBoardList(pid interface{}, board, list int, options ...OptionFunc) (*Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/boards/%d/lists/%d",
|
||||
url.QueryEscape(project),
|
||||
board,
|
||||
list,
|
||||
)
|
||||
|
||||
req, err := s.client.NewRequest("DELETE", u, nil, options)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return s.client.Do(req, nil)
|
||||
}
|
||||
238
vendor/github.com/xanzy/go-gitlab/branches.go
generated
vendored
Normal file
238
vendor/github.com/xanzy/go-gitlab/branches.go
generated
vendored
Normal file
@@ -0,0 +1,238 @@
|
||||
//
|
||||
// Copyright 2017, Sander van Harmelen
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
package gitlab
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/url"
|
||||
)
|
||||
|
||||
// BranchesService handles communication with the branch related methods
|
||||
// of the GitLab API.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/branches.html
|
||||
type BranchesService struct {
|
||||
client *Client
|
||||
}
|
||||
|
||||
// Branch represents a GitLab branch.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/branches.html
|
||||
type Branch struct {
|
||||
Commit *Commit `json:"commit"`
|
||||
Name string `json:"name"`
|
||||
Protected bool `json:"protected"`
|
||||
Merged bool `json:"merged"`
|
||||
DevelopersCanPush bool `json:"developers_can_push"`
|
||||
DevelopersCanMerge bool `json:"developers_can_merge"`
|
||||
}
|
||||
|
||||
func (b Branch) String() string {
|
||||
return Stringify(b)
|
||||
}
|
||||
|
||||
// ListBranchesOptions represents the available ListBranches() options.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/branches.html#list-repository-branches
|
||||
type ListBranchesOptions ListOptions
|
||||
|
||||
// ListBranches gets a list of repository branches from a project, sorted by
|
||||
// name alphabetically.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/branches.html#list-repository-branches
|
||||
func (s *BranchesService) ListBranches(pid interface{}, opts *ListBranchesOptions, options ...OptionFunc) ([]*Branch, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/repository/branches", url.QueryEscape(project))
|
||||
|
||||
req, err := s.client.NewRequest("GET", u, opts, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
var b []*Branch
|
||||
resp, err := s.client.Do(req, &b)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return b, resp, err
|
||||
}
|
||||
|
||||
// GetBranch gets a single project repository branch.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/branches.html#get-single-repository-branch
|
||||
func (s *BranchesService) GetBranch(pid interface{}, branch string, options ...OptionFunc) (*Branch, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/repository/branches/%s", url.QueryEscape(project), url.QueryEscape(branch))
|
||||
|
||||
req, err := s.client.NewRequest("GET", u, nil, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
b := new(Branch)
|
||||
resp, err := s.client.Do(req, b)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return b, resp, err
|
||||
}
|
||||
|
||||
// ProtectBranchOptions represents the available ProtectBranch() options.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/branches.html#protect-repository-branch
|
||||
type ProtectBranchOptions struct {
|
||||
DevelopersCanPush *bool `url:"developers_can_push,omitempty" json:"developers_can_push,omitempty"`
|
||||
DevelopersCanMerge *bool `url:"developers_can_merge,omitempty" json:"developers_can_merge,omitempty"`
|
||||
}
|
||||
|
||||
// ProtectBranch protects a single project repository branch. This is an
|
||||
// idempotent function, protecting an already protected repository branch
|
||||
// still returns a 200 OK status code.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/branches.html#protect-repository-branch
|
||||
func (s *BranchesService) ProtectBranch(pid interface{}, branch string, opts *ProtectBranchOptions, options ...OptionFunc) (*Branch, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/repository/branches/%s/protect", url.QueryEscape(project), url.QueryEscape(branch))
|
||||
|
||||
req, err := s.client.NewRequest("PUT", u, opts, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
b := new(Branch)
|
||||
resp, err := s.client.Do(req, b)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return b, resp, err
|
||||
}
|
||||
|
||||
// UnprotectBranch unprotects a single project repository branch. This is an
|
||||
// idempotent function, unprotecting an already unprotected repository branch
|
||||
// still returns a 200 OK status code.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/branches.html#unprotect-repository-branch
|
||||
func (s *BranchesService) UnprotectBranch(pid interface{}, branch string, options ...OptionFunc) (*Branch, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/repository/branches/%s/unprotect", url.QueryEscape(project), url.QueryEscape(branch))
|
||||
|
||||
req, err := s.client.NewRequest("PUT", u, nil, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
b := new(Branch)
|
||||
resp, err := s.client.Do(req, b)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return b, resp, err
|
||||
}
|
||||
|
||||
// CreateBranchOptions represents the available CreateBranch() options.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/branches.html#create-repository-branch
|
||||
type CreateBranchOptions struct {
|
||||
Branch *string `url:"branch,omitempty" json:"branch,omitempty"`
|
||||
Ref *string `url:"ref,omitempty" json:"ref,omitempty"`
|
||||
}
|
||||
|
||||
// CreateBranch creates branch from commit SHA or existing branch.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/branches.html#create-repository-branch
|
||||
func (s *BranchesService) CreateBranch(pid interface{}, opt *CreateBranchOptions, options ...OptionFunc) (*Branch, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/repository/branches", url.QueryEscape(project))
|
||||
|
||||
req, err := s.client.NewRequest("POST", u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
b := new(Branch)
|
||||
resp, err := s.client.Do(req, b)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return b, resp, err
|
||||
}
|
||||
|
||||
// DeleteBranch deletes an existing branch.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/branches.html#delete-repository-branch
|
||||
func (s *BranchesService) DeleteBranch(pid interface{}, branch string, options ...OptionFunc) (*Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/repository/branches/%s", url.QueryEscape(project), url.QueryEscape(branch))
|
||||
|
||||
req, err := s.client.NewRequest("DELETE", u, nil, options)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return s.client.Do(req, nil)
|
||||
}
|
||||
|
||||
// DeleteMergedBranches deletes all branches that are merged into the project's default branch.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/branches.html#delete-merged-branches
|
||||
func (s *BranchesService) DeleteMergedBranches(pid interface{}, options ...OptionFunc) (*Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/repository/merged_branches", url.QueryEscape(project))
|
||||
|
||||
req, err := s.client.NewRequest("DELETE", u, nil, options)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return s.client.Do(req, nil)
|
||||
}
|
||||
172
vendor/github.com/xanzy/go-gitlab/broadcast_messages.go
generated
vendored
Normal file
172
vendor/github.com/xanzy/go-gitlab/broadcast_messages.go
generated
vendored
Normal file
@@ -0,0 +1,172 @@
|
||||
//
|
||||
// Copyright 2018, Sander van Harmelen
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
package gitlab
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
)
|
||||
|
||||
// BroadcastMessagesService handles communication with the broadcast
|
||||
// messages methods of the GitLab API.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/broadcast_messages.html
|
||||
type BroadcastMessagesService struct {
|
||||
client *Client
|
||||
}
|
||||
|
||||
// BroadcastMessage represents a GitLab issue board.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/broadcast_messages.html#get-all-broadcast-messages
|
||||
type BroadcastMessage struct {
|
||||
Message string `json:"message"`
|
||||
StartsAt *time.Time `json:"starts_at"`
|
||||
EndsAt *time.Time `json:"ends_at"`
|
||||
Color string `json:"color"`
|
||||
Font string `json:"font"`
|
||||
ID int `json:"id"`
|
||||
Active bool `json:"active"`
|
||||
}
|
||||
|
||||
// ListBroadcastMessagesOptions represents the available ListBroadcastMessages()
|
||||
// options.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/broadcast_messages.html#get-all-broadcast-messages
|
||||
type ListBroadcastMessagesOptions ListOptions
|
||||
|
||||
// ListBroadcastMessages gets a list of all broadcasted messages.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/broadcast_messages.html#get-all-broadcast-messages
|
||||
func (s *BroadcastMessagesService) ListBroadcastMessages(opt *ListBroadcastMessagesOptions, options ...OptionFunc) ([]*BroadcastMessage, *Response, error) {
|
||||
req, err := s.client.NewRequest("GET", "broadcast_messages", opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
var bs []*BroadcastMessage
|
||||
resp, err := s.client.Do(req, &bs)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return bs, resp, err
|
||||
}
|
||||
|
||||
// GetBroadcastMessage gets a single broadcast message.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/broadcast_messages.html#get-a-specific-broadcast-message
|
||||
func (s *BroadcastMessagesService) GetBroadcastMessage(broadcast int, options ...OptionFunc) (*BroadcastMessage, *Response, error) {
|
||||
u := fmt.Sprintf("broadcast_messages/%d", broadcast)
|
||||
|
||||
req, err := s.client.NewRequest("GET", u, nil, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
b := new(BroadcastMessage)
|
||||
resp, err := s.client.Do(req, &b)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return b, resp, err
|
||||
}
|
||||
|
||||
// CreateBroadcastMessageOptions represents the available CreateBroadcastMessage()
|
||||
// options.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/broadcast_messages.html#create-a-broadcast-message
|
||||
type CreateBroadcastMessageOptions struct {
|
||||
Message *string `url:"message" json:"message"`
|
||||
StartsAt *time.Time `url:"starts_at,omitempty" json:"starts_at,omitempty"`
|
||||
EndsAt *time.Time `url:"ends_at,omitempty" json:"ends_at,omitempty"`
|
||||
Color *string `url:"color,omitempty" json:"color,omitempty"`
|
||||
Font *string `url:"font,omitempty" json:"font,omitempty"`
|
||||
}
|
||||
|
||||
// CreateBroadcastMessage creates a message to broadcast.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/broadcast_messages.html#create-a-broadcast-message
|
||||
func (s *BroadcastMessagesService) CreateBroadcastMessage(opt *CreateBroadcastMessageOptions, options ...OptionFunc) (*BroadcastMessage, *Response, error) {
|
||||
req, err := s.client.NewRequest("POST", "broadcast_messages", opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
b := new(BroadcastMessage)
|
||||
resp, err := s.client.Do(req, &b)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return b, resp, err
|
||||
}
|
||||
|
||||
// UpdateBroadcastMessageOptions represents the available CreateBroadcastMessage()
|
||||
// options.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/broadcast_messages.html#update-a-broadcast-message
|
||||
type UpdateBroadcastMessageOptions struct {
|
||||
Message *string `url:"message,omitempty" json:"message,omitempty"`
|
||||
StartsAt *time.Time `url:"starts_at,omitempty" json:"starts_at,omitempty"`
|
||||
EndsAt *time.Time `url:"ends_at,omitempty" json:"ends_at,omitempty"`
|
||||
Color *string `url:"color,omitempty" json:"color,omitempty"`
|
||||
Font *string `url:"font,omitempty" json:"font,omitempty"`
|
||||
}
|
||||
|
||||
// UpdateBroadcastMessage update a broadcasted message.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/broadcast_messages.html#update-a-broadcast-message
|
||||
func (s *BroadcastMessagesService) UpdateBroadcastMessage(broadcast int, opt *UpdateBroadcastMessageOptions, options ...OptionFunc) (*BroadcastMessage, *Response, error) {
|
||||
u := fmt.Sprintf("broadcast_messages/%d", broadcast)
|
||||
|
||||
req, err := s.client.NewRequest("PUT", u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
b := new(BroadcastMessage)
|
||||
resp, err := s.client.Do(req, &b)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return b, resp, err
|
||||
}
|
||||
|
||||
// DeleteBroadcastMessage deletes a broadcasted message.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/broadcast_messages.html#delete-a-broadcast-message
|
||||
func (s *BroadcastMessagesService) DeleteBroadcastMessage(broadcast int, options ...OptionFunc) (*Response, error) {
|
||||
u := fmt.Sprintf("broadcast_messages/%d", broadcast)
|
||||
|
||||
req, err := s.client.NewRequest("DELETE", u, nil, options)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return s.client.Do(req, nil)
|
||||
}
|
||||
173
vendor/github.com/xanzy/go-gitlab/build_variables.go
generated
vendored
Normal file
173
vendor/github.com/xanzy/go-gitlab/build_variables.go
generated
vendored
Normal file
@@ -0,0 +1,173 @@
|
||||
package gitlab
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/url"
|
||||
)
|
||||
|
||||
// BuildVariablesService handles communication with the project variables related methods
|
||||
// of the Gitlab API
|
||||
//
|
||||
// Gitlab API Docs : https://docs.gitlab.com/ce/api/build_variables.html
|
||||
type BuildVariablesService struct {
|
||||
client *Client
|
||||
}
|
||||
|
||||
// BuildVariable represents a variable available for each build of the given project
|
||||
//
|
||||
// Gitlab API Docs : https://docs.gitlab.com/ce/api/build_variables.html
|
||||
type BuildVariable struct {
|
||||
Key string `json:"key"`
|
||||
Value string `json:"value"`
|
||||
Protected bool `json:"protected"`
|
||||
}
|
||||
|
||||
func (v BuildVariable) String() string {
|
||||
return Stringify(v)
|
||||
}
|
||||
|
||||
// ListBuildVariablesOptions are the parameters to ListBuildVariables()
|
||||
//
|
||||
// Gitlab API Docs:
|
||||
// https://docs.gitlab.com/ce/api/build_variables.html#list-project-variables
|
||||
type ListBuildVariablesOptions ListOptions
|
||||
|
||||
// ListBuildVariables gets the a list of project variables in a project
|
||||
//
|
||||
// Gitlab API Docs:
|
||||
// https://docs.gitlab.com/ce/api/build_variables.html#list-project-variables
|
||||
func (s *BuildVariablesService) ListBuildVariables(pid interface{}, opts *ListBuildVariablesOptions, options ...OptionFunc) ([]*BuildVariable, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/variables", url.QueryEscape(project))
|
||||
|
||||
req, err := s.client.NewRequest("GET", u, opts, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
var v []*BuildVariable
|
||||
resp, err := s.client.Do(req, &v)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return v, resp, err
|
||||
}
|
||||
|
||||
// GetBuildVariable gets a single project variable of a project
|
||||
//
|
||||
// Gitlab API Docs:
|
||||
// https://docs.gitlab.com/ce/api/build_variables.html#show-variable-details
|
||||
func (s *BuildVariablesService) GetBuildVariable(pid interface{}, key string, options ...OptionFunc) (*BuildVariable, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/variables/%s", url.QueryEscape(project), key)
|
||||
|
||||
req, err := s.client.NewRequest("GET", u, nil, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
v := new(BuildVariable)
|
||||
resp, err := s.client.Do(req, v)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return v, resp, err
|
||||
}
|
||||
|
||||
// CreateBuildVariableOptions are the parameters to CreateBuildVariable()
|
||||
//
|
||||
// Gitlab API Docs:
|
||||
// https://docs.gitlab.com/ce/api/build_variables.html#create-variable
|
||||
type CreateBuildVariableOptions struct {
|
||||
Key *string `url:"key" json:"key"`
|
||||
Value *string `url:"value" json:"value"`
|
||||
Protected *bool `url:"protected,omitempty" json:"protected,omitempty"`
|
||||
}
|
||||
|
||||
// CreateBuildVariable creates a variable for a given project
|
||||
//
|
||||
// Gitlab API Docs:
|
||||
// https://docs.gitlab.com/ce/api/build_variables.html#create-variable
|
||||
func (s *BuildVariablesService) CreateBuildVariable(pid interface{}, opt *CreateBuildVariableOptions, options ...OptionFunc) (*BuildVariable, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/variables", url.QueryEscape(project))
|
||||
|
||||
req, err := s.client.NewRequest("POST", u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
v := new(BuildVariable)
|
||||
resp, err := s.client.Do(req, v)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return v, resp, err
|
||||
}
|
||||
|
||||
// UpdateBuildVariableOptions are the parameters to UpdateBuildVariable()
|
||||
//
|
||||
// Gitlab API Docs:
|
||||
// https://docs.gitlab.com/ce/api/build_variables.html#update-variable
|
||||
type UpdateBuildVariableOptions struct {
|
||||
Key *string `url:"key" json:"key"`
|
||||
Value *string `url:"value" json:"value"`
|
||||
Protected *bool `url:"protected,omitempty" json:"protected,omitempty"`
|
||||
}
|
||||
|
||||
// UpdateBuildVariable updates an existing project variable
|
||||
// The variable key must exist
|
||||
//
|
||||
// Gitlab API Docs:
|
||||
// https://docs.gitlab.com/ce/api/build_variables.html#update-variable
|
||||
func (s *BuildVariablesService) UpdateBuildVariable(pid interface{}, key string, opt *UpdateBuildVariableOptions, options ...OptionFunc) (*BuildVariable, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/variables/%s", url.QueryEscape(project), key)
|
||||
|
||||
req, err := s.client.NewRequest("PUT", u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
v := new(BuildVariable)
|
||||
resp, err := s.client.Do(req, v)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return v, resp, err
|
||||
}
|
||||
|
||||
// RemoveBuildVariable removes a project variable of a given project identified by its key
|
||||
//
|
||||
// Gitlab API Docs:
|
||||
// https://docs.gitlab.com/ce/api/build_variables.html#remove-variable
|
||||
func (s *BuildVariablesService) RemoveBuildVariable(pid interface{}, key string, options ...OptionFunc) (*Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/variables/%s", url.QueryEscape(project), key)
|
||||
|
||||
req, err := s.client.NewRequest("DELETE", u, nil, options)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return s.client.Do(req, nil)
|
||||
}
|
||||
448
vendor/github.com/xanzy/go-gitlab/commits.go
generated
vendored
Normal file
448
vendor/github.com/xanzy/go-gitlab/commits.go
generated
vendored
Normal file
@@ -0,0 +1,448 @@
|
||||
//
|
||||
// Copyright 2017, Sander van Harmelen
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
package gitlab
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/url"
|
||||
"time"
|
||||
)
|
||||
|
||||
// CommitsService handles communication with the commit related methods
|
||||
// of the GitLab API.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/commits.html
|
||||
type CommitsService struct {
|
||||
client *Client
|
||||
}
|
||||
|
||||
// Commit represents a GitLab commit.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/commits.html
|
||||
type Commit struct {
|
||||
ID string `json:"id"`
|
||||
ShortID string `json:"short_id"`
|
||||
Title string `json:"title"`
|
||||
AuthorName string `json:"author_name"`
|
||||
AuthorEmail string `json:"author_email"`
|
||||
AuthoredDate *time.Time `json:"authored_date"`
|
||||
CommitterName string `json:"committer_name"`
|
||||
CommitterEmail string `json:"committer_email"`
|
||||
CommittedDate *time.Time `json:"committed_date"`
|
||||
CreatedAt *time.Time `json:"created_at"`
|
||||
Message string `json:"message"`
|
||||
ParentIDs []string `json:"parent_ids"`
|
||||
Stats *CommitStats `json:"stats"`
|
||||
Status *BuildStateValue `json:"status"`
|
||||
}
|
||||
|
||||
// CommitStats represents the number of added and deleted files in a commit.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/commits.html
|
||||
type CommitStats struct {
|
||||
Additions int `json:"additions"`
|
||||
Deletions int `json:"deletions"`
|
||||
Total int `json:"total"`
|
||||
}
|
||||
|
||||
func (c Commit) String() string {
|
||||
return Stringify(c)
|
||||
}
|
||||
|
||||
// ListCommitsOptions represents the available ListCommits() options.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/commits.html#list-repository-commits
|
||||
type ListCommitsOptions struct {
|
||||
ListOptions
|
||||
RefName *string `url:"ref_name,omitempty" json:"ref_name,omitempty"`
|
||||
Since *time.Time `url:"since,omitempty" json:"since,omitempty"`
|
||||
Until *time.Time `url:"until,omitempty" json:"until,omitempty"`
|
||||
Path *string `url:"path,omitempty" json:"path,omitempty"`
|
||||
All *bool `url:"all,omitempty" json:"all,omitempty"`
|
||||
}
|
||||
|
||||
// ListCommits gets a list of repository commits in a project.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/commits.html#list-commits
|
||||
func (s *CommitsService) ListCommits(pid interface{}, opt *ListCommitsOptions, options ...OptionFunc) ([]*Commit, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/repository/commits", url.QueryEscape(project))
|
||||
|
||||
req, err := s.client.NewRequest("GET", u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
var c []*Commit
|
||||
resp, err := s.client.Do(req, &c)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return c, resp, err
|
||||
}
|
||||
|
||||
// FileAction represents the available actions that can be performed on a file.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/commits.html#create-a-commit-with-multiple-files-and-actions
|
||||
type FileAction string
|
||||
|
||||
// The available file actions.
|
||||
const (
|
||||
FileCreate FileAction = "create"
|
||||
FileDelete FileAction = "delete"
|
||||
FileMove FileAction = "move"
|
||||
FileUpdate FileAction = "update"
|
||||
)
|
||||
|
||||
// CommitAction represents a single file action within a commit.
|
||||
type CommitAction struct {
|
||||
Action FileAction `url:"action" json:"action"`
|
||||
FilePath string `url:"file_path" json:"file_path"`
|
||||
PreviousPath string `url:"previous_path,omitempty" json:"previous_path,omitempty"`
|
||||
Content string `url:"content,omitempty" json:"content,omitempty"`
|
||||
Encoding string `url:"encoding,omitempty" json:"encoding,omitempty"`
|
||||
}
|
||||
|
||||
// GetCommit gets a specific commit identified by the commit hash or name of a
|
||||
// branch or tag.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/commits.html#get-a-single-commit
|
||||
func (s *CommitsService) GetCommit(pid interface{}, sha string, options ...OptionFunc) (*Commit, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/repository/commits/%s", url.QueryEscape(project), sha)
|
||||
|
||||
req, err := s.client.NewRequest("GET", u, nil, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
c := new(Commit)
|
||||
resp, err := s.client.Do(req, c)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return c, resp, err
|
||||
}
|
||||
|
||||
// CreateCommitOptions represents the available options for a new commit.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/commits.html#create-a-commit-with-multiple-files-and-actions
|
||||
type CreateCommitOptions struct {
|
||||
Branch *string `url:"branch" json:"branch"`
|
||||
CommitMessage *string `url:"commit_message" json:"commit_message"`
|
||||
StartBranch *string `url:"start_branch,omitempty" json:"start_branch,omitempty"`
|
||||
Actions []*CommitAction `url:"actions" json:"actions"`
|
||||
AuthorEmail *string `url:"author_email,omitempty" json:"author_email,omitempty"`
|
||||
AuthorName *string `url:"author_name,omitempty" json:"author_name,omitempty"`
|
||||
}
|
||||
|
||||
// CreateCommit creates a commit with multiple files and actions.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/commits.html#create-a-commit-with-multiple-files-and-actions
|
||||
func (s *CommitsService) CreateCommit(pid interface{}, opt *CreateCommitOptions, options ...OptionFunc) (*Commit, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/repository/commits", url.QueryEscape(project))
|
||||
|
||||
req, err := s.client.NewRequest("POST", u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
var c *Commit
|
||||
resp, err := s.client.Do(req, &c)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return c, resp, err
|
||||
}
|
||||
|
||||
// Diff represents a GitLab diff.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/commits.html
|
||||
type Diff struct {
|
||||
Diff string `json:"diff"`
|
||||
NewPath string `json:"new_path"`
|
||||
OldPath string `json:"old_path"`
|
||||
AMode string `json:"a_mode"`
|
||||
BMode string `json:"b_mode"`
|
||||
NewFile bool `json:"new_file"`
|
||||
RenamedFile bool `json:"renamed_file"`
|
||||
DeletedFile bool `json:"deleted_file"`
|
||||
}
|
||||
|
||||
func (d Diff) String() string {
|
||||
return Stringify(d)
|
||||
}
|
||||
|
||||
// GetCommitDiffOptions represents the available GetCommitDiff() options.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/commits.html#get-the-diff-of-a-commit
|
||||
type GetCommitDiffOptions ListOptions
|
||||
|
||||
// GetCommitDiff gets the diff of a commit in a project..
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/commits.html#get-the-diff-of-a-commit
|
||||
func (s *CommitsService) GetCommitDiff(pid interface{}, sha string, opt *GetCommitDiffOptions, options ...OptionFunc) ([]*Diff, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/repository/commits/%s/diff", url.QueryEscape(project), sha)
|
||||
|
||||
req, err := s.client.NewRequest("GET", u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
var d []*Diff
|
||||
resp, err := s.client.Do(req, &d)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return d, resp, err
|
||||
}
|
||||
|
||||
// CommitComment represents a GitLab commit comment.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/commits.html
|
||||
type CommitComment struct {
|
||||
Note string `json:"note"`
|
||||
Path string `json:"path"`
|
||||
Line int `json:"line"`
|
||||
LineType string `json:"line_type"`
|
||||
Author Author `json:"author"`
|
||||
}
|
||||
|
||||
// Author represents a GitLab commit author
|
||||
type Author struct {
|
||||
ID int `json:"id"`
|
||||
Username string `json:"username"`
|
||||
Email string `json:"email"`
|
||||
Name string `json:"name"`
|
||||
State string `json:"state"`
|
||||
Blocked bool `json:"blocked"`
|
||||
CreatedAt *time.Time `json:"created_at"`
|
||||
}
|
||||
|
||||
func (c CommitComment) String() string {
|
||||
return Stringify(c)
|
||||
}
|
||||
|
||||
// GetCommitCommentsOptions represents the available GetCommitComments() options.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/commits.html#get-the-comments-of-a-commit
|
||||
type GetCommitCommentsOptions ListOptions
|
||||
|
||||
// GetCommitComments gets the comments of a commit in a project.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/commits.html#get-the-comments-of-a-commit
|
||||
func (s *CommitsService) GetCommitComments(pid interface{}, sha string, opt *GetCommitCommentsOptions, options ...OptionFunc) ([]*CommitComment, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/repository/commits/%s/comments", url.QueryEscape(project), sha)
|
||||
|
||||
req, err := s.client.NewRequest("GET", u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
var c []*CommitComment
|
||||
resp, err := s.client.Do(req, &c)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return c, resp, err
|
||||
}
|
||||
|
||||
// PostCommitCommentOptions represents the available PostCommitComment()
|
||||
// options.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/commits.html#post-comment-to-commit
|
||||
type PostCommitCommentOptions struct {
|
||||
Note *string `url:"note,omitempty" json:"note,omitempty"`
|
||||
Path *string `url:"path" json:"path"`
|
||||
Line *int `url:"line" json:"line"`
|
||||
LineType *string `url:"line_type" json:"line_type"`
|
||||
}
|
||||
|
||||
// PostCommitComment adds a comment to a commit. Optionally you can post
|
||||
// comments on a specific line of a commit. Therefor both path, line_new and
|
||||
// line_old are required.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/commits.html#post-comment-to-commit
|
||||
func (s *CommitsService) PostCommitComment(pid interface{}, sha string, opt *PostCommitCommentOptions, options ...OptionFunc) (*CommitComment, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/repository/commits/%s/comments", url.QueryEscape(project), sha)
|
||||
|
||||
req, err := s.client.NewRequest("POST", u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
c := new(CommitComment)
|
||||
resp, err := s.client.Do(req, c)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return c, resp, err
|
||||
}
|
||||
|
||||
// GetCommitStatusesOptions represents the available GetCommitStatuses() options.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/commits.html#get-the-status-of-a-commit
|
||||
type GetCommitStatusesOptions struct {
|
||||
ListOptions
|
||||
Ref *string `url:"ref,omitempty" json:"ref,omitempty"`
|
||||
Stage *string `url:"stage,omitempty" json:"stage,omitempty"`
|
||||
Name *string `url:"name,omitempty" json:"name,omitempty"`
|
||||
All *bool `url:"all,omitempty" json:"all,omitempty"`
|
||||
}
|
||||
|
||||
// CommitStatus represents a GitLab commit status.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/commits.html#get-the-status-of-a-commit
|
||||
type CommitStatus struct {
|
||||
ID int `json:"id"`
|
||||
SHA string `json:"sha"`
|
||||
Ref string `json:"ref"`
|
||||
Status string `json:"status"`
|
||||
Name string `json:"name"`
|
||||
TargetURL string `json:"target_url"`
|
||||
Description string `json:"description"`
|
||||
CreatedAt *time.Time `json:"created_at"`
|
||||
StartedAt *time.Time `json:"started_at"`
|
||||
FinishedAt *time.Time `json:"finished_at"`
|
||||
Author Author `json:"author"`
|
||||
}
|
||||
|
||||
// GetCommitStatuses gets the statuses of a commit in a project.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/commits.html#get-the-status-of-a-commit
|
||||
func (s *CommitsService) GetCommitStatuses(pid interface{}, sha string, opt *GetCommitStatusesOptions, options ...OptionFunc) ([]*CommitStatus, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/repository/commits/%s/statuses", url.QueryEscape(project), sha)
|
||||
|
||||
req, err := s.client.NewRequest("GET", u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
var cs []*CommitStatus
|
||||
resp, err := s.client.Do(req, &cs)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return cs, resp, err
|
||||
}
|
||||
|
||||
// SetCommitStatusOptions represents the available SetCommitStatus() options.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/commits.html#post-the-status-to-commit
|
||||
type SetCommitStatusOptions struct {
|
||||
State BuildStateValue `url:"state" json:"state"`
|
||||
Ref *string `url:"ref,omitempty" json:"ref,omitempty"`
|
||||
Name *string `url:"name,omitempty" json:"name,omitempty"`
|
||||
Context *string `url:"context,omitempty" json:"context,omitempty"`
|
||||
TargetURL *string `url:"target_url,omitempty" json:"target_url,omitempty"`
|
||||
Description *string `url:"description,omitempty" json:"description,omitempty"`
|
||||
}
|
||||
|
||||
// SetCommitStatus sets the status of a commit in a project.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/commits.html#post-the-status-to-commit
|
||||
func (s *CommitsService) SetCommitStatus(pid interface{}, sha string, opt *SetCommitStatusOptions, options ...OptionFunc) (*CommitStatus, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/statuses/%s", url.QueryEscape(project), sha)
|
||||
|
||||
req, err := s.client.NewRequest("POST", u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
var cs *CommitStatus
|
||||
resp, err := s.client.Do(req, &cs)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return cs, resp, err
|
||||
}
|
||||
|
||||
// CherryPickCommitOptions represents the available options for cherry-picking a commit.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/commits.html#cherry-pick-a-commit
|
||||
type CherryPickCommitOptions struct {
|
||||
TargetBranch *string `url:"branch" json:"branch,omitempty"`
|
||||
}
|
||||
|
||||
// CherryPickCommit sherry picks a commit to a given branch.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/commits.html#cherry-pick-a-commit
|
||||
func (s *CommitsService) CherryPickCommit(pid interface{}, sha string, opt *CherryPickCommitOptions, options ...OptionFunc) (*Commit, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/repository/commits/%s/cherry_pick",
|
||||
url.QueryEscape(project), url.QueryEscape(sha))
|
||||
|
||||
req, err := s.client.NewRequest("POST", u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
var c *Commit
|
||||
resp, err := s.client.Do(req, &c)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return c, resp, err
|
||||
}
|
||||
201
vendor/github.com/xanzy/go-gitlab/deploy_keys.go
generated
vendored
Normal file
201
vendor/github.com/xanzy/go-gitlab/deploy_keys.go
generated
vendored
Normal file
@@ -0,0 +1,201 @@
|
||||
//
|
||||
// Copyright 2017, Sander van Harmelen
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
package gitlab
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/url"
|
||||
"time"
|
||||
)
|
||||
|
||||
// DeployKeysService handles communication with the keys related methods
|
||||
// of the GitLab API.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/deploy_keys.html
|
||||
type DeployKeysService struct {
|
||||
client *Client
|
||||
}
|
||||
|
||||
// DeployKey represents a GitLab deploy key.
|
||||
type DeployKey struct {
|
||||
ID int `json:"id"`
|
||||
Title string `json:"title"`
|
||||
Key string `json:"key"`
|
||||
CanPush *bool `json:"can_push"`
|
||||
CreatedAt *time.Time `json:"created_at"`
|
||||
}
|
||||
|
||||
func (k DeployKey) String() string {
|
||||
return Stringify(k)
|
||||
}
|
||||
|
||||
// ListAllDeployKeys gets a list of all deploy keys
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/deploy_keys.html#list-all-deploy-keys
|
||||
func (s *DeployKeysService) ListAllDeployKeys(options ...OptionFunc) ([]*DeployKey, *Response, error) {
|
||||
req, err := s.client.NewRequest("GET", "deploy_keys", nil, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
var ks []*DeployKey
|
||||
resp, err := s.client.Do(req, &ks)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return ks, resp, err
|
||||
}
|
||||
|
||||
// ListProjectDeployKeysOptions represents the available ListProjectDeployKeys()
|
||||
// options.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/deploy_keys.html#list-project-deploy-keys
|
||||
type ListProjectDeployKeysOptions ListOptions
|
||||
|
||||
// ListProjectDeployKeys gets a list of a project's deploy keys
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/deploy_keys.html#list-project-deploy-keys
|
||||
func (s *DeployKeysService) ListProjectDeployKeys(pid interface{}, opt *ListProjectDeployKeysOptions, options ...OptionFunc) ([]*DeployKey, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/deploy_keys", url.QueryEscape(project))
|
||||
|
||||
req, err := s.client.NewRequest("GET", u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
var ks []*DeployKey
|
||||
resp, err := s.client.Do(req, &ks)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return ks, resp, err
|
||||
}
|
||||
|
||||
// GetDeployKey gets a single deploy key.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/deploy_keys.html#single-deploy-key
|
||||
func (s *DeployKeysService) GetDeployKey(pid interface{}, deployKey int, options ...OptionFunc) (*DeployKey, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/deploy_keys/%d", url.QueryEscape(project), deployKey)
|
||||
|
||||
req, err := s.client.NewRequest("GET", u, nil, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
k := new(DeployKey)
|
||||
resp, err := s.client.Do(req, k)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return k, resp, err
|
||||
}
|
||||
|
||||
// AddDeployKeyOptions represents the available ADDDeployKey() options.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/deploy_keys.html#add-deploy-key
|
||||
type AddDeployKeyOptions struct {
|
||||
Title *string `url:"title,omitempty" json:"title,omitempty"`
|
||||
Key *string `url:"key,omitempty" json:"key,omitempty"`
|
||||
CanPush *bool `url:"can_push,omitempty" json:"can_push,omitempty"`
|
||||
}
|
||||
|
||||
// AddDeployKey creates a new deploy key for a project. If deploy key already
|
||||
// exists in another project - it will be joined to project but only if
|
||||
// original one was is accessible by same user.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/deploy_keys.html#add-deploy-key
|
||||
func (s *DeployKeysService) AddDeployKey(pid interface{}, opt *AddDeployKeyOptions, options ...OptionFunc) (*DeployKey, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/deploy_keys", url.QueryEscape(project))
|
||||
|
||||
req, err := s.client.NewRequest("POST", u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
k := new(DeployKey)
|
||||
resp, err := s.client.Do(req, k)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return k, resp, err
|
||||
}
|
||||
|
||||
// DeleteDeployKey deletes a deploy key from a project.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/deploy_keys.html#delete-deploy-key
|
||||
func (s *DeployKeysService) DeleteDeployKey(pid interface{}, deployKey int, options ...OptionFunc) (*Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/deploy_keys/%d", url.QueryEscape(project), deployKey)
|
||||
|
||||
req, err := s.client.NewRequest("DELETE", u, nil, options)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return s.client.Do(req, nil)
|
||||
}
|
||||
|
||||
// EnableDeployKey enables a deploy key.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/deploy_keys.html#enable-deploy-key
|
||||
func (s *DeployKeysService) EnableDeployKey(pid interface{}, deployKey int, options ...OptionFunc) (*DeployKey, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/deploy_keys/%d/enable", url.QueryEscape(project), deployKey)
|
||||
|
||||
req, err := s.client.NewRequest("POST", u, nil, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
k := new(DeployKey)
|
||||
resp, err := s.client.Do(req, k)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return k, resp, err
|
||||
}
|
||||
121
vendor/github.com/xanzy/go-gitlab/deployments.go
generated
vendored
Normal file
121
vendor/github.com/xanzy/go-gitlab/deployments.go
generated
vendored
Normal file
@@ -0,0 +1,121 @@
|
||||
//
|
||||
// Copyright 2018, Sander van Harmelen
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package gitlab
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/url"
|
||||
"time"
|
||||
)
|
||||
|
||||
// DeploymentsService handles communication with the deployment related methods
|
||||
// of the GitLab API.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/deployments.html
|
||||
type DeploymentsService struct {
|
||||
client *Client
|
||||
}
|
||||
|
||||
// Deployment represents the Gitlab deployment
|
||||
type Deployment struct {
|
||||
ID int `json:"id"`
|
||||
IID int `json:"iid"`
|
||||
Ref string `json:"ref"`
|
||||
Sha string `json:"sha"`
|
||||
CreatedAt *time.Time `json:"created_at"`
|
||||
User *ProjectUser `json:"user"`
|
||||
Environment *Environment `json:"environment"`
|
||||
Deployable struct {
|
||||
ID int `json:"id"`
|
||||
Status string `json:"status"`
|
||||
Stage string `json:"stage"`
|
||||
Name string `json:"name"`
|
||||
Ref string `json:"ref"`
|
||||
Tag bool `json:"tag"`
|
||||
Coverage float64 `json:"coverage"`
|
||||
CreatedAt *time.Time `json:"created_at"`
|
||||
StartedAt *time.Time `json:"started_at"`
|
||||
FinishedAt *time.Time `json:"finished_at"`
|
||||
Duration float64 `json:"duration"`
|
||||
User *User `json:"user"`
|
||||
Commit *Commit `json:"commit"`
|
||||
Pipeline struct {
|
||||
ID int `json:"id"`
|
||||
Sha string `json:"sha"`
|
||||
Ref string `json:"ref"`
|
||||
Status string `json:"status"`
|
||||
} `json:"pipeline"`
|
||||
Runner *Runner `json:"runner"`
|
||||
} `json:"deployable"`
|
||||
}
|
||||
|
||||
// ListProjectDeploymentsOptions represents the available ListProjectDeployments() options.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/deployments.html#list-project-deployments
|
||||
type ListProjectDeploymentsOptions struct {
|
||||
ListOptions
|
||||
OrderBy *string `url:"order_by,omitempty" json:"order_by,omitempty"`
|
||||
Sort *string `url:"sort,omitempty" json:"sort,omitempty"`
|
||||
}
|
||||
|
||||
// ListProjectDeployments gets a list of deployments in a project.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/deployments.html#list-project-deployments
|
||||
func (s *DeploymentsService) ListProjectDeployments(pid interface{}, opts *ListProjectDeploymentsOptions, options ...OptionFunc) ([]*Deployment, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/deployments", url.QueryEscape(project))
|
||||
|
||||
req, err := s.client.NewRequest("GET", u, opts, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
var ds []*Deployment
|
||||
resp, err := s.client.Do(req, &ds)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return ds, resp, err
|
||||
}
|
||||
|
||||
// GetProjectDeployment get a deployment for a project.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/deployments.html#get-a-specific-deployment
|
||||
func (s *DeploymentsService) GetProjectDeployment(pid interface{}, deployment int, options ...OptionFunc) (*Deployment, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/deployments/%d", url.QueryEscape(project), deployment)
|
||||
|
||||
req, err := s.client.NewRequest("GET", u, nil, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
d := new(Deployment)
|
||||
resp, err := s.client.Do(req, d)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return d, resp, err
|
||||
}
|
||||
166
vendor/github.com/xanzy/go-gitlab/environments.go
generated
vendored
Normal file
166
vendor/github.com/xanzy/go-gitlab/environments.go
generated
vendored
Normal file
@@ -0,0 +1,166 @@
|
||||
//
|
||||
// Copyright 2017, Sander van Harmelen
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
package gitlab
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/url"
|
||||
)
|
||||
|
||||
// EnvironmentsService handles communication with the environment related methods
|
||||
// of the GitLab API.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/environments.html
|
||||
type EnvironmentsService struct {
|
||||
client *Client
|
||||
}
|
||||
|
||||
// Environment represents a GitLab environment.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/environments.html
|
||||
type Environment struct {
|
||||
ID int `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Slug string `json:"slug"`
|
||||
ExternalURL string `json:"external_url"`
|
||||
}
|
||||
|
||||
func (env Environment) String() string {
|
||||
return Stringify(env)
|
||||
}
|
||||
|
||||
// ListEnvironmentsOptions represents the available ListEnvironments() options.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ee/api/environments.html#list-environments
|
||||
type ListEnvironmentsOptions ListOptions
|
||||
|
||||
// ListEnvironments gets a list of environments from a project, sorted by name
|
||||
// alphabetically.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ee/api/environments.html#list-environments
|
||||
func (s *EnvironmentsService) ListEnvironments(pid interface{}, opts *ListEnvironmentsOptions, options ...OptionFunc) ([]*Environment, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/environments", url.QueryEscape(project))
|
||||
|
||||
req, err := s.client.NewRequest("GET", u, opts, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
var envs []*Environment
|
||||
resp, err := s.client.Do(req, &envs)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return envs, resp, err
|
||||
}
|
||||
|
||||
// CreateEnvironmentOptions represents the available CreateEnvironment() options.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ee/api/environments.html#create-a-new-environment
|
||||
type CreateEnvironmentOptions struct {
|
||||
Name *string `url:"name,omitempty" json:"name,omitempty"`
|
||||
ExternalURL *string `url:"external_url,omitempty" json:"external_url,omitempty"`
|
||||
}
|
||||
|
||||
// CreateEnvironment adds a environment to a project. This is an idempotent
|
||||
// method and can be called multiple times with the same parameters. Createing
|
||||
// an environment that is already a environment does not affect the
|
||||
// existing environmentship.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ee/api/environments.html#create-a-new-environment
|
||||
func (s *EnvironmentsService) CreateEnvironment(pid interface{}, opt *CreateEnvironmentOptions, options ...OptionFunc) (*Environment, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/environments", url.QueryEscape(project))
|
||||
|
||||
req, err := s.client.NewRequest("POST", u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
env := new(Environment)
|
||||
resp, err := s.client.Do(req, env)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return env, resp, err
|
||||
}
|
||||
|
||||
// EditEnvironmentOptions represents the available EditEnvironment() options.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ee/api/environments.html#edit-an-existing-environment
|
||||
type EditEnvironmentOptions struct {
|
||||
Name *string `url:"name,omitempty" json:"name,omitempty"`
|
||||
ExternalURL *string `url:"external_url,omitempty" json:"external_url,omitempty"`
|
||||
}
|
||||
|
||||
// EditEnvironment updates a project team environment to a specified access level..
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ee/api/environments.html#edit-an-existing-environment
|
||||
func (s *EnvironmentsService) EditEnvironment(pid interface{}, environment int, opt *EditEnvironmentOptions, options ...OptionFunc) (*Environment, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/environments/%d", url.QueryEscape(project), environment)
|
||||
|
||||
req, err := s.client.NewRequest("PUT", u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
env := new(Environment)
|
||||
resp, err := s.client.Do(req, env)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return env, resp, err
|
||||
}
|
||||
|
||||
// DeleteEnvironment removes a environment from a project team.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/environments.html#remove-a-environment-from-a-group-or-project
|
||||
func (s *EnvironmentsService) DeleteEnvironment(pid interface{}, environment int, options ...OptionFunc) (*Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/environments/%d", url.QueryEscape(project), environment)
|
||||
|
||||
req, err := s.client.NewRequest("DELETE", u, nil, options)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return s.client.Do(req, nil)
|
||||
}
|
||||
649
vendor/github.com/xanzy/go-gitlab/event_types.go
generated
vendored
Normal file
649
vendor/github.com/xanzy/go-gitlab/event_types.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
147
vendor/github.com/xanzy/go-gitlab/events.go
generated
vendored
Normal file
147
vendor/github.com/xanzy/go-gitlab/events.go
generated
vendored
Normal file
@@ -0,0 +1,147 @@
|
||||
//
|
||||
// Copyright 2017, Sander van Harmelen
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
package gitlab
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/url"
|
||||
"time"
|
||||
)
|
||||
|
||||
// EventsService handles communication with the event related methods of
|
||||
// the GitLab API.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/events.html
|
||||
type EventsService struct {
|
||||
client *Client
|
||||
}
|
||||
|
||||
// ContributionEvent represents a user's contribution
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/events.html#get-user-contribution-events
|
||||
type ContributionEvent struct {
|
||||
Title string `json:"title"`
|
||||
ProjectID int `json:"project_id"`
|
||||
ActionName string `json:"action_name"`
|
||||
TargetID int `json:"target_id"`
|
||||
TargetIID int `json:"target_iid"`
|
||||
TargetType string `json:"target_type"`
|
||||
AuthorID int `json:"author_id"`
|
||||
TargetTitle string `json:"target_title"`
|
||||
CreatedAt *time.Time `json:"created_at"`
|
||||
PushData struct {
|
||||
CommitCount int `json:"commit_count"`
|
||||
Action string `json:"action"`
|
||||
RefType string `json:"ref_type"`
|
||||
CommitFrom string `json:"commit_from"`
|
||||
CommitTo string `json:"commit_to"`
|
||||
Ref string `json:"ref"`
|
||||
CommitTitle string `json:"commit_title"`
|
||||
} `json:"push_data"`
|
||||
Note *Note `json:"note"`
|
||||
Author struct {
|
||||
Name string `json:"name"`
|
||||
Username string `json:"username"`
|
||||
ID int `json:"id"`
|
||||
State string `json:"state"`
|
||||
AvatarURL string `json:"avatar_url"`
|
||||
WebURL string `json:"web_url"`
|
||||
} `json:"author"`
|
||||
AuthorUsername string `json:"author_username"`
|
||||
}
|
||||
|
||||
// ListContributionEventsOptions represents the options for GetUserContributionEvents
|
||||
//
|
||||
// GitLap API docs:
|
||||
// https://docs.gitlab.com/ce/api/events.html#get-user-contribution-events
|
||||
type ListContributionEventsOptions struct {
|
||||
ListOptions
|
||||
Action *EventTypeValue `json:"action,omitempty"`
|
||||
TargetType *EventTargetTypeValue `json:"target_type,omitempty"`
|
||||
Before *ISOTime `json:"before,omitempty"`
|
||||
After *ISOTime `json:"after,omitempty"`
|
||||
Sort *string `json:"sort,omitempty"`
|
||||
}
|
||||
|
||||
// ListUserContributionEvents retrieves user contribution events
|
||||
// for the specified user, sorted from newest to oldest.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/events.html#get-user-contribution-events
|
||||
func (s *UsersService) ListUserContributionEvents(uid interface{}, opt *ListContributionEventsOptions, options ...OptionFunc) ([]*ContributionEvent, *Response, error) {
|
||||
user, err := parseID(uid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("users/%s/events", user)
|
||||
|
||||
req, err := s.client.NewRequest("GET", u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
var cs []*ContributionEvent
|
||||
resp, err := s.client.Do(req, &cs)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return cs, resp, err
|
||||
}
|
||||
|
||||
// ListCurrentUserContributionEvents gets a list currently authenticated user's events
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/events.html#list-currently-authenticated-user-39-s-events
|
||||
func (s *EventsService) ListCurrentUserContributionEvents(opt *ListContributionEventsOptions, options ...OptionFunc) ([]*ContributionEvent, *Response, error) {
|
||||
req, err := s.client.NewRequest("GET", "events", opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
var cs []*ContributionEvent
|
||||
resp, err := s.client.Do(req, &cs)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return cs, resp, err
|
||||
}
|
||||
|
||||
// ListProjectContributionEvents gets a list currently authenticated user's events
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/events.html#list-a-project-39-s-visible-events
|
||||
func (s *EventsService) ListProjectContributionEvents(pid interface{}, opt *ListContributionEventsOptions, options ...OptionFunc) ([]*ContributionEvent, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("%s/events", url.QueryEscape(project))
|
||||
|
||||
req, err := s.client.NewRequest("GET", u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
var cs []*ContributionEvent
|
||||
resp, err := s.client.Do(req, &cs)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return cs, resp, err
|
||||
}
|
||||
79
vendor/github.com/xanzy/go-gitlab/feature_flags.go
generated
vendored
Normal file
79
vendor/github.com/xanzy/go-gitlab/feature_flags.go
generated
vendored
Normal file
@@ -0,0 +1,79 @@
|
||||
package gitlab
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/url"
|
||||
)
|
||||
|
||||
// FeaturesService handles the communication with the application FeaturesService
|
||||
// related methods of the GitLab API.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/features.html
|
||||
type FeaturesService struct {
|
||||
client *Client
|
||||
}
|
||||
|
||||
// Feature represents a GitLab feature flag.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/features.html
|
||||
type Feature struct {
|
||||
Name string `json:"name"`
|
||||
State string `json:"state"`
|
||||
Gates []Gate
|
||||
}
|
||||
|
||||
// Gate represents a gate of a GitLab feature flag.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/features.html
|
||||
type Gate struct {
|
||||
Key string `json:"key"`
|
||||
Value interface{} `json:"value"`
|
||||
}
|
||||
|
||||
func (f Feature) String() string {
|
||||
return Stringify(f)
|
||||
}
|
||||
|
||||
// ListFeatures gets a list of feature flags
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/features.html#list-all-features
|
||||
func (s *FeaturesService) ListFeatures(options ...OptionFunc) ([]*Feature, *Response, error) {
|
||||
req, err := s.client.NewRequest("GET", "features", nil, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
var f []*Feature
|
||||
resp, err := s.client.Do(req, &f)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
return f, resp, err
|
||||
}
|
||||
|
||||
// SetFeatureFlag sets or creates a feature flag gate
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/features.html#set-or-create-a-feature
|
||||
func (s *FeaturesService) SetFeatureFlag(name string, value interface{}, options ...OptionFunc) (*Feature, *Response, error) {
|
||||
u := fmt.Sprintf("features/%s", url.QueryEscape(name))
|
||||
|
||||
opt := struct {
|
||||
Value interface{} `url:"value" json:"value"`
|
||||
}{
|
||||
value,
|
||||
}
|
||||
|
||||
req, err := s.client.NewRequest("POST", u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
f := &Feature{}
|
||||
resp, err := s.client.Do(req, f)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
return f, resp, err
|
||||
}
|
||||
84
vendor/github.com/xanzy/go-gitlab/gitignore_templates.go
generated
vendored
Normal file
84
vendor/github.com/xanzy/go-gitlab/gitignore_templates.go
generated
vendored
Normal file
@@ -0,0 +1,84 @@
|
||||
//
|
||||
// Copyright 2018, Sander van Harmelen
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
package gitlab
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/url"
|
||||
)
|
||||
|
||||
// GitIgnoreTemplatesService handles communication with the gitignore
|
||||
// templates related methods of the GitLab API.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/templates/gitignores.html
|
||||
type GitIgnoreTemplatesService struct {
|
||||
client *Client
|
||||
}
|
||||
|
||||
// GitIgnoreTemplate represents a GitLab gitignore template.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/templates/gitignores.html
|
||||
type GitIgnoreTemplate struct {
|
||||
Name string `json:"name"`
|
||||
Content string `json:"content"`
|
||||
}
|
||||
|
||||
// ListTemplatesOptions represents the available ListAllTemplates() options.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/templates/gitignores.html#list-gitignore-templates
|
||||
type ListTemplatesOptions ListOptions
|
||||
|
||||
// ListTemplates get a list of available git ignore templates
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/templates/gitignores.html#list-gitignore-templates
|
||||
func (s *GitIgnoreTemplatesService) ListTemplates(opt *ListTemplatesOptions, options ...OptionFunc) ([]*GitIgnoreTemplate, *Response, error) {
|
||||
req, err := s.client.NewRequest("GET", "templates/gitignores", opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
var gs []*GitIgnoreTemplate
|
||||
resp, err := s.client.Do(req, &gs)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return gs, resp, err
|
||||
}
|
||||
|
||||
// GetTemplate get a git ignore template
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/templates/gitignores.html#single-gitignore-template
|
||||
func (s *GitIgnoreTemplatesService) GetTemplate(key string, options ...OptionFunc) (*GitIgnoreTemplate, *Response, error) {
|
||||
u := fmt.Sprintf("templates/gitignores/%s", url.QueryEscape(key))
|
||||
|
||||
req, err := s.client.NewRequest("GET", u, nil, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
g := new(GitIgnoreTemplate)
|
||||
resp, err := s.client.Do(req, g)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return g, resp, err
|
||||
}
|
||||
836
vendor/github.com/xanzy/go-gitlab/gitlab.go
generated
vendored
Normal file
836
vendor/github.com/xanzy/go-gitlab/gitlab.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
195
vendor/github.com/xanzy/go-gitlab/group_members.go
generated
vendored
Normal file
195
vendor/github.com/xanzy/go-gitlab/group_members.go
generated
vendored
Normal file
@@ -0,0 +1,195 @@
|
||||
//
|
||||
// Copyright 2017, Sander van Harmelen
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
package gitlab
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/url"
|
||||
"time"
|
||||
)
|
||||
|
||||
// GroupMembersService handles communication with the group members
|
||||
// related methods of the GitLab API.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/members.html
|
||||
type GroupMembersService struct {
|
||||
client *Client
|
||||
}
|
||||
|
||||
// GroupMember represents a GitLab group member.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/members.html
|
||||
type GroupMember struct {
|
||||
ID int `json:"id"`
|
||||
Username string `json:"username"`
|
||||
Email string `json:"email"`
|
||||
Name string `json:"name"`
|
||||
State string `json:"state"`
|
||||
CreatedAt *time.Time `json:"created_at"`
|
||||
AccessLevel AccessLevelValue `json:"access_level"`
|
||||
ExpiresAt *ISOTime `json:"expires_at"`
|
||||
}
|
||||
|
||||
// ListGroupMembersOptions represents the available ListGroupMembers()
|
||||
// options.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/members.html#list-all-members-of-a-group-or-project
|
||||
type ListGroupMembersOptions struct {
|
||||
ListOptions
|
||||
Query *string `url:"query,omitempty" json:"query,omitempty"`
|
||||
}
|
||||
|
||||
// ListGroupMembers get a list of group members viewable by the authenticated
|
||||
// user.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/members.html#list-all-members-of-a-group-or-project
|
||||
func (s *GroupsService) ListGroupMembers(gid interface{}, opt *ListGroupMembersOptions, options ...OptionFunc) ([]*GroupMember, *Response, error) {
|
||||
group, err := parseID(gid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("groups/%s/members", url.QueryEscape(group))
|
||||
|
||||
req, err := s.client.NewRequest("GET", u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
var gm []*GroupMember
|
||||
resp, err := s.client.Do(req, &gm)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return gm, resp, err
|
||||
}
|
||||
|
||||
// AddGroupMemberOptions represents the available AddGroupMember() options.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/members.html#add-a-member-to-a-group-or-project
|
||||
type AddGroupMemberOptions struct {
|
||||
UserID *int `url:"user_id,omitempty" json:"user_id,omitempty"`
|
||||
AccessLevel *AccessLevelValue `url:"access_level,omitempty" json:"access_level,omitempty"`
|
||||
ExpiresAt *string `url:"expires_at,omitempty" json:"expires_at"`
|
||||
}
|
||||
|
||||
// GetGroupMember gets a member of a group.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/members.html#get-a-member-of-a-group-or-project
|
||||
func (s *GroupMembersService) GetGroupMember(gid interface{}, user int, options ...OptionFunc) (*GroupMember, *Response, error) {
|
||||
group, err := parseID(gid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("groups/%s/members/%d", url.QueryEscape(group), user)
|
||||
|
||||
req, err := s.client.NewRequest("GET", u, nil, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
gm := new(GroupMember)
|
||||
resp, err := s.client.Do(req, gm)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return gm, resp, err
|
||||
}
|
||||
|
||||
// AddGroupMember adds a user to the list of group members.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/members.html#add-a-member-to-a-group-or-project
|
||||
func (s *GroupMembersService) AddGroupMember(gid interface{}, opt *AddGroupMemberOptions, options ...OptionFunc) (*GroupMember, *Response, error) {
|
||||
group, err := parseID(gid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("groups/%s/members", url.QueryEscape(group))
|
||||
|
||||
req, err := s.client.NewRequest("POST", u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
gm := new(GroupMember)
|
||||
resp, err := s.client.Do(req, gm)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return gm, resp, err
|
||||
}
|
||||
|
||||
// EditGroupMemberOptions represents the available EditGroupMember()
|
||||
// options.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/members.html#edit-a-member-of-a-group-or-project
|
||||
type EditGroupMemberOptions struct {
|
||||
AccessLevel *AccessLevelValue `url:"access_level,omitempty" json:"access_level,omitempty"`
|
||||
ExpiresAt *string `url:"expires_at,omitempty" json:"expires_at"`
|
||||
}
|
||||
|
||||
// EditGroupMember updates a member of a group.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/members.html#edit-a-member-of-a-group-or-project
|
||||
func (s *GroupMembersService) EditGroupMember(gid interface{}, user int, opt *EditGroupMemberOptions, options ...OptionFunc) (*GroupMember, *Response, error) {
|
||||
group, err := parseID(gid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("groups/%s/members/%d", url.QueryEscape(group), user)
|
||||
|
||||
req, err := s.client.NewRequest("PUT", u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
gm := new(GroupMember)
|
||||
resp, err := s.client.Do(req, gm)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return gm, resp, err
|
||||
}
|
||||
|
||||
// RemoveGroupMember removes user from user team.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/members.html#remove-a-member-from-a-group-or-project
|
||||
func (s *GroupMembersService) RemoveGroupMember(gid interface{}, user int, options ...OptionFunc) (*Response, error) {
|
||||
group, err := parseID(gid)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
u := fmt.Sprintf("groups/%s/members/%d", url.QueryEscape(group), user)
|
||||
|
||||
req, err := s.client.NewRequest("DELETE", u, nil, options)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return s.client.Do(req, nil)
|
||||
}
|
||||
250
vendor/github.com/xanzy/go-gitlab/group_milestones.go
generated
vendored
Normal file
250
vendor/github.com/xanzy/go-gitlab/group_milestones.go
generated
vendored
Normal file
@@ -0,0 +1,250 @@
|
||||
//
|
||||
// Copyright 2018, Sander van Harmelen
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
package gitlab
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/url"
|
||||
"time"
|
||||
)
|
||||
|
||||
// GroupMilestonesService handles communication with the milestone related
|
||||
// methods of the GitLab API.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/group_milestones.html
|
||||
type GroupMilestonesService struct {
|
||||
client *Client
|
||||
}
|
||||
|
||||
// GroupMilestone represents a GitLab milestone.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/group_milestones.html
|
||||
type GroupMilestone struct {
|
||||
ID int `json:"id"`
|
||||
IID int `json:"iid"`
|
||||
GroupID int `json:"group_id"`
|
||||
Title string `json:"title"`
|
||||
Description string `json:"description"`
|
||||
StartDate *ISOTime `json:"start_date"`
|
||||
DueDate *ISOTime `json:"due_date"`
|
||||
State string `json:"state"`
|
||||
UpdatedAt *time.Time `json:"updated_at"`
|
||||
CreatedAt *time.Time `json:"created_at"`
|
||||
}
|
||||
|
||||
func (m GroupMilestone) String() string {
|
||||
return Stringify(m)
|
||||
}
|
||||
|
||||
// ListGroupMilestonesOptions represents the available
|
||||
// ListGroupMilestones() options.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/group_milestones.html#list-group-milestones
|
||||
type ListGroupMilestonesOptions struct {
|
||||
ListOptions
|
||||
IIDs []int `url:"iids,omitempty" json:"iids,omitempty"`
|
||||
State string `url:"state,omitempty" json:"state,omitempty"`
|
||||
Search string `url:"search,omitempty" json:"search,omitempty"`
|
||||
}
|
||||
|
||||
// ListGroupMilestones returns a list of group milestones.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/group_milestones.html#list-group-milestones
|
||||
func (s *GroupMilestonesService) ListGroupMilestones(gid interface{}, opt *ListGroupMilestonesOptions, options ...OptionFunc) ([]*GroupMilestone, *Response, error) {
|
||||
group, err := parseID(gid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("groups/%s/milestones", url.QueryEscape(group))
|
||||
|
||||
req, err := s.client.NewRequest("GET", u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
var m []*GroupMilestone
|
||||
resp, err := s.client.Do(req, &m)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return m, resp, err
|
||||
}
|
||||
|
||||
// GetGroupMilestone gets a single group milestone.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/group_milestones.html#get-single-milestone
|
||||
func (s *GroupMilestonesService) GetGroupMilestone(gid interface{}, milestone int, options ...OptionFunc) (*GroupMilestone, *Response, error) {
|
||||
group, err := parseID(gid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("groups/%s/milestones/%d", url.QueryEscape(group), milestone)
|
||||
|
||||
req, err := s.client.NewRequest("GET", u, nil, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
m := new(GroupMilestone)
|
||||
resp, err := s.client.Do(req, m)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return m, resp, err
|
||||
}
|
||||
|
||||
// CreateGroupMilestoneOptions represents the available CreateGroupMilestone() options.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/group_milestones.html#create-new-milestone
|
||||
type CreateGroupMilestoneOptions struct {
|
||||
Title *string `url:"title,omitempty" json:"title,omitempty"`
|
||||
Description *string `url:"description,omitempty" json:"description,omitempty"`
|
||||
StartDate *ISOTime `url:"start_date,omitempty" json:"start_date,omitempty"`
|
||||
DueDate *ISOTime `url:"due_date,omitempty" json:"due_date,omitempty"`
|
||||
}
|
||||
|
||||
// CreateGroupMilestone creates a new group milestone.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/group_milestones.html#create-new-milestone
|
||||
func (s *GroupMilestonesService) CreateGroupMilestone(gid interface{}, opt *CreateGroupMilestoneOptions, options ...OptionFunc) (*GroupMilestone, *Response, error) {
|
||||
group, err := parseID(gid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("groups/%s/milestones", url.QueryEscape(group))
|
||||
|
||||
req, err := s.client.NewRequest("POST", u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
m := new(GroupMilestone)
|
||||
resp, err := s.client.Do(req, m)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return m, resp, err
|
||||
}
|
||||
|
||||
// UpdateGroupMilestoneOptions represents the available UpdateGroupMilestone() options.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/group_milestones.html#edit-milestone
|
||||
type UpdateGroupMilestoneOptions struct {
|
||||
Title *string `url:"title,omitempty" json:"title,omitempty"`
|
||||
Description *string `url:"description,omitempty" json:"description,omitempty"`
|
||||
StartDate *ISOTime `url:"start_date,omitempty" json:"start_date,omitempty"`
|
||||
DueDate *ISOTime `url:"due_date,omitempty" json:"due_date,omitempty"`
|
||||
StateEvent *string `url:"state_event,omitempty" json:"state_event,omitempty"`
|
||||
}
|
||||
|
||||
// UpdateGroupMilestone updates an existing group milestone.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/group_milestones.html#edit-milestone
|
||||
func (s *GroupMilestonesService) UpdateGroupMilestone(gid interface{}, milestone int, opt *UpdateGroupMilestoneOptions, options ...OptionFunc) (*GroupMilestone, *Response, error) {
|
||||
group, err := parseID(gid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("groups/%s/milestones/%d", url.QueryEscape(group), milestone)
|
||||
|
||||
req, err := s.client.NewRequest("PUT", u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
m := new(GroupMilestone)
|
||||
resp, err := s.client.Do(req, m)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return m, resp, err
|
||||
}
|
||||
|
||||
// GetGroupMilestoneIssuesOptions represents the available GetGroupMilestoneIssues() options.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/group_milestones.html#get-all-issues-assigned-to-a-single-milestone
|
||||
type GetGroupMilestoneIssuesOptions ListOptions
|
||||
|
||||
// GetGroupMilestoneIssues gets all issues assigned to a single group milestone.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/group_milestones.html#get-all-issues-assigned-to-a-single-milestone
|
||||
func (s *GroupMilestonesService) GetGroupMilestoneIssues(gid interface{}, milestone int, opt *GetGroupMilestoneIssuesOptions, options ...OptionFunc) ([]*Issue, *Response, error) {
|
||||
group, err := parseID(gid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("groups/%s/milestones/%d/issues", url.QueryEscape(group), milestone)
|
||||
|
||||
req, err := s.client.NewRequest("GET", u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
var i []*Issue
|
||||
resp, err := s.client.Do(req, &i)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return i, resp, err
|
||||
}
|
||||
|
||||
// GetGroupMilestoneMergeRequestsOptions represents the available
|
||||
// GetGroupMilestoneMergeRequests() options.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/group_milestones.html#get-all-merge-requests-assigned-to-a-single-milestone
|
||||
type GetGroupMilestoneMergeRequestsOptions ListOptions
|
||||
|
||||
// GetGroupMilestoneMergeRequests gets all merge requests assigned to a
|
||||
// single group milestone.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/group_milestones.html#get-all-merge-requests-assigned-to-a-single-milestone
|
||||
func (s *GroupMilestonesService) GetGroupMilestoneMergeRequests(gid interface{}, milestone int, opt *GetGroupMilestoneMergeRequestsOptions, options ...OptionFunc) ([]*MergeRequest, *Response, error) {
|
||||
group, err := parseID(gid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("groups/%s/milestones/%d/merge_requests", url.QueryEscape(group), milestone)
|
||||
|
||||
req, err := s.client.NewRequest("GET", u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
var mr []*MergeRequest
|
||||
resp, err := s.client.Do(req, &mr)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return mr, resp, err
|
||||
}
|
||||
307
vendor/github.com/xanzy/go-gitlab/groups.go
generated
vendored
Normal file
307
vendor/github.com/xanzy/go-gitlab/groups.go
generated
vendored
Normal file
@@ -0,0 +1,307 @@
|
||||
//
|
||||
// Copyright 2017, Sander van Harmelen
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
package gitlab
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/url"
|
||||
)
|
||||
|
||||
// GroupsService handles communication with the group related methods of
|
||||
// the GitLab API.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/groups.html
|
||||
type GroupsService struct {
|
||||
client *Client
|
||||
}
|
||||
|
||||
// Group represents a GitLab group.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/groups.html
|
||||
type Group struct {
|
||||
ID int `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Path string `json:"path"`
|
||||
Description string `json:"description"`
|
||||
Visibility *VisibilityValue `json:"visibility"`
|
||||
LFSEnabled bool `json:"lfs_enabled"`
|
||||
AvatarURL string `json:"avatar_url"`
|
||||
WebURL string `json:"web_url"`
|
||||
RequestAccessEnabled bool `json:"request_access_enabled"`
|
||||
FullName string `json:"full_name"`
|
||||
FullPath string `json:"full_path"`
|
||||
ParentID int `json:"parent_id"`
|
||||
Projects []*Project `json:"projects"`
|
||||
Statistics *StorageStatistics `json:"statistics"`
|
||||
}
|
||||
|
||||
// ListGroupsOptions represents the available ListGroups() options.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/groups.html#list-project-groups
|
||||
type ListGroupsOptions struct {
|
||||
ListOptions
|
||||
AllAvailable *bool `url:"all_available,omitempty" json:"all_available,omitempty"`
|
||||
OrderBy *string `url:"order_by,omitempty" json:"order_by,omitempty"`
|
||||
Owned *bool `url:"owned,omitempty" json:"owned,omitempty"`
|
||||
Search *string `url:"search,omitempty" json:"search,omitempty"`
|
||||
Sort *string `url:"sort,omitempty" json:"sort,omitempty"`
|
||||
Statistics *bool `url:"statistics,omitempty" json:"statistics,omitempty"`
|
||||
}
|
||||
|
||||
// ListGroups gets a list of groups (as user: my groups, as admin: all groups).
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/groups.html#list-project-groups
|
||||
func (s *GroupsService) ListGroups(opt *ListGroupsOptions, options ...OptionFunc) ([]*Group, *Response, error) {
|
||||
req, err := s.client.NewRequest("GET", "groups", opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
var g []*Group
|
||||
resp, err := s.client.Do(req, &g)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return g, resp, err
|
||||
}
|
||||
|
||||
// GetGroup gets all details of a group.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/groups.html#details-of-a-group
|
||||
func (s *GroupsService) GetGroup(gid interface{}, options ...OptionFunc) (*Group, *Response, error) {
|
||||
group, err := parseID(gid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("groups/%s", url.QueryEscape(group))
|
||||
|
||||
req, err := s.client.NewRequest("GET", u, nil, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
g := new(Group)
|
||||
resp, err := s.client.Do(req, g)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return g, resp, err
|
||||
}
|
||||
|
||||
// CreateGroupOptions represents the available CreateGroup() options.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/groups.html#new-group
|
||||
type CreateGroupOptions struct {
|
||||
Name *string `url:"name,omitempty" json:"name,omitempty"`
|
||||
Path *string `url:"path,omitempty" json:"path,omitempty"`
|
||||
Description *string `url:"description,omitempty" json:"description,omitempty"`
|
||||
Visibility *VisibilityValue `url:"visibility,omitempty" json:"visibility,omitempty"`
|
||||
LFSEnabled *bool `url:"lfs_enabled,omitempty" json:"lfs_enabled,omitempty"`
|
||||
RequestAccessEnabled *bool `url:"request_access_enabled,omitempty" json:"request_access_enabled,omitempty"`
|
||||
ParentID *int `url:"parent_id,omitempty" json:"parent_id,omitempty"`
|
||||
}
|
||||
|
||||
// CreateGroup creates a new project group. Available only for users who can
|
||||
// create groups.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/groups.html#new-group
|
||||
func (s *GroupsService) CreateGroup(opt *CreateGroupOptions, options ...OptionFunc) (*Group, *Response, error) {
|
||||
req, err := s.client.NewRequest("POST", "groups", opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
g := new(Group)
|
||||
resp, err := s.client.Do(req, g)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return g, resp, err
|
||||
}
|
||||
|
||||
// TransferGroup transfers a project to the Group namespace. Available only
|
||||
// for admin.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/groups.html#transfer-project-to-group
|
||||
func (s *GroupsService) TransferGroup(gid interface{}, pid interface{}, options ...OptionFunc) (*Group, *Response, error) {
|
||||
group, err := parseID(gid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
u := fmt.Sprintf("groups/%s/projects/%s", url.QueryEscape(group),
|
||||
url.QueryEscape(project))
|
||||
|
||||
req, err := s.client.NewRequest("POST", u, nil, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
g := new(Group)
|
||||
resp, err := s.client.Do(req, g)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return g, resp, err
|
||||
}
|
||||
|
||||
// UpdateGroupOptions represents the set of available options to update a Group;
|
||||
// as of today these are exactly the same available when creating a new Group.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/groups.html#update-group
|
||||
type UpdateGroupOptions CreateGroupOptions
|
||||
|
||||
// UpdateGroup updates an existing group; only available to group owners and
|
||||
// administrators.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/groups.html#update-group
|
||||
func (s *GroupsService) UpdateGroup(gid interface{}, opt *UpdateGroupOptions, options ...OptionFunc) (*Group, *Response, error) {
|
||||
group, err := parseID(gid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("groups/%s", url.QueryEscape(group))
|
||||
|
||||
req, err := s.client.NewRequest("PUT", u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
g := new(Group)
|
||||
resp, err := s.client.Do(req, g)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return g, resp, err
|
||||
}
|
||||
|
||||
// DeleteGroup removes group with all projects inside.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/groups.html#remove-group
|
||||
func (s *GroupsService) DeleteGroup(gid interface{}, options ...OptionFunc) (*Response, error) {
|
||||
group, err := parseID(gid)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
u := fmt.Sprintf("groups/%s", url.QueryEscape(group))
|
||||
|
||||
req, err := s.client.NewRequest("DELETE", u, nil, options)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return s.client.Do(req, nil)
|
||||
}
|
||||
|
||||
// SearchGroup get all groups that match your string in their name or path.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/groups.html#search-for-group
|
||||
func (s *GroupsService) SearchGroup(query string, options ...OptionFunc) ([]*Group, *Response, error) {
|
||||
var q struct {
|
||||
Search string `url:"search,omitempty" json:"search,omitempty"`
|
||||
}
|
||||
q.Search = query
|
||||
|
||||
req, err := s.client.NewRequest("GET", "groups", &q, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
var g []*Group
|
||||
resp, err := s.client.Do(req, &g)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return g, resp, err
|
||||
}
|
||||
|
||||
// ListGroupProjectsOptions represents the available ListGroupProjects()
|
||||
// options.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/groups.html#list-a-group-39-s-projects
|
||||
type ListGroupProjectsOptions ListProjectsOptions
|
||||
|
||||
// ListGroupProjects get a list of group projects
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/groups.html#list-a-group-39-s-projects
|
||||
func (s *GroupsService) ListGroupProjects(gid interface{}, opt *ListGroupProjectsOptions, options ...OptionFunc) ([]*Project, *Response, error) {
|
||||
group, err := parseID(gid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("groups/%s/projects", url.QueryEscape(group))
|
||||
|
||||
req, err := s.client.NewRequest("GET", u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
var p []*Project
|
||||
resp, err := s.client.Do(req, &p)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return p, resp, err
|
||||
}
|
||||
|
||||
// ListSubgroupsOptions represents the available ListSubgroupsOptions()
|
||||
// options.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/groups.html#list-a-groups-s-subgroups
|
||||
type ListSubgroupsOptions ListGroupsOptions
|
||||
|
||||
// ListSubgroups gets a list of subgroups for a given project.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/groups.html#list-a-groups-s-subgroups
|
||||
func (s *GroupsService) ListSubgroups(gid interface{}, opt *ListSubgroupsOptions, options ...OptionFunc) ([]*Group, *Response, error) {
|
||||
group, err := parseID(gid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("groups/%s/subgroups", url.QueryEscape(group))
|
||||
|
||||
req, err := s.client.NewRequest("GET", u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
var g []*Group
|
||||
resp, err := s.client.Do(req, &g)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return g, resp, err
|
||||
}
|
||||
128
vendor/github.com/xanzy/go-gitlab/issue_links.go
generated
vendored
Normal file
128
vendor/github.com/xanzy/go-gitlab/issue_links.go
generated
vendored
Normal file
@@ -0,0 +1,128 @@
|
||||
//
|
||||
// Copyright 2017, Arkbriar
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
package gitlab
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/url"
|
||||
)
|
||||
|
||||
// IssueLinksService handles communication with the issue relations related methods
|
||||
// of the GitLab API.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ee/api/issue_links.html
|
||||
type IssueLinksService struct {
|
||||
client *Client
|
||||
}
|
||||
|
||||
// IssueLink represents a two-way relation between two issues.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ee/api/issue_links.html
|
||||
type IssueLink struct {
|
||||
SourceIssue *Issue `json:"source_issue"`
|
||||
TargetIssue *Issue `json:"target_issue"`
|
||||
}
|
||||
|
||||
// ListIssueRelations gets a list of related issues of a given issue,
|
||||
// sorted by the relationship creation datetime (ascending).
|
||||
//
|
||||
// Issues will be filtered according to the user authorizations.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ee/api/issue_links.html#list-issue-relations
|
||||
func (s *IssueLinksService) ListIssueRelations(pid interface{}, issueIID int, options ...OptionFunc) ([]*Issue, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/issues/%d/links", url.QueryEscape(project), issueIID)
|
||||
|
||||
req, err := s.client.NewRequest("GET", u, nil, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
var is []*Issue
|
||||
resp, err := s.client.Do(req, &is)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return is, resp, err
|
||||
}
|
||||
|
||||
// CreateIssueLinkOptions represents the available CreateIssueLink() options.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ee/api/issue_links.html
|
||||
type CreateIssueLinkOptions struct {
|
||||
TargetProjectID *string `json:"target_project_id"`
|
||||
TargetIssueIID *string `json:"target_issue_iid"`
|
||||
}
|
||||
|
||||
// CreateIssueLink creates a two-way relation between two issues.
|
||||
// User must be allowed to update both issues in order to succeed.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ee/api/issue_links.html#create-an-issue-link
|
||||
func (s *IssueLinksService) CreateIssueLink(pid interface{}, issueIID int, opt *CreateIssueLinkOptions, options ...OptionFunc) (*IssueLink, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/issues/%d/links", url.QueryEscape(project), issueIID)
|
||||
|
||||
req, err := s.client.NewRequest("POST", u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
i := new(IssueLink)
|
||||
resp, err := s.client.Do(req, &i)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return i, resp, err
|
||||
}
|
||||
|
||||
// DeleteIssueLink deletes an issue link, thus removes the two-way relationship.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ee/api/issue_links.html#delete-an-issue-link
|
||||
func (s *IssueLinksService) DeleteIssueLink(pid interface{}, issueIID, issueLinkID int, options ...OptionFunc) (*IssueLink, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/issues/%d/links/%d",
|
||||
url.QueryEscape(project),
|
||||
issueIID,
|
||||
issueLinkID)
|
||||
|
||||
req, err := s.client.NewRequest("DELETE", u, nil, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
i := new(IssueLink)
|
||||
resp, err := s.client.Do(req, &i)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return i, resp, err
|
||||
}
|
||||
436
vendor/github.com/xanzy/go-gitlab/issues.go
generated
vendored
Normal file
436
vendor/github.com/xanzy/go-gitlab/issues.go
generated
vendored
Normal file
@@ -0,0 +1,436 @@
|
||||
//
|
||||
// Copyright 2017, Sander van Harmelen
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
package gitlab
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/url"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
// IssuesService handles communication with the issue related methods
|
||||
// of the GitLab API.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/issues.html
|
||||
type IssuesService struct {
|
||||
client *Client
|
||||
timeStats *timeStatsService
|
||||
}
|
||||
|
||||
// Issue represents a GitLab issue.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/issues.html
|
||||
type Issue struct {
|
||||
ID int `json:"id"`
|
||||
IID int `json:"iid"`
|
||||
ProjectID int `json:"project_id"`
|
||||
Milestone *Milestone `json:"milestone"`
|
||||
Author struct {
|
||||
ID int `json:"id"`
|
||||
Username string `json:"username"`
|
||||
Email string `json:"email"`
|
||||
Name string `json:"name"`
|
||||
State string `json:"state"`
|
||||
CreatedAt *time.Time `json:"created_at"`
|
||||
} `json:"author"`
|
||||
Description string `json:"description"`
|
||||
State string `json:"state"`
|
||||
Assignees []struct {
|
||||
ID int `json:"id"`
|
||||
Username string `json:"username"`
|
||||
Email string `json:"email"`
|
||||
Name string `json:"name"`
|
||||
State string `json:"state"`
|
||||
CreatedAt *time.Time `json:"created_at"`
|
||||
} `json:"assignees"`
|
||||
Assignee struct {
|
||||
ID int `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Username string `json:"username"`
|
||||
State string `json:"state"`
|
||||
AvatarURL string `json:"avatar_url"`
|
||||
WebURL string `json:"web_url"`
|
||||
} `json:"assignee"`
|
||||
Upvotes int `json:"upvotes"`
|
||||
Downvotes int `json:"downvotes"`
|
||||
Labels []string `json:"labels"`
|
||||
Title string `json:"title"`
|
||||
UpdatedAt *time.Time `json:"updated_at"`
|
||||
CreatedAt *time.Time `json:"created_at"`
|
||||
ClosedAt *time.Time `json:"closed_at"`
|
||||
Subscribed bool `json:"subscribed"`
|
||||
UserNotesCount int `json:"user_notes_count"`
|
||||
DueDate *ISOTime `json:"due_date"`
|
||||
WebURL string `json:"web_url"`
|
||||
TimeStats *TimeStats `json:"time_stats"`
|
||||
Confidential bool `json:"confidential"`
|
||||
Weight int `json:"weight"`
|
||||
DiscussionLocked bool `json:"discussion_locked"`
|
||||
Links struct {
|
||||
Self string `json:"self"`
|
||||
Notes string `json:"notes"`
|
||||
AwardEmoji string `json:"award_emoji"`
|
||||
Project string `json:"project"`
|
||||
} `json:"_links"`
|
||||
IssueLinkID int `json:"issue_link_id"`
|
||||
}
|
||||
|
||||
func (i Issue) String() string {
|
||||
return Stringify(i)
|
||||
}
|
||||
|
||||
// Labels is a custom type with specific marshaling characteristics.
|
||||
type Labels []string
|
||||
|
||||
// MarshalJSON implements the json.Marshaler interface.
|
||||
func (l *Labels) MarshalJSON() ([]byte, error) {
|
||||
return json.Marshal(strings.Join(*l, ","))
|
||||
}
|
||||
|
||||
// ListIssuesOptions represents the available ListIssues() options.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/issues.html#list-issues
|
||||
type ListIssuesOptions struct {
|
||||
ListOptions
|
||||
State *string `url:"state,omitempty" json:"state,omitempty"`
|
||||
Labels Labels `url:"labels,comma,omitempty" json:"labels,omitempty"`
|
||||
Milestone *string `url:"milestone,omitempty" json:"milestone,omitempty"`
|
||||
Scope *string `url:"scope,omitempty" json:"scope,omitempty"`
|
||||
AuthorID *int `url:"author_id,omitempty" json:"author_id,omitempty"`
|
||||
AssigneeID *int `url:"assignee_id,omitempty" json:"assignee_id,omitempty"`
|
||||
MyReactionEmoji *string `url:"my_reaction_emoji,omitempty" json:"my_reaction_emoji,omitempty"`
|
||||
IIDs []int `url:"iids[],omitempty" json:"iids,omitempty"`
|
||||
OrderBy *string `url:"order_by,omitempty" json:"order_by,omitempty"`
|
||||
Sort *string `url:"sort,omitempty" json:"sort,omitempty"`
|
||||
Search *string `url:"search,omitempty" json:"search,omitempty"`
|
||||
CreatedAfter *time.Time `url:"created_after,omitempty" json:"created_after,omitempty"`
|
||||
CreatedBefore *time.Time `url:"created_before,omitempty" json:"created_before,omitempty"`
|
||||
UpdatedAfter *time.Time `url:"updated_after,omitempty" json:"updated_after,omitempty"`
|
||||
UpdatedBefore *time.Time `url:"updated_before,omitempty" json:"updated_before,omitempty"`
|
||||
}
|
||||
|
||||
// ListIssues gets all issues created by authenticated user. This function
|
||||
// takes pagination parameters page and per_page to restrict the list of issues.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/issues.html#list-issues
|
||||
func (s *IssuesService) ListIssues(opt *ListIssuesOptions, options ...OptionFunc) ([]*Issue, *Response, error) {
|
||||
req, err := s.client.NewRequest("GET", "issues", opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
var i []*Issue
|
||||
resp, err := s.client.Do(req, &i)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return i, resp, err
|
||||
}
|
||||
|
||||
// ListGroupIssuesOptions represents the available ListGroupIssues() options.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/issues.html#list-group-issues
|
||||
type ListGroupIssuesOptions struct {
|
||||
ListOptions
|
||||
State *string `url:"state,omitempty" json:"state,omitempty"`
|
||||
Labels Labels `url:"labels,comma,omitempty" json:"labels,omitempty"`
|
||||
IIDs []int `url:"iids[],omitempty" json:"iids,omitempty"`
|
||||
Milestone *string `url:"milestone,omitempty" json:"milestone,omitempty"`
|
||||
Scope *string `url:"scope,omitempty" json:"scope,omitempty"`
|
||||
AuthorID *int `url:"author_id,omitempty" json:"author_id,omitempty"`
|
||||
AssigneeID *int `url:"assignee_id,omitempty" json:"assignee_id,omitempty"`
|
||||
MyReactionEmoji *string `url:"my_reaction_emoji,omitempty" json:"my_reaction_emoji,omitempty"`
|
||||
OrderBy *string `url:"order_by,omitempty" json:"order_by,omitempty"`
|
||||
Sort *string `url:"sort,omitempty" json:"sort,omitempty"`
|
||||
Search *string `url:"search,omitempty" json:"search,omitempty"`
|
||||
CreatedAfter *time.Time `url:"created_after,omitempty" json:"created_after,omitempty"`
|
||||
CreatedBefore *time.Time `url:"created_before,omitempty" json:"created_before,omitempty"`
|
||||
UpdatedAfter *time.Time `url:"updated_after,omitempty" json:"updated_after,omitempty"`
|
||||
UpdatedBefore *time.Time `url:"updated_before,omitempty" json:"updated_before,omitempty"`
|
||||
}
|
||||
|
||||
// ListGroupIssues gets a list of group issues. This function accepts
|
||||
// pagination parameters page and per_page to return the list of group issues.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/issues.html#list-group-issues
|
||||
func (s *IssuesService) ListGroupIssues(pid interface{}, opt *ListGroupIssuesOptions, options ...OptionFunc) ([]*Issue, *Response, error) {
|
||||
group, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("groups/%s/issues", url.QueryEscape(group))
|
||||
|
||||
req, err := s.client.NewRequest("GET", u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
var i []*Issue
|
||||
resp, err := s.client.Do(req, &i)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return i, resp, err
|
||||
}
|
||||
|
||||
// ListProjectIssuesOptions represents the available ListProjectIssues() options.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/issues.html#list-project-issues
|
||||
type ListProjectIssuesOptions struct {
|
||||
ListOptions
|
||||
IIDs []int `url:"iids[],omitempty" json:"iids,omitempty"`
|
||||
State *string `url:"state,omitempty" json:"state,omitempty"`
|
||||
Labels Labels `url:"labels,comma,omitempty" json:"labels,omitempty"`
|
||||
Milestone *string `url:"milestone,omitempty" json:"milestone,omitempty"`
|
||||
Scope *string `url:"scope,omitempty" json:"scope,omitempty"`
|
||||
AuthorID *int `url:"author_id,omitempty" json:"author_id,omitempty"`
|
||||
AssigneeID *int `url:"assignee_id,omitempty" json:"assignee_id,omitempty"`
|
||||
MyReactionEmoji *string `url:"my_reaction_emoji,omitempty" json:"my_reaction_emoji,omitempty"`
|
||||
OrderBy *string `url:"order_by,omitempty" json:"order_by,omitempty"`
|
||||
Sort *string `url:"sort,omitempty" json:"sort,omitempty"`
|
||||
Search *string `url:"search,omitempty" json:"search,omitempty"`
|
||||
CreatedAfter *time.Time `url:"created_after,omitempty" json:"created_after,omitempty"`
|
||||
CreatedBefore *time.Time `url:"created_before,omitempty" json:"created_before,omitempty"`
|
||||
UpdatedAfter *time.Time `url:"updated_after,omitempty" json:"updated_after,omitempty"`
|
||||
UpdatedBefore *time.Time `url:"updated_before,omitempty" json:"updated_before,omitempty"`
|
||||
}
|
||||
|
||||
// ListProjectIssues gets a list of project issues. This function accepts
|
||||
// pagination parameters page and per_page to return the list of project issues.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/issues.html#list-project-issues
|
||||
func (s *IssuesService) ListProjectIssues(pid interface{}, opt *ListProjectIssuesOptions, options ...OptionFunc) ([]*Issue, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/issues", url.QueryEscape(project))
|
||||
|
||||
req, err := s.client.NewRequest("GET", u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
var i []*Issue
|
||||
resp, err := s.client.Do(req, &i)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return i, resp, err
|
||||
}
|
||||
|
||||
// GetIssue gets a single project issue.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/issues.html#single-issues
|
||||
func (s *IssuesService) GetIssue(pid interface{}, issue int, options ...OptionFunc) (*Issue, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/issues/%d", url.QueryEscape(project), issue)
|
||||
|
||||
req, err := s.client.NewRequest("GET", u, nil, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
i := new(Issue)
|
||||
resp, err := s.client.Do(req, i)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return i, resp, err
|
||||
}
|
||||
|
||||
// CreateIssueOptions represents the available CreateIssue() options.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/issues.html#new-issues
|
||||
type CreateIssueOptions struct {
|
||||
Title *string `url:"title,omitempty" json:"title,omitempty"`
|
||||
Description *string `url:"description,omitempty" json:"description,omitempty"`
|
||||
Confidential *bool `url:"confidential,omitempty" json:"confidential,omitempty"`
|
||||
AssigneeIDs []int `url:"assignee_ids,omitempty" json:"assignee_ids,omitempty"`
|
||||
MilestoneID *int `url:"milestone_id,omitempty" json:"milestone_id,omitempty"`
|
||||
Labels Labels `url:"labels,comma,omitempty" json:"labels,omitempty"`
|
||||
CreatedAt *time.Time `url:"created_at,omitempty" json:"created_at,omitempty"`
|
||||
DueDate *ISOTime `url:"due_date,omitempty" json:"due_date,omitempty"`
|
||||
MergeRequestToResolveDiscussionsOf *int `url:"merge_request_to_resolve_discussions_of,omitempty" json:"merge_request_to_resolve_discussions_of,omitempty"`
|
||||
DiscussionToResolve *string `url:"discussion_to_resolve,omitempty" json:"discussion_to_resolve,omitempty"`
|
||||
Weight *int `url:"weight,omitempty" json:"weight,omitempty"`
|
||||
}
|
||||
|
||||
// CreateIssue creates a new project issue.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/issues.html#new-issues
|
||||
func (s *IssuesService) CreateIssue(pid interface{}, opt *CreateIssueOptions, options ...OptionFunc) (*Issue, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/issues", url.QueryEscape(project))
|
||||
|
||||
req, err := s.client.NewRequest("POST", u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
i := new(Issue)
|
||||
resp, err := s.client.Do(req, i)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return i, resp, err
|
||||
}
|
||||
|
||||
// UpdateIssueOptions represents the available UpdateIssue() options.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/issues.html#edit-issues
|
||||
type UpdateIssueOptions struct {
|
||||
Title *string `url:"title,omitempty" json:"title,omitempty"`
|
||||
Description *string `url:"description,omitempty" json:"description,omitempty"`
|
||||
Confidential *bool `url:"confidential,omitempty" json:"confidential,omitempty"`
|
||||
AssigneeIDs []int `url:"assignee_ids,omitempty" json:"assignee_ids,omitempty"`
|
||||
MilestoneID *int `url:"milestone_id,omitempty" json:"milestone_id,omitempty"`
|
||||
Labels Labels `url:"labels,comma,omitempty" json:"labels,omitempty"`
|
||||
StateEvent *string `url:"state_event,omitempty" json:"state_event,omitempty"`
|
||||
UpdatedAt *time.Time `url:"updated_at,omitempty" json:"updated_at,omitempty"`
|
||||
DueDate *ISOTime `url:"due_date,omitempty" json:"due_date,omitempty"`
|
||||
DiscussionLocked *bool `url:"discussion_locked,omitempty" json:"discussion_locked,omitempty"`
|
||||
}
|
||||
|
||||
// UpdateIssue updates an existing project issue. This function is also used
|
||||
// to mark an issue as closed.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/issues.html#edit-issues
|
||||
func (s *IssuesService) UpdateIssue(pid interface{}, issue int, opt *UpdateIssueOptions, options ...OptionFunc) (*Issue, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/issues/%d", url.QueryEscape(project), issue)
|
||||
|
||||
req, err := s.client.NewRequest("PUT", u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
i := new(Issue)
|
||||
resp, err := s.client.Do(req, i)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return i, resp, err
|
||||
}
|
||||
|
||||
// DeleteIssue deletes a single project issue.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/issues.html#delete-an-issue
|
||||
func (s *IssuesService) DeleteIssue(pid interface{}, issue int, options ...OptionFunc) (*Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/issues/%d", url.QueryEscape(project), issue)
|
||||
|
||||
req, err := s.client.NewRequest("DELETE", u, nil, options)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return s.client.Do(req, nil)
|
||||
}
|
||||
|
||||
// ListMergeRequestsClosingIssueOptions represents the available
|
||||
// ListMergeRequestsClosingIssue() options.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/issues.html#list-merge-requests-that-will-close-issue-on-merge
|
||||
type ListMergeRequestsClosingIssueOptions ListOptions
|
||||
|
||||
// ListMergeRequestsClosingIssue gets all the merge requests that will close
|
||||
// issue when merged.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/issues.html#list-merge-requests-that-will-close-issue-on-merge
|
||||
func (s *IssuesService) ListMergeRequestsClosingIssue(pid interface{}, issue int, opt *ListMergeRequestsClosingIssueOptions, options ...OptionFunc) ([]*MergeRequest, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("/projects/%s/issues/%d/closed_by", url.QueryEscape(project), issue)
|
||||
|
||||
req, err := s.client.NewRequest("GET", u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
var m []*MergeRequest
|
||||
resp, err := s.client.Do(req, &m)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return m, resp, err
|
||||
}
|
||||
|
||||
// SetTimeEstimate sets the time estimate for a single project issue.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/issues.html#set-a-time-estimate-for-an-issue
|
||||
func (s *IssuesService) SetTimeEstimate(pid interface{}, issue int, opt *SetTimeEstimateOptions, options ...OptionFunc) (*TimeStats, *Response, error) {
|
||||
return s.timeStats.setTimeEstimate(pid, "issues", issue, opt, options...)
|
||||
}
|
||||
|
||||
// ResetTimeEstimate resets the time estimate for a single project issue.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/issues.html#reset-the-time-estimate-for-an-issue
|
||||
func (s *IssuesService) ResetTimeEstimate(pid interface{}, issue int, options ...OptionFunc) (*TimeStats, *Response, error) {
|
||||
return s.timeStats.resetTimeEstimate(pid, "issues", issue, options...)
|
||||
}
|
||||
|
||||
// AddSpentTime adds spent time for a single project issue.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/issues.html#add-spent-time-for-an-issue
|
||||
func (s *IssuesService) AddSpentTime(pid interface{}, issue int, opt *AddSpentTimeOptions, options ...OptionFunc) (*TimeStats, *Response, error) {
|
||||
return s.timeStats.addSpentTime(pid, "issues", issue, opt, options...)
|
||||
}
|
||||
|
||||
// ResetSpentTime resets the spent time for a single project issue.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/issues.html#reset-spent-time-for-an-issue
|
||||
func (s *IssuesService) ResetSpentTime(pid interface{}, issue int, options ...OptionFunc) (*TimeStats, *Response, error) {
|
||||
return s.timeStats.resetSpentTime(pid, "issues", issue, options...)
|
||||
}
|
||||
|
||||
// GetTimeSpent gets the spent time for a single project issue.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/issues.html#get-time-tracking-stats
|
||||
func (s *IssuesService) GetTimeSpent(pid interface{}, issue int, options ...OptionFunc) (*TimeStats, *Response, error) {
|
||||
return s.timeStats.getTimeSpent(pid, "issues", issue, options...)
|
||||
}
|
||||
350
vendor/github.com/xanzy/go-gitlab/jobs.go
generated
vendored
Normal file
350
vendor/github.com/xanzy/go-gitlab/jobs.go
generated
vendored
Normal file
@@ -0,0 +1,350 @@
|
||||
//
|
||||
// Copyright 2017, Arkbriar
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
package gitlab
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/url"
|
||||
"time"
|
||||
)
|
||||
|
||||
// JobsService handles communication with the ci builds related methods
|
||||
// of the GitLab API.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/jobs.html
|
||||
type JobsService struct {
|
||||
client *Client
|
||||
}
|
||||
|
||||
// Job represents a ci build.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/jobs.html
|
||||
type Job struct {
|
||||
Commit *Commit `json:"commit"`
|
||||
CreatedAt *time.Time `json:"created_at"`
|
||||
Coverage float64 `json:"coverage"`
|
||||
ArtifactsFile struct {
|
||||
Filename string `json:"filename"`
|
||||
Size int `json:"size"`
|
||||
} `json:"artifacts_file"`
|
||||
FinishedAt *time.Time `json:"finished_at"`
|
||||
ID int `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Ref string `json:"ref"`
|
||||
Runner struct {
|
||||
ID int `json:"id"`
|
||||
Description string `json:"description"`
|
||||
Active bool `json:"active"`
|
||||
IsShared bool `json:"is_shared"`
|
||||
Name string `json:"name"`
|
||||
} `json:"runner"`
|
||||
Stage string `json:"stage"`
|
||||
StartedAt *time.Time `json:"started_at"`
|
||||
Status string `json:"status"`
|
||||
Tag bool `json:"tag"`
|
||||
User *User `json:"user"`
|
||||
}
|
||||
|
||||
// ListJobsOptions are options for two list apis
|
||||
type ListJobsOptions struct {
|
||||
ListOptions
|
||||
Scope []BuildStateValue `url:"scope,omitempty" json:"scope,omitempty"`
|
||||
}
|
||||
|
||||
// ListProjectJobs gets a list of jobs in a project.
|
||||
//
|
||||
// The scope of jobs to show, one or array of: created, pending, running,
|
||||
// failed, success, canceled, skipped; showing all jobs if none provided
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/jobs.html#list-project-jobs
|
||||
func (s *JobsService) ListProjectJobs(pid interface{}, opts *ListJobsOptions, options ...OptionFunc) ([]Job, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/jobs", url.QueryEscape(project))
|
||||
|
||||
req, err := s.client.NewRequest("GET", u, opts, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
var jobs []Job
|
||||
resp, err := s.client.Do(req, &jobs)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return jobs, resp, err
|
||||
}
|
||||
|
||||
// ListPipelineJobs gets a list of jobs for specific pipeline in a
|
||||
// project. If the pipeline ID is not found, it will respond with 404.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/jobs.html#list-pipeline-jobs
|
||||
func (s *JobsService) ListPipelineJobs(pid interface{}, pipelineID int, opts *ListJobsOptions, options ...OptionFunc) ([]*Job, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/pipelines/%d/jobs", url.QueryEscape(project), pipelineID)
|
||||
|
||||
req, err := s.client.NewRequest("GET", u, opts, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
var jobs []*Job
|
||||
resp, err := s.client.Do(req, &jobs)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return jobs, resp, err
|
||||
}
|
||||
|
||||
// GetJob gets a single job of a project.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/jobs.html#get-a-single-job
|
||||
func (s *JobsService) GetJob(pid interface{}, jobID int, options ...OptionFunc) (*Job, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/jobs/%d", url.QueryEscape(project), jobID)
|
||||
|
||||
req, err := s.client.NewRequest("GET", u, nil, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
job := new(Job)
|
||||
resp, err := s.client.Do(req, job)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return job, resp, err
|
||||
}
|
||||
|
||||
// GetJobArtifacts get jobs artifacts of a project
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/jobs.html#get-job-artifacts
|
||||
func (s *JobsService) GetJobArtifacts(pid interface{}, jobID int, options ...OptionFunc) (io.Reader, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/jobs/%d/artifacts", url.QueryEscape(project), jobID)
|
||||
|
||||
req, err := s.client.NewRequest("GET", u, nil, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
artifactsBuf := new(bytes.Buffer)
|
||||
resp, err := s.client.Do(req, artifactsBuf)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return artifactsBuf, resp, err
|
||||
}
|
||||
|
||||
// DownloadArtifactsFile download the artifacts file from the given
|
||||
// reference name and job provided the job finished successfully.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/jobs.html#download-the-artifacts-file
|
||||
func (s *JobsService) DownloadArtifactsFile(pid interface{}, refName string, job string, options ...OptionFunc) (io.Reader, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/jobs/artifacts/%s/download?job=%s", url.QueryEscape(project), refName, job)
|
||||
|
||||
req, err := s.client.NewRequest("GET", u, nil, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
artifactsBuf := new(bytes.Buffer)
|
||||
resp, err := s.client.Do(req, artifactsBuf)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return artifactsBuf, resp, err
|
||||
}
|
||||
|
||||
// GetTraceFile gets a trace of a specific job of a project
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/jobs.html#get-a-trace-file
|
||||
func (s *JobsService) GetTraceFile(pid interface{}, jobID int, options ...OptionFunc) (io.Reader, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/jobs/%d/trace", url.QueryEscape(project), jobID)
|
||||
|
||||
req, err := s.client.NewRequest("GET", u, nil, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
traceBuf := new(bytes.Buffer)
|
||||
resp, err := s.client.Do(req, traceBuf)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return traceBuf, resp, err
|
||||
}
|
||||
|
||||
// CancelJob cancels a single job of a project.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/jobs.html#cancel-a-job
|
||||
func (s *JobsService) CancelJob(pid interface{}, jobID int, options ...OptionFunc) (*Job, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/jobs/%d/cancel", url.QueryEscape(project), jobID)
|
||||
|
||||
req, err := s.client.NewRequest("POST", u, nil, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
job := new(Job)
|
||||
resp, err := s.client.Do(req, job)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return job, resp, err
|
||||
}
|
||||
|
||||
// RetryJob retries a single job of a project
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/jobs.html#retry-a-job
|
||||
func (s *JobsService) RetryJob(pid interface{}, jobID int, options ...OptionFunc) (*Job, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/jobs/%d/retry", url.QueryEscape(project), jobID)
|
||||
|
||||
req, err := s.client.NewRequest("POST", u, nil, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
job := new(Job)
|
||||
resp, err := s.client.Do(req, job)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return job, resp, err
|
||||
}
|
||||
|
||||
// EraseJob erases a single job of a project, removes a job
|
||||
// artifacts and a job trace.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/jobs.html#erase-a-job
|
||||
func (s *JobsService) EraseJob(pid interface{}, jobID int, options ...OptionFunc) (*Job, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/jobs/%d/erase", url.QueryEscape(project), jobID)
|
||||
|
||||
req, err := s.client.NewRequest("POST", u, nil, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
job := new(Job)
|
||||
resp, err := s.client.Do(req, job)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return job, resp, err
|
||||
}
|
||||
|
||||
// KeepArtifacts prevents artifacts from being deleted when
|
||||
// expiration is set.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/jobs.html#keep-artifacts
|
||||
func (s *JobsService) KeepArtifacts(pid interface{}, jobID int, options ...OptionFunc) (*Job, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/jobs/%d/artifacts/keep", url.QueryEscape(project), jobID)
|
||||
|
||||
req, err := s.client.NewRequest("POST", u, nil, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
job := new(Job)
|
||||
resp, err := s.client.Do(req, job)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return job, resp, err
|
||||
}
|
||||
|
||||
// PlayJob triggers a manual action to start a job.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/jobs.html#play-a-job
|
||||
func (s *JobsService) PlayJob(pid interface{}, jobID int, options ...OptionFunc) (*Job, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/jobs/%d/play", url.QueryEscape(project), jobID)
|
||||
|
||||
req, err := s.client.NewRequest("POST", u, nil, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
job := new(Job)
|
||||
resp, err := s.client.Do(req, job)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return job, resp, err
|
||||
}
|
||||
228
vendor/github.com/xanzy/go-gitlab/labels.go
generated
vendored
Normal file
228
vendor/github.com/xanzy/go-gitlab/labels.go
generated
vendored
Normal file
@@ -0,0 +1,228 @@
|
||||
//
|
||||
// Copyright 2017, Sander van Harmelen
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
package gitlab
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/url"
|
||||
)
|
||||
|
||||
// LabelsService handles communication with the label related methods of the
|
||||
// GitLab API.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/labels.html
|
||||
type LabelsService struct {
|
||||
client *Client
|
||||
}
|
||||
|
||||
// Label represents a GitLab label.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/labels.html
|
||||
type Label struct {
|
||||
ID int `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Color string `json:"color"`
|
||||
Description string `json:"description"`
|
||||
OpenIssuesCount int `json:"open_issues_count"`
|
||||
ClosedIssuesCount int `json:"closed_issues_count"`
|
||||
OpenMergeRequestsCount int `json:"open_merge_requests_count"`
|
||||
Subscribed bool `json:"subscribed"`
|
||||
Priority int `json:"priority"`
|
||||
}
|
||||
|
||||
func (l Label) String() string {
|
||||
return Stringify(l)
|
||||
}
|
||||
|
||||
// ListLabelsOptions represents the available ListLabels() options.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/labels.html#list-labels
|
||||
type ListLabelsOptions ListOptions
|
||||
|
||||
// ListLabels gets all labels for given project.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/labels.html#list-labels
|
||||
func (s *LabelsService) ListLabels(pid interface{}, opt *ListLabelsOptions, options ...OptionFunc) ([]*Label, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/labels", url.QueryEscape(project))
|
||||
|
||||
req, err := s.client.NewRequest("GET", u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
var l []*Label
|
||||
resp, err := s.client.Do(req, &l)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return l, resp, err
|
||||
}
|
||||
|
||||
// CreateLabelOptions represents the available CreateLabel() options.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/labels.html#create-a-new-label
|
||||
type CreateLabelOptions struct {
|
||||
Name *string `url:"name,omitempty" json:"name,omitempty"`
|
||||
Color *string `url:"color,omitempty" json:"color,omitempty"`
|
||||
Description *string `url:"description,omitempty" json:"description,omitempty"`
|
||||
}
|
||||
|
||||
// CreateLabel creates a new label for given repository with given name and
|
||||
// color.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/labels.html#create-a-new-label
|
||||
func (s *LabelsService) CreateLabel(pid interface{}, opt *CreateLabelOptions, options ...OptionFunc) (*Label, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/labels", url.QueryEscape(project))
|
||||
|
||||
req, err := s.client.NewRequest("POST", u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
l := new(Label)
|
||||
resp, err := s.client.Do(req, l)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return l, resp, err
|
||||
}
|
||||
|
||||
// DeleteLabelOptions represents the available DeleteLabel() options.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/labels.html#delete-a-label
|
||||
type DeleteLabelOptions struct {
|
||||
Name *string `url:"name,omitempty" json:"name,omitempty"`
|
||||
}
|
||||
|
||||
// DeleteLabel deletes a label given by its name.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/labels.html#delete-a-label
|
||||
func (s *LabelsService) DeleteLabel(pid interface{}, opt *DeleteLabelOptions, options ...OptionFunc) (*Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/labels", url.QueryEscape(project))
|
||||
|
||||
req, err := s.client.NewRequest("DELETE", u, opt, options)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return s.client.Do(req, nil)
|
||||
}
|
||||
|
||||
// UpdateLabelOptions represents the available UpdateLabel() options.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/labels.html#delete-a-label
|
||||
type UpdateLabelOptions struct {
|
||||
Name *string `url:"name,omitempty" json:"name,omitempty"`
|
||||
NewName *string `url:"new_name,omitempty" json:"new_name,omitempty"`
|
||||
Color *string `url:"color,omitempty" json:"color,omitempty"`
|
||||
Description *string `url:"description,omitempty" json:"description,omitempty"`
|
||||
}
|
||||
|
||||
// UpdateLabel updates an existing label with new name or now color. At least
|
||||
// one parameter is required, to update the label.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/labels.html#edit-an-existing-label
|
||||
func (s *LabelsService) UpdateLabel(pid interface{}, opt *UpdateLabelOptions, options ...OptionFunc) (*Label, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/labels", url.QueryEscape(project))
|
||||
|
||||
req, err := s.client.NewRequest("PUT", u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
l := new(Label)
|
||||
resp, err := s.client.Do(req, l)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return l, resp, err
|
||||
}
|
||||
|
||||
// SubscribeToLabel subscribes the authenticated user to a label to receive
|
||||
// notifications. If the user is already subscribed to the label, the status
|
||||
// code 304 is returned.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/labels.html#subscribe-to-a-label
|
||||
func (s *LabelsService) SubscribeToLabel(pid interface{}, labelID interface{}, options ...OptionFunc) (*Label, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
label, err := parseID(labelID)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/labels/%s/subscribe", url.QueryEscape(project), label)
|
||||
|
||||
req, err := s.client.NewRequest("POST", u, nil, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
l := new(Label)
|
||||
resp, err := s.client.Do(req, l)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return l, resp, err
|
||||
}
|
||||
|
||||
// UnsubscribeFromLabel unsubscribes the authenticated user from a label to not
|
||||
// receive notifications from it. If the user is not subscribed to the label, the
|
||||
// status code 304 is returned.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/labels.html#unsubscribe-from-a-label
|
||||
func (s *LabelsService) UnsubscribeFromLabel(pid interface{}, labelID interface{}, options ...OptionFunc) (*Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
label, err := parseID(labelID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/labels/%s/unsubscribe", url.QueryEscape(project), label)
|
||||
|
||||
req, err := s.client.NewRequest("POST", u, nil, options)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return s.client.Do(req, nil)
|
||||
}
|
||||
125
vendor/github.com/xanzy/go-gitlab/merge_request_approvals.go
generated
vendored
Normal file
125
vendor/github.com/xanzy/go-gitlab/merge_request_approvals.go
generated
vendored
Normal file
@@ -0,0 +1,125 @@
|
||||
package gitlab
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/url"
|
||||
"time"
|
||||
)
|
||||
|
||||
// MergeRequestApprovalsService handles communication with the merge request
|
||||
// approvals related methods of the GitLab API. This includes reading/updating
|
||||
// approval settings and approve/unapproving merge requests
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ee/api/merge_request_approvals.html
|
||||
type MergeRequestApprovalsService struct {
|
||||
client *Client
|
||||
}
|
||||
|
||||
// MergeRequestApprovals represents GitLab merge request approvals.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ee/api/merge_request_approvals.html#merge-request-level-mr-approvals
|
||||
type MergeRequestApprovals struct {
|
||||
ID int `json:"id"`
|
||||
ProjectID int `json:"project_id"`
|
||||
Title string `json:"title"`
|
||||
Description string `json:"description"`
|
||||
State string `json:"state"`
|
||||
CreatedAt *time.Time `json:"created_at"`
|
||||
UpdatedAt *time.Time `json:"updated_at"`
|
||||
MergeStatus string `json:"merge_status"`
|
||||
ApprovalsRequired int `json:"approvals_required"`
|
||||
ApprovalsLeft int `json:"approvals_left"`
|
||||
ApprovedBy []struct {
|
||||
User struct {
|
||||
ID int `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Username string `json:"username"`
|
||||
State string `json:"state"`
|
||||
AvatarURL string `json:"avatar_url"`
|
||||
WebURL string `json:"web_url"`
|
||||
} `json:"user"`
|
||||
} `json:"approved_by"`
|
||||
Approvers []struct {
|
||||
User struct {
|
||||
ID int `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Username string `json:"username"`
|
||||
State string `json:"state"`
|
||||
AvatarURL string `json:"avatar_url"`
|
||||
WebURL string `json:"web_url"`
|
||||
} `json:"user"`
|
||||
} `json:"approvers"`
|
||||
ApproverGroups []struct {
|
||||
Group struct {
|
||||
ID int `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Path string `json:"path"`
|
||||
Description string `json:"description"`
|
||||
Visibility string `json:"visibility"`
|
||||
AvatarURL string `json:"avatar_url"`
|
||||
WebURL string `json:"web_url"`
|
||||
FullName string `json:"full_name"`
|
||||
FullPath string `json:"full_path"`
|
||||
LFSEnabled bool `json:"lfs_enabled"`
|
||||
RequestAccessEnabled bool `json:"request_access_enabled"`
|
||||
} `json:"group"`
|
||||
} `json:"approver_group"`
|
||||
}
|
||||
|
||||
func (m MergeRequestApprovals) String() string {
|
||||
return Stringify(m)
|
||||
}
|
||||
|
||||
// ApproveMergeRequestOptions represents the available ApproveMergeRequest() options.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ee/api/merge_request_approvals.html#approve-merge-request
|
||||
type ApproveMergeRequestOptions struct {
|
||||
Sha *string `url:"sha,omitempty" json:"sha,omitempty"`
|
||||
}
|
||||
|
||||
// ApproveMergeRequest approves a merge request on GitLab. If a non-empty sha
|
||||
// is provided then it must match the sha at the HEAD of the MR.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ee/api/merge_request_approvals.html#approve-merge-request
|
||||
func (s *MergeRequestApprovalsService) ApproveMergeRequest(pid interface{}, mr int, opt *ApproveMergeRequestOptions, options ...OptionFunc) (*MergeRequestApprovals, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/merge_requests/%d/approve", url.QueryEscape(project), mr)
|
||||
|
||||
req, err := s.client.NewRequest("GET", u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
m := new(MergeRequestApprovals)
|
||||
resp, err := s.client.Do(req, m)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return m, resp, err
|
||||
}
|
||||
|
||||
// UnapproveMergeRequest unapproves a previously approved merge request on GitLab.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ee/api/merge_request_approvals.html#unapprove-merge-request
|
||||
func (s *MergeRequestApprovalsService) UnapproveMergeRequest(pid interface{}, mr int, options ...OptionFunc) (*Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/merge_requests/%d/unapprove", url.QueryEscape(project), mr)
|
||||
|
||||
req, err := s.client.NewRequest("GET", u, nil, options)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return s.client.Do(req, nil)
|
||||
}
|
||||
743
vendor/github.com/xanzy/go-gitlab/merge_requests.go
generated
vendored
Normal file
743
vendor/github.com/xanzy/go-gitlab/merge_requests.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
267
vendor/github.com/xanzy/go-gitlab/milestones.go
generated
vendored
Normal file
267
vendor/github.com/xanzy/go-gitlab/milestones.go
generated
vendored
Normal file
@@ -0,0 +1,267 @@
|
||||
//
|
||||
// Copyright 2017, Sander van Harmelen
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
package gitlab
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/url"
|
||||
"time"
|
||||
)
|
||||
|
||||
// MilestonesService handles communication with the milestone related methods
|
||||
// of the GitLab API.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/milestones.html
|
||||
type MilestonesService struct {
|
||||
client *Client
|
||||
}
|
||||
|
||||
// Milestone represents a GitLab milestone.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/milestones.html
|
||||
type Milestone struct {
|
||||
ID int `json:"id"`
|
||||
IID int `json:"iid"`
|
||||
ProjectID int `json:"project_id"`
|
||||
Title string `json:"title"`
|
||||
Description string `json:"description"`
|
||||
StartDate *ISOTime `json:"start_date"`
|
||||
DueDate *ISOTime `json:"due_date"`
|
||||
State string `json:"state"`
|
||||
UpdatedAt *time.Time `json:"updated_at"`
|
||||
CreatedAt *time.Time `json:"created_at"`
|
||||
}
|
||||
|
||||
func (m Milestone) String() string {
|
||||
return Stringify(m)
|
||||
}
|
||||
|
||||
// ListMilestonesOptions represents the available ListMilestones() options.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/milestones.html#list-project-milestones
|
||||
type ListMilestonesOptions struct {
|
||||
ListOptions
|
||||
IIDs []int `url:"iids,omitempty" json:"iids,omitempty"`
|
||||
State string `url:"state,omitempty" json:"state,omitempty"`
|
||||
Search string `url:"search,omitempty" json:"search,omitempty"`
|
||||
}
|
||||
|
||||
// ListMilestones returns a list of project milestones.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/milestones.html#list-project-milestones
|
||||
func (s *MilestonesService) ListMilestones(pid interface{}, opt *ListMilestonesOptions, options ...OptionFunc) ([]*Milestone, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/milestones", url.QueryEscape(project))
|
||||
|
||||
req, err := s.client.NewRequest("GET", u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
var m []*Milestone
|
||||
resp, err := s.client.Do(req, &m)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return m, resp, err
|
||||
}
|
||||
|
||||
// GetMilestone gets a single project milestone.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/milestones.html#get-single-milestone
|
||||
func (s *MilestonesService) GetMilestone(pid interface{}, milestone int, options ...OptionFunc) (*Milestone, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/milestones/%d", url.QueryEscape(project), milestone)
|
||||
|
||||
req, err := s.client.NewRequest("GET", u, nil, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
m := new(Milestone)
|
||||
resp, err := s.client.Do(req, m)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return m, resp, err
|
||||
}
|
||||
|
||||
// CreateMilestoneOptions represents the available CreateMilestone() options.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/milestones.html#create-new-milestone
|
||||
type CreateMilestoneOptions struct {
|
||||
Title *string `url:"title,omitempty" json:"title,omitempty"`
|
||||
Description *string `url:"description,omitempty" json:"description,omitempty"`
|
||||
StartDate *ISOTime `url:"start_date,omitempty" json:"start_date,omitempty"`
|
||||
DueDate *ISOTime `url:"due_date,omitempty" json:"due_date,omitempty"`
|
||||
}
|
||||
|
||||
// CreateMilestone creates a new project milestone.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/milestones.html#create-new-milestone
|
||||
func (s *MilestonesService) CreateMilestone(pid interface{}, opt *CreateMilestoneOptions, options ...OptionFunc) (*Milestone, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/milestones", url.QueryEscape(project))
|
||||
|
||||
req, err := s.client.NewRequest("POST", u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
m := new(Milestone)
|
||||
resp, err := s.client.Do(req, m)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return m, resp, err
|
||||
}
|
||||
|
||||
// UpdateMilestoneOptions represents the available UpdateMilestone() options.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/milestones.html#edit-milestone
|
||||
type UpdateMilestoneOptions struct {
|
||||
Title *string `url:"title,omitempty" json:"title,omitempty"`
|
||||
Description *string `url:"description,omitempty" json:"description,omitempty"`
|
||||
StartDate *ISOTime `url:"start_date,omitempty" json:"start_date,omitempty"`
|
||||
DueDate *ISOTime `url:"due_date,omitempty" json:"due_date,omitempty"`
|
||||
StateEvent *string `url:"state_event,omitempty" json:"state_event,omitempty"`
|
||||
}
|
||||
|
||||
// UpdateMilestone updates an existing project milestone.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/milestones.html#edit-milestone
|
||||
func (s *MilestonesService) UpdateMilestone(pid interface{}, milestone int, opt *UpdateMilestoneOptions, options ...OptionFunc) (*Milestone, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/milestones/%d", url.QueryEscape(project), milestone)
|
||||
|
||||
req, err := s.client.NewRequest("PUT", u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
m := new(Milestone)
|
||||
resp, err := s.client.Do(req, m)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return m, resp, err
|
||||
}
|
||||
|
||||
// DeleteMilestone deletes a specified project milestone.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/milestones.html#delete-project-milestone
|
||||
func (s *MilestonesService) DeleteMilestone(pid interface{}, milestone int, options ...OptionFunc) (*Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/milestones/%d", url.QueryEscape(project), milestone)
|
||||
|
||||
req, err := s.client.NewRequest("DELETE", u, nil, options)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return s.client.Do(req, nil)
|
||||
}
|
||||
|
||||
// GetMilestoneIssuesOptions represents the available GetMilestoneIssues() options.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/milestones.html#get-all-issues-assigned-to-a-single-milestone
|
||||
type GetMilestoneIssuesOptions ListOptions
|
||||
|
||||
// GetMilestoneIssues gets all issues assigned to a single project milestone.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/milestones.html#get-all-issues-assigned-to-a-single-milestone
|
||||
func (s *MilestonesService) GetMilestoneIssues(pid interface{}, milestone int, opt *GetMilestoneIssuesOptions, options ...OptionFunc) ([]*Issue, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/milestones/%d/issues", url.QueryEscape(project), milestone)
|
||||
|
||||
req, err := s.client.NewRequest("GET", u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
var i []*Issue
|
||||
resp, err := s.client.Do(req, &i)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return i, resp, err
|
||||
}
|
||||
|
||||
// GetMilestoneMergeRequestsOptions represents the available
|
||||
// GetMilestoneMergeRequests() options.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/milestones.html#get-all-merge-requests-assigned-to-a-single-milestone
|
||||
type GetMilestoneMergeRequestsOptions ListOptions
|
||||
|
||||
// GetMilestoneMergeRequests gets all merge requests assigned to a single
|
||||
// project milestone.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/milestones.html#get-all-merge-requests-assigned-to-a-single-milestone
|
||||
func (s *MilestonesService) GetMilestoneMergeRequests(pid interface{}, milestone int, opt *GetMilestoneMergeRequestsOptions, options ...OptionFunc) ([]*MergeRequest, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/milestones/%d/merge_requests", url.QueryEscape(project), milestone)
|
||||
|
||||
req, err := s.client.NewRequest("GET", u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
var mr []*MergeRequest
|
||||
resp, err := s.client.Do(req, &mr)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return mr, resp, err
|
||||
}
|
||||
122
vendor/github.com/xanzy/go-gitlab/namespaces.go
generated
vendored
Normal file
122
vendor/github.com/xanzy/go-gitlab/namespaces.go
generated
vendored
Normal file
@@ -0,0 +1,122 @@
|
||||
//
|
||||
// Copyright 2017, Sander van Harmelen
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
package gitlab
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
// NamespacesService handles communication with the namespace related methods
|
||||
// of the GitLab API.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/namespaces.html
|
||||
type NamespacesService struct {
|
||||
client *Client
|
||||
}
|
||||
|
||||
// Namespace represents a GitLab namespace.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/namespaces.html
|
||||
type Namespace struct {
|
||||
ID int `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Path string `json:"path"`
|
||||
Kind string `json:"kind"`
|
||||
FullPath string `json:"full_path"`
|
||||
ParentID int `json:"parent_id"`
|
||||
MembersCountWithDescendants int `json:"members_count_with_descendants"`
|
||||
}
|
||||
|
||||
func (n Namespace) String() string {
|
||||
return Stringify(n)
|
||||
}
|
||||
|
||||
// ListNamespacesOptions represents the available ListNamespaces() options.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/namespaces.html#list-namespaces
|
||||
type ListNamespacesOptions struct {
|
||||
ListOptions
|
||||
Search *string `url:"search,omitempty" json:"search,omitempty"`
|
||||
}
|
||||
|
||||
// ListNamespaces gets a list of projects accessible by the authenticated user.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/namespaces.html#list-namespaces
|
||||
func (s *NamespacesService) ListNamespaces(opt *ListNamespacesOptions, options ...OptionFunc) ([]*Namespace, *Response, error) {
|
||||
req, err := s.client.NewRequest("GET", "namespaces", opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
var n []*Namespace
|
||||
resp, err := s.client.Do(req, &n)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return n, resp, err
|
||||
}
|
||||
|
||||
// SearchNamespace gets all namespaces that match your string in their name
|
||||
// or path.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/namespaces.html#search-for-namespace
|
||||
func (s *NamespacesService) SearchNamespace(query string, options ...OptionFunc) ([]*Namespace, *Response, error) {
|
||||
var q struct {
|
||||
Search string `url:"search,omitempty" json:"search,omitempty"`
|
||||
}
|
||||
q.Search = query
|
||||
|
||||
req, err := s.client.NewRequest("GET", "namespaces", &q, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
var n []*Namespace
|
||||
resp, err := s.client.Do(req, &n)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return n, resp, err
|
||||
}
|
||||
|
||||
// GetNamespace gets a namespace by id.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/namespaces.html#get-namespace-by-id
|
||||
func (s *NamespacesService) GetNamespace(id interface{}, options ...OptionFunc) (*Namespace, *Response, error) {
|
||||
namespace, err := parseID(id)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("namespaces/%s", namespace)
|
||||
|
||||
req, err := s.client.NewRequest("GET", u, nil, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
n := new(Namespace)
|
||||
resp, err := s.client.Do(req, n)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return n, resp, err
|
||||
}
|
||||
490
vendor/github.com/xanzy/go-gitlab/notes.go
generated
vendored
Normal file
490
vendor/github.com/xanzy/go-gitlab/notes.go
generated
vendored
Normal file
@@ -0,0 +1,490 @@
|
||||
//
|
||||
// Copyright 2017, Sander van Harmelen
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
package gitlab
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/url"
|
||||
"time"
|
||||
)
|
||||
|
||||
// NotesService handles communication with the notes related methods
|
||||
// of the GitLab API.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/notes.html
|
||||
type NotesService struct {
|
||||
client *Client
|
||||
}
|
||||
|
||||
// Note represents a GitLab note.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/notes.html
|
||||
type Note struct {
|
||||
ID int `json:"id"`
|
||||
Body string `json:"body"`
|
||||
Attachment string `json:"attachment"`
|
||||
Title string `json:"title"`
|
||||
FileName string `json:"file_name"`
|
||||
Author struct {
|
||||
ID int `json:"id"`
|
||||
Username string `json:"username"`
|
||||
Email string `json:"email"`
|
||||
Name string `json:"name"`
|
||||
State string `json:"state"`
|
||||
CreatedAt *time.Time `json:"created_at"`
|
||||
AvatarURL string `json:"avatar_url"`
|
||||
WebURL string `json:"web_url"`
|
||||
} `json:"author"`
|
||||
System bool `json:"system"`
|
||||
ExpiresAt *time.Time `json:"expires_at"`
|
||||
UpdatedAt *time.Time `json:"updated_at"`
|
||||
CreatedAt *time.Time `json:"created_at"`
|
||||
NoteableID int `json:"noteable_id"`
|
||||
NoteableType string `json:"noteable_type"`
|
||||
NoteableIID int `json:"noteable_iid"`
|
||||
}
|
||||
|
||||
func (n Note) String() string {
|
||||
return Stringify(n)
|
||||
}
|
||||
|
||||
// ListIssueNotesOptions represents the available ListIssueNotes() options.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/notes.html#list-project-issue-notes
|
||||
type ListIssueNotesOptions ListOptions
|
||||
|
||||
// ListIssueNotes gets a list of all notes for a single issue.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/notes.html#list-project-issue-notes
|
||||
func (s *NotesService) ListIssueNotes(pid interface{}, issue int, opt *ListIssueNotesOptions, options ...OptionFunc) ([]*Note, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/issues/%d/notes", url.QueryEscape(project), issue)
|
||||
|
||||
req, err := s.client.NewRequest("GET", u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
var n []*Note
|
||||
resp, err := s.client.Do(req, &n)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return n, resp, err
|
||||
}
|
||||
|
||||
// GetIssueNote returns a single note for a specific project issue.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/notes.html#get-single-issue-note
|
||||
func (s *NotesService) GetIssueNote(pid interface{}, issue, note int, options ...OptionFunc) (*Note, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/issues/%d/notes/%d", url.QueryEscape(project), issue, note)
|
||||
|
||||
req, err := s.client.NewRequest("GET", u, nil, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
n := new(Note)
|
||||
resp, err := s.client.Do(req, n)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return n, resp, err
|
||||
}
|
||||
|
||||
// CreateIssueNoteOptions represents the available CreateIssueNote()
|
||||
// options.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/notes.html#create-new-issue-note
|
||||
type CreateIssueNoteOptions struct {
|
||||
Body *string `url:"body,omitempty" json:"body,omitempty"`
|
||||
}
|
||||
|
||||
// CreateIssueNote creates a new note to a single project issue.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/notes.html#create-new-issue-note
|
||||
func (s *NotesService) CreateIssueNote(pid interface{}, issue int, opt *CreateIssueNoteOptions, options ...OptionFunc) (*Note, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/issues/%d/notes", url.QueryEscape(project), issue)
|
||||
|
||||
req, err := s.client.NewRequest("POST", u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
n := new(Note)
|
||||
resp, err := s.client.Do(req, n)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return n, resp, err
|
||||
}
|
||||
|
||||
// UpdateIssueNoteOptions represents the available UpdateIssueNote()
|
||||
// options.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/notes.html#modify-existing-issue-note
|
||||
type UpdateIssueNoteOptions struct {
|
||||
Body *string `url:"body,omitempty" json:"body,omitempty"`
|
||||
}
|
||||
|
||||
// UpdateIssueNote modifies existing note of an issue.
|
||||
//
|
||||
// https://docs.gitlab.com/ce/api/notes.html#modify-existing-issue-note
|
||||
func (s *NotesService) UpdateIssueNote(pid interface{}, issue, note int, opt *UpdateIssueNoteOptions, options ...OptionFunc) (*Note, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/issues/%d/notes/%d", url.QueryEscape(project), issue, note)
|
||||
|
||||
req, err := s.client.NewRequest("PUT", u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
n := new(Note)
|
||||
resp, err := s.client.Do(req, n)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return n, resp, err
|
||||
}
|
||||
|
||||
// DeleteIssueNote deletes an existing note of an issue.
|
||||
//
|
||||
// https://docs.gitlab.com/ce/api/notes.html#delete-an-issue-note
|
||||
func (s *NotesService) DeleteIssueNote(pid interface{}, issue, note int, options ...OptionFunc) (*Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/issues/%d/notes/%d", url.QueryEscape(project), issue, note)
|
||||
|
||||
req, err := s.client.NewRequest("DELETE", u, nil, options)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return s.client.Do(req, nil)
|
||||
}
|
||||
|
||||
// ListSnippetNotesOptions represents the available ListSnippetNotes() options.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/notes.html#list-all-snippet-notes
|
||||
type ListSnippetNotesOptions ListOptions
|
||||
|
||||
// ListSnippetNotes gets a list of all notes for a single snippet. Snippet
|
||||
// notes are comments users can post to a snippet.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/notes.html#list-all-snippet-notes
|
||||
func (s *NotesService) ListSnippetNotes(pid interface{}, snippet int, opt *ListSnippetNotesOptions, options ...OptionFunc) ([]*Note, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/snippets/%d/notes", url.QueryEscape(project), snippet)
|
||||
|
||||
req, err := s.client.NewRequest("GET", u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
var n []*Note
|
||||
resp, err := s.client.Do(req, &n)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return n, resp, err
|
||||
}
|
||||
|
||||
// GetSnippetNote returns a single note for a given snippet.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/notes.html#get-single-snippet-note
|
||||
func (s *NotesService) GetSnippetNote(pid interface{}, snippet, note int, options ...OptionFunc) (*Note, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/snippets/%d/notes/%d", url.QueryEscape(project), snippet, note)
|
||||
|
||||
req, err := s.client.NewRequest("GET", u, nil, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
n := new(Note)
|
||||
resp, err := s.client.Do(req, n)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return n, resp, err
|
||||
}
|
||||
|
||||
// CreateSnippetNoteOptions represents the available CreateSnippetNote()
|
||||
// options.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/notes.html#create-new-snippet-note
|
||||
type CreateSnippetNoteOptions struct {
|
||||
Body *string `url:"body,omitempty" json:"body,omitempty"`
|
||||
}
|
||||
|
||||
// CreateSnippetNote creates a new note for a single snippet. Snippet notes are
|
||||
// comments users can post to a snippet.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/notes.html#create-new-snippet-note
|
||||
func (s *NotesService) CreateSnippetNote(pid interface{}, snippet int, opt *CreateSnippetNoteOptions, options ...OptionFunc) (*Note, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/snippets/%d/notes", url.QueryEscape(project), snippet)
|
||||
|
||||
req, err := s.client.NewRequest("POST", u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
n := new(Note)
|
||||
resp, err := s.client.Do(req, n)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return n, resp, err
|
||||
}
|
||||
|
||||
// UpdateSnippetNoteOptions represents the available UpdateSnippetNote()
|
||||
// options.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/notes.html#modify-existing-snippet-note
|
||||
type UpdateSnippetNoteOptions struct {
|
||||
Body *string `url:"body,omitempty" json:"body,omitempty"`
|
||||
}
|
||||
|
||||
// UpdateSnippetNote modifies existing note of a snippet.
|
||||
//
|
||||
// https://docs.gitlab.com/ce/api/notes.html#modify-existing-snippet-note
|
||||
func (s *NotesService) UpdateSnippetNote(pid interface{}, snippet, note int, opt *UpdateSnippetNoteOptions, options ...OptionFunc) (*Note, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/snippets/%d/notes/%d", url.QueryEscape(project), snippet, note)
|
||||
|
||||
req, err := s.client.NewRequest("PUT", u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
n := new(Note)
|
||||
resp, err := s.client.Do(req, n)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return n, resp, err
|
||||
}
|
||||
|
||||
// DeleteSnippetNote deletes an existing note of a snippet.
|
||||
//
|
||||
// https://docs.gitlab.com/ce/api/notes.html#delete-a-snippet-note
|
||||
func (s *NotesService) DeleteSnippetNote(pid interface{}, snippet, note int, options ...OptionFunc) (*Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/snippets/%d/notes/%d", url.QueryEscape(project), snippet, note)
|
||||
|
||||
req, err := s.client.NewRequest("DELETE", u, nil, options)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return s.client.Do(req, nil)
|
||||
}
|
||||
|
||||
// ListMergeRequestNotesOptions represents the available ListMergeRequestNotes()
|
||||
// options.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/notes.html#list-all-merge-request-notes
|
||||
type ListMergeRequestNotesOptions ListOptions
|
||||
|
||||
// ListMergeRequestNotes gets a list of all notes for a single merge request.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/notes.html#list-all-merge-request-notes
|
||||
func (s *NotesService) ListMergeRequestNotes(pid interface{}, mergeRequest int, opt *ListMergeRequestNotesOptions, options ...OptionFunc) ([]*Note, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/merge_requests/%d/notes", url.QueryEscape(project), mergeRequest)
|
||||
|
||||
req, err := s.client.NewRequest("GET", u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
var n []*Note
|
||||
resp, err := s.client.Do(req, &n)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return n, resp, err
|
||||
}
|
||||
|
||||
// GetMergeRequestNote returns a single note for a given merge request.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/notes.html#get-single-merge-request-note
|
||||
func (s *NotesService) GetMergeRequestNote(pid interface{}, mergeRequest, note int, options ...OptionFunc) (*Note, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/merge_requests/%d/notes/%d", url.QueryEscape(project), mergeRequest, note)
|
||||
|
||||
req, err := s.client.NewRequest("GET", u, nil, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
n := new(Note)
|
||||
resp, err := s.client.Do(req, n)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return n, resp, err
|
||||
}
|
||||
|
||||
// CreateMergeRequestNoteOptions represents the available
|
||||
// CreateMergeRequestNote() options.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/notes.html#create-new-merge-request-note
|
||||
type CreateMergeRequestNoteOptions struct {
|
||||
Body *string `url:"body,omitempty" json:"body,omitempty"`
|
||||
}
|
||||
|
||||
// CreateMergeRequestNote creates a new note for a single merge request.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/notes.html#create-new-merge-request-note
|
||||
func (s *NotesService) CreateMergeRequestNote(pid interface{}, mergeRequest int, opt *CreateMergeRequestNoteOptions, options ...OptionFunc) (*Note, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/merge_requests/%d/notes", url.QueryEscape(project), mergeRequest)
|
||||
|
||||
req, err := s.client.NewRequest("POST", u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
n := new(Note)
|
||||
resp, err := s.client.Do(req, n)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return n, resp, err
|
||||
}
|
||||
|
||||
// UpdateMergeRequestNoteOptions represents the available
|
||||
// UpdateMergeRequestNote() options.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/notes.html#modify-existing-merge-request-note
|
||||
type UpdateMergeRequestNoteOptions struct {
|
||||
Body *string `url:"body,omitempty" json:"body,omitempty"`
|
||||
}
|
||||
|
||||
// UpdateMergeRequestNote modifies existing note of a merge request.
|
||||
//
|
||||
// https://docs.gitlab.com/ce/api/notes.html#modify-existing-merge-request-note
|
||||
func (s *NotesService) UpdateMergeRequestNote(pid interface{}, mergeRequest, note int, opt *UpdateMergeRequestNoteOptions, options ...OptionFunc) (*Note, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf(
|
||||
"projects/%s/merge_requests/%d/notes/%d", url.QueryEscape(project), mergeRequest, note)
|
||||
req, err := s.client.NewRequest("PUT", u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
n := new(Note)
|
||||
resp, err := s.client.Do(req, n)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return n, resp, err
|
||||
}
|
||||
|
||||
// DeleteMergeRequestNote deletes an existing note of a merge request.
|
||||
//
|
||||
// https://docs.gitlab.com/ce/api/notes.html#delete-a-merge-request-note
|
||||
func (s *NotesService) DeleteMergeRequestNote(pid interface{}, mergeRequest, note int, options ...OptionFunc) (*Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
u := fmt.Sprintf(
|
||||
"projects/%s/merge_requests/%d/notes/%d", url.QueryEscape(project), mergeRequest, note)
|
||||
|
||||
req, err := s.client.NewRequest("DELETE", u, nil, options)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return s.client.Do(req, nil)
|
||||
}
|
||||
214
vendor/github.com/xanzy/go-gitlab/notifications.go
generated
vendored
Normal file
214
vendor/github.com/xanzy/go-gitlab/notifications.go
generated
vendored
Normal file
@@ -0,0 +1,214 @@
|
||||
package gitlab
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/url"
|
||||
)
|
||||
|
||||
// NotificationSettingsService handles communication with the notification settings
|
||||
// related methods of the GitLab API.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/notification_settings.html
|
||||
type NotificationSettingsService struct {
|
||||
client *Client
|
||||
}
|
||||
|
||||
// NotificationSettings represents the Gitlab notification setting.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/notification_settings.html#notification-settings
|
||||
type NotificationSettings struct {
|
||||
Level NotificationLevelValue `json:"level"`
|
||||
NotificationEmail string `json:"notification_email"`
|
||||
Events *NotificationEvents `json:"events"`
|
||||
}
|
||||
|
||||
// NotificationEvents represents the available notification setting events.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/notification_settings.html#notification-settings
|
||||
type NotificationEvents struct {
|
||||
CloseIssue bool `json:"close_issue"`
|
||||
CloseMergeRequest bool `json:"close_merge_request"`
|
||||
FailedPipeline bool `json:"failed_pipeline"`
|
||||
MergeMergeRequest bool `json:"merge_merge_request"`
|
||||
NewIssue bool `json:"new_issue"`
|
||||
NewMergeRequest bool `json:"new_merge_request"`
|
||||
NewNote bool `json:"new_note"`
|
||||
ReassignIssue bool `json:"reassign_issue"`
|
||||
ReassignMergeRequest bool `json:"reassign_merge_request"`
|
||||
ReopenIssue bool `json:"reopen_issue"`
|
||||
ReopenMergeRequest bool `json:"reopen_merge_request"`
|
||||
SuccessPipeline bool `json:"success_pipeline"`
|
||||
}
|
||||
|
||||
func (ns NotificationSettings) String() string {
|
||||
return Stringify(ns)
|
||||
}
|
||||
|
||||
// GetGlobalSettings returns current notification settings and email address.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/notification_settings.html#global-notification-settings
|
||||
func (s *NotificationSettingsService) GetGlobalSettings(options ...OptionFunc) (*NotificationSettings, *Response, error) {
|
||||
u := "notification_settings"
|
||||
|
||||
req, err := s.client.NewRequest("GET", u, nil, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
ns := new(NotificationSettings)
|
||||
resp, err := s.client.Do(req, ns)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return ns, resp, err
|
||||
}
|
||||
|
||||
// NotificationSettingsOptions represents the available options that can be passed
|
||||
// to the API when updating the notification settings.
|
||||
type NotificationSettingsOptions struct {
|
||||
Level *NotificationLevelValue `url:"level,omitempty" json:"level,omitempty"`
|
||||
NotificationEmail *string `url:"notification_email,omitempty" json:"notification_email,omitempty"`
|
||||
CloseIssue *bool `url:"close_issue,omitempty" json:"close_issue,omitempty"`
|
||||
CloseMergeRequest *bool `url:"close_merge_request,omitempty" json:"close_merge_request,omitempty"`
|
||||
FailedPipeline *bool `url:"failed_pipeline,omitempty" json:"failed_pipeline,omitempty"`
|
||||
MergeMergeRequest *bool `url:"merge_merge_request,omitempty" json:"merge_merge_request,omitempty"`
|
||||
NewIssue *bool `url:"new_issue,omitempty" json:"new_issue,omitempty"`
|
||||
NewMergeRequest *bool `url:"new_merge_request,omitempty" json:"new_merge_request,omitempty"`
|
||||
NewNote *bool `url:"new_note,omitempty" json:"new_note,omitempty"`
|
||||
ReassignIssue *bool `url:"reassign_issue,omitempty" json:"reassign_issue,omitempty"`
|
||||
ReassignMergeRequest *bool `url:"reassign_merge_request,omitempty" json:"reassign_merge_request,omitempty"`
|
||||
ReopenIssue *bool `url:"reopen_issue,omitempty" json:"reopen_issue,omitempty"`
|
||||
ReopenMergeRequest *bool `url:"reopen_merge_request,omitempty" json:"reopen_merge_request,omitempty"`
|
||||
SuccessPipeline *bool `url:"success_pipeline,omitempty" json:"success_pipeline,omitempty"`
|
||||
}
|
||||
|
||||
// UpdateGlobalSettings updates current notification settings and email address.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/notification_settings.html#update-global-notification-settings
|
||||
func (s *NotificationSettingsService) UpdateGlobalSettings(opt *NotificationSettingsOptions, options ...OptionFunc) (*NotificationSettings, *Response, error) {
|
||||
if opt.Level != nil && *opt.Level == GlobalNotificationLevel {
|
||||
return nil, nil, errors.New(
|
||||
"notification level 'global' is not valid for global notification settings")
|
||||
}
|
||||
|
||||
u := "notification_settings"
|
||||
|
||||
req, err := s.client.NewRequest("PUT", u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
ns := new(NotificationSettings)
|
||||
resp, err := s.client.Do(req, ns)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return ns, resp, err
|
||||
}
|
||||
|
||||
// GetSettingsForGroup returns current group notification settings.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/notification_settings.html#group-project-level-notification-settings
|
||||
func (s *NotificationSettingsService) GetSettingsForGroup(gid interface{}, options ...OptionFunc) (*NotificationSettings, *Response, error) {
|
||||
group, err := parseID(gid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("groups/%s/notification_settings", url.QueryEscape(group))
|
||||
|
||||
req, err := s.client.NewRequest("GET", u, nil, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
ns := new(NotificationSettings)
|
||||
resp, err := s.client.Do(req, ns)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return ns, resp, err
|
||||
}
|
||||
|
||||
// GetSettingsForProject returns current project notification settings.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/notification_settings.html#group-project-level-notification-settings
|
||||
func (s *NotificationSettingsService) GetSettingsForProject(pid interface{}, options ...OptionFunc) (*NotificationSettings, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/notification_settings", url.QueryEscape(project))
|
||||
|
||||
req, err := s.client.NewRequest("GET", u, nil, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
ns := new(NotificationSettings)
|
||||
resp, err := s.client.Do(req, ns)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return ns, resp, err
|
||||
}
|
||||
|
||||
// UpdateSettingsForGroup updates current group notification settings.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/notification_settings.html#update-group-project-level-notification-settings
|
||||
func (s *NotificationSettingsService) UpdateSettingsForGroup(gid interface{}, opt *NotificationSettingsOptions, options ...OptionFunc) (*NotificationSettings, *Response, error) {
|
||||
group, err := parseID(gid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("groups/%s/notification_settings", url.QueryEscape(group))
|
||||
|
||||
req, err := s.client.NewRequest("PUT", u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
ns := new(NotificationSettings)
|
||||
resp, err := s.client.Do(req, ns)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return ns, resp, err
|
||||
}
|
||||
|
||||
// UpdateSettingsForProject updates current project notification settings.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/notification_settings.html#update-group-project-level-notification-settings
|
||||
func (s *NotificationSettingsService) UpdateSettingsForProject(pid interface{}, opt *NotificationSettingsOptions, options ...OptionFunc) (*NotificationSettings, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/notification_settings", url.QueryEscape(project))
|
||||
|
||||
req, err := s.client.NewRequest("PUT", u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
ns := new(NotificationSettings)
|
||||
resp, err := s.client.Do(req, ns)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return ns, resp, err
|
||||
}
|
||||
175
vendor/github.com/xanzy/go-gitlab/pages_domains.go
generated
vendored
Normal file
175
vendor/github.com/xanzy/go-gitlab/pages_domains.go
generated
vendored
Normal file
@@ -0,0 +1,175 @@
|
||||
package gitlab
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/url"
|
||||
"time"
|
||||
)
|
||||
|
||||
// PagesDomainsService handles communication with the pages domains
|
||||
// related methods of the GitLab API.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/pages_domains.html
|
||||
type PagesDomainsService struct {
|
||||
client *Client
|
||||
}
|
||||
|
||||
// PagesDomain represents a pages domain.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/pages_domains.html
|
||||
type PagesDomain struct {
|
||||
Domain string `json:"domain"`
|
||||
URL string `json:"url"`
|
||||
ProjectID int `json:"project_id"`
|
||||
Verified bool `json:"verified"`
|
||||
VerificationCode string `json:"verification_code"`
|
||||
EnabledUntil *time.Time `json:"enabled_until"`
|
||||
Certificate struct {
|
||||
Expired bool `json:"expired"`
|
||||
Expiration *time.Time `json:"expiration"`
|
||||
} `json:"certificate"`
|
||||
}
|
||||
|
||||
// ListPagesDomainsOptions represents the available ListPagesDomains() options.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/pages_domains.html#list-pages-domains
|
||||
type ListPagesDomainsOptions ListOptions
|
||||
|
||||
// ListPagesDomains gets a list of project pages domains.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/pages_domains.html#list-pages-domains
|
||||
func (s *PagesDomainsService) ListPagesDomains(pid interface{}, opt *ListPagesDomainsOptions, options ...OptionFunc) ([]*PagesDomain, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/pages/domains", url.QueryEscape(project))
|
||||
|
||||
req, err := s.client.NewRequest("GET", u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
var pd []*PagesDomain
|
||||
resp, err := s.client.Do(req, &pd)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return pd, resp, err
|
||||
}
|
||||
|
||||
// GetPagesDomain get a specific pages domain for a project.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/pages_domains.html#single-pages-domain
|
||||
func (s *PagesDomainsService) GetPagesDomain(pid interface{}, domain string, options ...OptionFunc) (*PagesDomain, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/pages/domains/%s", url.QueryEscape(project), domain)
|
||||
|
||||
req, err := s.client.NewRequest("GET", u, nil, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
pd := new(PagesDomain)
|
||||
resp, err := s.client.Do(req, pd)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return pd, resp, err
|
||||
}
|
||||
|
||||
// CreatePagesDomainOptions represents the available CreatePagesDomain() options.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// // https://docs.gitlab.com/ce/api/pages_domains.html#create-new-pages-domain
|
||||
type CreatePagesDomainOptions struct {
|
||||
Domain *string `url:"domain,omitempty" json:"domain,omitempty"`
|
||||
Certificate *string `url:"certifiate,omitempty" json:"certifiate,omitempty"`
|
||||
Key *string `url:"key,omitempty" json:"key,omitempty"`
|
||||
}
|
||||
|
||||
// CreatePagesDomain creates a new project pages domain.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/pages_domains.html#create-new-pages-domain
|
||||
func (s *PagesDomainsService) CreatePagesDomain(pid interface{}, opt *CreatePagesDomainOptions, options ...OptionFunc) (*PagesDomain, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/pages/domains", url.QueryEscape(project))
|
||||
|
||||
req, err := s.client.NewRequest("POST", u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
pd := new(PagesDomain)
|
||||
resp, err := s.client.Do(req, pd)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return pd, resp, err
|
||||
}
|
||||
|
||||
// UpdatePagesDomainOptions represents the available UpdatePagesDomain() options.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/pages_domains.html#update-pages-domain
|
||||
type UpdatePagesDomainOptions struct {
|
||||
Cerificate *string `url:"certifiate" json:"certifiate"`
|
||||
Key *string `url:"key" json:"key"`
|
||||
}
|
||||
|
||||
// UpdatePagesDomain updates an existing project pages domain.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/pages_domains.html#update-pages-domain
|
||||
func (s *PagesDomainsService) UpdatePagesDomain(pid interface{}, domain string, opt *UpdatePagesDomainOptions, options ...OptionFunc) (*PagesDomain, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/pages/domains/%s", url.QueryEscape(project), domain)
|
||||
|
||||
req, err := s.client.NewRequest("PUT", u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
pd := new(PagesDomain)
|
||||
resp, err := s.client.Do(req, pd)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return pd, resp, err
|
||||
}
|
||||
|
||||
// DeletePagesDomain deletes an existing prject pages domain.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/pages_domains.html#delete-pages-domain
|
||||
func (s *PagesDomainsService) DeletePagesDomain(pid interface{}, domain string, options ...OptionFunc) (*Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/pages/domains/%s", url.QueryEscape(project), domain)
|
||||
|
||||
req, err := s.client.NewRequest("DELETE", u, nil, options)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return s.client.Do(req, nil)
|
||||
}
|
||||
341
vendor/github.com/xanzy/go-gitlab/pipeline_schedules.go
generated
vendored
Normal file
341
vendor/github.com/xanzy/go-gitlab/pipeline_schedules.go
generated
vendored
Normal file
@@ -0,0 +1,341 @@
|
||||
//
|
||||
// Copyright 2018, Sander van Harmelen
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
package gitlab
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/url"
|
||||
"time"
|
||||
)
|
||||
|
||||
// PipelineSchedulesService handles communication with the pipeline
|
||||
// schedules related methods of the GitLab API.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/pipeline_schedules.html
|
||||
type PipelineSchedulesService struct {
|
||||
client *Client
|
||||
}
|
||||
|
||||
// PipelineVariable represents a pipeline schedule variable.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/pipeline_schedules.html#pipeline-schedule-variable
|
||||
type PipelineVariable struct {
|
||||
Key string `json:"key"`
|
||||
Value string `json:"value"`
|
||||
}
|
||||
|
||||
// PipelineSchedule represents a pipeline schedule.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/pipeline_schedules.html
|
||||
type PipelineSchedule struct {
|
||||
ID int `json:"id"`
|
||||
Description string `json:"description"`
|
||||
Ref string `json:"ref"`
|
||||
Cron string `json:"cron"`
|
||||
CronTimezone string `json:"cron_timezone"`
|
||||
NextRunAt *time.Time `json:"next_run_at"`
|
||||
Active bool `json:"active"`
|
||||
CreatedAt *time.Time `json:"created_at"`
|
||||
UpdatedAt *time.Time `json:"updated_at"`
|
||||
Owner *User `json:"owner"`
|
||||
LastPipeline struct {
|
||||
ID int `json:"id"`
|
||||
Sha string `json:"sha"`
|
||||
Ref string `json:"ref"`
|
||||
Status string `json:"status"`
|
||||
} `json:"last_pipeline"`
|
||||
Variables []*PipelineVariable `json:"variables"`
|
||||
}
|
||||
|
||||
// ListPipelineSchedulesOptions represents the available ListPipelineTriggers() options.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/pipeline_triggers.html#list-project-triggers
|
||||
type ListPipelineSchedulesOptions ListOptions
|
||||
|
||||
// ListPipelineSchedules gets a list of project triggers.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/pipeline_schedules.html
|
||||
func (s *PipelineSchedulesService) ListPipelineSchedules(pid interface{}, opt *ListPipelineSchedulesOptions, options ...OptionFunc) ([]*PipelineSchedule, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/pipeline_schedules", url.QueryEscape(project))
|
||||
|
||||
req, err := s.client.NewRequest("GET", u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
var ps []*PipelineSchedule
|
||||
resp, err := s.client.Do(req, &ps)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return ps, resp, err
|
||||
}
|
||||
|
||||
// GetPipelineSchedule gets a pipeline schedule.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/pipeline_schedules.html
|
||||
func (s *PipelineSchedulesService) GetPipelineSchedule(pid interface{}, schedule int, options ...OptionFunc) (*PipelineSchedule, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/pipeline_schedules/%d", url.QueryEscape(project), schedule)
|
||||
|
||||
req, err := s.client.NewRequest("GET", u, nil, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
p := new(PipelineSchedule)
|
||||
resp, err := s.client.Do(req, p)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return p, resp, err
|
||||
}
|
||||
|
||||
// CreatePipelineScheduleOptions represents the available
|
||||
// CreatePipelineSchedule() options.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/pipeline_schedules.html#create-a-new-pipeline-schedule
|
||||
type CreatePipelineScheduleOptions struct {
|
||||
Description *string `url:"description" json:"description"`
|
||||
Ref *string `url:"ref" json:"ref"`
|
||||
Cron *string `url:"cron" json:"cron"`
|
||||
CronTimezone *string `url:"cron_timezone,omitempty" json:"cron_timezone,omitempty"`
|
||||
Active *bool `url:"active,omitempty" json:"active,omitempty"`
|
||||
}
|
||||
|
||||
// CreatePipelineSchedule creates a pipeline schedule.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/pipeline_schedules.html#create-a-new-pipeline-schedule
|
||||
func (s *PipelineSchedulesService) CreatePipelineSchedule(pid interface{}, opt *CreatePipelineScheduleOptions, options ...OptionFunc) (*PipelineSchedule, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/pipeline_schedules", url.QueryEscape(project))
|
||||
|
||||
req, err := s.client.NewRequest("POST", u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
p := new(PipelineSchedule)
|
||||
resp, err := s.client.Do(req, p)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return p, resp, err
|
||||
}
|
||||
|
||||
// EditPipelineScheduleOptions represents the available
|
||||
// EditPipelineSchedule() options.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/pipeline_schedules.html#create-a-new-pipeline-schedule
|
||||
type EditPipelineScheduleOptions struct {
|
||||
Description *string `url:"description,omitempty" json:"description,omitempty"`
|
||||
Ref *string `url:"ref,omitempty" json:"ref,omitempty"`
|
||||
Cron *string `url:"cron,omitempty" json:"cron,omitempty"`
|
||||
CronTimezone *string `url:"cron_timezone,omitempty" json:"cron_timezone,omitempty"`
|
||||
Active *bool `url:"active,omitempty" json:"active,omitempty"`
|
||||
}
|
||||
|
||||
// EditPipelineSchedule edits a pipeline schedule.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/pipeline_schedules.html#edit-a-pipeline-schedule
|
||||
func (s *PipelineSchedulesService) EditPipelineSchedule(pid interface{}, schedule int, opt *EditPipelineScheduleOptions, options ...OptionFunc) (*PipelineSchedule, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/pipeline_schedules/%d", url.QueryEscape(project), schedule)
|
||||
|
||||
req, err := s.client.NewRequest("PUT", u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
p := new(PipelineSchedule)
|
||||
resp, err := s.client.Do(req, p)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return p, resp, err
|
||||
}
|
||||
|
||||
// TakeOwnershipOfPipelineSchedule sets the owner of the specified
|
||||
// pipeline schedule to the user issuing the request.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/pipeline_schedules.html#take-ownership-of-a-pipeline-schedule
|
||||
func (s *PipelineSchedulesService) TakeOwnershipOfPipelineSchedule(pid interface{}, schedule int, options ...OptionFunc) (*PipelineSchedule, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/pipeline_schedules/%d/take_ownership", url.QueryEscape(project), schedule)
|
||||
|
||||
req, err := s.client.NewRequest("POST", u, nil, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
p := new(PipelineSchedule)
|
||||
resp, err := s.client.Do(req, p)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return p, resp, err
|
||||
}
|
||||
|
||||
// DeletePipelineSchedule deletes a pipeline schedule.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/pipeline_schedules.html#delete-a-pipeline-schedule
|
||||
func (s *PipelineSchedulesService) DeletePipelineSchedule(pid interface{}, schedule int, options ...OptionFunc) (*PipelineSchedule, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/pipeline_schedules/%d", url.QueryEscape(project), schedule)
|
||||
|
||||
req, err := s.client.NewRequest("DELETE", u, nil, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
p := new(PipelineSchedule)
|
||||
resp, err := s.client.Do(req, p)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return p, resp, err
|
||||
}
|
||||
|
||||
// CreatePipelineScheduleVariableOptions represents the available
|
||||
// CreatePipelineScheduleVariable() options.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/pipeline_schedules.html#create-a-new-pipeline-schedule
|
||||
type CreatePipelineScheduleVariableOptions struct {
|
||||
Key *string `url:"key" json:"key"`
|
||||
Value *string `url:"value" json:"value"`
|
||||
}
|
||||
|
||||
// CreatePipelineScheduleVariable creates a pipeline schedule variable.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/pipeline_schedules.html#create-a-new-pipeline-schedule
|
||||
func (s *PipelineSchedulesService) CreatePipelineScheduleVariable(pid interface{}, schedule int, opt *CreatePipelineScheduleVariableOptions, options ...OptionFunc) (*PipelineVariable, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/pipeline_schedules/%d/variables", url.QueryEscape(project), schedule)
|
||||
|
||||
req, err := s.client.NewRequest("POST", u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
p := new(PipelineVariable)
|
||||
resp, err := s.client.Do(req, p)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return p, resp, err
|
||||
}
|
||||
|
||||
// EditPipelineScheduleVariableOptions represents the available
|
||||
// EditPipelineScheduleVariable() options.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/pipeline_schedules.html#edit-a-pipeline-schedule-variable
|
||||
type EditPipelineScheduleVariableOptions struct {
|
||||
Value *string `url:"value" json:"value"`
|
||||
}
|
||||
|
||||
// EditPipelineScheduleVariable creates a pipeline schedule variable.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/pipeline_schedules.html#edit-a-pipeline-schedule-variable
|
||||
func (s *PipelineSchedulesService) EditPipelineScheduleVariable(pid interface{}, schedule int, key string, opt *EditPipelineScheduleVariableOptions, options ...OptionFunc) (*PipelineVariable, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/pipeline_schedules/%d/variables/%s", url.QueryEscape(project), schedule, key)
|
||||
|
||||
req, err := s.client.NewRequest("PUT", u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
p := new(PipelineVariable)
|
||||
resp, err := s.client.Do(req, p)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return p, resp, err
|
||||
}
|
||||
|
||||
// DeletePipelineScheduleVariable creates a pipeline schedule variable.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/pipeline_schedules.html#delete-a-pipeline-schedule-variable
|
||||
func (s *PipelineSchedulesService) DeletePipelineScheduleVariable(pid interface{}, schedule int, key string, options ...OptionFunc) (*PipelineVariable, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/pipeline_schedules/%d/variables/%s", url.QueryEscape(project), schedule, key)
|
||||
|
||||
req, err := s.client.NewRequest("DELETE", u, nil, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
p := new(PipelineVariable)
|
||||
resp, err := s.client.Do(req, p)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return p, resp, err
|
||||
}
|
||||
232
vendor/github.com/xanzy/go-gitlab/pipeline_triggers.go
generated
vendored
Normal file
232
vendor/github.com/xanzy/go-gitlab/pipeline_triggers.go
generated
vendored
Normal file
@@ -0,0 +1,232 @@
|
||||
package gitlab
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/url"
|
||||
"time"
|
||||
)
|
||||
|
||||
// PipelineTriggersService handles Project pipeline triggers.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/pipeline_triggers.html
|
||||
type PipelineTriggersService struct {
|
||||
client *Client
|
||||
}
|
||||
|
||||
// PipelineTrigger represents a project pipeline trigger.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/pipeline_triggers.html#pipeline-triggers
|
||||
type PipelineTrigger struct {
|
||||
ID int `json:"id"`
|
||||
Description string `json:"description"`
|
||||
CreatedAt *time.Time `json:"created_at"`
|
||||
DeletedAt *time.Time `json:"deleted_at"`
|
||||
LastUsed *time.Time `json:"last_used"`
|
||||
Token string `json:"token"`
|
||||
UpdatedAt *time.Time `json:"updated_at"`
|
||||
Owner *User `json:"owner"`
|
||||
}
|
||||
|
||||
// ListPipelineTriggersOptions represents the available ListPipelineTriggers() options.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/pipeline_triggers.html#list-project-triggers
|
||||
type ListPipelineTriggersOptions ListOptions
|
||||
|
||||
// ListPipelineTriggers gets a list of project triggers.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/pipeline_triggers.html#list-project-triggers
|
||||
func (s *PipelineTriggersService) ListPipelineTriggers(pid interface{}, opt *ListPipelineTriggersOptions, options ...OptionFunc) ([]*PipelineTrigger, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/triggers", url.QueryEscape(project))
|
||||
|
||||
req, err := s.client.NewRequest("GET", u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
var pt []*PipelineTrigger
|
||||
resp, err := s.client.Do(req, &pt)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return pt, resp, err
|
||||
}
|
||||
|
||||
// GetPipelineTrigger gets a specific pipeline trigger for a project.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/pipeline_triggers.html#get-trigger-details
|
||||
func (s *PipelineTriggersService) GetPipelineTrigger(pid interface{}, trigger int, options ...OptionFunc) (*PipelineTrigger, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/triggers/%d", url.QueryEscape(project), trigger)
|
||||
|
||||
req, err := s.client.NewRequest("GET", u, nil, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
pt := new(PipelineTrigger)
|
||||
resp, err := s.client.Do(req, pt)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return pt, resp, err
|
||||
}
|
||||
|
||||
// AddPipelineTriggerOptions represents the available AddPipelineTrigger() options.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/pipeline_triggers.html#create-a-project-trigger
|
||||
type AddPipelineTriggerOptions struct {
|
||||
Description *string `url:"description,omitempty" json:"description,omitempty"`
|
||||
}
|
||||
|
||||
// AddPipelineTrigger adds a pipeline trigger to a specified project.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/pipeline_triggers.html#create-a-project-trigger
|
||||
func (s *PipelineTriggersService) AddPipelineTrigger(pid interface{}, opt *AddPipelineTriggerOptions, options ...OptionFunc) (*PipelineTrigger, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/triggers", url.QueryEscape(project))
|
||||
|
||||
req, err := s.client.NewRequest("POST", u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
pt := new(PipelineTrigger)
|
||||
resp, err := s.client.Do(req, pt)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return pt, resp, err
|
||||
}
|
||||
|
||||
// EditPipelineTriggerOptions represents the available EditPipelineTrigger() options.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/pipeline_triggers.html#update-a-project-trigger
|
||||
type EditPipelineTriggerOptions struct {
|
||||
Description *string `url:"description,omitempty" json:"description,omitempty"`
|
||||
}
|
||||
|
||||
// EditPipelineTrigger edits a trigger for a specified project.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/pipeline_triggers.html#update-a-project-trigger
|
||||
func (s *PipelineTriggersService) EditPipelineTrigger(pid interface{}, trigger int, opt *EditPipelineTriggerOptions, options ...OptionFunc) (*PipelineTrigger, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/triggers/%d", url.QueryEscape(project), trigger)
|
||||
|
||||
req, err := s.client.NewRequest("PUT", u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
pt := new(PipelineTrigger)
|
||||
resp, err := s.client.Do(req, pt)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return pt, resp, err
|
||||
}
|
||||
|
||||
// TakeOwnershipOfPipelineTrigger sets the owner of the specified
|
||||
// pipeline trigger to the user issuing the request.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/pipeline_triggers.html#take-ownership-of-a-project-trigger
|
||||
func (s *PipelineTriggersService) TakeOwnershipOfPipelineTrigger(pid interface{}, trigger int, options ...OptionFunc) (*PipelineTrigger, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/triggers/%d/take_ownership", url.QueryEscape(project), trigger)
|
||||
|
||||
req, err := s.client.NewRequest("POST", u, nil, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
pt := new(PipelineTrigger)
|
||||
resp, err := s.client.Do(req, pt)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return pt, resp, err
|
||||
}
|
||||
|
||||
// DeletePipelineTrigger removes a trigger from a project.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/pipeline_triggers.html#remove-a-project-trigger
|
||||
func (s *PipelineTriggersService) DeletePipelineTrigger(pid interface{}, trigger int, options ...OptionFunc) (*Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/triggers/%d", url.QueryEscape(project), trigger)
|
||||
|
||||
req, err := s.client.NewRequest("DELETE", u, nil, options)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return s.client.Do(req, nil)
|
||||
}
|
||||
|
||||
// RunPipelineTriggerOptions represents the available RunPipelineTrigger() options.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/ci/triggers/README.html#triggering-a-pipeline
|
||||
type RunPipelineTriggerOptions struct {
|
||||
Ref *string `url:"ref" json:"ref"`
|
||||
Token *string `url:"token" json:"token"`
|
||||
Variables map[string]string `url:"variables,omitempty" json:"variables,omitempty"`
|
||||
}
|
||||
|
||||
// RunPipelineTrigger starts a trigger from a project.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/ci/triggers/README.html#triggering-a-pipeline
|
||||
func (s *PipelineTriggersService) RunPipelineTrigger(pid interface{}, opt *RunPipelineTriggerOptions, options ...OptionFunc) (*Pipeline, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/trigger/pipeline", url.QueryEscape(project))
|
||||
|
||||
req, err := s.client.NewRequest("POST", u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
pt := new(Pipeline)
|
||||
resp, err := s.client.Do(req, pt)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return pt, resp, err
|
||||
}
|
||||
220
vendor/github.com/xanzy/go-gitlab/pipelines.go
generated
vendored
Normal file
220
vendor/github.com/xanzy/go-gitlab/pipelines.go
generated
vendored
Normal file
@@ -0,0 +1,220 @@
|
||||
//
|
||||
// Copyright 2017, Igor Varavko
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
package gitlab
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/url"
|
||||
"time"
|
||||
)
|
||||
|
||||
// PipelinesService handles communication with the repositories related
|
||||
// methods of the GitLab API.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/pipelines.html
|
||||
type PipelinesService struct {
|
||||
client *Client
|
||||
}
|
||||
|
||||
// Pipeline represents a GitLab pipeline.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/pipelines.html
|
||||
type Pipeline struct {
|
||||
ID int `json:"id"`
|
||||
Status string `json:"status"`
|
||||
Ref string `json:"ref"`
|
||||
Sha string `json:"sha"`
|
||||
BeforeSha string `json:"before_sha"`
|
||||
Tag bool `json:"tag"`
|
||||
YamlErrors string `json:"yaml_errors"`
|
||||
User struct {
|
||||
Name string `json:"name"`
|
||||
Username string `json:"username"`
|
||||
ID int `json:"id"`
|
||||
State string `json:"state"`
|
||||
AvatarURL string `json:"avatar_url"`
|
||||
WebURL string `json:"web_url"`
|
||||
}
|
||||
UpdatedAt *time.Time `json:"updated_at"`
|
||||
CreatedAt *time.Time `json:"created_at"`
|
||||
StartedAt *time.Time `json:"started_at"`
|
||||
FinishedAt *time.Time `json:"finished_at"`
|
||||
CommittedAt *time.Time `json:"committed_at"`
|
||||
Duration int `json:"duration"`
|
||||
Coverage string `json:"coverage"`
|
||||
}
|
||||
|
||||
func (i Pipeline) String() string {
|
||||
return Stringify(i)
|
||||
}
|
||||
|
||||
// PipelineList represents a GitLab list project pipelines
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/pipelines.html#list-project-pipelines
|
||||
type PipelineList []struct {
|
||||
ID int `json:"id"`
|
||||
Status string `json:"status"`
|
||||
Ref string `json:"ref"`
|
||||
Sha string `json:"sha"`
|
||||
}
|
||||
|
||||
func (i PipelineList) String() string {
|
||||
return Stringify(i)
|
||||
}
|
||||
|
||||
// ListProjectPipelinesOptions represents the available ListProjectPipelines() options.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/pipelines.html#list-project-pipelines
|
||||
type ListProjectPipelinesOptions struct {
|
||||
ListOptions
|
||||
Scope *string `url:"scope,omitempty" json:"scope,omitempty"`
|
||||
Status *BuildStateValue `url:"status,omitempty" json:"status,omitempty"`
|
||||
Ref *string `url:"ref,omitempty" json:"ref,omitempty"`
|
||||
YamlErrors *bool `url:"yaml_errors,omitempty" json:"yaml_errors,omitempty"`
|
||||
Name *string `url:"name,omitempty" json:"name,omitempty"`
|
||||
Username *string `url:"username,omitempty" json:"username,omitempty"`
|
||||
OrderBy *string `url:"order_by,omitempty" json:"order_by,omitempty"`
|
||||
Sort *string `url:"sort,omitempty" json:"sort,omitempty"`
|
||||
}
|
||||
|
||||
// ListProjectPipelines gets a list of project piplines.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/pipelines.html#list-project-pipelines
|
||||
func (s *PipelinesService) ListProjectPipelines(pid interface{}, opt *ListProjectPipelinesOptions, options ...OptionFunc) (PipelineList, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/pipelines", url.QueryEscape(project))
|
||||
|
||||
req, err := s.client.NewRequest("GET", u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
var p PipelineList
|
||||
resp, err := s.client.Do(req, &p)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
return p, resp, err
|
||||
}
|
||||
|
||||
// GetPipeline gets a single project pipeline.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/pipelines.html#get-a-single-pipeline
|
||||
func (s *PipelinesService) GetPipeline(pid interface{}, pipeline int, options ...OptionFunc) (*Pipeline, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/pipelines/%d", url.QueryEscape(project), pipeline)
|
||||
|
||||
req, err := s.client.NewRequest("GET", u, nil, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
p := new(Pipeline)
|
||||
resp, err := s.client.Do(req, p)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return p, resp, err
|
||||
}
|
||||
|
||||
// CreatePipelineOptions represents the available CreatePipeline() options.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/pipelines.html#create-a-new-pipeline
|
||||
type CreatePipelineOptions struct {
|
||||
Ref *string `url:"ref,omitempty" json:"ref"`
|
||||
}
|
||||
|
||||
// CreatePipeline creates a new project pipeline.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/pipelines.html#create-a-new-pipeline
|
||||
func (s *PipelinesService) CreatePipeline(pid interface{}, opt *CreatePipelineOptions, options ...OptionFunc) (*Pipeline, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/pipeline", url.QueryEscape(project))
|
||||
|
||||
req, err := s.client.NewRequest("POST", u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
p := new(Pipeline)
|
||||
resp, err := s.client.Do(req, p)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return p, resp, err
|
||||
}
|
||||
|
||||
// RetryPipelineBuild retries failed builds in a pipeline
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/pipelines.html#retry-failed-builds-in-a-pipeline
|
||||
func (s *PipelinesService) RetryPipelineBuild(pid interface{}, pipelineID int, options ...OptionFunc) (*Pipeline, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/pipelines/%d/retry", project, pipelineID)
|
||||
|
||||
req, err := s.client.NewRequest("POST", u, nil, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
p := new(Pipeline)
|
||||
resp, err := s.client.Do(req, p)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return p, resp, err
|
||||
}
|
||||
|
||||
// CancelPipelineBuild cancels a pipeline builds
|
||||
//
|
||||
// GitLab API docs:
|
||||
//https://docs.gitlab.com/ce/api/pipelines.html#cancel-a-pipelines-builds
|
||||
func (s *PipelinesService) CancelPipelineBuild(pid interface{}, pipelineID int, options ...OptionFunc) (*Pipeline, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/pipelines/%d/cancel", project, pipelineID)
|
||||
|
||||
req, err := s.client.NewRequest("POST", u, nil, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
p := new(Pipeline)
|
||||
resp, err := s.client.Do(req, p)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return p, resp, err
|
||||
}
|
||||
179
vendor/github.com/xanzy/go-gitlab/project_members.go
generated
vendored
Normal file
179
vendor/github.com/xanzy/go-gitlab/project_members.go
generated
vendored
Normal file
@@ -0,0 +1,179 @@
|
||||
//
|
||||
// Copyright 2017, Sander van Harmelen
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
package gitlab
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/url"
|
||||
)
|
||||
|
||||
// ProjectMembersService handles communication with the project members
|
||||
// related methods of the GitLab API.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/members.html
|
||||
type ProjectMembersService struct {
|
||||
client *Client
|
||||
}
|
||||
|
||||
// ListProjectMembersOptions represents the available ListProjectMembers()
|
||||
// options.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/members.html#list-all-members-of-a-group-or-project
|
||||
type ListProjectMembersOptions struct {
|
||||
ListOptions
|
||||
Query *string `url:"query,omitempty" json:"query,omitempty"`
|
||||
}
|
||||
|
||||
// ListProjectMembers gets a list of a project's team members.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/members.html#list-all-members-of-a-group-or-project
|
||||
func (s *ProjectMembersService) ListProjectMembers(pid interface{}, opt *ListProjectMembersOptions, options ...OptionFunc) ([]*ProjectMember, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/members", url.QueryEscape(project))
|
||||
|
||||
req, err := s.client.NewRequest("GET", u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
var pm []*ProjectMember
|
||||
resp, err := s.client.Do(req, &pm)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return pm, resp, err
|
||||
}
|
||||
|
||||
// GetProjectMember gets a project team member.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/members.html#get-a-member-of-a-group-or-project
|
||||
func (s *ProjectMembersService) GetProjectMember(pid interface{}, user int, options ...OptionFunc) (*ProjectMember, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/members/%d", url.QueryEscape(project), user)
|
||||
|
||||
req, err := s.client.NewRequest("GET", u, nil, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
pm := new(ProjectMember)
|
||||
resp, err := s.client.Do(req, pm)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return pm, resp, err
|
||||
}
|
||||
|
||||
// AddProjectMemberOptions represents the available AddProjectMember() options.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/members.html#add-a-member-to-a-group-or-project
|
||||
type AddProjectMemberOptions struct {
|
||||
UserID *int `url:"user_id,omitempty" json:"user_id,omitempty"`
|
||||
AccessLevel *AccessLevelValue `url:"access_level,omitempty" json:"access_level,omitempty"`
|
||||
}
|
||||
|
||||
// AddProjectMember adds a user to a project team. This is an idempotent
|
||||
// method and can be called multiple times with the same parameters. Adding
|
||||
// team membership to a user that is already a member does not affect the
|
||||
// existing membership.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/members.html#add-a-member-to-a-group-or-project
|
||||
func (s *ProjectMembersService) AddProjectMember(pid interface{}, opt *AddProjectMemberOptions, options ...OptionFunc) (*ProjectMember, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/members", url.QueryEscape(project))
|
||||
|
||||
req, err := s.client.NewRequest("POST", u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
pm := new(ProjectMember)
|
||||
resp, err := s.client.Do(req, pm)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return pm, resp, err
|
||||
}
|
||||
|
||||
// EditProjectMemberOptions represents the available EditProjectMember() options.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/members.html#edit-a-member-of-a-group-or-project
|
||||
type EditProjectMemberOptions struct {
|
||||
AccessLevel *AccessLevelValue `url:"access_level,omitempty" json:"access_level,omitempty"`
|
||||
}
|
||||
|
||||
// EditProjectMember updates a project team member to a specified access level..
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/members.html#edit-a-member-of-a-group-or-project
|
||||
func (s *ProjectMembersService) EditProjectMember(pid interface{}, user int, opt *EditProjectMemberOptions, options ...OptionFunc) (*ProjectMember, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/members/%d", url.QueryEscape(project), user)
|
||||
|
||||
req, err := s.client.NewRequest("PUT", u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
pm := new(ProjectMember)
|
||||
resp, err := s.client.Do(req, pm)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return pm, resp, err
|
||||
}
|
||||
|
||||
// DeleteProjectMember removes a user from a project team.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/members.html#remove-a-member-from-a-group-or-project
|
||||
func (s *ProjectMembersService) DeleteProjectMember(pid interface{}, user int, options ...OptionFunc) (*Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/members/%d", url.QueryEscape(project), user)
|
||||
|
||||
req, err := s.client.NewRequest("DELETE", u, nil, options)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return s.client.Do(req, nil)
|
||||
}
|
||||
207
vendor/github.com/xanzy/go-gitlab/project_snippets.go
generated
vendored
Normal file
207
vendor/github.com/xanzy/go-gitlab/project_snippets.go
generated
vendored
Normal file
@@ -0,0 +1,207 @@
|
||||
//
|
||||
// Copyright 2017, Sander van Harmelen
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
package gitlab
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"net/url"
|
||||
)
|
||||
|
||||
// ProjectSnippetsService handles communication with the project snippets
|
||||
// related methods of the GitLab API.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/project_snippets.html
|
||||
type ProjectSnippetsService struct {
|
||||
client *Client
|
||||
}
|
||||
|
||||
// ListProjectSnippetsOptions represents the available ListSnippets() options.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/project_snippets.html#list-snippets
|
||||
type ListProjectSnippetsOptions ListOptions
|
||||
|
||||
// ListSnippets gets a list of project snippets.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/project_snippets.html#list-snippets
|
||||
func (s *ProjectSnippetsService) ListSnippets(pid interface{}, opt *ListProjectSnippetsOptions, options ...OptionFunc) ([]*Snippet, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/snippets", url.QueryEscape(project))
|
||||
|
||||
req, err := s.client.NewRequest("GET", u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
var ps []*Snippet
|
||||
resp, err := s.client.Do(req, &ps)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return ps, resp, err
|
||||
}
|
||||
|
||||
// GetSnippet gets a single project snippet
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/project_snippets.html#single-snippet
|
||||
func (s *ProjectSnippetsService) GetSnippet(pid interface{}, snippet int, options ...OptionFunc) (*Snippet, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/snippets/%d", url.QueryEscape(project), snippet)
|
||||
|
||||
req, err := s.client.NewRequest("GET", u, nil, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
ps := new(Snippet)
|
||||
resp, err := s.client.Do(req, ps)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return ps, resp, err
|
||||
}
|
||||
|
||||
// CreateProjectSnippetOptions represents the available CreateSnippet() options.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/project_snippets.html#create-new-snippet
|
||||
type CreateProjectSnippetOptions struct {
|
||||
Title *string `url:"title,omitempty" json:"title,omitempty"`
|
||||
FileName *string `url:"file_name,omitempty" json:"file_name,omitempty"`
|
||||
Description *string `url:"description,omitempty" json:"description,omitempty"`
|
||||
Code *string `url:"code,omitempty" json:"code,omitempty"`
|
||||
Visibility *VisibilityValue `url:"visibility,omitempty" json:"visibility,omitempty"`
|
||||
}
|
||||
|
||||
// CreateSnippet creates a new project snippet. The user must have permission
|
||||
// to create new snippets.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/project_snippets.html#create-new-snippet
|
||||
func (s *ProjectSnippetsService) CreateSnippet(pid interface{}, opt *CreateProjectSnippetOptions, options ...OptionFunc) (*Snippet, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/snippets", url.QueryEscape(project))
|
||||
|
||||
req, err := s.client.NewRequest("POST", u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
ps := new(Snippet)
|
||||
resp, err := s.client.Do(req, ps)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return ps, resp, err
|
||||
}
|
||||
|
||||
// UpdateProjectSnippetOptions represents the available UpdateSnippet() options.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/project_snippets.html#update-snippet
|
||||
type UpdateProjectSnippetOptions struct {
|
||||
Title *string `url:"title,omitempty" json:"title,omitempty"`
|
||||
FileName *string `url:"file_name,omitempty" json:"file_name,omitempty"`
|
||||
Description *string `url:"description,omitempty" json:"description,omitempty"`
|
||||
Code *string `url:"code,omitempty" json:"code,omitempty"`
|
||||
Visibility *VisibilityValue `url:"visibility,omitempty" json:"visibility,omitempty"`
|
||||
}
|
||||
|
||||
// UpdateSnippet updates an existing project snippet. The user must have
|
||||
// permission to change an existing snippet.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/project_snippets.html#update-snippet
|
||||
func (s *ProjectSnippetsService) UpdateSnippet(pid interface{}, snippet int, opt *UpdateProjectSnippetOptions, options ...OptionFunc) (*Snippet, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/snippets/%d", url.QueryEscape(project), snippet)
|
||||
|
||||
req, err := s.client.NewRequest("PUT", u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
ps := new(Snippet)
|
||||
resp, err := s.client.Do(req, ps)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return ps, resp, err
|
||||
}
|
||||
|
||||
// DeleteSnippet deletes an existing project snippet. This is an idempotent
|
||||
// function and deleting a non-existent snippet still returns a 200 OK status
|
||||
// code.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/project_snippets.html#delete-snippet
|
||||
func (s *ProjectSnippetsService) DeleteSnippet(pid interface{}, snippet int, options ...OptionFunc) (*Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/snippets/%d", url.QueryEscape(project), snippet)
|
||||
|
||||
req, err := s.client.NewRequest("DELETE", u, nil, options)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return s.client.Do(req, nil)
|
||||
}
|
||||
|
||||
// SnippetContent returns the raw project snippet as plain text.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/project_snippets.html#snippet-content
|
||||
func (s *ProjectSnippetsService) SnippetContent(pid interface{}, snippet int, options ...OptionFunc) ([]byte, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/snippets/%d/raw", url.QueryEscape(project), snippet)
|
||||
|
||||
req, err := s.client.NewRequest("GET", u, nil, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
var b bytes.Buffer
|
||||
resp, err := s.client.Do(req, &b)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return b.Bytes(), resp, err
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user