diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..97d405761fee688b085e6f3966b88a475e5916f2
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,18 @@
+ci-bot
+
+# Binaries for programs and plugins
+*.exe
+*.exe~
+*.dll
+*.so
+*.dylib
+
+# Test binary, built with `go test -c`
+*.test
+
+# Output of the go coverage tool, specifically when used with LiteIDE
+*.out
+
+# Dependency directories (remove the comment below to include it)
+# vendor/
+.idea/
diff --git a/Dockerfile b/Dockerfile
new file mode 100644
index 0000000000000000000000000000000000000000..4409e3daf296ecb3729cba27709ecceb2d74d2a4
--- /dev/null
+++ b/Dockerfile
@@ -0,0 +1,16 @@
+FROM golang:1.12.1-alpine3.9 AS builder
+
+COPY . /go/src/gitee.com/openeuler/ci-bot
+
+RUN apk --no-cache update && \
+apk --no-cache upgrade && \
+CGO_ENABLED=1 go build -v -o /usr/local/bin/ci-bot -ldflags="-w -s -extldflags -static" \
+gitee.com/openeuler/ci-bot/cmd/cibot
+
+RUN mkdir -p /bot
+
+WORKDIR /bot
+
+EXPOSE 8888
+
+ENTRYPOINT ["ci-bot"]
diff --git a/Jenkinsfile b/Jenkinsfile
new file mode 100644
index 0000000000000000000000000000000000000000..d78ed6729040d425cc3e140ac7d88486e6a7fbf6
--- /dev/null
+++ b/Jenkinsfile
@@ -0,0 +1,17 @@
+pipeline {
+ agent { docker { image 'golang' } }
+ stages {
+ stage('build') {
+ steps {
+ sh '''
+ go get golang.org/x/crypto/ssh
+ go get -v -tags 'fixtures acceptance' ./...
+ go get github.com/wadey/gocovmerge
+ go get github.com/mattn/goveralls
+ go get golang.org/x/tools/cmd/goimports
+ '''
+ sh './script/coverage'
+ }
+ }
+ }
+}
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000000000000000000000000000000000000..a10985f0870b66a8385e18df5fe94ec35ff5919a
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,122 @@
+木兰宽松许可证, 第1版
+
+2019年8月 http://license.coscl.org.cn/MulanPSL
+
+您对“软件”的复制、使用、修改及分发受木兰宽松许可证,第1版(“本许可证”)的如下条款的约束:
+
+0. 定义
+
+“软件”是指由“贡献”构成的许可在“本许可证”下的程序和相关文档的集合。
+
+“贡献者”是指将受版权法保护的作品许可在“本许可证”下的自然人或“法人实体”。
+
+“法人实体”是指提交贡献的机构及其“关联实体”。
+
+“关联实体”是指,对“本许可证”下的一方而言,控制、受控制或与其共同受控制的机构,此处的控制是指有受控方或共同受控方至少50%直接或间接的投票权、资金或其他有价证券。
+
+“贡献”是指由任一“贡献者”许可在“本许可证”下的受版权法保护的作品。
+
+1. 授予版权许可
+
+每个“贡献者”根据“本许可证”授予您永久性的、全球性的、免费的、非独占的、不可撤销的版权许可,您可以复制、使用、修改、分发其“贡献”,不论修改与否。
+
+2. 授予专利许可
+
+每个“贡献者”根据“本许可证”授予您永久性的、全球性的、免费的、非独占的、不可撤销的(根据本条规定撤销除外)专利许可,供您制造、委托制造、使用、许诺销售、销售、进口其“贡献”或以其他方式转移其“贡献”。前述专利许可仅限于“贡献者”现在或将来拥有或控制的其“贡献”本身或其“贡献”与许可“贡献”时的“软件”结合而将必然会侵犯的专利权利要求,不包括仅因您或他人修改“贡献”或其他结合而将必然会侵犯到的专利权利要求。如您或您的“关联实体”直接或间接地(包括通过代理、专利被许可人或受让人),就“软件”或其中的“贡献”对任何人发起专利侵权诉讼(包括反诉或交叉诉讼)或其他专利维权行动,指控其侵犯专利权,则“本许可证”授予您对“软件”的专利许可自您提起诉讼或发起维权行动之日终止。
+
+3. 无商标许可
+
+“本许可证”不提供对“贡献者”的商品名称、商标、服务标志或产品名称的商标许可,但您为满足第4条规定的声明义务而必须使用除外。
+
+4. 分发限制
+
+您可以在任何媒介中将“软件”以源程序形式或可执行形式重新分发,不论修改与否,但您必须向接收者提供“本许可证”的副本,并保留“软件”中的版权、商标、专利及免责声明。
+
+5. 免责声明与责任限制
+
+“软件”及其中的“贡献”在提供时不带任何明示或默示的担保。在任何情况下,“贡献者”或版权所有者不对任何人因使用“软件”或其中的“贡献”而引发的任何直接或间接损失承担责任,不论因何种原因导致或者基于何种法律理论,即使其曾被建议有此种损失的可能性。
+
+条款结束
+
+如何将木兰宽松许可证,第1版,应用到您的软件
+
+如果您希望将木兰宽松许可证,第1版,应用到您的新软件,为了方便接收者查阅,建议您完成如下三步:
+
+1, 请您补充如下声明中的空白,包括软件名、软件的首次发表年份以及您作为版权人的名字;
+
+2, 请您在软件包的一级目录下创建以“LICENSE”为名的文件,将整个许可证文本放入该文件中;
+
+3, 请将如下声明文本放入每个源文件的头部注释中。
+
+Copyright (c) [2019] [name of copyright holder]
+[Software Name] is licensed under the Mulan PSL v1.
+You can use this software according to the terms and conditions of the Mulan PSL v1.
+You may obtain a copy of Mulan PSL v1 at:
+ http://license.coscl.org.cn/MulanPSL
+THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR
+PURPOSE.
+See the Mulan PSL v1 for more details.
+
+
+
+Mulan Permissive Software License,Version 1
+
+Mulan Permissive Software License,Version 1 (Mulan PSL v1)
+
+August 2019 http://license.coscl.org.cn/MulanPSL
+
+Your reproduction, use, modification and distribution of the Software shall be subject to Mulan PSL v1 (this License) with following terms and conditions:
+
+0. Definition
+
+Software means the program and related documents which are comprised of those Contribution and licensed under this License.
+
+Contributor means the Individual or Legal Entity who licenses its copyrightable work under this License.
+
+Legal Entity means the entity making a Contribution and all its Affiliates.
+
+Affiliates means entities that control, or are controlled by, or are under common control with a party to this License, ‘control’ means direct or indirect ownership of at least fifty percent (50%) of the voting power, capital or other securities of controlled or commonly controlled entity.
+
+Contribution means the copyrightable work licensed by a particular Contributor under this License.
+
+1. Grant of Copyright License
+
+Subject to the terms and conditions of this License, each Contributor hereby grants to you a perpetual, worldwide, royalty-free, non-exclusive, irrevocable copyright license to reproduce, use, modify, or distribute its Contribution, with modification or not.
+
+2. Grant of Patent License
+
+Subject to the terms and conditions of this License, each Contributor hereby grants to you a perpetual, worldwide, royalty-free, non-exclusive, irrevocable (except for revocation under this Section) patent license to make, have made, use, offer for sale, sell, import or otherwise transfer its Contribution where such patent license is only limited to the patent claims owned or controlled by such Contributor now or in future which will be necessarily infringed by its Contribution alone, or by combination of the Contribution with the Software to which the Contribution was contributed, excluding of any patent claims solely be infringed by your or others’ modification or other combinations. If you or your Affiliates directly or indirectly (including through an agent, patent licensee or assignee), institute patent litigation (including a cross claim or counterclaim in a litigation) or other patent enforcement activities against any individual or entity by alleging that the Software or any Contribution in it infringes patents, then any patent license granted to you under this License for the Software shall terminate as of the date such litigation or activity is filed or taken.
+
+3. No Trademark License
+
+No trademark license is granted to use the trade names, trademarks, service marks, or product names of Contributor, except as required to fulfill notice requirements in section 4.
+
+4. Distribution Restriction
+
+You may distribute the Software in any medium with or without modification, whether in source or executable forms, provided that you provide recipients with a copy of this License and retain copyright, patent, trademark and disclaimer statements in the Software.
+
+5. Disclaimer of Warranty and Limitation of Liability
+
+The Software and Contribution in it are provided without warranties of any kind, either express or implied. In no event shall any Contributor or copyright holder be liable to you for any damages, including, but not limited to any direct, or indirect, special or consequential damages arising from your use or inability to use the Software or the Contribution in it, no matter how it’s caused or based on which legal theory, even if advised of the possibility of such damages.
+
+End of the Terms and Conditions
+
+How to apply the Mulan Permissive Software License,Version 1 (Mulan PSL v1) to your software
+
+To apply the Mulan PSL v1 to your work, for easy identification by recipients, you are suggested to complete following three steps:
+
+1. Fill in the blanks in following statement, including insert your software name, the year of the first publication of your software, and your name identified as the copyright owner;
+2. Create a file named “LICENSE” which contains the whole context of this License in the first directory of your software package;
+3. Attach the statement to the appropriate annotated syntax at the beginning of each source file.
+
+Copyright (c) [2019] [name of copyright holder]
+[Software Name] is licensed under the Mulan PSL v1.
+You can use this software according to the terms and conditions of the Mulan PSL v1.
+You may obtain a copy of Mulan PSL v1 at:
+ http://license.coscl.org.cn/MulanPSL
+THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR
+PURPOSE.
+See the Mulan PSL v1 for more details.
+
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..aa558bb8e2a896d949b8490e7d6e8aed8b5158f4
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,16 @@
+.PHONY: all build ci-bot clean
+
+all:build
+
+build:ci-bot
+
+build-image:ci-bot-image
+
+ci-bot:
+ GOFLAGS=-mod=vendor go build -o ci-bot ./cmd/cibot
+
+ci-bot-image:
+ docker build -t openeuler/cibot:latest ./
+
+clean:
+ rm -rf ./ci-bot
diff --git a/OWNERS b/OWNERS
new file mode 100644
index 0000000000000000000000000000000000000000..81ac0e80a76aa65c1af1a3ed1b1cd950de3b7c6b
--- /dev/null
+++ b/OWNERS
@@ -0,0 +1,6 @@
+maintainers:
+ - edisontest
+ - freesky-edward
+ - TommyLike
+ - xiangxinyong
+ - zerodefect
diff --git a/README.en.md b/README.en.md
deleted file mode 100644
index 68983ef7e44f46cce22a8681856af7f0f23d1ece..0000000000000000000000000000000000000000
--- a/README.en.md
+++ /dev/null
@@ -1,36 +0,0 @@
-# ci-bot
-
-#### Description
-{**When you're done, you can delete the content in this README and update the file with details for others getting started with your repository**}
-
-#### Software Architecture
-Software architecture description
-
-#### Installation
-
-1. xxxx
-2. xxxx
-3. xxxx
-
-#### Instructions
-
-1. xxxx
-2. xxxx
-3. xxxx
-
-#### Contribution
-
-1. Fork the repository
-2. Create Feat_xxx branch
-3. Commit your code
-4. Create Pull Request
-
-
-#### Gitee Feature
-
-1. You can use Readme\_XXX.md to support different languages, such as Readme\_en.md, Readme\_zh.md
-2. Gitee blog [blog.gitee.com](https://blog.gitee.com)
-3. Explore open source project [https://gitee.com/explore](https://gitee.com/explore)
-4. The most valuable open source project [GVP](https://gitee.com/gvp)
-5. The manual of Gitee [https://gitee.com/help](https://gitee.com/help)
-6. The most popular members [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/)
diff --git a/README.md b/README.md
index f47c5ff322ffb6f0047142d761cd6bc7d9330417..052944302c8658a478d696a07f8d56fe4d0c7f32 100644
--- a/README.md
+++ b/README.md
@@ -1,39 +1,36 @@
# ci-bot
-#### 介绍
-{**以下是码云平台说明,您可以替换此简介**
-码云是 OSCHINA 推出的基于 Git 的代码托管平台(同时支持 SVN)。专为开发者提供稳定、高效、安全的云端软件开发协作平台
-无论是个人、团队、或是企业,都能够用码云实现代码托管、项目管理、协作开发。企业项目请看 [https://gitee.com/enterprises](https://gitee.com/enterprises)}
+## Introduction
-#### 软件架构
-软件架构说明
+This repository is used to address the code of openEuler ci bot.
+## Architecture
-#### 安装教程
+
-1. xxxx
-2. xxxx
-3. xxxx
+## Prerequisites
-#### 使用说明
+You'll need to setup a MySQL Database before you are getting started.
+This is an example to create Database instance.
-1. xxxx
-2. xxxx
-3. xxxx
+* Setup MySQL instance by the Huawei Cloud Relational Database Service (RDS)
+* Login in MySQL with your account and password
+* Create database instance by running the following command
+ ```
+ CREATE DATABASE cibot;
+ ```
+The information of database instance will be used in the following Installation.
-#### 参与贡献
+## Getting Started
-1. Fork 本仓库
-2. 新建 Feat_xxx 分支
-3. 提交代码
-4. 新建 Pull Request
+* [Getting Started on Locally](deploy/locally/README.md)
+* [Getting Started on CCE](deploy/cce/README.md)
+## Command Help
-#### 码云特技
+See the [Command Help](https://gitee.com/openeuler/community/blob/master/en/sig-infrastructure/command.md) file for details.
+> For Chinese version, please refer to [命令帮助](https://gitee.com/openeuler/community/blob/master/zh/sig-infrastructure/command.md).
-1. 使用 Readme\_XXX.md 来支持不同的语言,例如 Readme\_en.md, Readme\_zh.md
-2. 码云官方博客 [blog.gitee.com](https://blog.gitee.com)
-3. 你可以 [https://gitee.com/explore](https://gitee.com/explore) 这个地址来了解码云上的优秀开源项目
-4. [GVP](https://gitee.com/gvp) 全称是码云最有价值开源项目,是码云综合评定出的优秀开源项目
-5. 码云官方提供的使用手册 [https://gitee.com/help](https://gitee.com/help)
-6. 码云封面人物是一档用来展示码云会员风采的栏目 [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/)
+## License
+
+See the [LICENSE](LICENSE) file for details.
diff --git a/cmd/cibot/main.go b/cmd/cibot/main.go
new file mode 100644
index 0000000000000000000000000000000000000000..e7fdb32f9878f7e308c5e768c7ee671e48319e86
--- /dev/null
+++ b/cmd/cibot/main.go
@@ -0,0 +1,13 @@
+package main
+
+import (
+ "github.com/spf13/pflag"
+
+ "gitee.com/openeuler/ci-bot/pkg/cibot"
+)
+
+func main() {
+ wh := cibot.NewWebHook()
+ wh.AddFlags(pflag.CommandLine)
+ wh.Run()
+}
diff --git a/config.yaml b/config.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..1967f7bd146eea5a605bde3dc5594678c1b11bd4
--- /dev/null
+++ b/config.yaml
@@ -0,0 +1,36 @@
+giteeToken: "******"
+webhookSecret: "******"
+databaseType: "mysql"
+databaseHost: "127.0.0.1"
+databasePort: 3306
+databaseName: "cibot"
+databaseUserName: "root"
+databasePassword: "******"
+lgtmCountsRequired: 1
+watchProjectFiles:
+ - watchProjectFileOwner: openeuler
+ watchprojectFileRepo: infrastructure
+ watchprojectFilePath: repository/openeuler.yaml
+ watchProjectFileRef: master
+ - watchProjectFileOwner: openeuler
+ watchprojectFileRepo: infrastructure
+ watchprojectFilePath: repository/src-openeuler.yaml
+ watchProjectFileRef: master
+watchProjectFileDuration: 60
+watchSigFiles:
+ - watchSigFileOwner: openeuler
+ watchSigFileRepo: community
+ watchSigFilePath: sig/sigs.yaml
+ watchSigFileRef: master
+watchSigFileDuration: 60
+watchOwnerFiles:
+ - watchOwnerFileOwner: openeuler
+ watchOwnerFileRepo: community
+ watchOwnerFilePath: sig/*/OWNERS
+ watchOwnerFileRef: master
+watchOwnerFileDuration: 300
+botName: openeuler-ci-bot
+communityName: openEuler
+claLink: https://openeuler.org/en/cla.html
+commandLink: https://gitee.com/openeuler/community/blob/master/en/sig-infrastructure/command.md
+contactEmail: contact@openeuler.org
diff --git a/deploy/cce/README.md b/deploy/cce/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..cf6be4b6aa73390fab19f29634373005c5829439
--- /dev/null
+++ b/deploy/cce/README.md
@@ -0,0 +1,18 @@
+# Getting Started on CCE
+
+## Build
+
+```
+$ mkdir -p $GOPATH/src/gitee.com/openeuler
+$ cd $GOPATH/src/gitee.com/openeuler
+$ git clone https://gitee.com/openeuler/ci-bot
+$ cd ci-bot
+$ make ci-bot-image
+```
+
+## Usage
+
+```
+$ cd $GOPATH/src/gitee.com/openeuler/ci-bot/deploy/cce
+$ kubectl create -f .
+```
diff --git a/deploy/cce/configmap.yaml b/deploy/cce/configmap.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..8b51e517b33ea93517a24c2d6a4a1ae526c66380
--- /dev/null
+++ b/deploy/cce/configmap.yaml
@@ -0,0 +1,26 @@
+---
+apiVersion: v1
+kind: ConfigMap
+metadata:
+ name: bot-configmap
+ namespace: bot
+data:
+ config.yaml: |
+ giteeToken: "******"
+ webhookSecret: "123456789"
+ databaseType: "mysql"
+ databaseHost: "127.0.0.1"
+ databasePort: 3306
+ databaseName: "cibot"
+ databaseUserName: "root"
+ databasePassword: "******"
+ watchProjectFiles:
+ - watchProjectFileOwner: openeuler
+ watchprojectFileRepo: infrastructure
+ watchprojectFilePath: repository/openeuler.yaml
+ watchProjectFileRef: master
+ - watchProjectFileOwner: openeuler
+ watchprojectFileRepo: infrastructure
+ watchprojectFilePath: repository/src-openeuler.yaml
+ watchProjectFileRef: master
+ watchProjectFileDuration: 60
diff --git a/deploy/cce/deployment.yaml b/deploy/cce/deployment.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..9a467f5956663673c9e25078e59dc7e83632a888
--- /dev/null
+++ b/deploy/cce/deployment.yaml
@@ -0,0 +1,41 @@
+---
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+ name: botinfo
+ namespace: bot
+ labels:
+ app: botinfo
+ annotations:
+ flux.weave.works/automated: "true"
+ flux.weave.works/tag.nginxinfod: semver:~1.0
+spec:
+ strategy:
+ rollingUpdate:
+ maxUnavailable: 0
+ type: RollingUpdate
+ selector:
+ matchLabels:
+ app: botinfo
+ template:
+ metadata:
+ annotations:
+ prometheus.io/scrape: "true"
+ labels:
+ app: botinfo
+ spec:
+ containers:
+ - name: botinfod
+ image: swr.cn-south-1.myhuaweicloud.com/openeuler/bot:v1.0.201911121050334277
+ imagePullPolicy: IfNotPresent
+ ports:
+ - containerPort: 8888
+ name: http
+ protocol: TCP
+ volumeMounts:
+ - mountPath: /bot/
+ name: configmap-volume
+ volumes:
+ - name: configmap-volume
+ configMap:
+ name: bot-configmap
diff --git a/deploy/cce/namespace.yaml b/deploy/cce/namespace.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..867bbba9e0ccfe890936d4e46b06c05d079722d9
--- /dev/null
+++ b/deploy/cce/namespace.yaml
@@ -0,0 +1,6 @@
+apiVersion: v1
+kind: Namespace
+metadata:
+ labels:
+ name: bot
+ name: bot
diff --git a/deploy/cce/service.yaml b/deploy/cce/service.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..5458d055ec92e7103258cbfa27f1abc63b806417
--- /dev/null
+++ b/deploy/cce/service.yaml
@@ -0,0 +1,22 @@
+---
+apiVersion: v1
+kind: Service
+metadata:
+ name: botservice
+ namespace: bot
+ annotations:
+ kubernetes.io/elb.class: union
+ kubernetes.io/elb.id: e053029b-1898-4665-89eb-6ab598e448d7
+ kubernetes.io/elb.lb-algorithm: ROUND_ROBIN
+spec:
+ externalTrafficPolicy: Cluster
+ loadBalancerIP: 159.138.49.225
+ ports:
+ - name: httpport
+ protocol: TCP
+ port: 8888
+ targetPort: 8888
+ nodePort: 31200
+ selector:
+ app: botinfo
+ type: LoadBalancer
diff --git a/deploy/locally/README.md b/deploy/locally/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..3931cefb6a4a2a01c386828f47aff7e8596c9137
--- /dev/null
+++ b/deploy/locally/README.md
@@ -0,0 +1,19 @@
+# Getting Started on Locally
+
+## Build
+
+Before you get started, make sure to have [Go](https://golang.org/) already installed in your local machine.
+
+```
+$ mkdir -p $GOPATH/src/gitee.com/openeuler
+$ cd $GOPATH/src/gitee.com/openeuler
+$ git clone https://gitee.com/openeuler/ci-bot
+$ cd ci-bot
+$ make
+```
+
+## Usage
+
+```
+$ ./ci-bot
+```
\ No newline at end of file
diff --git a/docs/images/architecture.png b/docs/images/architecture.png
new file mode 100644
index 0000000000000000000000000000000000000000..3513b4f97ffdedf36b1b1d376fcb21d4353c4e5b
Binary files /dev/null and b/docs/images/architecture.png differ
diff --git a/go.mod b/go.mod
new file mode 100644
index 0000000000000000000000000000000000000000..b85ab544f77611a16c4c26c2ba4542eb433c5395
--- /dev/null
+++ b/go.mod
@@ -0,0 +1,17 @@
+module gitee.com/openeuler/ci-bot
+
+go 1.13
+
+require (
+ gitee.com/openeuler/go-gitee v0.0.0-20200320051710-5687412fb922
+ github.com/antihax/optional v1.0.0
+ github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b
+ github.com/golang/protobuf v1.3.2 // indirect
+ github.com/jinzhu/gorm v1.9.11
+ github.com/kr/pretty v0.1.0 // indirect
+ github.com/spf13/pflag v1.0.5
+ golang.org/x/net v0.0.0-20190923162816-aa69164e4478 // indirect
+ golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45
+ google.golang.org/appengine v1.6.3 // indirect
+ gopkg.in/yaml.v2 v2.2.2
+)
diff --git a/go.sum b/go.sum
new file mode 100644
index 0000000000000000000000000000000000000000..2292421741e719765d3480c08be238610105b1c6
--- /dev/null
+++ b/go.sum
@@ -0,0 +1,165 @@
+cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
+cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
+cloud.google.com/go v0.37.4 h1:glPeL3BQJsbF6aIIYfZizMwc5LTYz250bDMjttbBGAU=
+cloud.google.com/go v0.37.4/go.mod h1:NHPJ89PdicEuT9hdPXMROBD91xc5uRDxsMtSB16k7hw=
+gitee.com/openeuler/go-gitee v0.0.0-20200320051710-5687412fb922 h1:tH5xYCmBLUEgqr8QaplXvk7ciguomHNPY5sJVHFtsBI=
+gitee.com/openeuler/go-gitee v0.0.0-20200320051710-5687412fb922/go.mod h1:TQrS/LP/DFXLqM+lVrZd4nL2pbTrqiXABGT9PJepVTA=
+github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
+github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo=
+github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI=
+github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
+github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
+github.com/antihax/optional v1.0.0 h1:xK2lYat7ZLaVVcIuj82J8kIro4V6kDe0AUDFboUCwcg=
+github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
+github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ=
+github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
+github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
+github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/denisenkom/go-mssqldb v0.0.0-20190515213511-eb9f6a1743f3 h1:tkum0XDgfR0jcVVXuTsYv/erY2NnEDqwRojbxR1rBYA=
+github.com/denisenkom/go-mssqldb v0.0.0-20190515213511-eb9f6a1743f3/go.mod h1:zAg7JM8CkOJ43xKXIj7eRO9kmWm/TW578qo+oDO6tuM=
+github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs=
+github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU=
+github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I=
+github.com/erikstmartin/go-testdb v0.0.0-20160219214506-8d10e4a1bae5 h1:Yzb9+7DPaBjB8zlTR87/ElzFsnQfuHnVUVqpZZIcV5Y=
+github.com/erikstmartin/go-testdb v0.0.0-20160219214506-8d10e4a1bae5/go.mod h1:a2zkGnVExMxdzMo3M0Hi/3sEU+cWnZpSni0O6/Yb/P0=
+github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
+github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
+github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
+github.com/go-sql-driver/mysql v1.4.1 h1:g24URVg0OFbNUTx9qqY1IRZ9D9z3iPyi5zKhQZpNwpA=
+github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
+github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
+github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
+github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
+github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58=
+github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
+github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
+github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
+github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
+github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
+github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs=
+github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
+github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
+github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
+github.com/google/go-cmp v0.2.0 h1:+dTQ8DZQJz0Mb/HjFlkptS1FeQ4cWSnN941F8aEG4SQ=
+github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
+github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
+github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
+github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
+github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg=
+github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
+github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
+github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
+github.com/jinzhu/gorm v1.9.11 h1:gaHGvE+UnWGlbWG4Y3FUwY1EcZ5n6S9WtqBA/uySMLE=
+github.com/jinzhu/gorm v1.9.11/go.mod h1:bu/pK8szGZ2puuErfU0RwyeNdsf3e6nCX/noXaVxkfw=
+github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E=
+github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
+github.com/jinzhu/now v1.0.1 h1:HjfetcXq097iXP0uoPCdnM4Efp5/9MsM0/M+XOTeR3M=
+github.com/jinzhu/now v1.0.1/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
+github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
+github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
+github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
+github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
+github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
+github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
+github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
+github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
+github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
+github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
+github.com/lib/pq v1.1.1 h1:sJZmqHoEaY7f+NPP8pgLB/WxulyR3fewgCM2qaSlBb4=
+github.com/lib/pq v1.1.1/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
+github.com/mattn/go-sqlite3 v1.11.0 h1:LDdKkqtYlom37fkvqs8rMPFKAMe8+SgjbwZ6ex1/A/Q=
+github.com/mattn/go-sqlite3 v1.11.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
+github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
+github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
+github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
+github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
+github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
+github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw=
+github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=
+github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
+github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
+github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
+github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs=
+github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
+github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
+github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
+github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
+github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
+github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
+github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
+github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
+github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
+github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
+github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
+go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk=
+golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
+golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
+golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
+golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5 h1:58fnuSXlxZmFdJyvtTFVmVhcMLU6v5fEb/ok4wyqtNU=
+golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
+golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
+golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
+golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
+golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
+golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
+golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
+golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
+golang.org/x/net v0.0.0-20190923162816-aa69164e4478 h1:l5EDrHhldLYb3ZRHDUhXF7Om7MvYXnkV9/iQNo1lX6g=
+golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
+golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
+golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45 h1:SVwTIAaPC2U/AvvLNZ2a7OVsmBpC8L5BlwK1whH3hm0=
+golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
+golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
+golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
+golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
+golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
+golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
+golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
+golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
+golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
+golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
+golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
+google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk=
+google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
+google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
+google.golang.org/appengine v1.6.3 h1:hvZejVcIxAKHR8Pq2gXaDggf6CWT1QEqO+JEBeOKCG8=
+google.golang.org/appengine v1.6.3/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0=
+google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
+google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
+google.golang.org/genproto v0.0.0-20190404172233-64821d5d2107/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
+google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs=
+google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
+gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
+gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
+gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
+gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
+gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
+gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
+gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
+gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
+honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
+honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
+honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
diff --git a/pkg/cibot/approve.go b/pkg/cibot/approve.go
new file mode 100644
index 0000000000000000000000000000000000000000..2b24e90877808ace59b5b8d38c0cf626aa865150
--- /dev/null
+++ b/pkg/cibot/approve.go
@@ -0,0 +1,183 @@
+package cibot
+
+import (
+ "fmt"
+
+ "gitee.com/openeuler/go-gitee/gitee"
+ "github.com/antihax/optional"
+ "github.com/golang/glog"
+)
+
+const (
+ approvedAddedMessage = `***approved*** is added in this pull request by: ***@%s***. :wave: `
+ approvedRemovedMessage = `***approved*** is removed in this pull request by: ***@%s***. :flushed: `
+ approvedAddNoPermissionMessage = `***@%s*** has no permission to add ***approved*** in this pull request. :astonished:
+please contact to the collaborators in this repository.`
+ approvedRemoveNoPermissionMessage = `***@%s*** has no permission to remove ***approved*** in this pull request. :astonished:
+please contact to the collaborators in this repository.`
+)
+
+// AddApprove adds approved label
+func (s *Server) AddApprove(event *gitee.NoteEvent) error {
+ // handle PullRequest
+ if *event.NoteableType == "PullRequest" {
+ // handle open
+ if event.PullRequest.State == "open" {
+ // get basic params
+ comment := event.Comment.Body
+ owner := event.Repository.Namespace
+ repo := event.Repository.Name
+ prAuthor := event.PullRequest.User.Login
+ prNumber := event.PullRequest.Number
+ commentAuthor := event.Comment.User.Login
+ glog.Infof("add approve started. comment: %s prAuthor: %s commentAuthor: %s owner: %s repo: %s number: %d",
+ comment, prAuthor, commentAuthor, owner, repo, prNumber)
+
+ // check if current author has write permission
+ localVarOptionals := &gitee.GetV5ReposOwnerRepoCollaboratorsUsernamePermissionOpts{}
+ localVarOptionals.AccessToken = optional.NewString(s.Config.GiteeToken)
+ // get permission
+ permission, _, err := s.GiteeClient.RepositoriesApi.GetV5ReposOwnerRepoCollaboratorsUsernamePermission(
+ s.Context, owner, repo, commentAuthor, localVarOptionals)
+ if err != nil {
+ glog.Errorf("unable to get comment author permission: %v", err)
+ return err
+ }
+ // check author is owner
+ isOwner := s.CheckIsOwner(event, commentAuthor)
+
+ // check sigs
+ r, err := canCommentPrIncludingSigDirectory(s, owner, repo, prNumber, commentAuthor)
+ glog.Infof("sig owners check: can comment, r=%v, err=%v\n", r, err)
+ if err != nil {
+ glog.Errorf("unable to check sigs permission: %v", err)
+ return err
+ }
+
+ // permission: admin, write, read, none
+ if permission.Permission == "admin" || permission.Permission == "write" || isOwner || r == 1 {
+ // add approved label
+ addlabel := &gitee.NoteEvent{}
+ addlabel.PullRequest = event.PullRequest
+ addlabel.Repository = event.Repository
+ addlabel.Comment = &gitee.NoteHook{}
+ err = s.AddSpecifyLabelsInPulRequest(addlabel, []string{LabelNameApproved}, false)
+ if err != nil {
+ return err
+ }
+ // add comment
+ body := gitee.PullRequestCommentPostParam{}
+ body.AccessToken = s.Config.GiteeToken
+ body.Body = fmt.Sprintf(approvedAddedMessage, commentAuthor)
+ owner := event.Repository.Namespace
+ repo := event.Repository.Name
+ number := event.PullRequest.Number
+ _, _, err := s.GiteeClient.PullRequestsApi.PostV5ReposOwnerRepoPullsNumberComments(s.Context, owner, repo, number, body)
+ if err != nil {
+ glog.Errorf("unable to add comment in pull request: %v", err)
+ return err
+ }
+ // try to merge pr
+ err = s.MergePullRequest(event)
+ if err != nil {
+ return err
+ }
+ } else {
+ // add comment
+ body := gitee.PullRequestCommentPostParam{}
+ body.AccessToken = s.Config.GiteeToken
+ body.Body = fmt.Sprintf(approvedAddNoPermissionMessage, commentAuthor)
+ owner := event.Repository.Namespace
+ repo := event.Repository.Name
+ number := event.PullRequest.Number
+ _, _, err := s.GiteeClient.PullRequestsApi.PostV5ReposOwnerRepoPullsNumberComments(s.Context, owner, repo, number, body)
+ if err != nil {
+ glog.Errorf("unable to add comment in pull request: %v", err)
+ return err
+ }
+ }
+ }
+ }
+ return nil
+}
+
+// RemoveApprove removes approved label
+func (s *Server) RemoveApprove(event *gitee.NoteEvent) error {
+ // handle PullRequest
+ if *event.NoteableType == "PullRequest" {
+ // handle open
+ if event.PullRequest.State == "open" {
+ // get basic params
+ comment := event.Comment.Body
+ owner := event.Repository.Namespace
+ repo := event.Repository.Name
+ prAuthor := event.PullRequest.User.Login
+ prNumber := event.PullRequest.Number
+ commentAuthor := event.Comment.User.Login
+ glog.Infof("remove approve started. comment: %s prAuthor: %s commentAuthor: %s owner: %s repo: %s number: %d",
+ comment, prAuthor, commentAuthor, owner, repo, prNumber)
+
+ // check if current author has write permission
+ localVarOptionals := &gitee.GetV5ReposOwnerRepoCollaboratorsUsernamePermissionOpts{}
+ localVarOptionals.AccessToken = optional.NewString(s.Config.GiteeToken)
+ // get permission
+ permission, _, err := s.GiteeClient.RepositoriesApi.GetV5ReposOwnerRepoCollaboratorsUsernamePermission(
+ s.Context, owner, repo, commentAuthor, localVarOptionals)
+ if err != nil {
+ glog.Errorf("unable to get comment author permission: %v", err)
+ return err
+ }
+ // check author is owner
+ isOwner := s.CheckIsOwner(event, commentAuthor)
+
+ // check sigs
+ r, err := canCommentPrIncludingSigDirectory(s, owner, repo, prNumber, commentAuthor)
+ glog.Infof("sig owners check: can comment, r=%v, err=%v\n", r, err)
+ if err != nil {
+ glog.Errorf("unable to check sigs permission: %v", err)
+ return err
+ }
+
+ // permission: admin, write, read, none
+ if permission.Permission == "admin" || permission.Permission == "write" || isOwner || r == 1 {
+ // remove approved label
+ removelabel := &gitee.NoteEvent{}
+ removelabel.PullRequest = event.PullRequest
+ removelabel.Repository = event.Repository
+ removelabel.Comment = &gitee.NoteHook{}
+ mapOfRemoveLabels := map[string]string{}
+ mapOfRemoveLabels[LabelNameApproved] = LabelNameApproved
+ err = s.RemoveSpecifyLabelsInPulRequest(removelabel, mapOfRemoveLabels)
+ if err != nil {
+ return err
+ }
+ // add comment
+ body := gitee.PullRequestCommentPostParam{}
+ body.AccessToken = s.Config.GiteeToken
+ body.Body = fmt.Sprintf(approvedRemovedMessage, commentAuthor)
+ owner := event.Repository.Namespace
+ repo := event.Repository.Name
+ number := event.PullRequest.Number
+ _, _, err := s.GiteeClient.PullRequestsApi.PostV5ReposOwnerRepoPullsNumberComments(s.Context, owner, repo, number, body)
+ if err != nil {
+ glog.Errorf("unable to add comment in pull request: %v", err)
+ return err
+ }
+ } else {
+ // add comment
+ body := gitee.PullRequestCommentPostParam{}
+ body.AccessToken = s.Config.GiteeToken
+ body.Body = fmt.Sprintf(approvedRemoveNoPermissionMessage, commentAuthor)
+ owner := event.Repository.Namespace
+ repo := event.Repository.Name
+ number := event.PullRequest.Number
+ _, _, err := s.GiteeClient.PullRequestsApi.PostV5ReposOwnerRepoPullsNumberComments(s.Context, owner, repo, number, body)
+ if err != nil {
+ glog.Errorf("unable to add comment in pull request: %v", err)
+ return err
+ }
+ }
+ }
+ }
+ return nil
+}
diff --git a/pkg/cibot/assign.go b/pkg/cibot/assign.go
new file mode 100644
index 0000000000000000000000000000000000000000..8ed6ab2679d31e8ec473a70071fa8ad8478c7567
--- /dev/null
+++ b/pkg/cibot/assign.go
@@ -0,0 +1,108 @@
+package cibot
+
+import (
+ "fmt"
+ "strings"
+
+ "gitee.com/openeuler/go-gitee/gitee"
+ "github.com/golang/glog"
+)
+
+const (
+ issueAssignMessage = `this issue is assigned to: ***@%s***.`
+ issueCanNotAssignMessage = `this issue can not be assigned to: ***@%s***.
+please try to assign to the repository collaborators.`
+ issueNoNeedAssignMessage = `this issue is already assigned to: ***@%s***.
+please do not assign repeatedly.`
+)
+
+// Assign a collaborator for issue
+func (s *Server) Assign(event *gitee.NoteEvent) error {
+ if *event.NoteableType == "Issue" {
+ // handle open
+ if event.Issue.State == "open" {
+ // get basic informations
+ comment := event.Comment.Body
+ owner := event.Repository.Namespace
+ repo := event.Repository.Name
+ issueNumber := event.Issue.Number
+ issueAuthor := event.Issue.User.Login
+ commentAuthor := event.Comment.User.Login
+ glog.Infof("assign started. comment: %s owner: %s repo: %s issueNumber: %s issueAuthor: %s commentAuthor: %s",
+ comment, owner, repo, issueNumber, issueAuthor, commentAuthor)
+
+ // split the assignees and operation to be performed.
+ substrings := strings.Split(comment, "@")
+ // default is comment author
+ assignee := commentAuthor
+ if len(substrings) > 1 {
+ assignee = strings.TrimSpace(substrings[1])
+ }
+
+ // if issue assignee is the same with assignee
+ issueAssignee := ""
+ if event.Issue.Assignee != nil {
+ issueAssignee = event.Issue.Assignee.Login
+ }
+
+ if issueAssignee != assignee {
+ body := gitee.IssueUpdateParam{}
+ body.Repo = repo
+ body.Assignee = assignee
+ body.AccessToken = s.Config.GiteeToken
+ // build label string
+ var strLabel string
+ for _, l := range event.Issue.Labels {
+ strLabel += l.Name + ","
+ }
+ strLabel = strings.TrimRight(strLabel, ",")
+ if strLabel == "" {
+ strLabel = ","
+ }
+ body.Labels = strLabel
+
+ glog.Infof("invoke api to assign: %s", issueNumber)
+
+ // patch assignee
+ _, response, err := s.GiteeClient.IssuesApi.PatchV5ReposOwnerIssuesNumber(s.Context, owner, issueNumber, body)
+ if err != nil {
+ if response.StatusCode == 403 {
+ glog.Infof("unable to assign with status code %d: %s", response.StatusCode, issueNumber)
+ // add comment
+ body := gitee.IssueCommentPostParam{}
+ body.AccessToken = s.Config.GiteeToken
+ body.Body = fmt.Sprintf(issueCanNotAssignMessage, assignee)
+ _, _, err := s.GiteeClient.IssuesApi.PostV5ReposOwnerRepoIssuesNumberComments(s.Context, owner, repo, issueNumber, body)
+ if err != nil {
+ glog.Errorf("unable to add comment in issue: %v", err)
+ }
+ } else {
+ glog.Errorf("unable to assign: %s err: %v", issueNumber, err)
+ return err
+ }
+ } else {
+ glog.Infof("assign successfully: %v", issueNumber)
+ // add comment
+ body := gitee.IssueCommentPostParam{}
+ body.AccessToken = s.Config.GiteeToken
+ body.Body = fmt.Sprintf(issueAssignMessage, assignee)
+ _, _, err := s.GiteeClient.IssuesApi.PostV5ReposOwnerRepoIssuesNumberComments(s.Context, owner, repo, issueNumber, body)
+ if err != nil {
+ glog.Errorf("unable to add comment in issue: %v", err)
+ }
+ }
+ } else {
+ glog.Infof("already assign: %v", issueNumber)
+ // add comment
+ body := gitee.IssueCommentPostParam{}
+ body.AccessToken = s.Config.GiteeToken
+ body.Body = fmt.Sprintf(issueNoNeedAssignMessage, assignee)
+ _, _, err := s.GiteeClient.IssuesApi.PostV5ReposOwnerRepoIssuesNumberComments(s.Context, owner, repo, issueNumber, body)
+ if err != nil {
+ glog.Errorf("unable to add comment in issue: %v", err)
+ }
+ }
+ }
+ }
+ return nil
+}
diff --git a/pkg/cibot/checkcla.go b/pkg/cibot/checkcla.go
new file mode 100644
index 0000000000000000000000000000000000000000..c7272c91338f868eeb6c800816e5a1e17d414922
--- /dev/null
+++ b/pkg/cibot/checkcla.go
@@ -0,0 +1,196 @@
+package cibot
+
+import (
+ "fmt"
+ "strings"
+
+ "gitee.com/openeuler/ci-bot/pkg/cibot/database"
+ "gitee.com/openeuler/go-gitee/gitee"
+ "github.com/golang/glog"
+)
+
+const (
+ claNotFoundMessage = `Thanks for your pull request.
+**Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA).**
+**Please follow instructions at <%s> to sign the CLA.**
+It may take a couple minutes for the CLA signature to be fully registered;
+after that, please reply here with a new comment **/check-cla** and we'll verify.
+- If you've already signed a CLA, it's possible we don't have your Gitee username or you're using a different email address.
+ Check your existing CLA data and verify that your email at .
+- If you have done the above and are still having issues with the CLA being reported as unsigned,
+ send a message to the backup e-mail support address at: %s
+`
+ claFoundMessage = `Thanks for your pull request. you've already signed %s CLA successfully. :wave: `
+)
+
+// CheckCLAByNoteEvent check cla by NoteEvent
+func (s *Server) CheckCLAByNoteEvent(event *gitee.NoteEvent) error {
+ if *event.NoteableType == "PullRequest" {
+ // PullRequest
+ email := event.PullRequest.User.Email
+ // check the email from sender
+ var lenEmail int
+ err := database.DBConnection.Model(&database.CLADetails{}).
+ Where("email = ?", email).Count(&lenEmail).Error
+ if err != nil {
+ glog.Errorf("failed to check user email: %v", err)
+ return err
+ }
+ if lenEmail > 0 {
+ // add label openeuler-cla/yes
+ addlabel := &gitee.NoteEvent{}
+ addlabel.PullRequest = event.PullRequest
+ addlabel.Repository = event.Repository
+ addlabel.Comment = &gitee.NoteHook{}
+ addlabel.Comment.Body = fmt.Sprintf(AddClaYes, strings.ToLower(s.Config.CommunityName))
+ err = s.AddLabelInPulRequest(addlabel)
+ if err != nil {
+ return err
+ }
+
+ // remove label openeuler-cla/no
+ removelabel := &gitee.NoteEvent{}
+ removelabel.PullRequest = event.PullRequest
+ removelabel.Repository = event.Repository
+ removelabel.Comment = &gitee.NoteHook{}
+ removelabel.Comment.Body = fmt.Sprintf(RemoveClaNo, strings.ToLower(s.Config.CommunityName))
+ err = s.RemoveLabelInPullRequest(removelabel)
+ if err != nil {
+ return err
+ }
+
+ // add comment
+ body := gitee.PullRequestCommentPostParam{}
+ body.AccessToken = s.Config.GiteeToken
+ body.Body = fmt.Sprintf(claFoundMessage, s.Config.CommunityName)
+ owner := event.Repository.Namespace
+ repo := event.Repository.Name
+ number := event.PullRequest.Number
+ _, _, err = s.GiteeClient.PullRequestsApi.PostV5ReposOwnerRepoPullsNumberComments(s.Context, owner, repo, number, body)
+ if err != nil {
+ glog.Errorf("unable to add comment in pull request: %v", err)
+ return err
+ }
+ } else {
+ // add label openeuler-cla/no
+ addlabel := &gitee.NoteEvent{}
+ addlabel.PullRequest = event.PullRequest
+ addlabel.Repository = event.Repository
+ addlabel.Comment = &gitee.NoteHook{}
+ addlabel.Comment.Body = fmt.Sprintf(AddClaNo, strings.ToLower(s.Config.CommunityName))
+ err = s.AddLabelInPulRequest(addlabel)
+ if err != nil {
+ return err
+ }
+
+ // remove label openeuler-cla/yes
+ removelabel := &gitee.NoteEvent{}
+ removelabel.PullRequest = event.PullRequest
+ removelabel.Repository = event.Repository
+ removelabel.Comment = &gitee.NoteHook{}
+ removelabel.Comment.Body = fmt.Sprintf(RemoveClaYes, strings.ToLower(s.Config.CommunityName))
+ err = s.RemoveLabelInPullRequest(removelabel)
+ if err != nil {
+ return err
+ }
+
+ // add comment
+ body := gitee.PullRequestCommentPostParam{}
+ body.AccessToken = s.Config.GiteeToken
+ body.Body = fmt.Sprintf(claNotFoundMessage, s.Config.ClaLink, s.Config.ContactEmail)
+ owner := event.Repository.Namespace
+ repo := event.Repository.Name
+ number := event.PullRequest.Number
+ _, _, err = s.GiteeClient.PullRequestsApi.PostV5ReposOwnerRepoPullsNumberComments(s.Context, owner, repo, number, body)
+ if err != nil {
+ glog.Errorf("unable to add comment in pull request: %v", err)
+ return err
+ }
+ }
+ }
+ return nil
+}
+
+// CheckCLAByPullRequestEvent check cla by PullRequestEvent
+func (s *Server) CheckCLAByPullRequestEvent(event *gitee.PullRequestEvent) error {
+ // check the email from sender
+ var lenEmail int
+ err := database.DBConnection.Model(&database.CLADetails{}).
+ Where("email = ?", event.Sender.Email).Count(&lenEmail).Error
+ if err != nil {
+ glog.Errorf("failed to check user email: %v", err)
+ return err
+ }
+ if lenEmail > 0 {
+ // add label openeuler-cla/yes
+ addlabel := &gitee.NoteEvent{}
+ addlabel.PullRequest = event.PullRequest
+ addlabel.Repository = event.Repository
+ addlabel.Comment = &gitee.NoteHook{}
+ addlabel.Comment.Body = fmt.Sprintf(AddClaYes, strings.ToLower(s.Config.CommunityName))
+ err = s.AddLabelInPulRequest(addlabel)
+ if err != nil {
+ return err
+ }
+
+ // remove label openeuler-cla/no
+ removelabel := &gitee.NoteEvent{}
+ removelabel.PullRequest = event.PullRequest
+ removelabel.Repository = event.Repository
+ removelabel.Comment = &gitee.NoteHook{}
+ removelabel.Comment.Body = fmt.Sprintf(RemoveClaNo, strings.ToLower(s.Config.CommunityName))
+ err = s.RemoveLabelInPullRequest(removelabel)
+ if err != nil {
+ return err
+ }
+
+ // add comment
+ body := gitee.PullRequestCommentPostParam{}
+ body.AccessToken = s.Config.GiteeToken
+ body.Body = fmt.Sprintf(claFoundMessage, s.Config.CommunityName)
+ owner := event.Repository.Namespace
+ repo := event.Repository.Name
+ number := event.PullRequest.Number
+ _, _, err = s.GiteeClient.PullRequestsApi.PostV5ReposOwnerRepoPullsNumberComments(s.Context, owner, repo, number, body)
+ if err != nil {
+ glog.Errorf("unable to add comment in pull request: %v", err)
+ return err
+ }
+ } else {
+ // add label openeuler-cla/no
+ addlabel := &gitee.NoteEvent{}
+ addlabel.PullRequest = event.PullRequest
+ addlabel.Repository = event.Repository
+ addlabel.Comment = &gitee.NoteHook{}
+ addlabel.Comment.Body = fmt.Sprintf(AddClaNo, strings.ToLower(s.Config.CommunityName))
+ err = s.AddLabelInPulRequest(addlabel)
+ if err != nil {
+ return err
+ }
+
+ // remove label openeuler-cla/yes
+ removelabel := &gitee.NoteEvent{}
+ removelabel.PullRequest = event.PullRequest
+ removelabel.Repository = event.Repository
+ removelabel.Comment = &gitee.NoteHook{}
+ removelabel.Comment.Body = fmt.Sprintf(RemoveClaYes, strings.ToLower(s.Config.CommunityName))
+ err = s.RemoveLabelInPullRequest(removelabel)
+ if err != nil {
+ return err
+ }
+
+ // add comment
+ body := gitee.PullRequestCommentPostParam{}
+ body.AccessToken = s.Config.GiteeToken
+ body.Body = fmt.Sprintf(claNotFoundMessage, s.Config.ClaLink, s.Config.ContactEmail)
+ owner := event.Repository.Namespace
+ repo := event.Repository.Name
+ number := event.PullRequest.Number
+ _, _, err = s.GiteeClient.PullRequestsApi.PostV5ReposOwnerRepoPullsNumberComments(s.Context, owner, repo, number, body)
+ if err != nil {
+ glog.Errorf("unable to add comment in pull request: %v", err)
+ return err
+ }
+ }
+ return nil
+}
diff --git a/pkg/cibot/clahandler.go b/pkg/cibot/clahandler.go
new file mode 100644
index 0000000000000000000000000000000000000000..9dfaf6e47f61ad09427e9a4cd4592b22c7919497
--- /dev/null
+++ b/pkg/cibot/clahandler.go
@@ -0,0 +1,400 @@
+package cibot
+
+import (
+ "context"
+ "encoding/json"
+ "fmt"
+ "io/ioutil"
+ "net/http"
+ "os"
+
+ "gitee.com/openeuler/ci-bot/pkg/cibot/database"
+ "gitee.com/openeuler/go-gitee/gitee"
+ "github.com/golang/glog"
+ "golang.org/x/oauth2"
+)
+
+type CLAHandler struct {
+ Context context.Context
+}
+
+type CLARequest struct {
+ Type int `json:"type,omitempty"`
+ Name *string `json:"name,omitempty"`
+ Title *string `json:"title,omitempty"`
+ Corporation *string `json:"corporation,omitempty"`
+ Address *string `json:"address,omitempty"`
+ Date *string `json:"date,omitempty"`
+ Email *string `json:"email,omitempty"`
+ Telephone *string `json:"telephone,omitempty"`
+ Fax *string `json:"fax,omitempty"`
+}
+
+type CLAResult struct {
+ IsSuccess bool `json:"isSuccess"`
+ ErrorCode int `json:"errorCode"`
+ Description string `json:"description,omitempty"`
+}
+
+const (
+ ErrorCode_OK = iota
+ ErrorCode_ServerHandleError
+ ErrorCode_EmailError
+ ErrorCode_TelephoneError
+ ErrorCode_EmailNotTheSameError
+)
+
+const COOKIE_KEY string = "cla-info"
+
+// ServeHTTP validates an incoming cla request.
+func (s *CLAHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
+ glog.Info("received a cla request")
+ if r.Method == "POST" {
+ // add logs
+ glog.Infof("CLA Request Header: %v", r.Header)
+ glog.Infof("CLA Request Host: %v", r.Host)
+ glog.Infof("CLA Request RemoteAddr: %v", r.RemoteAddr)
+
+ // read body
+ body, err := ioutil.ReadAll(r.Body)
+ if err != nil {
+ s.HandleResult(w, CLAResult{
+ IsSuccess: false,
+ Description: fmt.Sprintf("read body error: %v", err),
+ ErrorCode: ErrorCode_ServerHandleError,
+ })
+ return
+ }
+
+ // unmarshal request
+ var clarequest CLARequest
+ err = json.Unmarshal(body, &clarequest)
+ if err != nil {
+ s.HandleResult(w, CLAResult{
+ IsSuccess: false,
+ Description: fmt.Sprintf("unmarshal json error: %v", err),
+ ErrorCode: ErrorCode_ServerHandleError,
+ })
+ return
+ }
+
+ cookie, err := r.Cookie(COOKIE_KEY)
+ if err != nil {
+ glog.Infof("Get cookie err: %v", err)
+ }
+
+ glog.Infof("cla request content: %v", clarequest)
+ s.HandleRequest(w, clarequest, cookie.Value)
+ } else if r.Method == "GET" {
+ codes, ok := r.URL.Query()["code"]
+ if !ok || len(codes[0]) <= 0 {
+ s.HandleResult(w, CLAResult{
+ IsSuccess: false,
+ Description: fmt.Sprintf("code is nil"),
+ ErrorCode: ErrorCode_ServerHandleError,
+ })
+ return
+ }
+
+ code := codes[0]
+
+ s.HandleClaCheck(w, r, code)
+
+ } else if r.Method == "OPTIONS" {
+ // CORS
+ w.Header().Set("Access-Control-Allow-Origin", "*")
+ w.Header().Set("Access-Control-Allow-Headers", "Content-Type")
+ glog.Infof("finish request method: %s", r.Method)
+ } else {
+ glog.Infof("unsupport request method: %s", r.Method)
+ }
+}
+
+func (s *CLAHandler) HandleClaCheck(w http.ResponseWriter, r *http.Request, code string) {
+ accesskey := ""
+ cookie, err := r.Cookie(COOKIE_KEY)
+ if err == nil {
+ accesskey = cookie.Value
+ } else {
+ glog.Infof("Get cookie err: %v", err)
+ }
+
+ if accesskey == "" {
+
+ token, err := GetToken(code)
+
+ if err != nil {
+ s.HandleResult(w, CLAResult{
+ IsSuccess: false,
+ Description: fmt.Sprintf("request gitee user error: %v", err),
+ ErrorCode: ErrorCode_ServerHandleError,
+ })
+ return
+ }
+ accesskey = token.AccessToken
+ glog.Infof("access key get successfully.")
+ }
+
+ setCookie(w, COOKIE_KEY, accesskey)
+
+ emails, err := GetEmails(accesskey)
+ if err != nil {
+ s.HandleResult(w, CLAResult{
+ IsSuccess: false,
+ Description: fmt.Sprintf("request parameter error: %v", err),
+ ErrorCode: ErrorCode_ServerHandleError,
+ })
+ return
+ }
+
+ primaryEmail := ""
+
+ for _, email := range emails {
+ if email.State == "confirmed" {
+ for _, t := range email.Scope {
+ if t == "primary" {
+ primaryEmail = email.Email
+ break
+ }
+ }
+ }
+ }
+
+ redirectUrl := os.Getenv("CLA_REDIRECT_URL")
+ if len(redirectUrl) == 0 {
+ redirectUrl = "/en/cla.html"
+ }
+
+ if primaryEmail != "" {
+
+ setCookie(w, "email", primaryEmail)
+
+ var clainfo database.CLADetails
+ err = database.DBConnection.Model(&database.CLADetails{}).
+ Where("email = ?", primaryEmail).First(&clainfo).Error
+ if err == nil && clainfo.Email != "" {
+
+ setCookie(w, "name", clainfo.Name)
+ setCookie(w, "type", fmt.Sprintf("%d", clainfo.Type))
+ setCookie(w, "title", clainfo.Title)
+ setCookie(w, "corporation", clainfo.Corporation)
+ setCookie(w, "address", clainfo.Address)
+ setCookie(w, "date", clainfo.Date)
+ setCookie(w, "email", clainfo.Email)
+ setCookie(w, "telephone", clainfo.Telephone)
+ setCookie(w, "fax", clainfo.Fax)
+
+ http.Redirect(w, r, redirectUrl, http.StatusFound)
+ return
+ }
+ }
+
+ http.Redirect(w, r, redirectUrl, http.StatusFound)
+
+}
+
+func setCookie(w http.ResponseWriter, key string, value string) {
+ cookie := http.Cookie{Name: key, Value: value, Path: "/", MaxAge: 86400}
+ http.SetCookie(w, &cookie)
+}
+
+// HandleResult output result to client
+func (s *CLAHandler) HandleResult(w http.ResponseWriter, r CLAResult) {
+ // log error code
+ if !r.IsSuccess {
+ glog.Errorf("handle result error code: %v description: %v",
+ r.ErrorCode, r.Description)
+ }
+
+ // constuct result
+ result, err := json.Marshal(r)
+ if err != nil {
+ glog.Errorf("marshal result error: %v", err)
+ return
+ }
+
+ // CORS
+ w.Header().Set("Access-Control-Allow-Origin", "*")
+ w.Header().Set("Access-Control-Allow-Headers", "Content-Type")
+ // Content type
+ w.Header().Set("Content-Type", "application/json; charset=utf-8")
+ if r.IsSuccess {
+ w.WriteHeader(http.StatusOK)
+ } else {
+ w.WriteHeader(http.StatusInternalServerError)
+ }
+ w.Write([]byte(result))
+}
+
+// HandleRequest handles the cla request
+func (s *CLAHandler) HandleRequest(w http.ResponseWriter, request CLARequest, accesskey string) {
+ // build model object
+ setCookie(w, COOKIE_KEY, accesskey)
+
+ emails, err := GetEmails(accesskey)
+ if err != nil {
+ s.HandleResult(w, CLAResult{
+ IsSuccess: false,
+ Description: fmt.Sprintf("request parameter error: %v", err),
+ ErrorCode: ErrorCode_ServerHandleError,
+ })
+ return
+ }
+
+ primaryEmail := ""
+
+ for _, email := range emails {
+ if email.State == "confirmed" {
+ for _, t := range email.Scope {
+ if t == "primary" {
+ primaryEmail = email.Email
+ break
+ }
+ }
+ }
+ }
+
+ if primaryEmail == "" || primaryEmail != *request.Email {
+ s.HandleResult(w, CLAResult{
+ IsSuccess: false,
+ Description: "The email is not the same as gitee account email.",
+ ErrorCode: ErrorCode_EmailNotTheSameError,
+ })
+ return
+ }
+
+ cds := database.CLADetails{
+ Type: request.Type,
+ }
+ if request.Name != nil {
+ cds.Name = *request.Name
+ }
+ if request.Title != nil {
+ cds.Title = *request.Title
+ }
+ if request.Corporation != nil {
+ cds.Corporation = *request.Corporation
+ }
+ if request.Address != nil {
+ cds.Address = *request.Address
+ }
+ if request.Date != nil {
+ cds.Date = *request.Date
+ }
+ if request.Email != nil {
+ cds.Email = *request.Email
+ }
+ if request.Telephone != nil {
+ cds.Telephone = *request.Telephone
+ }
+ if request.Fax != nil {
+ cds.Fax = *request.Fax
+ }
+
+ // tostring
+ data, err := cds.ToString()
+ if err != nil {
+ s.HandleResult(w, CLAResult{
+ IsSuccess: false,
+ Description: fmt.Sprintf("request tostring error: %v", err),
+ ErrorCode: ErrorCode_ServerHandleError,
+ })
+ return
+ }
+ glog.Infof("add cla details data: %s", data)
+
+ // Check email in database
+ var lenEmail int
+ err = database.DBConnection.Model(&database.CLADetails{}).
+ Where("email = ?", cds.Email).Count(&lenEmail).Error
+ if err != nil {
+ s.HandleResult(w, CLAResult{
+ IsSuccess: false,
+ Description: fmt.Sprintf("check email exitency error: %v", err),
+ ErrorCode: ErrorCode_ServerHandleError,
+ })
+ return
+ }
+ if lenEmail > 0 {
+ s.HandleResult(w, CLAResult{
+ IsSuccess: false,
+ Description: "email is already registered",
+ ErrorCode: ErrorCode_EmailError,
+ })
+ return
+ }
+
+ /* Check telephone in database
+ var lenTelephone int
+ err = database.DBConnection.Model(&database.CLADetails{}).
+ Where("telephone = ?", cds.Telephone).Count(&lenTelephone).Error
+ if err != nil {
+ s.HandleResult(w, CLAResult{
+ IsSuccess: false,
+ Description: fmt.Sprintf("check telephone exitency error: %v", err),
+ ErrorCode: ErrorCode_ServerHandleError,
+ })
+ return
+ }
+ if lenTelephone > 0 {
+ s.HandleResult(w, CLAResult{
+ IsSuccess: false,
+ Description: "telephone is already registered",
+ ErrorCode: ErrorCode_TelephoneError,
+ })
+ return
+ }*/
+
+ // add cla in database
+ err = database.DBConnection.Create(&cds).Error
+ if err != nil {
+ s.HandleResult(w, CLAResult{
+ IsSuccess: false,
+ Description: fmt.Sprintf("add cla details error: %v", err),
+ ErrorCode: ErrorCode_ServerHandleError,
+ })
+ return
+ }
+
+ // constuct result
+ s.HandleResult(w, CLAResult{
+ IsSuccess: true,
+ ErrorCode: ErrorCode_OK,
+ })
+}
+
+func GetUser(ak string) (gitee.User, error) {
+
+ ctx2 := context.Background()
+ ts := oauth2.StaticTokenSource(
+ &oauth2.Token{AccessToken: ak},
+ )
+
+ // configuration
+ giteeConf := gitee.NewConfiguration()
+ giteeConf.HTTPClient = oauth2.NewClient(ctx2, ts)
+
+ // git client
+ giteeClient := gitee.NewAPIClient(giteeConf)
+
+ user, _, err := giteeClient.UsersApi.GetV5User(ctx2, nil)
+ return user, err
+}
+
+func GetEmails(ak string) ([]gitee.Email, error) {
+ ctx2 := context.Background()
+ ts := oauth2.StaticTokenSource(
+ &oauth2.Token{AccessToken: ak},
+ )
+
+ // configuration
+ giteeConf := gitee.NewConfiguration()
+ giteeConf.HTTPClient = oauth2.NewClient(ctx2, ts)
+
+ // git client
+ giteeClient := gitee.NewAPIClient(giteeConf)
+
+ emails, _, err := giteeClient.EmailsApi.GetV5Emails(ctx2, nil)
+ return emails, err
+
+}
diff --git a/pkg/cibot/close.go b/pkg/cibot/close.go
new file mode 100644
index 0000000000000000000000000000000000000000..482691c1b743ea7c288a5e369aea535ce6c8ecfd
--- /dev/null
+++ b/pkg/cibot/close.go
@@ -0,0 +1,143 @@
+package cibot
+
+import (
+ "fmt"
+ "strings"
+
+ "github.com/antihax/optional"
+
+ "gitee.com/openeuler/go-gitee/gitee"
+ "github.com/golang/glog"
+)
+
+const (
+ closeIssueMessage = `this issue is closed by: ***@%s***.`
+ closePullRequestMessage = `this pull request is closed by: ***@%s***.`
+)
+
+// Close closes pr or issue
+func (s *Server) Close(event *gitee.NoteEvent) error {
+ // handle PullRequest
+ if *event.NoteableType == "PullRequest" {
+ // handle open
+ if event.PullRequest.State == "open" {
+ // get basic params
+ comment := event.Comment.Body
+ owner := event.Repository.Namespace
+ repo := event.Repository.Name
+ prAuthor := event.PullRequest.User.Login
+ prNumber := event.PullRequest.Number
+ commentAuthor := event.Comment.User.Login
+ glog.Infof("close started. comment: %s prAuthor: %s commentAuthor: %s owner: %s repo: %s number: %d",
+ comment, prAuthor, commentAuthor, owner, repo, prNumber)
+
+ // check if current author has write permission
+ localVarOptionals := &gitee.GetV5ReposOwnerRepoCollaboratorsUsernamePermissionOpts{}
+ localVarOptionals.AccessToken = optional.NewString(s.Config.GiteeToken)
+ // get permission
+ permission, _, err := s.GiteeClient.RepositoriesApi.GetV5ReposOwnerRepoCollaboratorsUsernamePermission(
+ s.Context, owner, repo, commentAuthor, localVarOptionals)
+ if err != nil {
+ glog.Errorf("unable to get comment author permission: %v", err)
+ return err
+ }
+ // permission: admin, write, read, none
+ if permission.Permission == "admin" || permission.Permission == "write" || prAuthor == commentAuthor {
+ // pr author or permission: admin, write
+ body := gitee.PullRequestUpdateParam{}
+ body.AccessToken = s.Config.GiteeToken
+ body.State = "closed"
+ glog.Infof("invoke api to close: %d", prNumber)
+
+ // patch state
+ _, response, err := s.GiteeClient.PullRequestsApi.PatchV5ReposOwnerRepoPullsNumber(s.Context, owner, repo, prNumber, body)
+ if err != nil {
+ if response.StatusCode == 400 {
+ glog.Infof("close successfully with status code %d: %d", response.StatusCode, prNumber)
+ } else {
+ glog.Errorf("unable to close: %d err: %v", prNumber, err)
+ return err
+ }
+ } else {
+ glog.Infof("close successfully: %v", prNumber)
+ }
+
+ // add comment
+ bodyComment := gitee.PullRequestCommentPostParam{}
+ bodyComment.AccessToken = s.Config.GiteeToken
+ bodyComment.Body = fmt.Sprintf(closePullRequestMessage, commentAuthor)
+ _, _, err = s.GiteeClient.PullRequestsApi.PostV5ReposOwnerRepoPullsNumberComments(s.Context, owner, repo, prNumber, bodyComment)
+ if err != nil {
+ glog.Errorf("unable to add comment in pull request: %v", err)
+ return err
+ }
+ return nil
+ }
+ }
+ } else if *event.NoteableType == "Issue" {
+ // handle open
+ if event.Issue.State == "open" {
+ // get basic informations
+ comment := event.Comment.Body
+ owner := event.Repository.Namespace
+ repo := event.Repository.Name
+ issueNumber := event.Issue.Number
+ issueAuthor := event.Issue.User.Login
+ commentAuthor := event.Comment.User.Login
+ glog.Infof("close started. comment: %s owner: %s repo: %s issueNumber: %s issueAuthor: %s commentAuthor: %s",
+ comment, owner, repo, issueNumber, issueAuthor, commentAuthor)
+
+ // check if current author has write permission
+ localVarOptionals := &gitee.GetV5ReposOwnerRepoCollaboratorsUsernamePermissionOpts{}
+ localVarOptionals.AccessToken = optional.NewString(s.Config.GiteeToken)
+ // get permission
+ permission, _, err := s.GiteeClient.RepositoriesApi.GetV5ReposOwnerRepoCollaboratorsUsernamePermission(
+ s.Context, owner, repo, commentAuthor, localVarOptionals)
+ if err != nil {
+ glog.Errorf("unable to get comment author permission: %v", err)
+ return err
+ }
+ // permission: admin, write, read, none
+ if permission.Permission == "admin" || permission.Permission == "write" || issueAuthor == commentAuthor {
+ // issue author or permission: admin, write
+ body := gitee.IssueUpdateParam{}
+ body.Repo = repo
+ body.AccessToken = s.Config.GiteeToken
+ body.State = "closed"
+ // build label string
+ var strLabel string
+ for _, l := range event.Issue.Labels {
+ strLabel += l.Name + ","
+ }
+ strLabel = strings.TrimRight(strLabel, ",")
+ if strLabel == "" {
+ strLabel = ","
+ }
+ body.Labels = strLabel
+ glog.Infof("invoke api to close: %s", issueNumber)
+
+ // patch state
+ _, response, err := s.GiteeClient.IssuesApi.PatchV5ReposOwnerIssuesNumber(s.Context, owner, issueNumber, body)
+ if err != nil {
+ if response.StatusCode == 400 {
+ glog.Infof("close successfully with status code %d: %s", response.StatusCode, issueNumber)
+ } else {
+ glog.Errorf("unable to close: %s err: %v", issueNumber, err)
+ return err
+ }
+ } else {
+ glog.Infof("close successfully: %v", issueNumber)
+ }
+ // add comment
+ bodyComment := gitee.IssueCommentPostParam{}
+ bodyComment.AccessToken = s.Config.GiteeToken
+ bodyComment.Body = fmt.Sprintf(closeIssueMessage, commentAuthor)
+ _, _, err = s.GiteeClient.IssuesApi.PostV5ReposOwnerRepoIssuesNumberComments(s.Context, owner, repo, issueNumber, bodyComment)
+ if err != nil {
+ glog.Errorf("unable to add comment in issue: %v", err)
+ }
+ }
+ }
+ }
+ return nil
+}
diff --git a/pkg/cibot/config/config.go b/pkg/cibot/config/config.go
new file mode 100644
index 0000000000000000000000000000000000000000..875d15b2320f0e9a87b9955a91111471169d0f37
--- /dev/null
+++ b/pkg/cibot/config/config.go
@@ -0,0 +1,45 @@
+package config
+
+type Config struct {
+ GiteeToken string `yaml:"giteeToken"`
+ WebhookSecret string `yaml:"webhookSecret"`
+ DataBaseType string `yaml:"databaseType"`
+ DataBaseHost string `yaml:"databaseHost"`
+ DataBasePort int `yaml:"databasePort"`
+ DataBaseName string `yaml:"databaseName"`
+ DataBaseUserName string `yaml:"databaseUserName"`
+ DataBasePassword string `yaml:"databasePassword"`
+ WatchProjectFiles []WatchProjectFile `yaml:"watchProjectFiles"`
+ WatchProjectFileDuration int `yaml:"watchProjectFileDuration"`
+ WatchSigFiles []WatchSigFile `yaml:"watchSigFiles"`
+ WatchSigFileDuration int `yaml:"watchSigFileDuration"`
+ WatchOwnerFiles []WatchOwnerFile `yaml:"watchOwnerFiles"`
+ WatchOwnerFileDuration int `yaml:"watchOwnerFileDuration"`
+ BotName string `yaml:"botName"`
+ CommunityName string `yaml:"communityName"`
+ ClaLink string `yaml:"claLink"`
+ CommandLink string `yaml:"commandLink"`
+ ContactEmail string `yaml:"contactEmail"`
+ LgtmCountsRequired int `yaml:"lgtmCountsRequired"`
+}
+
+type WatchProjectFile struct {
+ WatchProjectFileOwner string `yaml:"watchProjectFileOwner"`
+ WatchprojectFileRepo string `yaml:"watchprojectFileRepo"`
+ WatchprojectFilePath string `yaml:"watchprojectFilePath"`
+ WatchProjectFileRef string `yaml:"watchProjectFileRef"`
+}
+
+type WatchSigFile struct {
+ WatchSigFileOwner string `yaml:"watchSigFileOwner"`
+ WatchSigFileRepo string `yaml:"watchSigFileRepo"`
+ WatchSigFilePath string `yaml:"watchSigFilePath"`
+ WatchSigFileRef string `yaml:"watchSigFileRef"`
+}
+
+type WatchOwnerFile struct {
+ WatchOwnerFileOwner string `yaml:"watchOwnerFileOwner"`
+ WatchOwnerFileRepo string `yaml:"watchOwnerFileRepo"`
+ WatchOwnerFilePath string `yaml:"watchOwnerFilePath"`
+ WatchOwnerFileRef string `yaml:"watchOwnerFileRef"`
+}
diff --git a/pkg/cibot/database/branches.go b/pkg/cibot/database/branches.go
new file mode 100644
index 0000000000000000000000000000000000000000..be4b40595f597a02b6b3d22e00280dee5a71dfff
--- /dev/null
+++ b/pkg/cibot/database/branches.go
@@ -0,0 +1,57 @@
+package database
+
+import (
+ "encoding/json"
+ "fmt"
+
+ "github.com/jinzhu/gorm"
+)
+
+// BranchesTableName defines
+var BranchesTableName = "branches"
+
+// BranchesTableSQL matches with Branches Object
+var BranchesTableSQL = fmt.Sprintf(`CREATE TABLE %s (
+ id int(10) unsigned NOT NULL AUTO_INCREMENT,
+ created_at timestamp NULL DEFAULT NULL,
+ updated_at timestamp NULL DEFAULT NULL,
+ deleted_at timestamp NULL DEFAULT NULL,
+ owner varchar(255) DEFAULT NULL,
+ repo varchar(255) DEFAULT NULL,
+ name varchar(255) DEFAULT NULL,
+ type varchar(255) DEFAULT NULL,
+ additional_info text,
+ PRIMARY KEY (id)
+ ) ENGINE=InnoDB DEFAULT CHARSET=utf8`, BranchesTableName)
+
+// Branches defines
+type Branches struct {
+ gorm.Model
+ Owner string
+ Repo string
+ Name string
+ // "protected" or "readonly", only protected is supported yet
+ Type string
+ AdditionalInfo string `sql:"type:text"`
+}
+
+// GetAdditionalInfo for Branches
+func (bs Branches) GetAdditionalInfo(additionalinfo interface{}) error {
+ if bs.AdditionalInfo != "" {
+ err := json.Unmarshal([]byte(bs.AdditionalInfo), &additionalinfo)
+ if err != nil {
+ return err
+ }
+ }
+ return nil
+}
+
+// ToString for convert
+func (bs Branches) ToString() (string, error) {
+ // Marshal datas
+ datas, err := json.Marshal(bs)
+ if err != nil {
+ return "", fmt.Errorf("marshal branches failed. Error: %s", err)
+ }
+ return string(datas), nil
+}
diff --git a/pkg/cibot/database/cladetails.go b/pkg/cibot/database/cladetails.go
new file mode 100644
index 0000000000000000000000000000000000000000..4a3c90dacbc003d432873cbd69974cf61c86e004
--- /dev/null
+++ b/pkg/cibot/database/cladetails.go
@@ -0,0 +1,66 @@
+package database
+
+import (
+ "encoding/json"
+ "fmt"
+
+ "github.com/jinzhu/gorm"
+)
+
+// CLADetailsTableName defines
+var CLADetailsTableName = "cla_details"
+
+// CLADetailsTableSQL matches with CLADetails Object
+var CLADetailsTableSQL = fmt.Sprintf(`CREATE TABLE %s (
+ id int(10) unsigned NOT NULL AUTO_INCREMENT,
+ created_at timestamp NULL DEFAULT NULL,
+ updated_at timestamp NULL DEFAULT NULL,
+ deleted_at timestamp NULL DEFAULT NULL,
+ type int(10) unsigned DEFAULT NULL,
+ name varchar(255) DEFAULT NULL,
+ title varchar(255) DEFAULT NULL,
+ corporation varchar(255) DEFAULT NULL,
+ address varchar(255) DEFAULT NULL,
+ date varchar(255) DEFAULT NULL,
+ email varchar(255) DEFAULT NULL,
+ telephone varchar(255) DEFAULT NULL,
+ fax varchar(255) DEFAULT NULL,
+ additional_info text,
+ PRIMARY KEY (id)
+ ) ENGINE=InnoDB DEFAULT CHARSET=utf8`, CLADetailsTableName)
+
+// CLADetails defines
+type CLADetails struct {
+ gorm.Model
+ Type int
+ Name string
+ Title string
+ Corporation string
+ Address string
+ Date string
+ Email string
+ Telephone string
+ Fax string
+ AdditionalInfo string `sql:"type:text"`
+}
+
+// GetAdditionalInfo for CLADetails
+func (cds CLADetails) GetAdditionalInfo(additionalinfo interface{}) error {
+ if cds.AdditionalInfo != "" {
+ err := json.Unmarshal([]byte(cds.AdditionalInfo), &additionalinfo)
+ if err != nil {
+ return err
+ }
+ }
+ return nil
+}
+
+// ToString for convert
+func (cds CLADetails) ToString() (string, error) {
+ // Marshal operation datas
+ operationdatas, err := json.Marshal(cds)
+ if err != nil {
+ return "", fmt.Errorf("marshal operation details failed. Error: %s", err)
+ }
+ return string(operationdatas), nil
+}
diff --git a/pkg/cibot/database/database.go b/pkg/cibot/database/database.go
new file mode 100644
index 0000000000000000000000000000000000000000..c7b2b04c07d5b4da59772179ba0a1863241beee4
--- /dev/null
+++ b/pkg/cibot/database/database.go
@@ -0,0 +1,158 @@
+package database
+
+import (
+ "fmt"
+ "sync"
+
+ "gitee.com/openeuler/ci-bot/pkg/cibot/config"
+ "github.com/golang/glog"
+ "github.com/jinzhu/gorm"
+
+ // import mysql driver
+ _ "github.com/jinzhu/gorm/dialects/mysql"
+)
+
+// DBConnection is used to operate on database
+var DBConnection *gorm.DB
+
+// once is used to init DBConnection
+var once sync.Once
+
+// New Database Connection
+func New(config config.Config) error {
+ once.Do(func() {
+ // Connect DataBase
+ dbConnection, err := ConnectDataBase(config)
+ if err != nil {
+ glog.Errorf("connecting to database error: %v", err)
+ panic(err)
+ }
+ err = UpgradeDataBase(dbConnection)
+ if err != nil {
+ glog.Errorf("upgrading database error: %v", err)
+ panic(err)
+ }
+ DBConnection = dbConnection
+ })
+ return nil
+}
+
+// ConnectDataBase connect database
+func ConnectDataBase(config config.Config) (*gorm.DB, error) {
+ // connect to database
+ connStr := fmt.Sprintf(
+ "%v:%v@tcp(%v:%v)/%v?charset=utf8&parseTime=True&loc=Local",
+ config.DataBaseUserName,
+ config.DataBasePassword,
+ config.DataBaseHost,
+ config.DataBasePort,
+ config.DataBaseName)
+ glog.Infof("connecting str: %v", connStr)
+
+ return gorm.Open(config.DataBaseType, connStr)
+}
+
+// UpgradeDataBase upgrades tables and datas
+func UpgradeDataBase(db *gorm.DB) error {
+
+ // upgrades defines
+ upgrades := make([]func() error, 5)
+ upgrades[0] = func() error {
+ // table upgrades
+ if err := db.Exec(UpgradesTableSQL).Error; err != nil {
+ return err
+ }
+ // table cla_details
+ if err := db.Exec(CLADetailsTableSQL).Error; err != nil {
+ return err
+ }
+ return nil
+ }
+ upgrades[1] = func() error {
+ // table projectfiles
+ if err := db.Exec(ProjectFilesTableSQL).Error; err != nil {
+ return err
+ }
+ // table repositories
+ if err := db.Exec(RepositoriesTableSQL).Error; err != nil {
+ return err
+ }
+ // table privileges
+ if err := db.Exec(PrivilegesTableSQL).Error; err != nil {
+ return err
+ }
+ return nil
+ }
+ upgrades[2] = func() error {
+ // table branches
+ if err := db.Exec(BranchesTableSQL).Error; err != nil {
+ return err
+ }
+ return nil
+ }
+ upgrades[3] = func() error {
+ // table sigfiles
+ if err := db.Exec(SigFilesTableSQL).Error; err != nil {
+ return err
+ }
+ // table sig_records
+ if err := db.Exec(SigRecordsTableSQL).Error; err != nil {
+ return err
+ }
+ // table sig_repositories
+ if err := db.Exec(SigRepositoriesTableSQL).Error; err != nil {
+ return err
+ }
+ return nil
+ }
+ upgrades[4] = func() error {
+ // add commentable column for table repositories
+ if err := db.Exec(AddCommentableColumnRepositoriesTableSQL).Error; err != nil {
+ return err
+ }
+ return nil
+ }
+
+ // Get UpgradeID
+ var lastUpgrade = -1
+ if db.HasTable(UpgradesTableName) {
+ var ups []Upgrades
+ err := db.Order("upgrade_id desc").Find(&ups).Error
+ if err != nil {
+ glog.Errorf("getting upgrades error: %v", err)
+ return err
+ }
+
+ // Get value
+ if len(ups) > 0 {
+ lastUpgrade = ups[0].UpgradeID
+ }
+ }
+
+ // Exec upgrades one by one
+ for index := lastUpgrade + 1; index < len(upgrades); index++ {
+ // Begin transaction
+ tx := db.Begin()
+
+ // Exec upgrades
+ err := upgrades[index]()
+ if err != nil {
+ tx.Rollback()
+ return err
+ }
+
+ // Save last upgrade
+ err = db.Save(&Upgrades{
+ UpgradeID: index,
+ }).Error
+ if err != nil {
+ tx.Rollback()
+ return err
+ }
+
+ // End transaction
+ tx.Commit()
+ }
+
+ return nil
+}
diff --git a/pkg/cibot/database/privileges.go b/pkg/cibot/database/privileges.go
new file mode 100644
index 0000000000000000000000000000000000000000..c7bddf25ca39b6570c791c2a9e92b7781283978f
--- /dev/null
+++ b/pkg/cibot/database/privileges.go
@@ -0,0 +1,56 @@
+package database
+
+import (
+ "encoding/json"
+ "fmt"
+
+ "github.com/jinzhu/gorm"
+)
+
+// PrivilegesTableName defines
+var PrivilegesTableName = "privileges"
+
+// PrivilegesTableSQL matches with Privileges Object
+var PrivilegesTableSQL = fmt.Sprintf(`CREATE TABLE %s (
+ id int(10) unsigned NOT NULL AUTO_INCREMENT,
+ created_at timestamp NULL DEFAULT NULL,
+ updated_at timestamp NULL DEFAULT NULL,
+ deleted_at timestamp NULL DEFAULT NULL,
+ owner varchar(255) DEFAULT NULL,
+ repo varchar(255) DEFAULT NULL,
+ user varchar(255) DEFAULT NULL,
+ type varchar(255) DEFAULT NULL,
+ additional_info text,
+ PRIMARY KEY (id)
+ ) ENGINE=InnoDB DEFAULT CHARSET=utf8`, PrivilegesTableName)
+
+// Privileges defines
+type Privileges struct {
+ gorm.Model
+ Owner string
+ Repo string
+ User string
+ Type string
+ AdditionalInfo string `sql:"type:text"`
+}
+
+// GetAdditionalInfo for Privileges
+func (ps Privileges) GetAdditionalInfo(additionalinfo interface{}) error {
+ if ps.AdditionalInfo != "" {
+ err := json.Unmarshal([]byte(ps.AdditionalInfo), &additionalinfo)
+ if err != nil {
+ return err
+ }
+ }
+ return nil
+}
+
+// ToString for convert
+func (ps Privileges) ToString() (string, error) {
+ // Marshal datas
+ datas, err := json.Marshal(ps)
+ if err != nil {
+ return "", fmt.Errorf("marshal privileges failed. Error: %s", err)
+ }
+ return string(datas), nil
+}
diff --git a/pkg/cibot/database/projectfiles.go b/pkg/cibot/database/projectfiles.go
new file mode 100644
index 0000000000000000000000000000000000000000..85296e077c0746881eb5df3f73e6909c39b4526c
--- /dev/null
+++ b/pkg/cibot/database/projectfiles.go
@@ -0,0 +1,62 @@
+package database
+
+import (
+ "encoding/json"
+ "fmt"
+
+ "github.com/jinzhu/gorm"
+)
+
+// ProjectFilesTableName defines
+var ProjectFilesTableName = "project_files"
+
+// ProjectFilesTableSQL matches with ProjectFiles Object
+var ProjectFilesTableSQL = fmt.Sprintf(`CREATE TABLE %s (
+ id int(10) unsigned NOT NULL AUTO_INCREMENT,
+ created_at timestamp NULL DEFAULT NULL,
+ updated_at timestamp NULL DEFAULT NULL,
+ deleted_at timestamp NULL DEFAULT NULL,
+ owner varchar(255) DEFAULT NULL,
+ repo varchar(255) DEFAULT NULL,
+ path varchar(255) DEFAULT NULL,
+ ref varchar(255) DEFAULT NULL,
+ current_sha varchar(255) DEFAULT NULL,
+ target_sha varchar(255) DEFAULT NULL,
+ waiting_sha varchar(255) DEFAULT NULL,
+ additional_info text,
+ PRIMARY KEY (id)
+ ) ENGINE=InnoDB DEFAULT CHARSET=utf8`, ProjectFilesTableName)
+
+// ProjectFiles defines
+type ProjectFiles struct {
+ gorm.Model
+ Owner string
+ Repo string
+ Path string
+ Ref string
+ CurrentSha string
+ TargetSha string
+ WaitingSha string
+ AdditionalInfo string `sql:"type:text"`
+}
+
+// GetAdditionalInfo for ProjectFiles
+func (pfs ProjectFiles) GetAdditionalInfo(additionalinfo interface{}) error {
+ if pfs.AdditionalInfo != "" {
+ err := json.Unmarshal([]byte(pfs.AdditionalInfo), &additionalinfo)
+ if err != nil {
+ return err
+ }
+ }
+ return nil
+}
+
+// ToString for convert
+func (pfs ProjectFiles) ToString() (string, error) {
+ // Marshal datas
+ datas, err := json.Marshal(pfs)
+ if err != nil {
+ return "", fmt.Errorf("marshal project files failed. Error: %s", err)
+ }
+ return string(datas), nil
+}
diff --git a/pkg/cibot/database/repositories.go b/pkg/cibot/database/repositories.go
new file mode 100644
index 0000000000000000000000000000000000000000..546cbbd982cd5872359f6053308acacdf149ea09
--- /dev/null
+++ b/pkg/cibot/database/repositories.go
@@ -0,0 +1,61 @@
+package database
+
+import (
+ "encoding/json"
+ "fmt"
+
+ "github.com/jinzhu/gorm"
+)
+
+// RepositoriesTableName defines
+var RepositoriesTableName = "repositories"
+
+// RepositoriesTableSQL matches with Repositories Object
+var RepositoriesTableSQL = fmt.Sprintf(`CREATE TABLE %s (
+ id int(10) unsigned NOT NULL AUTO_INCREMENT,
+ created_at timestamp NULL DEFAULT NULL,
+ updated_at timestamp NULL DEFAULT NULL,
+ deleted_at timestamp NULL DEFAULT NULL,
+ owner varchar(255) DEFAULT NULL,
+ repo varchar(255) DEFAULT NULL,
+ description varchar(255) DEFAULT NULL,
+ type varchar(255) DEFAULT NULL,
+ additional_info text,
+ PRIMARY KEY (id)
+ ) ENGINE=InnoDB DEFAULT CHARSET=utf8`, RepositoriesTableName)
+
+// AddCommentableColumnRepositoriesTableSQL adds a new column: commmentable
+var AddCommentableColumnRepositoriesTableSQL = fmt.Sprintf(`ALTER TABLE %s
+ ADD commentable BOOLEAN NOT NULL DEFAULT 1`, RepositoriesTableName)
+
+// Repositories defines
+type Repositories struct {
+ gorm.Model
+ Owner string
+ Repo string
+ Description string
+ Type string
+ Commentable bool
+ AdditionalInfo string `sql:"type:text"`
+}
+
+// GetAdditionalInfo for Repositories
+func (rs Repositories) GetAdditionalInfo(additionalinfo interface{}) error {
+ if rs.AdditionalInfo != "" {
+ err := json.Unmarshal([]byte(rs.AdditionalInfo), &additionalinfo)
+ if err != nil {
+ return err
+ }
+ }
+ return nil
+}
+
+// ToString for convert
+func (rs Repositories) ToString() (string, error) {
+ // Marshal datas
+ datas, err := json.Marshal(rs)
+ if err != nil {
+ return "", fmt.Errorf("marshal repositories failed. Error: %s", err)
+ }
+ return string(datas), nil
+}
diff --git a/pkg/cibot/database/sigfiles.go b/pkg/cibot/database/sigfiles.go
new file mode 100644
index 0000000000000000000000000000000000000000..e884a23bb18472fb54f7b5e4df7faea0038b25f4
--- /dev/null
+++ b/pkg/cibot/database/sigfiles.go
@@ -0,0 +1,62 @@
+package database
+
+import (
+ "encoding/json"
+ "fmt"
+
+ "github.com/jinzhu/gorm"
+)
+
+// SigFilesTableName defines
+var SigFilesTableName = "sig_files"
+
+// SigFilesTableSQL matches with SigFiles Object
+var SigFilesTableSQL = fmt.Sprintf(`CREATE TABLE %s (
+ id int(10) unsigned NOT NULL AUTO_INCREMENT,
+ created_at timestamp NULL DEFAULT NULL,
+ updated_at timestamp NULL DEFAULT NULL,
+ deleted_at timestamp NULL DEFAULT NULL,
+ owner varchar(255) DEFAULT NULL,
+ repo varchar(255) DEFAULT NULL,
+ path varchar(255) DEFAULT NULL,
+ ref varchar(255) DEFAULT NULL,
+ current_sha varchar(255) DEFAULT NULL,
+ target_sha varchar(255) DEFAULT NULL,
+ waiting_sha varchar(255) DEFAULT NULL,
+ additional_info text,
+ PRIMARY KEY (id)
+ ) ENGINE=InnoDB DEFAULT CHARSET=utf8`, SigFilesTableName)
+
+// SigFiles defines
+type SigFiles struct {
+ gorm.Model
+ Owner string
+ Repo string
+ Path string
+ Ref string
+ CurrentSha string
+ TargetSha string
+ WaitingSha string
+ AdditionalInfo string `sql:"type:text"`
+}
+
+// GetAdditionalInfo for SigFiles
+func (sfs SigFiles) GetAdditionalInfo(additionalinfo interface{}) error {
+ if sfs.AdditionalInfo != "" {
+ err := json.Unmarshal([]byte(sfs.AdditionalInfo), &additionalinfo)
+ if err != nil {
+ return err
+ }
+ }
+ return nil
+}
+
+// ToString for convert
+func (sfs SigFiles) ToString() (string, error) {
+ // Marshal datas
+ datas, err := json.Marshal(sfs)
+ if err != nil {
+ return "", fmt.Errorf("marshal sig files failed. Error: %s", err)
+ }
+ return string(datas), nil
+}
diff --git a/pkg/cibot/database/sigrecords.go b/pkg/cibot/database/sigrecords.go
new file mode 100644
index 0000000000000000000000000000000000000000..873f41532ee485c988102c2a8429972bc365b2cc
--- /dev/null
+++ b/pkg/cibot/database/sigrecords.go
@@ -0,0 +1,50 @@
+package database
+
+import (
+ "encoding/json"
+ "fmt"
+
+ "github.com/jinzhu/gorm"
+)
+
+// SigRecordsTableName defines
+var SigRecordsTableName = "sig_records"
+
+// SigRecordsTableSQL matches with sig_records Object
+var SigRecordsTableSQL = fmt.Sprintf(`CREATE TABLE %s (
+ id int(10) unsigned NOT NULL AUTO_INCREMENT,
+ created_at timestamp NULL DEFAULT NULL,
+ updated_at timestamp NULL DEFAULT NULL,
+ deleted_at timestamp NULL DEFAULT NULL,
+ name varchar(255) DEFAULT NULL,
+ additional_info text,
+ PRIMARY KEY (id)
+ ) ENGINE=InnoDB DEFAULT CHARSET=utf8`, SigRecordsTableName)
+
+// SigRecords defines
+type SigRecords struct {
+ gorm.Model
+ Name string
+ AdditionalInfo string `sql:"type:text"`
+}
+
+// GetAdditionalInfo for SigRecords
+func (srs SigRecords) GetAdditionalInfo(additionalinfo interface{}) error {
+ if srs.AdditionalInfo != "" {
+ err := json.Unmarshal([]byte(srs.AdditionalInfo), &additionalinfo)
+ if err != nil {
+ return err
+ }
+ }
+ return nil
+}
+
+// ToString for convert
+func (srs SigRecords) ToString() (string, error) {
+ // Marshal datas
+ datas, err := json.Marshal(srs)
+ if err != nil {
+ return "", fmt.Errorf("marshal sig records failed. Error: %s", err)
+ }
+ return string(datas), nil
+}
diff --git a/pkg/cibot/database/sigrepositories.go b/pkg/cibot/database/sigrepositories.go
new file mode 100644
index 0000000000000000000000000000000000000000..4250277e3317747c57a9b3e783fde226bd939b04
--- /dev/null
+++ b/pkg/cibot/database/sigrepositories.go
@@ -0,0 +1,52 @@
+package database
+
+import (
+ "encoding/json"
+ "fmt"
+
+ "github.com/jinzhu/gorm"
+)
+
+// SigRepositoriesTableName defines
+var SigRepositoriesTableName = "sig_repositories"
+
+// SigRepositoriesTableSQL matches with sig_repositories Object
+var SigRepositoriesTableSQL = fmt.Sprintf(`CREATE TABLE %s (
+ id int(10) unsigned NOT NULL AUTO_INCREMENT,
+ created_at timestamp NULL DEFAULT NULL,
+ updated_at timestamp NULL DEFAULT NULL,
+ deleted_at timestamp NULL DEFAULT NULL,
+ name varchar(255) DEFAULT NULL,
+ repo_name varchar(255) DEFAULT NULL,
+ additional_info text,
+ PRIMARY KEY (id)
+ ) ENGINE=InnoDB DEFAULT CHARSET=utf8`, SigRepositoriesTableName)
+
+// SigRepositories defines
+type SigRepositories struct {
+ gorm.Model
+ Name string
+ RepoName string
+ AdditionalInfo string `sql:"type:text"`
+}
+
+// GetAdditionalInfo for SigRepositories
+func (srs SigRepositories) GetAdditionalInfo(additionalinfo interface{}) error {
+ if srs.AdditionalInfo != "" {
+ err := json.Unmarshal([]byte(srs.AdditionalInfo), &additionalinfo)
+ if err != nil {
+ return err
+ }
+ }
+ return nil
+}
+
+// ToString for convert
+func (srs SigRepositories) ToString() (string, error) {
+ // Marshal datas
+ datas, err := json.Marshal(srs)
+ if err != nil {
+ return "", fmt.Errorf("marshal sig repositories failed. Error: %s", err)
+ }
+ return string(datas), nil
+}
diff --git a/pkg/cibot/database/upgrades.go b/pkg/cibot/database/upgrades.go
new file mode 100644
index 0000000000000000000000000000000000000000..4df285df4b8e68c6b2ed5f16b8e95273a0e0875f
--- /dev/null
+++ b/pkg/cibot/database/upgrades.go
@@ -0,0 +1,26 @@
+package database
+
+import (
+ "fmt"
+
+ "github.com/jinzhu/gorm"
+)
+
+// UpgradesTableName defines
+var UpgradesTableName = "upgrades"
+
+// UpgradesTableSQL matches with Upgrades Object
+var UpgradesTableSQL = fmt.Sprintf(`CREATE TABLE %s (
+ id int(10) unsigned NOT NULL AUTO_INCREMENT,
+ created_at timestamp NULL DEFAULT NULL,
+ updated_at timestamp NULL DEFAULT NULL,
+ deleted_at timestamp NULL DEFAULT NULL,
+ upgrade_id int(10) DEFAULT NULL,
+ PRIMARY KEY (id)
+ ) ENGINE=InnoDB DEFAULT CHARSET=utf8`, UpgradesTableName)
+
+// Upgrades defines for back database
+type Upgrades struct {
+ gorm.Model
+ UpgradeID int
+}
diff --git a/pkg/cibot/inithandler.go b/pkg/cibot/inithandler.go
new file mode 100644
index 0000000000000000000000000000000000000000..8050793fa783c2f68c69cd1dedfd8bf480284d0c
--- /dev/null
+++ b/pkg/cibot/inithandler.go
@@ -0,0 +1,1076 @@
+package cibot
+
+import (
+ "context"
+ "encoding/base64"
+ "strconv"
+ "time"
+
+ "gitee.com/openeuler/ci-bot/pkg/cibot/config"
+ "gitee.com/openeuler/ci-bot/pkg/cibot/database"
+ "gitee.com/openeuler/go-gitee/gitee"
+ "github.com/antihax/optional"
+ "github.com/golang/glog"
+ "gopkg.in/yaml.v2"
+)
+
+const (
+ PrivilegeManager = "manager"
+ PrivilegeDeveloper = "developer"
+ PrivilegeViewer = "viewer"
+ PrivilegeReporter = "reporter"
+
+ PermissionAdmin = "admin"
+ PermissionPush = "push"
+ PermissionPull = "pull"
+
+ BranchProtected = "protected"
+ // not supported yet
+ BranchReadonly = "readonly"
+)
+
+type InitHandler struct {
+ Config config.Config
+ Context context.Context
+ GiteeClient *gitee.APIClient
+}
+
+type Projects struct {
+ Community Community `yaml:"community"`
+ Repositories []Repository `yaml:"repositories"`
+}
+
+type Community struct {
+ Name *string `yaml:"name"`
+ ProtectedBranches []string `yaml:"protected_branches"`
+ Managers []string `yaml:"managers"`
+ Developers []string `yaml:"developers"`
+ Viewers []string `yaml:"viewers"`
+ Reporters []string `yaml:"reporters"`
+}
+
+type Repository struct {
+ Name *string `yaml:"name"`
+ Description *string `yaml:"description"`
+ ProtectedBranches []string `yaml:"protected_branches"`
+ Commentable *bool `yaml:"commentable"`
+ Type *string `yaml:"type"`
+ RenameFrom *string `yaml:"rename_from"`
+ Managers []string `yaml:"managers"`
+ Developers []string `yaml:"developers"`
+ Viewers []string `yaml:"viewers"`
+ Reporters []string `yaml:"reporters"`
+}
+
+// IsCommentable returns if contributors are able to comment
+// to the repository.
+// It will be true only if Commentable is explicitly sepecified as true
+func (r Repository) IsCommentable() bool {
+ return (r.Commentable != nil && *r.Commentable)
+}
+
+// Serve
+func (handler *InitHandler) Serve() {
+ // init waiting sha
+ err := handler.initWaitingSha()
+ if err != nil {
+ glog.Errorf("unable to initWaitingSha: %v", err)
+ return
+ }
+ // watch database
+ handler.watch()
+}
+
+// initWaitingSha init waiting sha
+func (handler *InitHandler) initWaitingSha() error {
+ if len(handler.Config.WatchProjectFiles) == 0 {
+ return nil
+ }
+
+ for _, wf := range handler.Config.WatchProjectFiles {
+ // get params
+ watchOwner := wf.WatchProjectFileOwner
+ watchRepo := wf.WatchprojectFileRepo
+ watchPath := wf.WatchprojectFilePath
+ watchRef := wf.WatchProjectFileRef
+
+ // invoke api to get file contents
+ localVarOptionals := &gitee.GetV5ReposOwnerRepoContentsPathOpts{}
+ localVarOptionals.AccessToken = optional.NewString(handler.Config.GiteeToken)
+ localVarOptionals.Ref = optional.NewString(watchRef)
+
+ // get contents
+ contents, _, err := handler.GiteeClient.RepositoriesApi.GetV5ReposOwnerRepoContentsPath(
+ handler.Context, watchOwner, watchRepo, watchPath, localVarOptionals)
+ if err != nil {
+ glog.Errorf("unable to get repository content: %v", err)
+ return err
+ }
+ // Check project file
+ var lenProjectFiles int
+ err = database.DBConnection.Model(&database.ProjectFiles{}).
+ Where("owner = ? and repo = ? and path = ? and ref = ?", watchOwner, watchRepo, watchPath, watchRef).
+ Count(&lenProjectFiles).Error
+ if err != nil {
+ glog.Errorf("unable to get project files: %v", err)
+ return err
+ }
+ if lenProjectFiles > 0 {
+ glog.Infof("project file is exist: %s", contents.Sha)
+ // Check sha in database
+ updatepf := database.ProjectFiles{}
+ err = database.DBConnection.
+ Where("owner = ? and repo = ? and path = ? and ref = ?", watchOwner, watchRepo, watchPath, watchRef).
+ First(&updatepf).Error
+ if err != nil {
+ glog.Errorf("unable to get project files: %v", err)
+ return err
+ }
+ // write sha in waitingsha
+ updatepf.WaitingSha = contents.Sha
+ err = database.DBConnection.Save(&updatepf).Error
+ if err != nil {
+ glog.Errorf("unable to get project files: %v", err)
+ return err
+ }
+
+ } else {
+ glog.Infof("project file is non-exist: %s", contents.Sha)
+ // add project file
+ addpf := database.ProjectFiles{
+ Owner: watchOwner,
+ Repo: watchRepo,
+ Path: watchPath,
+ Ref: watchRef,
+ WaitingSha: contents.Sha,
+ }
+
+ // create project file
+ err = database.DBConnection.Create(&addpf).Error
+ if err != nil {
+ glog.Errorf("unable to create project files: %v", err)
+ return err
+ }
+ glog.Infof("add project file successfully: %s", contents.Sha)
+ }
+ }
+ return nil
+}
+
+// watch database
+func (handler *InitHandler) watch() {
+ if len(handler.Config.WatchProjectFiles) == 0 {
+ return
+ }
+
+ for {
+ watchDuration := handler.Config.WatchProjectFileDuration
+ for _, wf := range handler.Config.WatchProjectFiles {
+ // get params
+ watchOwner := wf.WatchProjectFileOwner
+ watchRepo := wf.WatchprojectFileRepo
+ watchPath := wf.WatchprojectFilePath
+ watchRef := wf.WatchProjectFileRef
+
+ glog.Infof("begin to serve. watchOwner: %s watchRepo: %s watchPath: %s watchRef: %s watchDuration: %d",
+ watchOwner, watchRepo, watchPath, watchRef, watchDuration)
+
+ // get project file
+ pf := database.ProjectFiles{}
+ err := database.DBConnection.
+ Where("owner = ? and repo = ? and path = ? and ref = ?", watchOwner, watchRepo, watchPath, watchRef).
+ First(&pf).Error
+ if err != nil {
+ glog.Errorf("unable to get project files: %v", err)
+ } else {
+ glog.Infof("init handler current sha: %v target sha: %v waiting sha: %v",
+ pf.CurrentSha, pf.TargetSha, pf.WaitingSha)
+ if pf.TargetSha != "" {
+ // skip when there is executing target sha
+ glog.Infof("there is executing target sha: %v", pf.TargetSha)
+ } else {
+ if pf.WaitingSha != "" && pf.CurrentSha != pf.WaitingSha {
+ // waiting -> target
+ pf.TargetSha = pf.WaitingSha
+ err = database.DBConnection.Save(&pf).Error
+ if err != nil {
+ glog.Errorf("unable to save project files: %v", err)
+ } else {
+ // define update pf
+ updatepf := &database.ProjectFiles{}
+ updatepf.ID = pf.ID
+
+ // get file content from target sha
+ glog.Infof("get target sha blob: %v", pf.TargetSha)
+ localVarOptionals := &gitee.GetV5ReposOwnerRepoGitBlobsShaOpts{}
+ localVarOptionals.AccessToken = optional.NewString(handler.Config.GiteeToken)
+ blob, _, err := handler.GiteeClient.GitDataApi.GetV5ReposOwnerRepoGitBlobsSha(
+ handler.Context, watchOwner, watchRepo, pf.TargetSha, localVarOptionals)
+ if err != nil {
+ glog.Errorf("unable to get blob: %v", err)
+ } else {
+ // base64 decode
+ glog.Infof("decode target sha blob: %v", pf.TargetSha)
+ decodeBytes, err := base64.StdEncoding.DecodeString(blob.Content)
+ if err != nil {
+ glog.Errorf("decode content with error: %v", err)
+ } else {
+ // unmarshal owners file
+ glog.Infof("unmarshal target sha blob: %v", pf.TargetSha)
+ var ps Projects
+ err = yaml.Unmarshal(decodeBytes, &ps)
+ if err != nil {
+ glog.Errorf("failed to unmarshal projects: %v", err)
+ } else {
+ glog.Infof("get blob result: %v", ps)
+ result := true
+ for i := 0; i < len(ps.Repositories); i++ {
+ // get repositories length
+ lenRepositories, err := handler.getRepositoriesLength(*ps.Community.Name, *ps.Repositories[i].Name)
+ if err != nil {
+ glog.Errorf("failed to get repositories length: %v", err)
+ result = false
+ continue
+ }
+ if lenRepositories > 0 {
+ glog.Infof("repository: %s is exist. no action.", *ps.Repositories[i].Name)
+ } else {
+ // add repository
+ err = handler.addRepositories(*ps.Community.Name, *ps.Repositories[i].Name,
+ *ps.Repositories[i].Description, *ps.Repositories[i].Type)
+ if err != nil {
+ glog.Errorf("failed to add repositories: %v", err)
+ result = false
+ continue
+ }
+ }
+ // add members
+ err = handler.handleMembers(ps.Community, ps.Repositories[i])
+ if err != nil {
+ glog.Errorf("failed to add members: %v", err)
+ result = false
+ }
+ // handle branches
+ err = handler.handleBranches(ps.Community, ps.Repositories[i])
+ if err != nil {
+ glog.Errorf("failed to handle branches: %v", err)
+ result = false
+ }
+ // handle repository type
+ err = handler.handleRepositoryTypes(ps.Community, ps.Repositories[i])
+ if err != nil {
+ glog.Errorf("failed to handle repository types: %v", err)
+ result = false
+ }
+ }
+ glog.Infof("running result: %v", result)
+ if result {
+ err = database.DBConnection.Model(updatepf).Update("CurrentSha", pf.TargetSha).Error
+ if err != nil {
+ glog.Errorf("unable to update current sha: %v", err)
+ }
+ }
+ }
+ }
+ }
+
+ // at last update target sha
+ err = database.DBConnection.Model(updatepf).Update("TargetSha", "").Error
+ if err != nil {
+ glog.Errorf("unable to update target sha: %v", err)
+ }
+ glog.Info("update sha successfully")
+ }
+ } else {
+ glog.Infof("no waiting sha: %v", pf.WaitingSha)
+ }
+ }
+ }
+ }
+
+ // watch duration
+ glog.Info("end to serve")
+ time.Sleep(time.Duration(watchDuration) * time.Second)
+ }
+}
+
+// GetRepositoriesLength get repositories length
+func (handler *InitHandler) getRepositoriesLength(owner string, repo string) (int, error) {
+ // Check repositories file
+ var lenRepositories int
+ err := database.DBConnection.Model(&database.Repositories{}).
+ Where("owner = ? and repo = ?", owner, repo).
+ Count(&lenRepositories).Error
+ if err != nil {
+ glog.Errorf("unable to get repositories files: %v", err)
+ }
+ return lenRepositories, err
+}
+
+// addRepositories add repository
+func (handler *InitHandler) addRepositories(owner, repo, description, t string) error {
+ // add repository in gitee
+ err := handler.addRepositoriesinGitee(owner, repo, description, t)
+ if err != nil {
+ glog.Errorf("failed to add repositories: %v", err)
+ return err
+ }
+
+ // add repository in database
+ err = handler.addRepositoriesinDB(owner, repo, description, t)
+ if err != nil {
+ glog.Errorf("failed to add repositories: %v", err)
+ return err
+ }
+ return nil
+}
+
+// addRepositoriesinDB add repository in database
+func (handler *InitHandler) addRepositoriesinDB(owner, repo, description, t string) error {
+ // add repository
+ addrepo := database.Repositories{
+ Owner: owner,
+ Repo: repo,
+ Description: description,
+ Type: t,
+ }
+
+ // create repository
+ err := database.DBConnection.Create(&addrepo).Error
+ if err != nil {
+ glog.Errorf("unable to create repository: %v", err)
+ return err
+ }
+ return nil
+}
+
+// addRepositoriesinGitee add repository in giteee
+func (handler *InitHandler) addRepositoriesinGitee(owner, repo, description, t string) error {
+ // build create repository param
+ repobody := gitee.RepositoryPostParam{}
+ repobody.AccessToken = handler.Config.GiteeToken
+ repobody.Name = repo
+ repobody.Description = description
+ repobody.HasIssues = true
+ repobody.HasWiki = true
+ // set `auto_init` as true to initialize `master` branch with README after repo creation
+ repobody.AutoInit = true
+ if t == "private" {
+ repobody.Private = true
+ } else {
+ repobody.Private = false
+ }
+
+ // invoke query repository
+ glog.Infof("begin to query repository: %s", repo)
+ localVarOptionals := &gitee.GetV5ReposOwnerRepoOpts{}
+ localVarOptionals.AccessToken = optional.NewString(handler.Config.GiteeToken)
+ _, response, _ := handler.GiteeClient.RepositoriesApi.GetV5ReposOwnerRepo(handler.Context, owner, repo, localVarOptionals)
+ if response.StatusCode == 404 {
+ glog.Infof("repository is not exist: %s", repo)
+ } else {
+ glog.Infof("repository is already exist: %s", repo)
+ return nil
+ }
+
+ // invoke create repository
+ glog.Infof("begin to create repository: %s", repo)
+ _, _, err := handler.GiteeClient.RepositoriesApi.PostV5OrgsOrgRepos(handler.Context, owner, repobody)
+ if err != nil {
+ glog.Errorf("fail to create repository: %v", err)
+ return err
+ }
+ glog.Infof("end to create repository: %s", repo)
+ return nil
+}
+
+// isUsingRepositoryMember check if using repository member not community member
+func (handler *InitHandler) isUsingRepositoryMember(r Repository) bool {
+ return len(r.Managers) > 0 || len(r.Developers) > 0 || len(r.Viewers) > 0 || len(r.Reporters) > 0
+}
+
+// handleMembers handle members
+func (handler *InitHandler) handleMembers(c Community, r Repository) error {
+ // if the members is defined in the repositories, it means that
+ // all the members defined in the community will not be inherited by repositories.
+ members := make(map[string]map[string]string)
+ if handler.isUsingRepositoryMember(r) {
+ // using repositories members
+ glog.Infof("using repository members: %s", *r.Name)
+ members = handler.getMembersMap(r.Managers, r.Developers, r.Viewers, r.Reporters)
+
+ } else {
+ // using community members
+ glog.Infof("using community members: %s", *r.Name)
+ members = handler.getMembersMap(c.Managers, c.Developers, c.Viewers, c.Reporters)
+ }
+
+ // get members from database
+ var ps []database.Privileges
+ err := database.DBConnection.Model(&database.Privileges{}).
+ Where("owner = ? and repo = ?", c.Name, r.Name).Find(&ps).Error
+ if err != nil {
+ glog.Errorf("unable to get members: %v", err)
+ return err
+ }
+ membersinDB := handler.getMembersMapByDB(ps)
+
+ /* reporters
+ err = handler.removeReporters(c, r, members[PrivilegeReporter], membersinDB[PrivilegeReporter])
+ if err != nil {
+ glog.Errorf("unable to remove reporters: %v", err)
+ }*/
+ // viewers
+ err = handler.removeViewers(c, r, members[PrivilegeViewer], membersinDB[PrivilegeViewer])
+ if err != nil {
+ glog.Errorf("unable to remove viewers: %v", err)
+ }
+ // developers
+ err = handler.removeDevelopers(c, r, members[PrivilegeDeveloper], membersinDB[PrivilegeDeveloper])
+ if err != nil {
+ glog.Errorf("unable to remove developers: %v", err)
+ }
+ // managers
+ err = handler.removeManagers(c, r, members[PrivilegeManager], membersinDB[PrivilegeManager])
+ if err != nil {
+ glog.Errorf("unable to remove managers: %v", err)
+ }
+
+ /* currently reporters are not supported by gitee api
+ err = handler.addReporters(c, r, members[PrivilegeReporter], membersinDB[PrivilegeReporter])
+ if err != nil {
+ glog.Errorf("unable to add reporters: %v", err)
+ }*/
+ // viewers
+ err = handler.addViewers(c, r, members[PrivilegeViewer], membersinDB[PrivilegeViewer])
+ if err != nil {
+ glog.Errorf("unable to add viewers: %v", err)
+ }
+ // developers
+ err = handler.addDevelopers(c, r, members[PrivilegeDeveloper], membersinDB[PrivilegeDeveloper])
+ if err != nil {
+ glog.Errorf("unable to add developers: %v", err)
+ }
+ // managers
+ err = handler.addManagers(c, r, members[PrivilegeManager], membersinDB[PrivilegeManager])
+ if err != nil {
+ glog.Errorf("unable to add managers: %v", err)
+ }
+
+ return nil
+}
+
+// getMembersMap get members map
+func (handler *InitHandler) getMembersMap(managers, developers, viewers, reporters []string) map[string]map[string]string {
+ mapManagers := make(map[string]string)
+ mapDevelopers := make(map[string]string)
+ mapViewers := make(map[string]string)
+ mapReporters := make(map[string]string)
+ if len(managers) > 0 {
+ for _, m := range managers {
+ mapManagers[m] = m
+ }
+ }
+ if len(developers) > 0 {
+ for _, d := range developers {
+ // skip when developer is already in managers
+ _, okinManagers := mapManagers[d]
+ if !okinManagers {
+ mapDevelopers[d] = d
+ }
+ }
+ }
+ if len(viewers) > 0 {
+ for _, v := range viewers {
+ // skip when viewer is already in managers or developers
+ _, okinManagers := mapManagers[v]
+ _, okinDevelopers := mapDevelopers[v]
+ if !okinManagers && !okinDevelopers {
+ mapViewers[v] = v
+ }
+ }
+ }
+ if len(reporters) > 0 {
+ for _, rt := range reporters {
+ // skip when reporter is already in managers or developers or viewer
+ _, okinManagers := mapManagers[rt]
+ _, okinDevelopers := mapDevelopers[rt]
+ _, okinViewers := mapViewers[rt]
+ if !okinManagers && !okinDevelopers && !okinViewers {
+ mapReporters[rt] = rt
+ }
+ }
+ }
+
+ // all members map
+ members := make(map[string]map[string]string)
+ members[PrivilegeManager] = mapManagers
+ members[PrivilegeDeveloper] = mapDevelopers
+ members[PrivilegeViewer] = mapViewers
+ members[PrivilegeReporter] = mapReporters
+ return members
+}
+
+// getMembersMapByDB get members map from database
+func (handler *InitHandler) getMembersMapByDB(ps []database.Privileges) map[string]map[string]string {
+ members := make(map[string]map[string]string)
+ mapManagers := make(map[string]string)
+ mapDevelopers := make(map[string]string)
+ mapViewers := make(map[string]string)
+ mapReporters := make(map[string]string)
+ // all members map
+ members[PrivilegeManager] = mapManagers
+ members[PrivilegeDeveloper] = mapDevelopers
+ members[PrivilegeViewer] = mapViewers
+ members[PrivilegeReporter] = mapReporters
+ if len(ps) > 0 {
+ for _, p := range ps {
+ members[p.Type][p.User] = strconv.Itoa(int(p.ID))
+ }
+ }
+
+ return members
+}
+
+// addManagers add managers
+func (handler *InitHandler) addManagers(c Community, r Repository, mapManagers, mapManagersInDB map[string]string) error {
+ // managers added
+ listOfAddManagers := make([]string, 0)
+ for m := range mapManagers {
+ _, okinManagers := mapManagersInDB[m]
+ if !okinManagers {
+ listOfAddManagers = append(listOfAddManagers, m)
+ }
+ }
+ glog.Infof("list of add managers: %v", listOfAddManagers)
+ if len(listOfAddManagers) > 0 {
+ // build create project member param
+ memberbody := gitee.ProjectMemberPutParam{}
+ memberbody.AccessToken = handler.Config.GiteeToken
+ memberbody.Permission = PermissionAdmin
+
+ glog.Infof("begin to create manager for: %s", *r.Name)
+ for j := 0; j < len(listOfAddManagers); j++ {
+ _, _, err := handler.GiteeClient.RepositoriesApi.PutV5ReposOwnerRepoCollaboratorsUsername(
+ handler.Context, *c.Name, *r.Name, listOfAddManagers[j], memberbody)
+ if err != nil {
+ glog.Errorf("fail to create manager: %v", err)
+ continue
+ }
+ // create privilege
+ ps := database.Privileges{
+ Owner: *c.Name,
+ Repo: *r.Name,
+ User: listOfAddManagers[j],
+ Type: PrivilegeManager,
+ }
+ err = database.DBConnection.Create(&ps).Error
+ if err != nil {
+ glog.Errorf("fail to create manager in database: %v", err)
+ }
+ }
+ glog.Infof("end to create manager for: %s", *r.Name)
+ }
+ return nil
+}
+
+// removeManagers remove managers
+func (handler *InitHandler) removeManagers(c Community, r Repository, mapManagers, mapManagersInDB map[string]string) error {
+ // managers removed
+ listOfRemoveManagers := make([]string, 0)
+ for m := range mapManagersInDB {
+ _, okinManagers := mapManagers[m]
+ if !okinManagers {
+ listOfRemoveManagers = append(listOfRemoveManagers, m)
+ }
+ }
+ glog.Infof("list of removed managers: %v", listOfRemoveManagers)
+ if len(listOfRemoveManagers) > 0 {
+ // build remove project member param
+ memberbody := &gitee.DeleteV5ReposOwnerRepoCollaboratorsUsernameOpts{}
+ memberbody.AccessToken = optional.NewString(handler.Config.GiteeToken)
+
+ glog.Infof("begin to remove managers for: %s", *r.Name)
+ for j := 0; j < len(listOfRemoveManagers); j++ {
+ _, err := handler.GiteeClient.RepositoriesApi.DeleteV5ReposOwnerRepoCollaboratorsUsername(
+ handler.Context, *c.Name, *r.Name, listOfRemoveManagers[j], memberbody)
+ if err != nil {
+ glog.Errorf("fail to remove managers: %v", err)
+ continue
+ }
+ // delete privilege
+ id, _ := strconv.Atoi(mapManagersInDB[listOfRemoveManagers[j]])
+ ps := database.Privileges{}
+ ps.ID = uint(id)
+ err = database.DBConnection.Delete(&ps).Error
+ if err != nil {
+ glog.Errorf("fail to remove manager in database: %v", err)
+ }
+ }
+ glog.Infof("end to remove managers for: %s", *r.Name)
+ }
+ return nil
+}
+
+// addDevelopers add developers
+func (handler *InitHandler) addDevelopers(c Community, r Repository, mapDevelopers, mapDevelopersInDB map[string]string) error {
+ // developers added
+ listOfAddDevelopers := make([]string, 0)
+ for d := range mapDevelopers {
+ _, okinDevelopers := mapDevelopersInDB[d]
+ if !okinDevelopers {
+ listOfAddDevelopers = append(listOfAddDevelopers, d)
+ }
+ }
+ glog.Infof("list of add developers: %v", listOfAddDevelopers)
+ if len(listOfAddDevelopers) > 0 {
+ // build create project member param
+ memberbody := gitee.ProjectMemberPutParam{}
+ memberbody.AccessToken = handler.Config.GiteeToken
+ memberbody.Permission = PermissionPush
+
+ glog.Infof("begin to create developers for: %s", *r.Name)
+ for j := 0; j < len(listOfAddDevelopers); j++ {
+ _, _, err := handler.GiteeClient.RepositoriesApi.PutV5ReposOwnerRepoCollaboratorsUsername(
+ handler.Context, *c.Name, *r.Name, listOfAddDevelopers[j], memberbody)
+ if err != nil {
+ glog.Errorf("fail to create developers: %v", err)
+ continue
+ }
+ // create privilege
+ ps := database.Privileges{
+ Owner: *c.Name,
+ Repo: *r.Name,
+ User: listOfAddDevelopers[j],
+ Type: PrivilegeDeveloper,
+ }
+ err = database.DBConnection.Create(&ps).Error
+ if err != nil {
+ glog.Errorf("fail to create developers in database: %v", err)
+ }
+ }
+ glog.Infof("end to create developers for: %s", *r.Name)
+ }
+ return nil
+}
+
+// removeDevelopers remove developers
+func (handler *InitHandler) removeDevelopers(c Community, r Repository, mapDevelopers, mapDevelopersInDB map[string]string) error {
+ // developers removed
+ listOfRemoveDevelopers := make([]string, 0)
+ for d := range mapDevelopersInDB {
+ _, okinDevelopers := mapDevelopers[d]
+ if !okinDevelopers {
+ listOfRemoveDevelopers = append(listOfRemoveDevelopers, d)
+ }
+ }
+ glog.Infof("list of removed developers: %v", listOfRemoveDevelopers)
+ if len(listOfRemoveDevelopers) > 0 {
+ // build remove project member param
+ memberbody := &gitee.DeleteV5ReposOwnerRepoCollaboratorsUsernameOpts{}
+ memberbody.AccessToken = optional.NewString(handler.Config.GiteeToken)
+
+ glog.Infof("begin to remove developers for: %s", *r.Name)
+ for j := 0; j < len(listOfRemoveDevelopers); j++ {
+ _, err := handler.GiteeClient.RepositoriesApi.DeleteV5ReposOwnerRepoCollaboratorsUsername(
+ handler.Context, *c.Name, *r.Name, listOfRemoveDevelopers[j], memberbody)
+ if err != nil {
+ glog.Errorf("fail to remove developers: %v", err)
+ continue
+ }
+ // delete privilege
+ id, _ := strconv.Atoi(mapDevelopersInDB[listOfRemoveDevelopers[j]])
+ ps := database.Privileges{}
+ ps.ID = uint(id)
+ err = database.DBConnection.Delete(&ps).Error
+ if err != nil {
+ glog.Errorf("fail to remove developers in database: %v", err)
+ }
+ }
+ glog.Infof("end to remove developers for: %s", *r.Name)
+ }
+ return nil
+}
+
+// addViewers add viewers
+func (handler *InitHandler) addViewers(c Community, r Repository, mapViewers, mapViewersInDB map[string]string) error {
+ // viewers added
+ listOfAddViewers := make([]string, 0)
+ for v := range mapViewers {
+ _, okinViewers := mapViewersInDB[v]
+ if !okinViewers {
+ listOfAddViewers = append(listOfAddViewers, v)
+ }
+ }
+ glog.Infof("list of add viewers: %v", listOfAddViewers)
+ if len(listOfAddViewers) > 0 {
+ // build create project member param
+ memberbody := gitee.ProjectMemberPutParam{}
+ memberbody.AccessToken = handler.Config.GiteeToken
+ memberbody.Permission = PermissionPull
+
+ glog.Infof("begin to create viewers for: %s", *r.Name)
+ for j := 0; j < len(listOfAddViewers); j++ {
+ _, _, err := handler.GiteeClient.RepositoriesApi.PutV5ReposOwnerRepoCollaboratorsUsername(
+ handler.Context, *c.Name, *r.Name, listOfAddViewers[j], memberbody)
+ if err != nil {
+ glog.Errorf("fail to create viewers: %v", err)
+ continue
+ }
+ // create privilege
+ ps := database.Privileges{
+ Owner: *c.Name,
+ Repo: *r.Name,
+ User: listOfAddViewers[j],
+ Type: PrivilegeViewer,
+ }
+ err = database.DBConnection.Create(&ps).Error
+ if err != nil {
+ glog.Errorf("fail to create viewers in database: %v", err)
+ }
+ }
+ glog.Infof("end to create viewers for: %s", *r.Name)
+ }
+ return nil
+}
+
+// removeViewers remove viewers
+func (handler *InitHandler) removeViewers(c Community, r Repository, mapViewers, mapViewersInDB map[string]string) error {
+ // viewers removed
+ listOfRemoveViewers := make([]string, 0)
+ for v := range mapViewersInDB {
+ _, okinViewers := mapViewers[v]
+ if !okinViewers {
+ listOfRemoveViewers = append(listOfRemoveViewers, v)
+ }
+ }
+ glog.Infof("list of removed viewers: %v", listOfRemoveViewers)
+ if len(listOfRemoveViewers) > 0 {
+ // build remove project member param
+ memberbody := &gitee.DeleteV5ReposOwnerRepoCollaboratorsUsernameOpts{}
+ memberbody.AccessToken = optional.NewString(handler.Config.GiteeToken)
+
+ glog.Infof("begin to remove viewers for: %s", *r.Name)
+ for j := 0; j < len(listOfRemoveViewers); j++ {
+ _, err := handler.GiteeClient.RepositoriesApi.DeleteV5ReposOwnerRepoCollaboratorsUsername(
+ handler.Context, *c.Name, *r.Name, listOfRemoveViewers[j], memberbody)
+ if err != nil {
+ glog.Errorf("fail to remove viewers: %v", err)
+ continue
+ }
+ // delete privilege
+ id, _ := strconv.Atoi(mapViewersInDB[listOfRemoveViewers[j]])
+ ps := database.Privileges{}
+ ps.ID = uint(id)
+ err = database.DBConnection.Delete(&ps).Error
+ if err != nil {
+ glog.Errorf("fail to remove viewers in database: %v", err)
+ }
+ }
+ glog.Infof("end to remove viewers for: %s", *r.Name)
+ }
+ return nil
+}
+
+// addReporters add reporters
+func (handler *InitHandler) addReporters(c Community, r Repository, mapReporters, mapReportersInDB map[string]string) error {
+ // reporters added
+ listOfAddReporters := make([]string, 0)
+ for rt := range mapReporters {
+ _, okinReporters := mapReportersInDB[rt]
+ if !okinReporters {
+ listOfAddReporters = append(listOfAddReporters, rt)
+ }
+ }
+ glog.Infof("list of add reporters: %v", listOfAddReporters)
+ if len(listOfAddReporters) > 0 {
+ // build create project member param
+ memberbody := gitee.ProjectMemberPutParam{}
+ memberbody.AccessToken = handler.Config.GiteeToken
+ // memberbody.Permission = PermissionPull
+
+ glog.Infof("begin to create reporters for: %s", *r.Name)
+ for j := 0; j < len(listOfAddReporters); j++ {
+ _, _, err := handler.GiteeClient.RepositoriesApi.PutV5ReposOwnerRepoCollaboratorsUsername(
+ handler.Context, *c.Name, *r.Name, listOfAddReporters[j], memberbody)
+ if err != nil {
+ glog.Errorf("fail to create reporters: %v", err)
+ continue
+ }
+ // create privilege
+ ps := database.Privileges{
+ Owner: *c.Name,
+ Repo: *r.Name,
+ User: listOfAddReporters[j],
+ Type: PrivilegeViewer,
+ }
+ err = database.DBConnection.Create(&ps).Error
+ if err != nil {
+ glog.Errorf("fail to create reporters in database: %v", err)
+ }
+ }
+ glog.Infof("end to create reporters for: %s", *r.Name)
+ }
+ return nil
+}
+
+// removeReporters remove reporters
+func (handler *InitHandler) removeReporters(c Community, r Repository, mapReporters, mapReportersInDB map[string]string) error {
+ // reporters removed
+ listOfRemoveReporters := make([]string, 0)
+ for rt := range mapReportersInDB {
+ _, okinReporters := mapReporters[rt]
+ if !okinReporters {
+ listOfRemoveReporters = append(listOfRemoveReporters, rt)
+ }
+ }
+ glog.Infof("list of removed reporters: %v", listOfRemoveReporters)
+ if len(listOfRemoveReporters) > 0 {
+ // build remove project member param
+ memberbody := &gitee.DeleteV5ReposOwnerRepoCollaboratorsUsernameOpts{}
+ memberbody.AccessToken = optional.NewString(handler.Config.GiteeToken)
+
+ glog.Infof("begin to remove reporters for: %s", *r.Name)
+ for j := 0; j < len(listOfRemoveReporters); j++ {
+ _, err := handler.GiteeClient.RepositoriesApi.DeleteV5ReposOwnerRepoCollaboratorsUsername(
+ handler.Context, *c.Name, *r.Name, listOfRemoveReporters[j], memberbody)
+ if err != nil {
+ glog.Errorf("fail to remove reporters: %v", err)
+ continue
+ }
+ // delete privilege
+ id, _ := strconv.Atoi(mapReportersInDB[listOfRemoveReporters[j]])
+ ps := database.Privileges{}
+ ps.ID = uint(id)
+ err = database.DBConnection.Delete(&ps).Error
+ if err != nil {
+ glog.Errorf("fail to remove reporters in database: %v", err)
+ }
+ }
+ glog.Infof("end to remove reporters for: %s", *r.Name)
+ }
+ return nil
+}
+
+// handleBranches handle branches
+// currently for protecting branches only
+func (handler *InitHandler) handleBranches(c Community, r Repository) error {
+ // if the branches are defined in the repositories, it means that
+ // all the branches defined in the community will not inherited by repositories
+ mapBranches := make(map[string]string)
+
+ if len(r.ProtectedBranches) > 0 {
+ // using repository branches
+ glog.Infof("using repository branches: %s", *r.Name)
+ for _, b := range r.ProtectedBranches {
+ mapBranches[b] = b
+ }
+ } else {
+ // using community branches
+ glog.Infof("using community branches: %s", *r.Name)
+ for _, b := range c.ProtectedBranches {
+ mapBranches[b] = b
+ }
+ }
+
+ // get branches from DB
+ var bs []database.Branches
+ err := database.DBConnection.Model(&database.Branches{}).
+ Where("owner = ? and repo = ?", c.Name, r.Name).Find(&bs).Error
+ if err != nil {
+ glog.Errorf("unable to get branches: %v", err)
+ return err
+ }
+ mapBranchesInDB := make(map[string]string)
+ for _, b := range bs {
+ mapBranchesInDB[b.Name] = strconv.Itoa(int(b.ID))
+ }
+
+ // un-protected branches
+ err = handler.removeBranchProtections(c, r, mapBranches, mapBranchesInDB)
+ if err != nil {
+ glog.Errorf("unable to un-protected branches: %v", err)
+ }
+
+ // protected branches
+ err = handler.addBranchProtections(c, r, mapBranches, mapBranchesInDB)
+ if err != nil {
+ glog.Errorf("unable to protected branches: %v", err)
+ }
+
+ return nil
+}
+
+// unprotectedBranches unprotect branches
+func (handler *InitHandler) removeBranchProtections(c Community, r Repository, mapBranches, mapBranchesInDB map[string]string) error {
+ // remove branch protections
+ listOfUnprotectedBranches := make([]string, 0)
+
+ for k := range mapBranchesInDB {
+ if _, exists := mapBranches[k]; !exists {
+ listOfUnprotectedBranches = append(listOfUnprotectedBranches, k)
+ }
+ }
+ glog.Infof("list of un-protected branches: %v", listOfUnprotectedBranches)
+
+ if len(listOfUnprotectedBranches) > 0 {
+ opts := &gitee.DeleteV5ReposOwnerRepoBranchesBranchProtectionOpts{}
+ opts.AccessToken = optional.NewString(handler.Config.GiteeToken)
+
+ glog.Infof("begin to remove branch protections for %s", *r.Name)
+ for _, v := range listOfUnprotectedBranches {
+ // remove branch protection from gitee
+ _, err := handler.GiteeClient.RepositoriesApi.DeleteV5ReposOwnerRepoBranchesBranchProtection(
+ handler.Context, *c.Name, *r.Name, v, opts)
+ if err != nil {
+ glog.Errorf("failed to remove branch protection: %v", err)
+ continue
+ }
+ // remove branch protection from DB
+ id, _ := strconv.Atoi(mapBranchesInDB[v])
+ bs := database.Branches{}
+ bs.ID = uint(id)
+ err = database.DBConnection.Delete(&bs).Error
+ if err != nil {
+ glog.Errorf("failed to remove branch protection in database: %v", err)
+ }
+ }
+ glog.Infof("end to remove branch protections for %s", *r.Name)
+ }
+
+ return nil
+}
+
+// addBranchProtections protects branches
+func (handler *InitHandler) addBranchProtections(c Community, r Repository, mapBranches, mapBranchesInDB map[string]string) error {
+ // add branch protections
+ listOfProtectedBranches := make([]string, 0)
+
+ for k := range mapBranches {
+ if _, exits := mapBranchesInDB[k]; !exits {
+ listOfProtectedBranches = append(listOfProtectedBranches, k)
+ }
+ }
+ glog.Infof("list of protected branches: %v", listOfProtectedBranches)
+
+ if len(listOfProtectedBranches) > 0 {
+ getOpts := &gitee.GetV5ReposOwnerRepoBranchesBranchOpts{}
+ getOpts.AccessToken = optional.NewString(handler.Config.GiteeToken)
+
+ protectBody := gitee.BranchProtectionPutParam{}
+ protectBody.AccessToken = handler.Config.GiteeToken
+
+ glog.Infof("begin to add branch protections for %s", *r.Name)
+ for _, v := range listOfProtectedBranches {
+ // check if protected branch exists
+ branchObj, response, _ := handler.GiteeClient.RepositoriesApi.GetV5ReposOwnerRepoBranchesBranch(
+ handler.Context, *c.Name, *r.Name, v, getOpts)
+ if response.StatusCode == 404 {
+ glog.Errorf("branch %s not exists, no need for protection", v)
+ continue
+ }
+
+ // If branch has alreay been protected, no need for protection
+ if branchObj.Protected == "true" {
+ glog.Errorf("branch %s has been protected already, no need for protection", v)
+ continue
+ }
+
+ // add branch protection to gitee
+ _, response, err := handler.GiteeClient.RepositoriesApi.PutV5ReposOwnerRepoBranchesBranchProtection(
+ handler.Context, *c.Name, *r.Name, v, protectBody)
+ if err != nil {
+ glog.Errorf("failed to add branch protection: %v", err)
+ continue
+ }
+ // add branch protection to database
+ bs := database.Branches{
+ Owner: *c.Name,
+ Repo: *r.Name,
+ Name: v,
+ Type: BranchProtected,
+ }
+ err = database.DBConnection.Create(&bs).Error
+ if err != nil {
+ glog.Errorf("failed to add branch protection in database: %v", err)
+ }
+ }
+ glog.Infof("end to add branch protections for %s", *r.Name)
+ }
+
+ return nil
+}
+
+// handleRepositoryTypes handles that the repo is private or public
+func (handler *InitHandler) handleRepositoryTypes(c Community, r Repository) error {
+ // get repos from DB
+ var rs database.Repositories
+ err := database.DBConnection.Model(&database.Repositories{}).
+ Where("owner = ? and repo = ?", c.Name, r.Name).First(&rs).Error
+ if err != nil {
+ glog.Errorf("unable to get repositories files: %v", err)
+ return err
+ }
+
+ // the type is changed
+ if rs.Type != *r.Type {
+ // set value
+ isSetPrivate := false
+ if *r.Type == "private" {
+ isSetPrivate = true
+ }
+
+ // invoke query repository
+ glog.Infof("begin to query repository: %s", *r.Name)
+ localVarOptionals := &gitee.GetV5ReposOwnerRepoOpts{}
+ localVarOptionals.AccessToken = optional.NewString(handler.Config.GiteeToken)
+ pj, response, _ := handler.GiteeClient.RepositoriesApi.GetV5ReposOwnerRepo(
+ handler.Context, *c.Name, *r.Name, localVarOptionals)
+ if response.StatusCode == 404 {
+ glog.Infof("repository is not exist: %s", *r.Name)
+ return nil
+ }
+ if pj.Private == isSetPrivate {
+ glog.Infof("repository type is already: %s", *r.Type)
+ } else {
+ // build patch repository param
+ patchBody := gitee.RepoPatchParam{}
+ patchBody.AccessToken = handler.Config.GiteeToken
+ patchBody.Name = pj.Name
+ patchBody.Description = pj.Description
+ patchBody.Homepage = pj.Homepage
+ if pj.HasIssues {
+ patchBody.HasIssues = "true"
+ } else {
+ patchBody.HasIssues = "false"
+ }
+ if pj.HasWiki {
+ patchBody.HasWiki = "true"
+ } else {
+ patchBody.HasWiki = "false"
+ }
+ if isSetPrivate {
+ patchBody.Private = "true"
+ } else {
+ patchBody.Private = "false"
+ }
+
+ // invoke set type
+ _, _, err = handler.GiteeClient.RepositoriesApi.PatchV5ReposOwnerRepo(handler.Context, *c.Name, *r.Name, patchBody)
+ if err != nil {
+ glog.Errorf("unable to set repository type: %v", err)
+ return err
+ }
+ }
+
+ // define update repository
+ updaterepo := &database.Repositories{}
+ updaterepo.ID = rs.ID
+ err = database.DBConnection.Model(updaterepo).Update("Type", *r.Type).Error
+ if err != nil {
+ glog.Errorf("unable to update type: %v", err)
+ }
+ }
+
+ return nil
+}
diff --git a/pkg/cibot/issue.go b/pkg/cibot/issue.go
new file mode 100644
index 0000000000000000000000000000000000000000..d78378eda251222a438e0520e696f2b534390b5a
--- /dev/null
+++ b/pkg/cibot/issue.go
@@ -0,0 +1,39 @@
+package cibot
+
+import (
+ "fmt"
+
+ "gitee.com/openeuler/go-gitee/gitee"
+ "github.com/golang/glog"
+)
+
+// HandleIssueEvent handles issue event
+func (s *Server) HandleIssueEvent(event *gitee.IssueEvent) {
+ if event == nil {
+ return
+ }
+
+ // handle events
+ switch *event.Action {
+ case "open":
+ glog.Info("received a issue open event")
+
+ // add comment
+ body := gitee.IssueCommentPostParam{}
+ body.AccessToken = s.Config.GiteeToken
+ body.Body = fmt.Sprintf(tipBotMessage, event.Sender.Login, s.Config.CommunityName, s.Config.CommunityName,
+ s.Config.BotName, s.Config.CommandLink)
+ //Issue could exists without belonging to any repo.
+ if event.Repository == nil {
+ glog.Warningf("Issue is not created on repo, skip posting issue comment.")
+ return
+ }
+ owner := event.Repository.Namespace
+ repo := event.Repository.Name
+ number := event.Issue.Number
+ _, _, err := s.GiteeClient.IssuesApi.PostV5ReposOwnerRepoIssuesNumberComments(s.Context, owner, repo, number, body)
+ if err != nil {
+ glog.Errorf("unable to add comment in issue: %v", err)
+ }
+ }
+}
diff --git a/pkg/cibot/label.go b/pkg/cibot/label.go
new file mode 100644
index 0000000000000000000000000000000000000000..ec2df41608c63c34bc65bb0739ae56b1444d06f5
--- /dev/null
+++ b/pkg/cibot/label.go
@@ -0,0 +1,632 @@
+package cibot
+
+import (
+ "fmt"
+ "math/rand"
+ "strings"
+ "time"
+
+ "github.com/antihax/optional"
+
+ "gitee.com/openeuler/go-gitee/gitee"
+ "github.com/golang/glog"
+)
+
+// GetLabelsMap for add or remove labels
+func GetLabelsMap(comment string) map[string]string {
+ // init labels map
+ mapOfLabels := map[string]string{}
+ // split with blank space
+ substrings := strings.Split(strings.TrimSpace(comment), " ")
+ // init label group
+ labelGroup := ""
+ // range over the substrings to get the map of labels
+ for i, l := range substrings {
+ if i == 0 {
+ // first index is the operation to be performed, rest will be the labels
+ // the label group. e.g kind, priority
+ labelGroup = strings.Replace(strings.Replace(l, "/", "", 1), "remove-", "", 1)
+ } else {
+ // the whole label = label group + / + label. e.g kind/feature
+ wholeLabel := labelGroup + "/" + l
+ // use map to avoid the reduplicate label
+ mapOfLabels[wholeLabel] = wholeLabel
+ }
+ }
+ return mapOfLabels
+}
+
+// GetListOfAddLabels return the exact list of add labels
+func GetListOfAddLabels(mapOfAddLabels map[string]string, listofRepoLabels []gitee.Label, listofItemLabels []gitee.Label) []string {
+ // init
+ listOfAddLabels := make([]string, 0)
+ // range over the map to filter the list of labels
+ for l := range mapOfAddLabels {
+ // check if the label is existing in current gitee repository
+ existingInRepo := false
+ for _, repoLabel := range listofRepoLabels {
+ if l == repoLabel.Name {
+ existingInRepo = true
+ break
+ }
+ }
+ // the label is not existing in current gitee repository so it can not add this label
+ if !existingInRepo {
+ glog.Infof("label %s is not existing in repository", l)
+ continue
+ }
+
+ // check if the label is existing in current item
+ existingInItem := false
+ for _, itemLabel := range listofItemLabels {
+ if l == itemLabel.Name {
+ existingInItem = true
+ break
+ }
+ }
+ // the label is already existing in current item so it is no need to add this label
+ if existingInItem {
+ glog.Infof("label %s is already existing in current item", l)
+ continue
+ }
+
+ // append
+ listOfAddLabels = append(listOfAddLabels, l)
+ }
+ return listOfAddLabels
+}
+
+// GetListOfRemoveLabels return the exact list of remove labels
+func GetListOfRemoveLabels(mapOfRemoveLabels map[string]string, listofItemLabels []gitee.Label) []string {
+ // init
+ listOfRemoveLabels := make([]string, 0)
+ // range over the map to filter the list of labels
+ for l := range mapOfRemoveLabels {
+ // check if the label is existing in current item
+ existingInItem := false
+ for _, itemLabel := range listofItemLabels {
+ if l == itemLabel.Name {
+ existingInItem = true
+ break
+ }
+ }
+ // the label is not existing in current item so it is no need to remove this label
+ if !existingInItem {
+ glog.Infof("label %s is not existing in current item", l)
+ continue
+ }
+
+ // append
+ listOfRemoveLabels = append(listOfRemoveLabels, l)
+ }
+ return listOfRemoveLabels
+}
+
+// AddLabel adds label
+func (s *Server) AddLabel(event *gitee.NoteEvent) error {
+ if *event.NoteableType == "PullRequest" {
+ // PullRequest
+ return s.AddLabelInPulRequest(event)
+ } else if *event.NoteableType == "Issue" {
+ // Issue
+ return s.AddLabelInIssue(event)
+ } else {
+ return nil
+ }
+}
+
+// AddLabelInPulRequest adds label in pull request
+func (s *Server) AddLabelInPulRequest(event *gitee.NoteEvent) error {
+ // get basic informations
+ comment := event.Comment.Body
+ owner := event.Repository.Namespace
+ repo := event.Repository.Name
+ var number int32
+ if event.PullRequest != nil {
+ number = event.PullRequest.Number
+ }
+ glog.Infof("add label started. comment: %s owner: %s repo: %s number: %d",
+ comment, owner, repo, number)
+
+ // /kind label1
+ // /kind label2
+ getLabels := strings.Split(comment, "\r\n")
+
+ for _, labelToAdd := range getLabels {
+ // map of add labels
+ mapOfAddLabels := GetLabelsMap(labelToAdd)
+ glog.Infof("map of add labels: %v", mapOfAddLabels)
+
+ // list labels in current gitee repository
+ lvosRepo := &gitee.GetV5ReposOwnerRepoLabelsOpts{}
+ lvosRepo.AccessToken = optional.NewString(s.Config.GiteeToken)
+ listofRepoLabels, _, err := s.GiteeClient.LabelsApi.GetV5ReposOwnerRepoLabels(s.Context, owner, repo, lvosRepo)
+ if err != nil {
+ glog.Errorf("unable to list repository labels. err: %v", err)
+ return err
+ }
+ glog.Infof("list of repository labels: %v", listofRepoLabels)
+
+ // list labels in current item
+ lvos := &gitee.GetV5ReposOwnerRepoPullsNumberOpts{}
+ lvos.AccessToken = optional.NewString(s.Config.GiteeToken)
+ pr, _, err := s.GiteeClient.PullRequestsApi.GetV5ReposOwnerRepoPullsNumber(s.Context, owner, repo, number, lvos)
+ if err != nil {
+ glog.Errorf("unable to get pull request. err: %v", err)
+ return err
+ }
+ listofItemLabels := pr.Labels
+ glog.Infof("list of item labels: %v", listofItemLabels)
+
+ // list of add labels
+ listOfAddLabels := GetListOfAddLabels(mapOfAddLabels, listofRepoLabels, listofItemLabels)
+ glog.Infof("list of add labels: %v", listOfAddLabels)
+
+ // invoke gitee api to add labels
+ if len(listOfAddLabels) > 0 {
+ // build label string
+ var strLabel string
+ for _, currentlabel := range listofItemLabels {
+ strLabel += currentlabel.Name + ","
+ }
+ for _, addedlabel := range listOfAddLabels {
+ strLabel += addedlabel + ","
+ }
+ strLabel = strings.TrimRight(strLabel, ",")
+ body := gitee.PullRequestUpdateParam{}
+ body.AccessToken = s.Config.GiteeToken
+ body.Labels = strLabel
+ glog.Infof("invoke api to add labels: %v", strLabel)
+
+ // patch labels
+ _, response, err := s.GiteeClient.PullRequestsApi.PatchV5ReposOwnerRepoPullsNumber(s.Context, owner, repo, number, body)
+ if err != nil {
+ if response.StatusCode == 400 {
+ glog.Infof("add labels successfully with status code %d: %v", response.StatusCode, listOfAddLabels)
+ } else {
+ glog.Errorf("unable to add labels: %v err: %v", listOfAddLabels, err)
+ return err
+ }
+ } else {
+ glog.Infof("add labels successfully: %v", listOfAddLabels)
+ }
+ } else {
+ glog.Infof("no label to add for this event")
+ }
+ }
+
+ return nil
+}
+
+func (s *Server) labelDiffer(new []string, existing []gitee.Label) ([]string, []string) {
+ mb := make(map[string]struct{}, len(existing))
+ for _, x := range existing {
+ mb[x.Name] = struct{}{}
+ }
+ var diff []string
+ var same []string
+ for _, x := range new {
+ if _, found := mb[x]; !found {
+ diff = append(diff, x)
+ } else {
+ same = append(same, x)
+ }
+ }
+ return diff, same
+}
+
+// AddLabelInIssue adds label in issue
+func (s *Server) AddLabelInIssue(event *gitee.NoteEvent) error {
+ // get basic informations
+ comment := event.Comment.Body
+ owner := event.Repository.Namespace
+ repo := event.Repository.Name
+ var number string
+ if event.Issue != nil {
+ number = event.Issue.Number
+ }
+ glog.Infof("add label started. comment: %s owner: %s repo: %s number: %s",
+ comment, owner, repo, number)
+
+ // /kind label1
+ // /kind label2
+ getLabels := strings.Split(comment, "\r\n")
+
+ for _, labelToAdd := range getLabels {
+ // map of add labels
+ mapOfAddLabels := GetLabelsMap(labelToAdd)
+ glog.Infof("map of add labels: %v", mapOfAddLabels)
+
+ // list labels in current gitee repository
+ lvosRepo := &gitee.GetV5ReposOwnerRepoLabelsOpts{}
+ lvosRepo.AccessToken = optional.NewString(s.Config.GiteeToken)
+ listofRepoLabels, _, err := s.GiteeClient.LabelsApi.GetV5ReposOwnerRepoLabels(s.Context, owner, repo, lvosRepo)
+ if err != nil {
+ glog.Errorf("unable to list repository labels. err: %v", err)
+ return err
+ }
+ glog.Infof("list of repository labels: %v", listofRepoLabels)
+
+ // list labels in current item
+ lvos := &gitee.GetV5ReposOwnerRepoIssuesNumberLabelsOpts{}
+ lvos.AccessToken = optional.NewString(s.Config.GiteeToken)
+ listofItemLabels, _, err := s.GiteeClient.LabelsApi.GetV5ReposOwnerRepoIssuesNumberLabels(s.Context, owner, repo, number, lvos)
+ if err != nil {
+ glog.Errorf("unable to get labels in issue. err: %v", err)
+ return err
+ }
+ glog.Infof("list of item labels: %v", listofItemLabels)
+
+ // list of add labels
+ listOfAddLabels := GetListOfAddLabels(mapOfAddLabels, listofRepoLabels, listofItemLabels)
+ glog.Infof("list of add labels: %v", listOfAddLabels)
+
+ // invoke gitee api to add labels
+ if len(listOfAddLabels) > 0 {
+ // build label string
+ var strLabel string
+ for _, currentlabel := range listofItemLabels {
+ strLabel += currentlabel.Name + ","
+ }
+ for _, addedlabel := range listOfAddLabels {
+ strLabel += addedlabel + ","
+ }
+ strLabel = strings.TrimRight(strLabel, ",")
+ body := gitee.IssueUpdateParam{}
+ body.Repo = repo
+ body.AccessToken = s.Config.GiteeToken
+ body.Labels = strLabel
+ glog.Infof("invoke api to add labels: %v", strLabel)
+
+ // patch labels
+ _, _, err := s.GiteeClient.IssuesApi.PatchV5ReposOwnerIssuesNumber(s.Context, owner, number, body)
+ if err != nil {
+ glog.Errorf("unable to add labels: %v err: %v", listOfAddLabels, err)
+ return err
+ } else {
+ glog.Infof("add labels successfully: %v", listOfAddLabels)
+ }
+ } else {
+ glog.Infof("no label to add for this event")
+ }
+ }
+
+ return nil
+}
+
+// RemoveLabel removes label
+func (s *Server) RemoveLabel(event *gitee.NoteEvent) error {
+ if *event.NoteableType == "PullRequest" {
+ // PullRequest
+ return s.RemoveLabelInPullRequest(event)
+ } else if *event.NoteableType == "Issue" {
+ // Issue
+ return s.RemoveLabelInIssue(event)
+ } else {
+ return nil
+ }
+}
+
+// RemoveLabelInPullRequest removes label in pull request
+func (s *Server) RemoveLabelInPullRequest(event *gitee.NoteEvent) error {
+ // get basic informations
+ comment := event.Comment.Body
+ owner := event.Repository.Namespace
+ repo := event.Repository.Name
+ var number int32
+ if event.PullRequest != nil {
+ number = event.PullRequest.Number
+ }
+ glog.Infof("remove label started. comment: %s owner: %s repo: %s number: %d",
+ comment, owner, repo, number)
+
+ // /remove-kind label1
+ // /remove-kind label2
+ getLables := strings.Split(comment, "\r\n")
+
+ for _, labelToRemove := range getLables {
+ // map of add labels
+ mapOfRemoveLabels := GetLabelsMap(labelToRemove)
+ glog.Infof("map of remove labels: %v", mapOfRemoveLabels)
+
+ // list labels in current item
+ lvos := &gitee.GetV5ReposOwnerRepoPullsNumberOpts{}
+ lvos.AccessToken = optional.NewString(s.Config.GiteeToken)
+ pr, _, err := s.GiteeClient.PullRequestsApi.GetV5ReposOwnerRepoPullsNumber(s.Context, owner, repo, number, lvos)
+ if err != nil {
+ glog.Errorf("unable to get pull request. err: %v", err)
+ return err
+ }
+ listofItemLabels := pr.Labels
+ glog.Infof("list of item labels: %v", listofItemLabels)
+
+ // list of remove labels
+ listOfRemoveLabels := GetListOfRemoveLabels(mapOfRemoveLabels, listofItemLabels)
+ glog.Infof("list of remove labels: %v", listOfRemoveLabels)
+
+ // invoke gitee api to remove labels
+ if len(listOfRemoveLabels) > 0 {
+ // build label string
+ var strLabel string
+ for _, currentlabel := range listofItemLabels {
+ strLabel += currentlabel.Name + ","
+ }
+ for _, removedlabel := range listOfRemoveLabels {
+ strLabel = strings.Replace(strLabel, removedlabel+",", "", 1)
+
+ }
+ strLabel = strings.TrimRight(strLabel, ",")
+ // avoid to unable to remove labels when no label is exsit
+ if strLabel == "" {
+ strLabel = ","
+ }
+ body := gitee.PullRequestUpdateParam{}
+ body.AccessToken = s.Config.GiteeToken
+ body.Labels = strLabel
+ glog.Infof("invoke api to remove labels: %v", strLabel)
+
+ // patch labels
+ _, response, err := s.GiteeClient.PullRequestsApi.PatchV5ReposOwnerRepoPullsNumber(s.Context, owner, repo, number, body)
+ if err != nil {
+ if response.StatusCode == 400 {
+ glog.Infof("remove labels successfully with status code %d: %v", response.StatusCode, listOfRemoveLabels)
+ } else {
+ glog.Errorf("unable to remove labels: %v err: %v", listOfRemoveLabels, err)
+ return err
+ }
+ } else {
+ glog.Infof("remove labels successfully: %v", listOfRemoveLabels)
+ }
+ } else {
+ glog.Infof("no label to remove for this event")
+ }
+ }
+
+ return nil
+}
+
+// RemoveLabelInIssue removes label in issue
+func (s *Server) RemoveLabelInIssue(event *gitee.NoteEvent) error {
+ // get basic informations
+ comment := event.Comment.Body
+ owner := event.Repository.Namespace
+ repo := event.Repository.Name
+ var number string
+ if event.Issue != nil {
+ number = event.Issue.Number
+ }
+ glog.Infof("remove label started. comment: %s owner: %s repo: %s number: %s",
+ comment, owner, repo, number)
+
+ // /remove-kind label1
+ // /remove-kind label2
+ getLables := strings.Split(comment, "\r\n")
+
+ for _, labelToRemove := range getLables {
+ // map of add labels
+ mapOfRemoveLabels := GetLabelsMap(labelToRemove)
+ glog.Infof("map of remove labels: %v", mapOfRemoveLabels)
+
+ // list labels in current item
+ lvos := &gitee.GetV5ReposOwnerRepoIssuesNumberLabelsOpts{}
+ lvos.AccessToken = optional.NewString(s.Config.GiteeToken)
+ listofItemLabels, _, err := s.GiteeClient.LabelsApi.GetV5ReposOwnerRepoIssuesNumberLabels(s.Context, owner, repo, number, lvos)
+ if err != nil {
+ glog.Errorf("unable to get labels in issue. err: %v", err)
+ return err
+ }
+ glog.Infof("list of item labels: %v", listofItemLabels)
+
+ // list of remove labels
+ listOfRemoveLabels := GetListOfRemoveLabels(mapOfRemoveLabels, listofItemLabels)
+ glog.Infof("list of remove labels: %v", listOfRemoveLabels)
+
+ // invoke gitee api to remove labels
+ if len(listOfRemoveLabels) > 0 {
+ glog.Infof("invoke api to remove labels: %v", listOfRemoveLabels)
+ // remove labels
+ for _, removedlabel := range listOfRemoveLabels {
+ localVarOptionals := &gitee.DeleteV5ReposOwnerRepoIssuesNumberLabelsNameOpts{}
+ localVarOptionals.AccessToken = optional.NewString(s.Config.GiteeToken)
+ _, err := s.GiteeClient.LabelsApi.DeleteV5ReposOwnerRepoIssuesNumberLabelsName(
+ s.Context, owner, repo, number, UrlEncode(removedlabel), localVarOptionals)
+ if err != nil {
+ glog.Errorf("unable to remove label: %s err: %v", removedlabel, err)
+ return err
+ } else {
+ glog.Infof("remove label successfully: %s", removedlabel)
+ }
+ }
+ } else {
+ glog.Infof("no label to remove for this event")
+ }
+ }
+
+ return nil
+}
+
+func (s *Server) generateLabelLuckyColor() string {
+ cRand := rand.New(rand.NewSource(time.Now().Unix()))
+ return fmt.Sprintf("%02x%02x%02x", cRand.Intn(255), cRand.Intn(255), cRand.Intn(255))
+}
+
+func (s *Server) patchPRLabels(labels []string, owner, repo string, number int32) error {
+ // list labels in current pr
+ lvos := &gitee.GetV5ReposOwnerRepoPullsNumberOpts{
+ AccessToken: optional.NewString(s.Config.GiteeToken),
+ }
+ pr, _, err := s.GiteeClient.PullRequestsApi.GetV5ReposOwnerRepoPullsNumber(s.Context, owner, repo, number, lvos)
+ if err != nil {
+ glog.Errorf("unable to get pull request. err: %v", err)
+ return err
+ }
+ glog.Infof("list of pr labels: %v", pr.Labels)
+
+ // list of add labels
+ newLabels, _ := s.labelDiffer(labels, pr.Labels)
+ if len(newLabels) == 0 {
+ glog.Info("all labels existed in pr, skip updating.")
+ return nil
+ }
+ glog.Infof("list of add labels in pr: %v", newLabels)
+
+ // invoke gitee api to add labels
+ if len(newLabels) > 0 {
+ // build label string
+ var labelSlice []string
+ for _, l := range pr.Labels {
+ labelSlice = append(labelSlice, l.Name)
+ }
+ labelSlice = append(labelSlice, newLabels...)
+ body := gitee.PullRequestUpdateParam{}
+ body.AccessToken = s.Config.GiteeToken
+ body.Labels = strings.Join(labelSlice, ",")
+ glog.Infof("invoke api to add labels: %v", labelSlice)
+
+ // patch labels
+ _, response, err := s.GiteeClient.PullRequestsApi.PatchV5ReposOwnerRepoPullsNumber(s.Context, owner, repo, number, body)
+ if err != nil {
+ if response.StatusCode == 400 {
+ glog.Infof("add labels successfully with status code %d: %v", response.StatusCode, newLabels)
+ } else {
+ glog.Errorf("unable to add labels: %v err: %v", newLabels, err)
+ return err
+ }
+ } else {
+ glog.Infof("add labels successfully: %v", newLabels)
+ }
+ } else {
+ glog.Infof("no label to add for this event")
+ }
+ return nil
+}
+
+func (s *Server) patchRepoLabels(labels []string, owner, repo string, createNew bool) ([]string, error) {
+ // list labels in current gitee repository
+ lvosRepo := &gitee.GetV5ReposOwnerRepoLabelsOpts{
+ AccessToken: optional.NewString(s.Config.GiteeToken),
+ }
+ listofRepoLabels, _, err := s.GiteeClient.LabelsApi.GetV5ReposOwnerRepoLabels(s.Context, owner, repo, lvosRepo)
+ if err != nil {
+ glog.Errorf("unable to list repository labels. err: %v", err)
+ return []string{}, err
+ }
+ glog.Infof("list of repository labels: %v", listofRepoLabels)
+ newLabels, existlabel := s.labelDiffer(labels, listofRepoLabels)
+ if len(newLabels) == 0 {
+ glog.Info("all labels existed in repo, skip creating.")
+ return existlabel, nil
+ }
+ if !createNew {
+ glog.Info("'createNew' flag is false, skip creating.")
+ return existlabel,nil
+ }
+ createLabelParam := gitee.LabelPostParam{
+ AccessToken: s.Config.GiteeToken,
+ }
+ for _, label := range newLabels {
+ createLabelParam.Name = label
+ createLabelParam.Color = s.generateLabelLuckyColor()
+ result, httpResponse, err := s.GiteeClient.LabelsApi.PostV5ReposOwnerRepoLabels(
+ s.Context, owner, repo, createLabelParam)
+ if err != nil {
+ glog.Errorf("unable to create repository label. %v, err: %v and %v", result, err.Error(), *httpResponse)
+ return []string{}, err
+ }
+ }
+ return labels, nil
+}
+
+// AddSpecifyLabelInPulRequest adds specify labels in pull request
+func (s *Server) AddSpecifyLabelsInPulRequest(event *gitee.NoteEvent, newLabels []string, createNew bool) error {
+ // get basic information
+ comment := event.Comment.Body
+ owner := event.Repository.Namespace
+ repo := event.Repository.Name
+ var number int32
+ if event.PullRequest != nil {
+ number = event.PullRequest.Number
+ }
+ glog.Infof("add specify label started. comment: %s owner: %s repo: %s number: %d",
+ comment, owner, repo, number)
+
+ // patch repo labels
+ legalLabels, err := s.patchRepoLabels(newLabels, owner, repo, createNew)
+ if err != nil {
+ return err
+ }
+
+ // patch pr labels
+ if err := s.patchPRLabels(legalLabels, owner, repo, number); err != nil {
+ return err
+ }
+ return nil
+}
+
+// RemoveSpecifyLabelsInPulRequest removes specify labels in pull request
+func (s *Server) RemoveSpecifyLabelsInPulRequest(event *gitee.NoteEvent, mapOfRemoveLabels map[string]string) error {
+ // get basic information
+ comment := event.Comment.Body
+ owner := event.Repository.Namespace
+ repo := event.Repository.Name
+ var number int32
+ if event.PullRequest != nil {
+ number = event.PullRequest.Number
+ }
+ glog.Infof("remove label started. comment: %s owner: %s repo: %s number: %d",
+ comment, owner, repo, number)
+
+ // list labels in current item
+ lvos := &gitee.GetV5ReposOwnerRepoPullsNumberOpts{}
+ lvos.AccessToken = optional.NewString(s.Config.GiteeToken)
+ pr, _, err := s.GiteeClient.PullRequestsApi.GetV5ReposOwnerRepoPullsNumber(s.Context, owner, repo, number, lvos)
+ if err != nil {
+ glog.Errorf("unable to get pull request. err: %v", err)
+ return err
+ }
+ listofItemLabels := pr.Labels
+ glog.Infof("list of item labels: %v", listofItemLabels)
+
+ // list of remove labels
+ listOfRemoveLabels := GetListOfRemoveLabels(mapOfRemoveLabels, listofItemLabels)
+ glog.Infof("list of remove labels: %v", listOfRemoveLabels)
+
+ // invoke gitee api to remove labels
+ if len(listOfRemoveLabels) > 0 {
+ // build label string
+ var strLabel string
+ for _, currentlabel := range listofItemLabels {
+ strLabel += currentlabel.Name + ","
+ }
+ for _, removedlabel := range listOfRemoveLabels {
+ strLabel = strings.Replace(strLabel, removedlabel+",", "", 1)
+
+ }
+ strLabel = strings.TrimRight(strLabel, ",")
+ // avoid to unable to remove labels when no label is exsit
+ if strLabel == "" {
+ strLabel = ","
+ }
+ body := gitee.PullRequestUpdateParam{}
+ body.AccessToken = s.Config.GiteeToken
+ body.Labels = strLabel
+ glog.Infof("invoke api to remove labels: %v", strLabel)
+
+ // patch labels
+ _, response, err := s.GiteeClient.PullRequestsApi.PatchV5ReposOwnerRepoPullsNumber(s.Context, owner, repo, number, body)
+ if err != nil {
+ if response.StatusCode == 400 {
+ glog.Infof("remove labels successfully with status code %d: %v", response.StatusCode, listOfRemoveLabels)
+ } else {
+ glog.Errorf("unable to remove labels: %v err: %v", listOfRemoveLabels, err)
+ return err
+ }
+ } else {
+ glog.Infof("remove labels successfully: %v", listOfRemoveLabels)
+ }
+ } else {
+ glog.Infof("no label to remove for this event")
+ }
+
+ return nil
+}
diff --git a/pkg/cibot/lgtm.go b/pkg/cibot/lgtm.go
new file mode 100644
index 0000000000000000000000000000000000000000..42ba225d03201edfce0287fba47c54d52c3cc01f
--- /dev/null
+++ b/pkg/cibot/lgtm.go
@@ -0,0 +1,319 @@
+package cibot
+
+import (
+ "fmt"
+ "strings"
+
+ "github.com/antihax/optional"
+
+ "gitee.com/openeuler/go-gitee/gitee"
+ "github.com/golang/glog"
+)
+
+const (
+ lgtmSelfOwnMessage = `***lgtm*** can not be added in your self-own pull request. :astonished: `
+ lgtmAddedMessage = `***lgtm*** is added in this pull request by: ***@%s***. :wave: `
+ lgtmRemovedMessage = `***lgtm*** is removed in this pull request by: ***@%s***. :flushed: `
+ lgtmAddNoPermissionMessage = `***@%s*** has no permission to add ***lgtm*** in this pull request. :astonished:
+please contact to the collaborators in this repository.`
+ lgtmRemoveNoPermissionMessage = `***@%s*** has no permission to remove ***lgtm*** in this pull request. :astonished:
+please contact to the collaborators in this repository.`
+ lgtmRemovePullRequestChangeMessage = `new changes are detected. ***lgtm*** is removed in this pull request by: ***@%s***. :flushed: `
+)
+
+// AddLgtm adds lgtm label
+func (s *Server) AddLgtm(event *gitee.NoteEvent) error {
+ // handle PullRequest
+ if *event.NoteableType == "PullRequest" {
+ // handle open
+ if event.PullRequest.State == "open" {
+ // get basic params
+ comment := event.Comment.Body
+ owner := event.Repository.Namespace
+ repo := event.Repository.Name
+ prAuthor := event.PullRequest.User.Login
+ prNumber := event.PullRequest.Number
+ commentAuthor := event.Comment.User.Login
+ glog.Infof("add lgtm started. comment: %s prAuthor: %s commentAuthor: %s owner: %s repo: %s number: %d",
+ comment, prAuthor, commentAuthor, owner, repo, prNumber)
+
+ // can not lgtm on self-own pr
+ if prAuthor == commentAuthor {
+ glog.Info("can not lgtm on self-own pr")
+ // add comment
+ body := gitee.PullRequestCommentPostParam{}
+ body.AccessToken = s.Config.GiteeToken
+ body.Body = lgtmSelfOwnMessage
+ owner := event.Repository.Namespace
+ repo := event.Repository.Name
+ number := event.PullRequest.Number
+ _, _, err := s.GiteeClient.PullRequestsApi.PostV5ReposOwnerRepoPullsNumberComments(s.Context, owner, repo, number, body)
+ if err != nil {
+ glog.Errorf("unable to add comment in pull request: %v", err)
+ return err
+ }
+ return nil
+ }
+
+ // check if current author has write permission
+ localVarOptionals := &gitee.GetV5ReposOwnerRepoCollaboratorsUsernamePermissionOpts{}
+ localVarOptionals.AccessToken = optional.NewString(s.Config.GiteeToken)
+ // get permission
+ permission, _, err := s.GiteeClient.RepositoriesApi.GetV5ReposOwnerRepoCollaboratorsUsernamePermission(
+ s.Context, owner, repo, commentAuthor, localVarOptionals)
+ if err != nil {
+ glog.Errorf("unable to get comment author permission: %v", err)
+ return err
+ }
+ // check author is owner
+ isOwner := s.CheckIsOwner(event, commentAuthor)
+
+ // check sigs
+ r, err := canCommentPrIncludingSigDirectory(s, owner, repo, prNumber, commentAuthor)
+ glog.Infof("sig owners check: can comment, r=%v, err=%v\n", r, err)
+ if err != nil {
+ glog.Errorf("unable to check sigs permission: %v", err)
+ return err
+ }
+
+ // permission: admin, write, read, none
+ if permission.Permission == "admin" || permission.Permission == "write" || isOwner || r == 1 {
+ // add lgtm label
+ addlabel := &gitee.NoteEvent{}
+ addlabel.PullRequest = event.PullRequest
+ addlabel.Repository = event.Repository
+ addlabel.Comment = &gitee.NoteHook{}
+ err = s.AddSpecifyLabelsInPulRequest(addlabel, []string{s.getLgtmLable(commentAuthor)}, true)
+ if err != nil {
+ return err
+ }
+ // add comment
+ body := gitee.PullRequestCommentPostParam{}
+ body.AccessToken = s.Config.GiteeToken
+ body.Body = fmt.Sprintf(lgtmAddedMessage, commentAuthor) + fmt.Sprintf(LabelHiddenValue, event.PullRequest.Head.Sha)
+ owner := event.Repository.Namespace
+ repo := event.Repository.Name
+ number := event.PullRequest.Number
+ _, _, err := s.GiteeClient.PullRequestsApi.PostV5ReposOwnerRepoPullsNumberComments(s.Context, owner, repo, number, body)
+ if err != nil {
+ glog.Errorf("unable to add comment in pull request: %v", err)
+ return err
+ }
+ // try to merge pr
+ err = s.MergePullRequest(event)
+ if err != nil {
+ return err
+ }
+ } else {
+ // add comment
+ body := gitee.PullRequestCommentPostParam{}
+ body.AccessToken = s.Config.GiteeToken
+ body.Body = fmt.Sprintf(lgtmAddNoPermissionMessage, commentAuthor)
+ owner := event.Repository.Namespace
+ repo := event.Repository.Name
+ number := event.PullRequest.Number
+ _, _, err := s.GiteeClient.PullRequestsApi.PostV5ReposOwnerRepoPullsNumberComments(s.Context, owner, repo, number, body)
+ if err != nil {
+ glog.Errorf("unable to add comment in pull request: %v", err)
+ return err
+ }
+ }
+ }
+ }
+ return nil
+}
+
+func (s *Server) getLgtmLable(commenter string) string {
+ if s.Config.LgtmCountsRequired > 1 {
+ return fmt.Sprintf(LabelLgtmWithCommenter, strings.ToLower(commenter))
+ }
+ return LabelNameLgtm
+}
+
+// RemoveLgtm removes lgtm label
+func (s *Server) RemoveLgtm(event *gitee.NoteEvent) error {
+ // handle PullRequest
+ if *event.NoteableType == "PullRequest" {
+ // handle open
+ if event.PullRequest.State == "open" {
+ // get basic params
+ comment := event.Comment.Body
+ owner := event.Repository.Namespace
+ repo := event.Repository.Name
+ prAuthor := event.PullRequest.User.Login
+ prNumber := event.PullRequest.Number
+ commentAuthor := event.Comment.User.Login
+ glog.Infof("remove lgtm started. comment: %s prAuthor: %s commentAuthor: %s owner: %s repo: %s number: %d",
+ comment, prAuthor, commentAuthor, owner, repo, prNumber)
+
+ // can cancel lgtm on self-own pr
+ if prAuthor != commentAuthor {
+ // check if current author has write permission
+ localVarOptionals := &gitee.GetV5ReposOwnerRepoCollaboratorsUsernamePermissionOpts{}
+ localVarOptionals.AccessToken = optional.NewString(s.Config.GiteeToken)
+ // get permission
+ permission, _, err := s.GiteeClient.RepositoriesApi.GetV5ReposOwnerRepoCollaboratorsUsernamePermission(
+ s.Context, owner, repo, commentAuthor, localVarOptionals)
+ if err != nil {
+ glog.Errorf("unable to get comment author permission: %v", err)
+ return err
+ }
+ // check author is owner
+ isOwner := s.CheckIsOwner(event, commentAuthor)
+
+ // check sigs
+ r, err := canCommentPrIncludingSigDirectory(s, owner, repo, prNumber, commentAuthor)
+ glog.Infof("sig owners check: can comment, r=%v, err=%v\n", r, err)
+ if err != nil {
+ glog.Errorf("unable to check sigs permission: %v", err)
+ return err
+ }
+
+ // permission: admin, write, read, none
+ if permission.Permission != "admin" && permission.Permission != "write" && !isOwner && r != 1 {
+ glog.Info("no permission to remove lgtm")
+ // add comment
+ body := gitee.PullRequestCommentPostParam{}
+ body.AccessToken = s.Config.GiteeToken
+ body.Body = fmt.Sprintf(lgtmRemoveNoPermissionMessage, commentAuthor)
+ owner := event.Repository.Namespace
+ repo := event.Repository.Name
+ number := event.PullRequest.Number
+ _, _, err := s.GiteeClient.PullRequestsApi.PostV5ReposOwnerRepoPullsNumberComments(s.Context, owner, repo, number, body)
+ if err != nil {
+ glog.Errorf("unable to add comment in pull request: %v", err)
+ return err
+ }
+ return nil
+ }
+ }
+
+ // remove lgtm label
+ removelabel := &gitee.NoteEvent{}
+ removelabel.PullRequest = event.PullRequest
+ removelabel.Repository = event.Repository
+ removelabel.Comment = &gitee.NoteHook{}
+ mapOfRemoveLabels := map[string]string{}
+ lgtmLable := s.getLgtmLable(commentAuthor)
+ mapOfRemoveLabels[lgtmLable] = lgtmLable
+ err := s.RemoveSpecifyLabelsInPulRequest(removelabel, mapOfRemoveLabels)
+ if err != nil {
+ return err
+ }
+
+ // add comment
+ body := gitee.PullRequestCommentPostParam{}
+ body.AccessToken = s.Config.GiteeToken
+ body.Body = fmt.Sprintf(lgtmRemovedMessage, commentAuthor)
+ number := event.PullRequest.Number
+ _, _, err = s.GiteeClient.PullRequestsApi.PostV5ReposOwnerRepoPullsNumberComments(s.Context, owner, repo, number, body)
+ if err != nil {
+ glog.Errorf("unable to add comment in pull request: %v", err)
+ return err
+ }
+ }
+ }
+ return nil
+}
+
+func (s *Server) collectExistingLgtmLabel(owner, repo string, number int32) (map[string]string, error) {
+ labels := make(map[string]string)
+ if s.Config.LgtmCountsRequired > 1 {
+ lvos := &gitee.GetV5ReposOwnerRepoPullsNumberOpts{
+ AccessToken: optional.NewString(s.Config.GiteeToken),
+ }
+ pr, _, err := s.GiteeClient.PullRequestsApi.GetV5ReposOwnerRepoPullsNumber(s.Context, owner, repo, number, lvos)
+ if err != nil {
+ glog.Errorf("unable to get pull request. err: %v", err)
+ return nil, err
+ }
+ glog.Infof("list of pr labels: %v", pr.Labels)
+ for _, label := range pr.Labels {
+ if strings.HasPrefix(label.Name, fmt.Sprintf(LabelLgtmWithCommenter, "")) {
+ labels[label.Name] = label.Name
+ }
+ }
+ } else {
+ labels[LabelNameLgtm] = LabelNameLgtm
+ }
+ return labels, nil
+}
+
+// CheckLgtmByPullRequestUpdate checks lgtm when received the pull request update event
+func (s *Server) CheckLgtmByPullRequestUpdate(event *gitee.PullRequestEvent) error {
+ owner := event.Repository.Namespace
+ repo := event.Repository.Name
+ prNumber := event.PullRequest.Number
+ commentCount := event.PullRequest.Comments
+ var perPage int32 = 20
+ pageCount := commentCount / perPage
+ if commentCount%perPage > 0 {
+ pageCount++
+ }
+ if perPage == 0 {
+ pageCount++
+ }
+ glog.Infof("pull request comment count: %v page count: %v per page: %v", commentCount, pageCount, perPage)
+
+ // find comments from the last page
+ lastlgtmSha := ""
+ for page := pageCount; page > 0; page-- {
+ localVarOptionals := &gitee.GetV5ReposOwnerRepoPullsNumberCommentsOpts{}
+ localVarOptionals.AccessToken = optional.NewString(s.Config.GiteeToken)
+ localVarOptionals.PerPage = optional.NewInt32(perPage)
+ localVarOptionals.Page = optional.NewInt32(page)
+
+ comments, _, err := s.GiteeClient.PullRequestsApi.GetV5ReposOwnerRepoPullsNumberComments(s.Context, owner, repo, prNumber, localVarOptionals)
+ if err != nil {
+ glog.Errorf("unable to get pull request comments. err: %v", err)
+ return err
+ }
+ if len(comments) > 0 {
+ // from the last comment
+ for length := len(comments) - 1; length >= 0; length-- {
+ comment := comments[length]
+ m := RegBotAddLgtm.FindStringSubmatch(comment.Body)
+ if /*comment.User.Login == BotName &&*/ m != nil && comment.UpdatedAt == comment.CreatedAt {
+ lastlgtmSha = m[1]
+ glog.Infof("pull request comment with lastlgtmSha: %v", comment)
+ break
+ }
+ }
+ }
+
+ // get the last sha when lgtm
+ if lastlgtmSha != "" {
+ glog.Infof("lastlgtmSha: %v sha: %v", lastlgtmSha, event.PullRequest.Head.Sha)
+ // if the sha is changed
+ if lastlgtmSha != event.PullRequest.Head.Sha {
+ // remove lgtm label
+ removelabel := &gitee.NoteEvent{}
+ removelabel.PullRequest = event.PullRequest
+ removelabel.Repository = event.Repository
+ removelabel.Comment = &gitee.NoteHook{}
+ labels, err := s.collectExistingLgtmLabel(owner, repo, prNumber)
+ if err != nil {
+ glog.Errorf("unable to pick lgtm label in pr: %v", err)
+ return err
+ }
+ err = s.RemoveSpecifyLabelsInPulRequest(removelabel, labels)
+ if err != nil {
+ return err
+ }
+
+ // add comment
+ body := gitee.PullRequestCommentPostParam{}
+ body.AccessToken = s.Config.GiteeToken
+ body.Body = fmt.Sprintf(lgtmRemovePullRequestChangeMessage, s.Config.BotName)
+ _, _, err = s.GiteeClient.PullRequestsApi.PostV5ReposOwnerRepoPullsNumberComments(s.Context, owner, repo, prNumber, body)
+ if err != nil {
+ glog.Errorf("unable to add comment in pull request: %v", err)
+ return err
+ }
+ }
+ break
+ }
+ }
+
+ return nil
+}
diff --git a/pkg/cibot/note.go b/pkg/cibot/note.go
new file mode 100644
index 0000000000000000000000000000000000000000..cc45b868ecaa1134fef131baf608fd87da360488
--- /dev/null
+++ b/pkg/cibot/note.go
@@ -0,0 +1,105 @@
+package cibot
+
+import (
+ "gitee.com/openeuler/go-gitee/gitee"
+ "github.com/golang/glog"
+)
+
+// HandleNoteEvent handles note event
+func (s *Server) HandleNoteEvent(event *gitee.NoteEvent) {
+ if event == nil {
+ return
+ }
+ // just handle create comment event
+ if *event.Action != "comment" {
+ return
+ }
+
+ // add label
+ if RegAddLabel.MatchString(event.Comment.Body) {
+ err := s.AddLabel(event)
+ if err != nil {
+ glog.Errorf("failed to add label: %v", err)
+ }
+ }
+
+ // remove label
+ if RegRemoveLabel.MatchString(event.Comment.Body) {
+ err := s.RemoveLabel(event)
+ if err != nil {
+ glog.Errorf("failed to remove label: %v", err)
+ }
+ }
+
+ // check cla by note event
+ if RegCheckCLA.MatchString(event.Comment.Body) {
+ err := s.CheckCLAByNoteEvent(event)
+ if err != nil {
+ glog.Errorf("failed to check cla by note event: %v", err)
+ }
+ }
+
+ // add lgtm
+ if RegAddLgtm.MatchString(event.Comment.Body) {
+ err := s.AddLgtm(event)
+ if err != nil {
+ glog.Errorf("failed to add lgtm: %v", err)
+ }
+ }
+
+ // remove lgtm
+ if RegRemoveLgtm.MatchString(event.Comment.Body) {
+ err := s.RemoveLgtm(event)
+ if err != nil {
+ glog.Errorf("failed to remove lgtm: %v", err)
+ }
+ }
+
+ // add approve
+ if RegAddApprove.MatchString(event.Comment.Body) {
+ err := s.AddApprove(event)
+ if err != nil {
+ glog.Errorf("failed to add approved: %v", err)
+ }
+ }
+
+ // remove approve
+ if RegRemoveApprove.MatchString(event.Comment.Body) {
+ err := s.RemoveApprove(event)
+ if err != nil {
+ glog.Errorf("failed to remove approved: %v", err)
+ }
+ }
+
+ // close
+ if RegClose.MatchString(event.Comment.Body) {
+ err := s.Close(event)
+ if err != nil {
+ glog.Errorf("failed to close: %v", err)
+ }
+ }
+
+ // reopen
+ if RegReOpen.MatchString(event.Comment.Body) {
+ err := s.ReOpen(event)
+ if err != nil {
+ glog.Errorf("failed to reopen: %v", err)
+ }
+ }
+
+ // assign
+ if RegAssign.MatchString(event.Comment.Body) {
+ err := s.Assign(event)
+ if err != nil {
+ glog.Errorf("failed to assign: %v", err)
+ }
+ }
+
+ // unassign
+ if RegUnAssign.MatchString(event.Comment.Body) {
+ err := s.UnAssign(event)
+ if err != nil {
+ glog.Errorf("failed to unassign: %v", err)
+ }
+ }
+}
diff --git a/pkg/cibot/oauth.go b/pkg/cibot/oauth.go
new file mode 100644
index 0000000000000000000000000000000000000000..79fac4b02cca4114988bc9d4056c45e679683c21
--- /dev/null
+++ b/pkg/cibot/oauth.go
@@ -0,0 +1,52 @@
+package cibot
+
+import (
+ "context"
+ "fmt"
+ "os"
+ "strings"
+
+ "github.com/golang/glog"
+ "golang.org/x/oauth2"
+)
+
+func GetToken(code string) (*oauth2.Token, error) {
+
+ url := os.Getenv("WEBSITE_URL")
+ if url == "" {
+ url = "https://openeuler.org"
+ }
+
+ secret := os.Getenv("GITEE_OAUTH2_SECRET")
+
+ client := os.Getenv("GITEE_OAUTH2_CLIENT_CODE")
+
+ if !strings.HasSuffix(url, "/") {
+ url = fmt.Sprintf("%s/", url)
+ }
+
+ redirect := fmt.Sprintf("%scla", strings.TrimSpace(url))
+
+ ctx := context.Background()
+ config := Setup(client, redirect, secret)
+
+ glog.Infof("Token request config : %v, code:", config, code)
+
+ return config.Exchange(ctx, code)
+
+}
+
+var Endpoint = oauth2.Endpoint{
+ AuthURL: "https://gitee.com/oauth/authorize",
+ TokenURL: "https://gitee.com/oauth/token",
+}
+
+func Setup(client, redirect, secret string) *oauth2.Config {
+ return &oauth2.Config{
+ ClientID: client,
+ ClientSecret: secret,
+ Scopes: []string{"emails", "user_info"},
+ Endpoint: Endpoint,
+ RedirectURL: redirect,
+ }
+}
diff --git a/pkg/cibot/ownerhandler.go b/pkg/cibot/ownerhandler.go
new file mode 100644
index 0000000000000000000000000000000000000000..738270cfdc0868e214fcf1f9ddeaeb90eb42a467
--- /dev/null
+++ b/pkg/cibot/ownerhandler.go
@@ -0,0 +1,261 @@
+package cibot
+
+import (
+ "context"
+ "encoding/base64"
+ "strconv"
+ "strings"
+ "time"
+
+ "gitee.com/openeuler/ci-bot/pkg/cibot/config"
+ "gitee.com/openeuler/ci-bot/pkg/cibot/database"
+ "gitee.com/openeuler/go-gitee/gitee"
+ "github.com/antihax/optional"
+ "github.com/golang/glog"
+ "gopkg.in/yaml.v2"
+)
+
+type OwnerHandler struct {
+ Config config.Config
+ Context context.Context
+ GiteeClient *gitee.APIClient
+}
+
+// Serve
+func (handler *OwnerHandler) Serve() {
+ // watch database
+ handler.watch()
+}
+
+// watch database
+func (handler *OwnerHandler) watch() {
+ for {
+ watchDuration := handler.Config.WatchOwnerFileDuration
+ // get repositories from DB
+ var rs []database.Repositories
+ err := database.DBConnection.Model(&database.Repositories{}).Find(&rs).Error
+ if err != nil {
+ glog.Errorf("unable to get repos: %v", err)
+ } else {
+ if len(rs) > 0 {
+ // get sigs from DB
+ var srs []database.SigRecords
+ err := database.DBConnection.Model(&database.SigRecords{}).Find(&srs).Error
+ if err != nil {
+ glog.Errorf("unable to get sigs: %v", err)
+ } else {
+ if len(srs) > 0 {
+ // get owner from files
+ getOwnersResult := true
+ mapSigOwners := make(map[string]map[string]string)
+ for _, sr := range srs {
+ for _, wf := range handler.Config.WatchOwnerFiles {
+ mapOwners := make(map[string]string)
+ owners, err := handler.getOwners(wf, sr.Name)
+ if err != nil {
+ // set result into false
+ getOwnersResult = false
+ glog.Errorf("unable to getOwners: %v", err)
+ }
+ if len(owners) > 0 {
+ for _, o := range owners {
+ mapOwners[o] = o
+ }
+ }
+ mapSigOwners[sr.Name] = mapOwners
+ break
+ }
+ }
+
+ // based on repository
+ if getOwnersResult {
+ for _, repo := range rs {
+ err = handler.handleOwners(repo, mapSigOwners)
+ if err != nil {
+ glog.Errorf("unable to handle owners: %v", err)
+ }
+ }
+ }
+ } else {
+ glog.Info("current sig length is zero")
+ }
+ }
+ } else {
+ glog.Info("current repository length is zero")
+ }
+ }
+
+ // watch duration
+ glog.Info("end to serve in owner")
+ time.Sleep(time.Duration(watchDuration) * time.Second)
+ }
+}
+
+// getOwners get owners
+func (handler *OwnerHandler) getOwners(wf config.WatchOwnerFile, name string) ([]string, error) {
+ // get params
+ watchOwner := wf.WatchOwnerFileOwner
+ watchRepo := wf.WatchOwnerFileRepo
+ watchPath := strings.Replace(wf.WatchOwnerFilePath, "*", name, -1)
+ watchRef := wf.WatchOwnerFileRef
+
+ // invoke api to get file contents
+ localVarOptionals := &gitee.GetV5ReposOwnerRepoContentsPathOpts{}
+ localVarOptionals.AccessToken = optional.NewString(handler.Config.GiteeToken)
+ localVarOptionals.Ref = optional.NewString(watchRef)
+
+ // get contents
+ contents, _, err := handler.GiteeClient.RepositoriesApi.GetV5ReposOwnerRepoContentsPath(
+ handler.Context, watchOwner, watchRepo, watchPath, localVarOptionals)
+ if err != nil {
+ glog.Errorf("unable to get repository content: %v", err)
+ return nil, err
+ }
+
+ // base64 decode
+ decodeBytes, err := base64.StdEncoding.DecodeString(contents.Content)
+ if err != nil {
+ glog.Errorf("decode content with error: %v", err)
+ return nil, err
+ }
+ // unmarshal owners file
+ var owners OwnersFile
+ err = yaml.Unmarshal(decodeBytes, &owners)
+ if err != nil {
+ glog.Errorf("fail to unmarshal owners: %v", err)
+ return nil, err
+ }
+
+ // return owners
+ if len(owners.Maintainers) > 0 {
+ return owners.Maintainers, nil
+ }
+
+ return nil, nil
+}
+
+// handleOwners handle owners
+func (handler *OwnerHandler) handleOwners(repo database.Repositories, mapSigOwners map[string]map[string]string) error {
+ // get owner for sig
+ var srepos []database.SigRepositories
+ err := database.DBConnection.Model(&database.SigRepositories{}).
+ Where("repo_name = ?", repo.Owner+"/"+repo.Repo).Find(&srepos).Error
+ if err != nil {
+ glog.Errorf("unable to get sig repos: %v", err)
+ }
+ expectedMembers := make(map[string]string)
+ for _, srepo := range srepos {
+ for k, v := range mapSigOwners[srepo.Name] {
+ expectedMembers[k] = v
+ }
+ }
+
+ // get current owners
+ var ps []database.Privileges
+ err = database.DBConnection.Model(&database.Privileges{}).
+ Where("owner = ? and repo = ? and type = ?", repo.Owner, repo.Repo, PrivilegeDeveloper).Find(&ps).Error
+ if err != nil {
+ glog.Errorf("unable to get members: %v", err)
+ }
+ actualMembers := make(map[string]string)
+ if len(ps) > 0 {
+ for _, p := range ps {
+ actualMembers[p.User] = strconv.Itoa(int(p.ID))
+ }
+ }
+
+ // remove
+ err = handler.removeOwners(repo, expectedMembers, actualMembers)
+ if err != nil {
+ glog.Errorf("unable to remove sig: %v", err)
+ }
+
+ // add
+ err = handler.addOwners(repo, expectedMembers, actualMembers)
+ if err != nil {
+ glog.Errorf("unable to add sig: %v", err)
+ }
+
+ return nil
+}
+
+// removeOwners
+func (handler *OwnerHandler) removeOwners(repo database.Repositories, expectedMembers, actualMembers map[string]string) error {
+ listOfRemove := make([]string, 0)
+
+ for k := range actualMembers {
+ if _, exists := expectedMembers[k]; !exists {
+ listOfRemove = append(listOfRemove, k)
+ }
+ }
+ glog.Infof("list of remove privileges: %v", listOfRemove)
+
+ if len(listOfRemove) > 0 {
+ memberbody := &gitee.DeleteV5ReposOwnerRepoCollaboratorsUsernameOpts{}
+ memberbody.AccessToken = optional.NewString(handler.Config.GiteeToken)
+
+ glog.Infof("begin to remove privileges for %s/%s", repo.Owner, repo.Repo)
+ for _, v := range listOfRemove {
+ _, err := handler.GiteeClient.RepositoriesApi.DeleteV5ReposOwnerRepoCollaboratorsUsername(
+ handler.Context, repo.Owner, repo.Repo, v, memberbody)
+ if err != nil {
+ glog.Errorf("fail to remove privileges: %v", err)
+ continue
+ }
+
+ // remove from DB
+ id, _ := strconv.Atoi(actualMembers[v])
+ sr := database.Privileges{}
+ sr.ID = uint(id)
+ err = database.DBConnection.Delete(&sr).Error
+ if err != nil {
+ glog.Errorf("failed to remove privilege in database: %v", err)
+ }
+ }
+ glog.Infof("end to remove privileges for %s/%s", repo.Owner, repo.Repo)
+ }
+
+ return nil
+}
+
+// addOwners
+func (handler *OwnerHandler) addOwners(repo database.Repositories, expectedMembers, actualMembers map[string]string) error {
+ listOfAdd := make([]string, 0)
+
+ for k := range expectedMembers {
+ if _, exits := actualMembers[k]; !exits {
+ listOfAdd = append(listOfAdd, k)
+ }
+ }
+ glog.Infof("list of add privileges: %v", listOfAdd)
+
+ if len(listOfAdd) > 0 {
+ memberbody := gitee.ProjectMemberPutParam{}
+ memberbody.AccessToken = handler.Config.GiteeToken
+ memberbody.Permission = PermissionPush
+
+ glog.Infof("begin to add privileges for %s/%s", repo.Owner, repo.Repo)
+ for _, v := range listOfAdd {
+ _, _, err := handler.GiteeClient.RepositoriesApi.PutV5ReposOwnerRepoCollaboratorsUsername(
+ handler.Context, repo.Owner, repo.Repo, v, memberbody)
+ if err != nil {
+ glog.Errorf("fail to create developers: %v", err)
+ continue
+ }
+ // create privilege
+ ps := database.Privileges{
+ Owner: repo.Owner,
+ Repo: repo.Repo,
+ User: v,
+ Type: PrivilegeDeveloper,
+ }
+ err = database.DBConnection.Create(&ps).Error
+ if err != nil {
+ glog.Errorf("failed to add privileges in database: %v", err)
+ }
+ }
+ glog.Infof("end to add privileges for %s/%s", repo.Owner, repo.Repo)
+ }
+
+ return nil
+}
diff --git a/pkg/cibot/owners.go b/pkg/cibot/owners.go
new file mode 100644
index 0000000000000000000000000000000000000000..c1314e4d6b42c74c19a26adbf08b0a05fc007597
--- /dev/null
+++ b/pkg/cibot/owners.go
@@ -0,0 +1,83 @@
+package cibot
+
+import (
+ "encoding/base64"
+
+ "gitee.com/openeuler/go-gitee/gitee"
+ "github.com/antihax/optional"
+ "github.com/golang/glog"
+ "gopkg.in/yaml.v2"
+)
+
+var (
+ DefaultOwnerFileName = "OWNERS"
+)
+
+type OwnersFile struct {
+ Maintainers []string `yaml:"maintainers"`
+}
+
+// CheckIsOwner checks the author is owner in repository
+func (s *Server) CheckIsOwner(event *gitee.NoteEvent, author string) bool {
+ isOwner := false
+ // get owners
+ owners := s.GetOwners(event)
+ if owners != nil {
+ glog.Infof("check isowner started. owners: %v", owners)
+ if len(owners) > 0 {
+ for _, owner := range owners {
+ if owner == author {
+ isOwner = true
+ break
+ }
+ }
+ }
+ }
+ glog.Infof("check %s isowner result: %t", author, isOwner)
+ return isOwner
+}
+
+// GetOwners gets owners from owners file in repository
+func (s *Server) GetOwners(event *gitee.NoteEvent) []string {
+ // get basic params
+ owner := event.Repository.Namespace
+ repo := event.Repository.Name
+ branch := event.PullRequest.Base.Ref
+ glog.Infof("get owners started. owner: %s repo: %s branch: %s", owner, repo, branch)
+
+ localVarOptionals := &gitee.GetV5ReposOwnerRepoContentsPathOpts{}
+ localVarOptionals.AccessToken = optional.NewString(s.Config.GiteeToken)
+ localVarOptionals.Ref = optional.NewString(branch)
+ // get contents
+ contents, _, err := s.GiteeClient.RepositoriesApi.GetV5ReposOwnerRepoContentsPath(
+ s.Context, owner, repo, DefaultOwnerFileName, localVarOptionals)
+ if err != nil {
+ glog.Errorf("unable to get repository content by path: %v", err)
+ return nil
+ }
+
+ return DecodeOwners(contents.Content)
+}
+
+func DecodeOwners(content string) []string {
+ // base64 decode
+ decodeBytes, err := base64.StdEncoding.DecodeString(content)
+ if err != nil {
+ glog.Errorf("decode content with error: %v", err)
+ return nil
+ }
+ // unmarshal owners file
+ var owners OwnersFile
+ err = yaml.Unmarshal(decodeBytes, &owners)
+ if err != nil {
+ glog.Errorf("fail to unmarshal owners: %v", err)
+ return nil
+ }
+
+ // return owners
+ if len(owners.Maintainers) > 0 {
+ return owners.Maintainers
+ }
+
+ return nil
+}
diff --git a/pkg/cibot/pullrequest.go b/pkg/cibot/pullrequest.go
new file mode 100644
index 0000000000000000000000000000000000000000..8fb12f1dbaf762d86fd0306dd46503bac7d98ce1
--- /dev/null
+++ b/pkg/cibot/pullrequest.go
@@ -0,0 +1,217 @@
+package cibot
+
+import (
+ "fmt"
+ "strings"
+
+ "gitee.com/openeuler/go-gitee/gitee"
+ "github.com/antihax/optional"
+ "github.com/golang/glog"
+)
+
+// HandlePullRequestEvent handles pull request event
+func (s *Server) HandlePullRequestEvent(event *gitee.PullRequestEvent) {
+ if event == nil {
+ return
+ }
+
+ glog.Infof("pull request sender: %v", event.Sender.Login)
+
+ // handle events
+ switch *event.Action {
+ case "open":
+ glog.Info("received a pull request open event")
+
+ // add comment
+ body := gitee.PullRequestCommentPostParam{}
+ body.AccessToken = s.Config.GiteeToken
+ body.Body = fmt.Sprintf(tipBotMessage, event.Sender.Login, s.Config.CommunityName, s.Config.CommunityName,
+ s.Config.BotName, s.Config.CommandLink)
+ owner := event.Repository.Namespace
+ repo := event.Repository.Name
+ number := event.PullRequest.Number
+ _, _, err := s.GiteeClient.PullRequestsApi.PostV5ReposOwnerRepoPullsNumberComments(s.Context, owner, repo, number, body)
+ if err != nil {
+ glog.Errorf("unable to add comment in pull request: %v", err)
+ }
+
+ err = s.CheckCLAByPullRequestEvent(event)
+ if err != nil {
+ glog.Errorf("failed to check cla by pull request event: %v", err)
+ }
+ case "update":
+ glog.Info("received a pull request update event")
+
+ // get pr info
+ owner := event.Repository.Namespace
+ repo := event.Repository.Name
+ number := event.PullRequest.Number
+ lvos := &gitee.GetV5ReposOwnerRepoPullsNumberOpts{}
+ lvos.AccessToken = optional.NewString(s.Config.GiteeToken)
+ pr, _, err := s.GiteeClient.PullRequestsApi.GetV5ReposOwnerRepoPullsNumber(s.Context, owner, repo, number, lvos)
+ if err != nil {
+ glog.Errorf("unable to get pull request. err: %v", err)
+ return
+ }
+ listofPrLabels := pr.Labels
+ glog.Infof("List of pr labels: %v", listofPrLabels)
+
+ // remove lgtm if changes happen
+ if s.hasLgtmLabel(pr.Labels) {
+ err = s.CheckLgtmByPullRequestUpdate(event)
+ if err != nil {
+ glog.Errorf("check lgtm by pull request update. err: %v", err)
+ return
+ }
+ }
+ }
+}
+
+// RemoveAssigneesInPullRequest remove assignees in pull request
+func (s *Server) RemoveAssigneesInPullRequest(event *gitee.NoteEvent) error {
+ if event != nil {
+ if event.PullRequest != nil {
+ assignees := event.PullRequest.Assignees
+ glog.Infof("remove assignees: %v", assignees)
+ if len(assignees) > 0 {
+ var strAssignees string
+ for _, assignee := range assignees {
+ strAssignees += assignee.Login + ","
+ }
+ strAssignees = strings.TrimRight(strAssignees, ",")
+ glog.Infof("remove assignees str: %s", strAssignees)
+
+ // get basic params
+ owner := event.Repository.Namespace
+ repo := event.Repository.Name
+ prNumber := event.PullRequest.Number
+ localVarOptionals := &gitee.DeleteV5ReposOwnerRepoPullsNumberAssigneesOpts{}
+ localVarOptionals.AccessToken = optional.NewString(s.Config.GiteeToken)
+
+ // invoke api
+ _, _, err := s.GiteeClient.PullRequestsApi.DeleteV5ReposOwnerRepoPullsNumberAssignees(s.Context, owner, repo, prNumber, strAssignees, localVarOptionals)
+ if err != nil {
+ glog.Errorf("unable to remove assignees in pull request. err: %v", err)
+ return err
+ }
+ glog.Infof("remove assignees successfully: %s", strAssignees)
+ }
+ }
+ }
+ return nil
+}
+
+// RemoveTestersInPullRequest remove testers in pull request
+func (s *Server) RemoveTestersInPullRequest(event *gitee.NoteEvent) error {
+ if event != nil {
+ if event.PullRequest != nil {
+ testers := event.PullRequest.Testers
+ glog.Infof("remove testers: %v", testers)
+ if len(testers) > 0 {
+ var strTesters string
+ for _, tester := range testers {
+ strTesters += tester.Login + ","
+ }
+ strTesters = strings.TrimRight(strTesters, ",")
+ glog.Infof("remove testers str: %s", strTesters)
+
+ // get basic params
+ owner := event.Repository.Namespace
+ repo := event.Repository.Name
+ prNumber := event.PullRequest.Number
+ localVarOptionals := &gitee.DeleteV5ReposOwnerRepoPullsNumberTestersOpts{}
+ localVarOptionals.AccessToken = optional.NewString(s.Config.GiteeToken)
+
+ // invoke api
+ _, _, err := s.GiteeClient.PullRequestsApi.DeleteV5ReposOwnerRepoPullsNumberTesters(s.Context, owner, repo, prNumber, strTesters, localVarOptionals)
+ if err != nil {
+ glog.Errorf("unable to remove testers in pull request. err: %v", err)
+ return err
+ }
+ glog.Infof("remove testers successfully: %s", strTesters)
+ }
+ }
+ }
+ return nil
+}
+
+func (s *Server) hasLgtmLabel(labels []gitee.Label) bool {
+ for _, l := range labels {
+ if strings.HasPrefix(l.Name, fmt.Sprintf(LabelLgtmWithCommenter, "")) || l.Name == LabelNameLgtm {
+ return true
+ }
+ }
+ return false
+}
+
+func (s *Server) legalForMerge(labels []gitee.Label) bool {
+ aproveLabel := 0
+ lgtmLabel := 0
+ lgtmPrefix := ""
+ leastLgtm := 0
+ if s.Config.LgtmCountsRequired > 1 {
+ leastLgtm = s.Config.LgtmCountsRequired
+ lgtmPrefix =fmt.Sprintf(LabelLgtmWithCommenter, "")
+ } else {
+ leastLgtm = 1
+ lgtmPrefix = LabelNameLgtm
+ }
+ for _, l := range labels {
+ if strings.HasPrefix(l.Name, lgtmPrefix) {
+ lgtmLabel++
+ } else if l.Name == LabelNameApproved {
+ aproveLabel++
+ }
+ }
+ glog.Infof("Pr labels have approved: %d lgtm: %d, required (%d)", aproveLabel, lgtmLabel, leastLgtm)
+ return aproveLabel == 1 && lgtmLabel >= leastLgtm
+}
+
+// MergePullRequest with lgtm and approved label
+func (s *Server) MergePullRequest(event *gitee.NoteEvent) error {
+ // get basic params
+ owner := event.Repository.Namespace
+ repo := event.Repository.Name
+ prNumber := event.PullRequest.Number
+ glog.Infof("merge pull request started. owner: %s repo: %s number: %d", owner, repo, prNumber)
+
+ // list labels in current pull request
+ lvos := &gitee.GetV5ReposOwnerRepoPullsNumberOpts{}
+ lvos.AccessToken = optional.NewString(s.Config.GiteeToken)
+ pr, _, err := s.GiteeClient.PullRequestsApi.GetV5ReposOwnerRepoPullsNumber(s.Context, owner, repo, prNumber, lvos)
+ if err != nil {
+ glog.Errorf("unable to get pull request. err: %v", err)
+ return err
+ }
+ listofPrLabels := pr.Labels
+ glog.Infof("List of pr labels: %v", listofPrLabels)
+
+ // ready to merge
+ if s.legalForMerge(listofPrLabels) {
+ // current pr can be merged
+ if event.PullRequest.Mergeable {
+ // remove assignees
+ err = s.RemoveAssigneesInPullRequest(event)
+ if err != nil {
+ glog.Errorf("unable to remove assignees. err: %v", err)
+ return err
+ }
+ // remove testers
+ err = s.RemoveTestersInPullRequest(event)
+ if err != nil {
+ glog.Errorf("unable to remove testers. err: %v", err)
+ return err
+ }
+ // merge pr
+ body := gitee.PullRequestMergePutParam{}
+ body.AccessToken = s.Config.GiteeToken
+ _, err = s.GiteeClient.PullRequestsApi.PutV5ReposOwnerRepoPullsNumberMerge(s.Context, owner, repo, prNumber, body)
+ if err != nil {
+ glog.Errorf("unable to merge pull request. err: %v", err)
+ return err
+ }
+ }
+ }
+
+ return nil
+}
diff --git a/pkg/cibot/push.go b/pkg/cibot/push.go
new file mode 100644
index 0000000000000000000000000000000000000000..a64a97ce79b60f70d65b83a295ba032f750edab0
--- /dev/null
+++ b/pkg/cibot/push.go
@@ -0,0 +1,202 @@
+package cibot
+
+import (
+ "strings"
+
+ "gitee.com/openeuler/ci-bot/pkg/cibot/database"
+ "gitee.com/openeuler/go-gitee/gitee"
+ "github.com/antihax/optional"
+ "github.com/golang/glog"
+)
+
+// HandlePushEvent handles push event
+func (s *Server) HandlePushEvent(event *gitee.PushEvent) {
+ if event == nil {
+ return
+ }
+ s.HandleWatchProjectFiles(event)
+ s.HandleWatchSigFiles(event)
+}
+
+// HandleWatchProjectFiles
+func (s *Server) HandleWatchProjectFiles(event *gitee.PushEvent) {
+ if len(s.Config.WatchProjectFiles) > 0 {
+ for _, wf := range s.Config.WatchProjectFiles {
+ // handle events
+ if (event.Repository.Namespace == wf.WatchProjectFileOwner) && (event.Repository.Name == wf.WatchprojectFileRepo) {
+ // owner and repo are matched
+ if event.Ref != nil {
+ ref := *event.Ref
+ configRef := wf.WatchProjectFileRef
+ if configRef == "" {
+ configRef = "master"
+ }
+ // refs/heads/master
+ if strings.Index(ref, configRef) >= 0 {
+ // the branch is matched
+ glog.Infof("push event is triggered. owner: %s repo: %s ref: %s", event.Repository.Namespace, event.Repository.Name, ref)
+ // invoke api to get file contents
+ localVarOptionals := &gitee.GetV5ReposOwnerRepoContentsPathOpts{}
+ localVarOptionals.AccessToken = optional.NewString(s.Config.GiteeToken)
+ localVarOptionals.Ref = optional.NewString(configRef)
+ // get contents
+ contents, _, err := s.GiteeClient.RepositoriesApi.GetV5ReposOwnerRepoContentsPath(
+ s.Context, event.Repository.Namespace, event.Repository.Name, wf.WatchprojectFilePath, localVarOptionals)
+ if err != nil {
+ glog.Errorf("unable to get repository content by path: %v", err)
+ return
+ }
+ glog.Infof("get triggered sha: %s", contents.Sha)
+
+ // Check project file in database
+ var lenProjectFiles int
+ err = database.DBConnection.Model(&database.ProjectFiles{}).
+ Where("owner = ? and repo = ? and path = ? and ref = ?",
+ event.Repository.Namespace, event.Repository.Name, wf.WatchprojectFilePath, configRef).
+ Count(&lenProjectFiles).Error
+ if err != nil {
+ glog.Errorf("unable to get project files in database: %v", err)
+ return
+ }
+ if lenProjectFiles > 0 {
+ glog.Infof("project file is exist. triggered sha: %s", contents.Sha)
+ // Check sha in database
+ updatepf := database.ProjectFiles{}
+ err = database.DBConnection.
+ Where("owner = ? and repo = ? and path = ? and ref = ?",
+ event.Repository.Namespace, event.Repository.Name, wf.WatchprojectFilePath, configRef).
+ First(&updatepf).Error
+ if err != nil {
+ glog.Errorf("unable to get project files in database: %v", err)
+ return
+ }
+ glog.Infof("project file current sha: %v target sha: %v waiting sha: %v", updatepf.CurrentSha, updatepf.TargetSha, updatepf.WaitingSha)
+ if (updatepf.CurrentSha != contents.Sha) && (updatepf.TargetSha != contents.Sha) && (updatepf.WaitingSha != contents.Sha) {
+ // write sha in waitingsha
+ /*updatepf.WaitingSha = contents.Sha
+ err = database.DBConnection.Save(&updatepf).Error
+ if err != nil {
+ glog.Errorf("unable to save project files in database: %v", err)
+ return
+ }*/
+ pf := &database.ProjectFiles{}
+ pf.ID = updatepf.ID
+ err = database.DBConnection.Model(pf).Update("WaitingSha", contents.Sha).Error
+ if err != nil {
+ glog.Errorf("unable to update waiting sha: %v", err)
+ }
+ glog.Infof("update waiting sha successfully. triggered sha: %s", contents.Sha)
+ }
+ } else {
+ glog.Infof("project file is non-exist. triggered sha: %s", contents.Sha)
+ // add project file
+ addpf := database.ProjectFiles{
+ Owner: event.Repository.Namespace,
+ Repo: event.Repository.Name,
+ Path: wf.WatchprojectFilePath,
+ Ref: configRef,
+ WaitingSha: contents.Sha,
+ }
+
+ // create project file
+ err = database.DBConnection.Create(&addpf).Error
+ if err != nil {
+ glog.Errorf("unable to create project files in database: %v", err)
+ return
+ }
+ glog.Infof("add project file successfully. triggered sha: %s", contents.Sha)
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+// HandleWatchSigFiles
+func (s *Server) HandleWatchSigFiles(event *gitee.PushEvent) {
+ if len(s.Config.WatchSigFiles) > 0 {
+ for _, wf := range s.Config.WatchSigFiles {
+ // handle events
+ if (event.Repository.Namespace == wf.WatchSigFileOwner) && (event.Repository.Name == wf.WatchSigFileRepo) {
+ // owner and repo are matched
+ if event.Ref != nil {
+ ref := *event.Ref
+ configRef := wf.WatchSigFileRef
+ if configRef == "" {
+ configRef = "master"
+ }
+ // refs/heads/master
+ if strings.Index(ref, configRef) >= 0 {
+ // the branch is matched
+ glog.Infof("push event is triggered. owner: %s repo: %s ref: %s", event.Repository.Namespace, event.Repository.Name, ref)
+ // invoke api to get file contents
+ localVarOptionals := &gitee.GetV5ReposOwnerRepoContentsPathOpts{}
+ localVarOptionals.AccessToken = optional.NewString(s.Config.GiteeToken)
+ localVarOptionals.Ref = optional.NewString(configRef)
+ // get contents
+ contents, _, err := s.GiteeClient.RepositoriesApi.GetV5ReposOwnerRepoContentsPath(
+ s.Context, event.Repository.Namespace, event.Repository.Name, wf.WatchSigFilePath, localVarOptionals)
+ if err != nil {
+ glog.Errorf("unable to get repository content by path: %v", err)
+ return
+ }
+ glog.Infof("get triggered sha: %s", contents.Sha)
+
+ // Check sig file in database
+ var lenSigFiles int
+ err = database.DBConnection.Model(&database.SigFiles{}).
+ Where("owner = ? and repo = ? and path = ? and ref = ?",
+ event.Repository.Namespace, event.Repository.Name, wf.WatchSigFilePath, configRef).
+ Count(&lenSigFiles).Error
+ if err != nil {
+ glog.Errorf("unable to get sig files in database: %v", err)
+ return
+ }
+ if lenSigFiles > 0 {
+ glog.Infof("sig file is exist. triggered sha: %s", contents.Sha)
+ // Check sha in database
+ updatesf := database.SigFiles{}
+ err = database.DBConnection.
+ Where("owner = ? and repo = ? and path = ? and ref = ?",
+ event.Repository.Namespace, event.Repository.Name, wf.WatchSigFilePath, configRef).
+ First(&updatesf).Error
+ if err != nil {
+ glog.Errorf("unable to get sig files in database: %v", err)
+ return
+ }
+ glog.Infof("sig file current sha: %v target sha: %v waiting sha: %v", updatesf.CurrentSha, updatesf.TargetSha, updatesf.WaitingSha)
+ if (updatesf.CurrentSha != contents.Sha) && (updatesf.TargetSha != contents.Sha) && (updatesf.WaitingSha != contents.Sha) {
+ sf := &database.SigFiles{}
+ sf.ID = updatesf.ID
+ err = database.DBConnection.Model(sf).Update("WaitingSha", contents.Sha).Error
+ if err != nil {
+ glog.Errorf("unable to update waiting sha: %v", err)
+ }
+ glog.Infof("update waiting sha successfully. triggered sha: %s", contents.Sha)
+ }
+ } else {
+ glog.Infof("sig file is non-exist. triggered sha: %s", contents.Sha)
+ // add sig file
+ addsf := database.SigFiles{
+ Owner: event.Repository.Namespace,
+ Repo: event.Repository.Name,
+ Path: wf.WatchSigFilePath,
+ Ref: configRef,
+ WaitingSha: contents.Sha,
+ }
+
+ // create sig file
+ err = database.DBConnection.Create(&addsf).Error
+ if err != nil {
+ glog.Errorf("unable to create sig files in database: %v", err)
+ return
+ }
+ glog.Infof("add sig file successfully. triggered sha: %s", contents.Sha)
+ }
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/pkg/cibot/reopen.go b/pkg/cibot/reopen.go
new file mode 100644
index 0000000000000000000000000000000000000000..bad6fe32f2e80ccf73dfee73d1162d81099b7071
--- /dev/null
+++ b/pkg/cibot/reopen.go
@@ -0,0 +1,132 @@
+package cibot
+
+import (
+ "fmt"
+ "strings"
+
+ "github.com/antihax/optional"
+
+ "gitee.com/openeuler/go-gitee/gitee"
+ "github.com/golang/glog"
+)
+
+const (
+ reopenIssueMessage = `this issue is reopened by: ***@%s***.`
+)
+
+// ReOpen reopens pr or issue
+func (s *Server) ReOpen(event *gitee.NoteEvent) error {
+ // handle PullRequest
+ if *event.NoteableType == "PullRequest" {
+ /* when gitee support to close pr by api
+ // handle open
+ if event.PullRequest.State == "closed" {
+ // get basic params
+ comment := event.Comment.Body
+ owner := event.Repository.Namespace
+ repo := event.Repository.Name
+ prAuthor := event.PullRequest.User.Login
+ prNumber := event.PullRequest.Number
+ commentAuthor := event.Comment.User.Login
+ glog.Infof("reopen started. comment: %s prAuthor: %s commentAuthor: %s owner: %s repo: %s number: %d",
+ comment, prAuthor, commentAuthor, owner, repo, prNumber)
+
+ // check if current author has write permission
+ localVarOptionals := &gitee.GetV5ReposOwnerRepoCollaboratorsUsernamePermissionOpts{}
+ localVarOptionals.AccessToken = optional.NewString(s.Config.GiteeToken)
+ // get permission
+ permission, _, err := s.GiteeClient.RepositoriesApi.GetV5ReposOwnerRepoCollaboratorsUsernamePermission(
+ s.Context, owner, repo, commentAuthor, localVarOptionals)
+ if err != nil {
+ glog.Errorf("unable to get comment author permission: %v", err)
+ return err
+ }
+ // permission: admin, write, read, none
+ if permission.Permission == "admin" || permission.Permission == "write" || prAuthor == commentAuthor {
+ // pr author or permission: admin, write
+ body := gitee.PullRequestUpdateParam{}
+ body.AccessToken = s.Config.GiteeToken
+ body.State = "open"
+ glog.Infof("invoke api to reopen: %d", prNumber)
+
+ // patch state
+ _, response, err := s.GiteeClient.PullRequestsApi.PatchV5ReposOwnerRepoPullsNumber(s.Context, owner, repo, prNumber, body)
+ if err != nil {
+ if response.StatusCode == 400 {
+ glog.Infof("reopen successfully with status code %d: %d", response.StatusCode, prNumber)
+ } else {
+ glog.Errorf("unable to reopen: %d err: %v", prNumber, err)
+ return err
+ }
+ } else {
+ glog.Infof("reopen successfully: %v", prNumber)
+ }
+ }
+ }*/
+ } else if *event.NoteableType == "Issue" {
+ // handle open
+ if event.Issue.State == "closed" {
+ // get basic informations
+ comment := event.Comment.Body
+ owner := event.Repository.Namespace
+ repo := event.Repository.Name
+ issueNumber := event.Issue.Number
+ issueAuthor := event.Issue.User.Login
+ commentAuthor := event.Comment.User.Login
+ glog.Infof("reopen started. comment: %s owner: %s repo: %s issueNumber: %s issueAuthor: %s commentAuthor: %s",
+ comment, owner, repo, issueNumber, issueAuthor, commentAuthor)
+
+ // check if current author has write permission
+ localVarOptionals := &gitee.GetV5ReposOwnerRepoCollaboratorsUsernamePermissionOpts{}
+ localVarOptionals.AccessToken = optional.NewString(s.Config.GiteeToken)
+ // get permission
+ permission, _, err := s.GiteeClient.RepositoriesApi.GetV5ReposOwnerRepoCollaboratorsUsernamePermission(
+ s.Context, owner, repo, commentAuthor, localVarOptionals)
+ if err != nil {
+ glog.Errorf("unable to get comment author permission: %v", err)
+ return err
+ }
+ // permission: admin, write, read, none
+ if permission.Permission == "admin" || permission.Permission == "write" || issueAuthor == commentAuthor {
+ // issue author or permission: admin, write
+ body := gitee.IssueUpdateParam{}
+ body.Repo = repo
+ body.AccessToken = s.Config.GiteeToken
+ body.State = "open"
+ // build label string
+ var strLabel string
+ for _, l := range event.Issue.Labels {
+ strLabel += l.Name + ","
+ }
+ strLabel = strings.TrimRight(strLabel, ",")
+ if strLabel == "" {
+ strLabel = ","
+ }
+ body.Labels = strLabel
+ glog.Infof("invoke api to reopen: %s", issueNumber)
+
+ // patch state
+ _, response, err := s.GiteeClient.IssuesApi.PatchV5ReposOwnerIssuesNumber(s.Context, owner, issueNumber, body)
+ if err != nil {
+ if response.StatusCode == 400 {
+ glog.Infof("reopen successfully with status code %d: %s", response.StatusCode, issueNumber)
+ } else {
+ glog.Errorf("unable to reopen: %s err: %v", issueNumber, err)
+ return err
+ }
+ } else {
+ glog.Infof("reopen successfully: %v", issueNumber)
+ }
+ // add comment
+ bodyComment := gitee.IssueCommentPostParam{}
+ bodyComment.AccessToken = s.Config.GiteeToken
+ bodyComment.Body = fmt.Sprintf(reopenIssueMessage, commentAuthor)
+ _, _, err = s.GiteeClient.IssuesApi.PostV5ReposOwnerRepoIssuesNumberComments(s.Context, owner, repo, issueNumber, bodyComment)
+ if err != nil {
+ glog.Errorf("unable to add comment in issue: %v", err)
+ }
+ }
+ }
+ }
+ return nil
+}
diff --git a/pkg/cibot/repohandler.go b/pkg/cibot/repohandler.go
new file mode 100644
index 0000000000000000000000000000000000000000..caf174212768cf5c35aea76f457f4dd73f73c081
--- /dev/null
+++ b/pkg/cibot/repohandler.go
@@ -0,0 +1,621 @@
+package cibot
+
+import (
+ "context"
+ "encoding/base64"
+ "fmt"
+ "strconv"
+ "time"
+
+ "gitee.com/openeuler/ci-bot/pkg/cibot/config"
+ "gitee.com/openeuler/ci-bot/pkg/cibot/database"
+ "gitee.com/openeuler/go-gitee/gitee"
+ "github.com/antihax/optional"
+ "github.com/golang/glog"
+ "gopkg.in/yaml.v2"
+)
+
+type RepoHandler struct {
+ Config config.Config
+ Context context.Context
+ GiteeClient *gitee.APIClient
+}
+
+type Repos struct {
+ Community string `yaml:"community"`
+ Repositories []Repository `yaml:"repositories"`
+}
+
+// Serve
+func (handler *RepoHandler) Serve() {
+ // init sha
+ err := handler.initSha()
+ if err != nil {
+ glog.Errorf("unable to initSha: %v", err)
+ return
+ }
+ // watch database
+ handler.watch()
+}
+
+// initSha init sha
+func (handler *RepoHandler) initSha() error {
+ if len(handler.Config.WatchProjectFiles) == 0 {
+ return nil
+ }
+
+ for _, wf := range handler.Config.WatchProjectFiles {
+ // get params
+ watchOwner := wf.WatchProjectFileOwner
+ watchRepo := wf.WatchprojectFileRepo
+ watchPath := wf.WatchprojectFilePath
+ watchRef := wf.WatchProjectFileRef
+
+ // invoke api to get file contents
+ localVarOptionals := &gitee.GetV5ReposOwnerRepoContentsPathOpts{}
+ localVarOptionals.AccessToken = optional.NewString(handler.Config.GiteeToken)
+ localVarOptionals.Ref = optional.NewString(watchRef)
+
+ // get contents
+ contents, _, err := handler.GiteeClient.RepositoriesApi.GetV5ReposOwnerRepoContentsPath(
+ handler.Context, watchOwner, watchRepo, watchPath, localVarOptionals)
+ if err != nil {
+ glog.Errorf("unable to get repository content: %v", err)
+ return err
+ }
+ // Check project file
+ var lenProjectFiles int
+ err = database.DBConnection.Model(&database.ProjectFiles{}).
+ Where("owner = ? and repo = ? and path = ? and ref = ?", watchOwner, watchRepo, watchPath, watchRef).
+ Count(&lenProjectFiles).Error
+ if err != nil {
+ glog.Errorf("unable to get project files: %v", err)
+ return err
+ }
+ if lenProjectFiles > 0 {
+ glog.Infof("project file exists: %s", contents.Sha)
+ // Check sha in database
+ updatepf := database.ProjectFiles{}
+ err = database.DBConnection.
+ Where("owner = ? and repo = ? and path = ? and ref = ?", watchOwner, watchRepo, watchPath, watchRef).
+ First(&updatepf).Error
+ if err != nil {
+ glog.Errorf("unable to get project files: %v", err)
+ return err
+ }
+ // write sha in waitingsha
+ updatepf.WaitingSha = contents.Sha
+ // init targetsha
+ updatepf.TargetSha = ""
+ err = database.DBConnection.Save(&updatepf).Error
+ if err != nil {
+ glog.Errorf("unable to get project files: %v", err)
+ return err
+ }
+
+ } else {
+ glog.Infof("project file does not exist: %s", contents.Sha)
+ // add project file
+ addpf := database.ProjectFiles{
+ Owner: watchOwner,
+ Repo: watchRepo,
+ Path: watchPath,
+ Ref: watchRef,
+ WaitingSha: contents.Sha,
+ }
+
+ // create project file
+ err = database.DBConnection.Create(&addpf).Error
+ if err != nil {
+ glog.Errorf("unable to create project files: %v", err)
+ return err
+ }
+ glog.Infof("add project file successfully: %s", contents.Sha)
+ }
+ }
+ return nil
+}
+
+// watch database
+func (handler *RepoHandler) watch() {
+ if len(handler.Config.WatchProjectFiles) == 0 {
+ return
+ }
+
+ for {
+ watchDuration := handler.Config.WatchProjectFileDuration
+ for _, wf := range handler.Config.WatchProjectFiles {
+ // get params
+ watchOwner := wf.WatchProjectFileOwner
+ watchRepo := wf.WatchprojectFileRepo
+ watchPath := wf.WatchprojectFilePath
+ watchRef := wf.WatchProjectFileRef
+
+ glog.Infof("begin to serve. watchOwner: %s watchRepo: %s watchPath: %s watchRef: %s watchDuration: %d",
+ watchOwner, watchRepo, watchPath, watchRef, watchDuration)
+
+ // get project file
+ pf := database.ProjectFiles{}
+ err := database.DBConnection.
+ Where("owner = ? and repo = ? and path = ? and ref = ?", watchOwner, watchRepo, watchPath, watchRef).
+ First(&pf).Error
+ if err != nil {
+ glog.Errorf("unable to get project files: %v", err)
+ } else {
+ glog.Infof("init handler current sha: %v target sha: %v waiting sha: %v",
+ pf.CurrentSha, pf.TargetSha, pf.WaitingSha)
+ if pf.TargetSha != "" {
+ // skip when there is executing target sha
+ glog.Infof("there is executing target sha: %v", pf.TargetSha)
+ } else {
+ if pf.WaitingSha != "" && pf.CurrentSha != pf.WaitingSha {
+ // waiting -> target
+ pf.TargetSha = pf.WaitingSha
+ err = database.DBConnection.Save(&pf).Error
+ if err != nil {
+ glog.Errorf("unable to save project files: %v", err)
+ } else {
+ // define update pf
+ updatepf := &database.ProjectFiles{}
+ updatepf.ID = pf.ID
+
+ // get file content from target sha
+ glog.Infof("get target sha blob: %v", pf.TargetSha)
+ localVarOptionals := &gitee.GetV5ReposOwnerRepoGitBlobsShaOpts{}
+ localVarOptionals.AccessToken = optional.NewString(handler.Config.GiteeToken)
+ blob, _, err := handler.GiteeClient.GitDataApi.GetV5ReposOwnerRepoGitBlobsSha(
+ handler.Context, watchOwner, watchRepo, pf.TargetSha, localVarOptionals)
+ if err != nil {
+ glog.Errorf("unable to get blob: %v", err)
+ } else {
+ // base64 decode
+ glog.Infof("decode target sha blob: %v", pf.TargetSha)
+ decodeBytes, err := base64.StdEncoding.DecodeString(blob.Content)
+ if err != nil {
+ glog.Errorf("decode content with error: %v", err)
+ } else {
+ // unmarshal owners file
+ glog.Infof("unmarshal target sha blob: %v", pf.TargetSha)
+ var ps Repos
+ err = yaml.Unmarshal(decodeBytes, &ps)
+ if err != nil {
+ glog.Errorf("failed to unmarshal repos: %v", err)
+ } else {
+ glog.Infof("get blob result: %v", ps)
+ result := true
+ for i := 0; i < len(ps.Repositories); i++ {
+ // get repositories length
+ lenRepositories, err := handler.getRepositoriesLength(ps.Community, *ps.Repositories[i].Name)
+ if err != nil {
+ glog.Errorf("failed to get repositories length: %v", err)
+ result = false
+ continue
+ }
+ if lenRepositories > 0 {
+ glog.Infof("repository: %s exists. no action.", *ps.Repositories[i].Name)
+ } else {
+ // add repository
+ err = handler.addRepositories(ps.Community, ps.Repositories[i])
+ if err != nil {
+ glog.Errorf("failed to add repositories: %v", err)
+ result = false
+ continue
+ }
+ }
+ // handle branches
+ err = handler.handleBranches(ps.Community, ps.Repositories[i])
+ if err != nil {
+ glog.Errorf("failed to handle branches: %v", err)
+ result = false
+ }
+ // handle repository settings, currently type and can_comment are supported
+ err = handler.handleRepositorySetting(ps.Community, ps.Repositories[i])
+ if err != nil {
+ glog.Errorf("failed to handle repository setting: %v", err)
+ result = false
+ }
+ }
+ glog.Infof("running result: %v", result)
+ if result {
+ err = database.DBConnection.Model(updatepf).Update("CurrentSha", pf.TargetSha).Error
+ if err != nil {
+ glog.Errorf("unable to update current sha: %v", err)
+ }
+ }
+ }
+ }
+ }
+
+ // at last update target sha
+ err = database.DBConnection.Model(updatepf).Update("TargetSha", "").Error
+ if err != nil {
+ glog.Errorf("unable to update target sha: %v", err)
+ }
+ glog.Info("update sha successfully")
+ }
+ } else {
+ glog.Infof("no waiting sha: %v", pf.WaitingSha)
+ }
+ }
+ }
+ }
+
+ // watch duration
+ glog.Info("end to serve")
+ time.Sleep(time.Duration(watchDuration) * time.Second)
+ }
+}
+
+// GetRepositoriesLength get repositories length
+func (handler *RepoHandler) getRepositoriesLength(owner string, repo string) (int, error) {
+ // Check repositories file
+ var lenRepositories int
+ err := database.DBConnection.Model(&database.Repositories{}).
+ Where("owner = ? and repo = ?", owner, repo).
+ Count(&lenRepositories).Error
+ if err != nil {
+ glog.Errorf("unable to get repositories files: %v", err)
+ }
+ return lenRepositories, err
+}
+
+// addRepositories add repository
+func (handler *RepoHandler) addRepositories(owner string, repo Repository) error {
+ // add repository in gitee
+ err := handler.addRepositoriesinGitee(owner, repo)
+ if err != nil {
+ glog.Errorf("failed to add repositories: %v", err)
+ return err
+ }
+
+ // add repository in database
+ err = handler.addRepositoriesinDB(owner, repo)
+ if err != nil {
+ glog.Errorf("failed to add repositories: %v", err)
+ return err
+ }
+ return nil
+}
+
+// addRepositoriesinDB add repository in database
+func (handler *RepoHandler) addRepositoriesinDB(owner string, repo Repository) error {
+ // this is a rename instead of create operation,
+ // so only update existing repository in DB
+ if repo.RenameFrom != nil && len(*repo.RenameFrom) > 0 {
+ // Update the repositories and branches table in a single transactions
+ tx := database.DBConnection.Begin()
+ err := tx.Model(&database.Repositories{}).
+ Where("owner = ? and repo = ?", owner, *repo.RenameFrom).
+ Update("repo", *repo.Name).Error
+ if err != nil {
+ glog.Errorf("unable to rename repository: %v", err)
+ tx.Rollback()
+ return err
+ }
+ err = tx.Model(&database.Branches{}).
+ Where("owner = ? and repo = ?", owner, *repo.RenameFrom).
+ Update("repo", *repo.Name).Error
+ if err != nil {
+ glog.Errorf("unable to rename repository for relevant branches: %v", err)
+ tx.Rollback()
+ return err
+ }
+ tx.Commit()
+ return nil
+ }
+
+ // add repository
+ addrepo := database.Repositories{
+ Owner: owner,
+ Repo: *repo.Name,
+ Description: *repo.Description,
+ Type: *repo.Type,
+ Commentable: repo.IsCommentable(),
+ }
+
+ // create repository
+ err := database.DBConnection.Create(&addrepo).Error
+ if err != nil {
+ glog.Errorf("unable to create repository: %v", err)
+ return err
+ }
+ return nil
+}
+
+// addRepositoriesinGitee add repository in giteee
+func (handler *RepoHandler) addRepositoriesinGitee(owner string, repo Repository) error {
+ // build create repository param
+ repobody := gitee.RepositoryPostParam{}
+ repobody.AccessToken = handler.Config.GiteeToken
+ repobody.Name = *repo.Name
+ repobody.Description = *repo.Description
+ repobody.HasIssues = true
+ repobody.HasWiki = true
+ // set `auto_init` as true to initialize `master` branch with README after repo creation
+ repobody.AutoInit = true
+ repobody.CanComment = repo.IsCommentable()
+ repobody.Private = *repo.Type == "private"
+
+ // invoke query repository
+ glog.Infof("begin to query repository: %s", *repo.Name)
+ localVarOptionals := &gitee.GetV5ReposOwnerRepoOpts{}
+ localVarOptionals.AccessToken = optional.NewString(handler.Config.GiteeToken)
+ _, response, _ := handler.GiteeClient.RepositoriesApi.GetV5ReposOwnerRepo(handler.Context, owner, *repo.Name, localVarOptionals)
+ if response.StatusCode == 404 {
+ glog.Infof("repository does not exist: %s", *repo.Name)
+ } else {
+ glog.Infof("repository has already existed: %s", *repo.Name)
+ return nil
+ }
+
+ // if rename_from does exist, now go to invoke rename repository
+ if repo.RenameFrom != nil && len(*repo.RenameFrom) > 0 {
+ // invoke query repoisitory with the name defined by rename_from
+ glog.Infof("begin to query repository: %s defined by rename_from ", *repo.RenameFrom)
+ localVarRenameOptionals := &gitee.GetV5ReposOwnerRepoOpts{}
+ localVarRenameOptionals.AccessToken = optional.NewString(handler.Config.GiteeToken)
+ _, response, _ = handler.GiteeClient.RepositoriesApi.GetV5ReposOwnerRepo(handler.Context, owner, *repo.RenameFrom, localVarRenameOptionals)
+ if response.StatusCode == 404 {
+ errMsg := fmt.Sprintf("repository defined by rename_from does not exist: %s", *repo.RenameFrom)
+ glog.Errorf("failed to rename repository: %s", errMsg)
+ return fmt.Errorf(errMsg)
+ }
+ // everything seems fine, then build patch repository param
+ repoPatchParam := gitee.RepoPatchParam{}
+ repoPatchParam.AccessToken = handler.Config.GiteeToken
+ repoPatchParam.Name = *repo.Name
+ repoPatchParam.Path = *repo.Name
+ // invoke patching repository API to change *repo.RenameFrom to *repo.Name
+ _, _, err := handler.GiteeClient.RepositoriesApi.PatchV5ReposOwnerRepo(handler.Context, owner, *repo.RenameFrom, repoPatchParam)
+ if err != nil {
+ glog.Errorf("unable to rename the repository from %s to %s", *repo.RenameFrom, *repo.Name)
+ return err
+ }
+ return nil
+ }
+
+ // invoke create repository
+ glog.Infof("begin to create repository: %s", *repo.Name)
+ _, _, err := handler.GiteeClient.RepositoriesApi.PostV5OrgsOrgRepos(handler.Context, owner, repobody)
+ if err != nil {
+ glog.Errorf("fail to create repository: %v", err)
+ return err
+ }
+ glog.Infof("end to create repository: %s", *repo.Name)
+ return nil
+}
+
+// handleBranches handle branches
+// currently for protecting branches only
+func (handler *RepoHandler) handleBranches(community string, r Repository) error {
+ // if the branches are defined in the repositories, it means that
+ // all the branches defined in the community will not inherited by repositories
+ mapBranches := make(map[string]string)
+
+ if len(r.ProtectedBranches) > 0 {
+ // using repository branches
+ glog.Infof("using repository branches: %s", *r.Name)
+ for _, b := range r.ProtectedBranches {
+ mapBranches[b] = b
+ }
+ }
+
+ // get branches from DB
+ var bs []database.Branches
+ err := database.DBConnection.Model(&database.Branches{}).
+ Where("owner = ? and repo = ?", community, r.Name).Find(&bs).Error
+ if err != nil {
+ glog.Errorf("unable to get branches: %v", err)
+ return err
+ }
+ mapBranchesInDB := make(map[string]string)
+ for _, b := range bs {
+ mapBranchesInDB[b.Name] = strconv.Itoa(int(b.ID))
+ }
+
+ // un-protected branches
+ err = handler.removeBranchProtections(community, r, mapBranches, mapBranchesInDB)
+ if err != nil {
+ glog.Errorf("unable to un-protected branches: %v", err)
+ }
+
+ // protected branches
+ err = handler.addBranchProtections(community, r, mapBranches, mapBranchesInDB)
+ if err != nil {
+ glog.Errorf("unable to protected branches: %v", err)
+ }
+
+ return nil
+}
+
+// unprotectedBranches unprotect branches
+func (handler *RepoHandler) removeBranchProtections(community string, r Repository, mapBranches, mapBranchesInDB map[string]string) error {
+ // remove branch protections
+ listOfUnprotectedBranches := make([]string, 0)
+
+ for k := range mapBranchesInDB {
+ if _, exists := mapBranches[k]; !exists {
+ listOfUnprotectedBranches = append(listOfUnprotectedBranches, k)
+ }
+ }
+ glog.Infof("list of un-protected branches: %v", listOfUnprotectedBranches)
+
+ if len(listOfUnprotectedBranches) > 0 {
+ opts := &gitee.DeleteV5ReposOwnerRepoBranchesBranchProtectionOpts{}
+ opts.AccessToken = optional.NewString(handler.Config.GiteeToken)
+
+ glog.Infof("begin to remove branch protections for %s", *r.Name)
+ for _, v := range listOfUnprotectedBranches {
+ // remove branch protection from gitee
+ _, err := handler.GiteeClient.RepositoriesApi.DeleteV5ReposOwnerRepoBranchesBranchProtection(
+ handler.Context, community, *r.Name, v, opts)
+ if err != nil {
+ glog.Errorf("failed to remove branch protection: %v", err)
+ continue
+ }
+ // remove branch protection from DB
+ id, _ := strconv.Atoi(mapBranchesInDB[v])
+ bs := database.Branches{}
+ bs.ID = uint(id)
+ err = database.DBConnection.Delete(&bs).Error
+ if err != nil {
+ glog.Errorf("failed to remove branch protection in database: %v", err)
+ }
+ }
+ glog.Infof("end to remove branch protections for %s", *r.Name)
+ }
+
+ return nil
+}
+
+// addBranchProtections protects branches
+func (handler *RepoHandler) addBranchProtections(community string, r Repository, mapBranches, mapBranchesInDB map[string]string) error {
+ // add branch protections
+ listOfProtectedBranches := make([]string, 0)
+
+ for k := range mapBranches {
+ if _, exits := mapBranchesInDB[k]; !exits {
+ listOfProtectedBranches = append(listOfProtectedBranches, k)
+ }
+ }
+ glog.Infof("list of protected branches: %v", listOfProtectedBranches)
+
+ if len(listOfProtectedBranches) > 0 {
+ getOpts := &gitee.GetV5ReposOwnerRepoBranchesBranchOpts{}
+ getOpts.AccessToken = optional.NewString(handler.Config.GiteeToken)
+
+ protectBody := gitee.BranchProtectionPutParam{}
+ protectBody.AccessToken = handler.Config.GiteeToken
+
+ glog.Infof("begin to add branch protections for %s", *r.Name)
+ for _, v := range listOfProtectedBranches {
+ // check if protected branch exists
+ branchObj, response, _ := handler.GiteeClient.RepositoriesApi.GetV5ReposOwnerRepoBranchesBranch(
+ handler.Context, community, *r.Name, v, getOpts)
+ if response.StatusCode == 404 {
+ glog.Errorf("branch %s does not exist, no need for protection", v)
+ continue
+ }
+
+ // If branch has alreay been protected, no need for protection
+ if branchObj.Protected == "true" {
+ glog.Errorf("branch %s has been protected already, no need for protection", v)
+ continue
+ }
+
+ // add branch protection to gitee
+ _, response, err := handler.GiteeClient.RepositoriesApi.PutV5ReposOwnerRepoBranchesBranchProtection(
+ handler.Context, community, *r.Name, v, protectBody)
+ if err != nil {
+ glog.Errorf("failed to add branch protection: %v", err)
+ continue
+ }
+ // add branch protection to database
+ bs := database.Branches{
+ Owner: community,
+ Repo: *r.Name,
+ Name: v,
+ Type: BranchProtected,
+ }
+ err = database.DBConnection.Create(&bs).Error
+ if err != nil {
+ glog.Errorf("failed to add branch protection in database: %v", err)
+ }
+ }
+ glog.Infof("end to add branch protections for %s", *r.Name)
+ }
+
+ return nil
+}
+
+// handleRepositorySetting handles that the repo settings, including:
+// 1. type is private or public
+// 2. commentable is true or false
+func (handler *RepoHandler) handleRepositorySetting(community string, r Repository) error {
+ // get repos from DB
+ var rs database.Repositories
+ err := database.DBConnection.Model(&database.Repositories{}).
+ Where("owner = ? and repo = ?", community, r.Name).First(&rs).Error
+ if err != nil {
+ glog.Errorf("unable to get repositories: %v", err)
+ return err
+ }
+
+ typePrivateExpected := (*r.Type == "private")
+ // mark type as changed if the type from DB is NOT identical to yaml
+ typeChanged := (rs.Type != *r.Type)
+
+ commentableExpected := r.IsCommentable()
+ // mark commentable as changed if the commentable from DB is NOT identical to yaml
+ commentableChanged := (rs.Commentable != commentableExpected)
+
+ if typeChanged || commentableChanged {
+ // invoke query repository
+ glog.Infof("begin to query repository: %s", *r.Name)
+ localVarOptionals := &gitee.GetV5ReposOwnerRepoOpts{}
+ localVarOptionals.AccessToken = optional.NewString(handler.Config.GiteeToken)
+ pj, response, _ := handler.GiteeClient.RepositoriesApi.GetV5ReposOwnerRepo(
+ handler.Context, community, *r.Name, localVarOptionals)
+ if response.StatusCode == 404 {
+ glog.Infof("repository dose not exist: %s", *r.Name)
+ return nil
+ }
+
+ // do we need to invoke the gitee patch api to change the setting of the repository
+ needInvokeRepoPatchAPI := false
+ // handle the change of type
+ if typeChanged {
+ // if the repo type from gitee is identical to yaml
+ if pj.Private == typePrivateExpected {
+ glog.Infof("repository type is already: %s", *r.Type)
+ } else {
+ needInvokeRepoPatchAPI = true
+ glog.Infof("going to change repo type via gitee API")
+ }
+ }
+ // handle the change of commentable
+ if commentableChanged {
+ // if the repo commentable from gitee is identical to yaml
+ if pj.CanComment == commentableExpected {
+ glog.Infof("repository commentable is already: %t", pj.CanComment)
+ } else {
+ needInvokeRepoPatchAPI = true
+ glog.Infof("going to change repo commentable via gitee API")
+ }
+ }
+
+ // now to invoke gitee api to change the repo settings
+ if needInvokeRepoPatchAPI {
+ // build patch repository param
+ patchBody := gitee.RepoPatchParam{}
+ patchBody.AccessToken = handler.Config.GiteeToken
+ patchBody.Name = pj.Name
+ patchBody.Description = pj.Description
+ patchBody.Homepage = pj.Homepage
+ patchBody.HasIssues = strconv.FormatBool(pj.HasIssues)
+ patchBody.HasWiki = strconv.FormatBool(pj.HasWiki)
+ patchBody.Private = strconv.FormatBool(typePrivateExpected)
+ patchBody.CanComment = strconv.FormatBool(commentableExpected)
+
+ // invoke set type
+ _, _, err = handler.GiteeClient.RepositoriesApi.PatchV5ReposOwnerRepo(handler.Context, community, *r.Name, patchBody)
+ if err != nil {
+ glog.Errorf("unable to set repository settings: %v", err)
+ return err
+ }
+ }
+
+ // define update repository
+ updaterepo := &database.Repositories{}
+ updaterepo.ID = rs.ID
+ err = database.DBConnection.Model(updaterepo).
+ Update("Type", *r.Type).
+ Update("Commentable", commentableExpected).
+ Error
+ if err != nil {
+ glog.Errorf("unable to update repository settings: %v", err)
+ }
+ }
+
+ return nil
+}
diff --git a/pkg/cibot/server.go b/pkg/cibot/server.go
new file mode 100644
index 0000000000000000000000000000000000000000..8b4c4b1d16772a6b1437bb56ecbc244aaa99d3f4
--- /dev/null
+++ b/pkg/cibot/server.go
@@ -0,0 +1,65 @@
+package cibot
+
+import (
+ "context"
+ "fmt"
+ "net/http"
+
+ "gitee.com/openeuler/ci-bot/pkg/cibot/config"
+ "gitee.com/openeuler/go-gitee/gitee"
+ "github.com/golang/glog"
+)
+
+type Server struct {
+ Config config.Config
+ Context context.Context
+ GiteeClient *gitee.APIClient
+}
+
+// ServeHTTP validates an incoming webhook and invoke its handler.
+func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
+ glog.Info("received a webhook event")
+ // validate the webhook secret
+ payload, err := gitee.ValidatePayload(r, []byte(s.Config.WebhookSecret))
+ if err != nil {
+ glog.Errorf("invalid payload: %v", err)
+ w.WriteHeader(http.StatusBadRequest)
+ fmt.Fprint(w, err.Error())
+ return
+ }
+ glog.Infof("payload: %v", string(payload))
+
+ // parse into Event
+ messagetype := gitee.WebHookType(r)
+ glog.Infof("message type: %v", messagetype)
+ event, err := gitee.ParseWebHook(messagetype, payload)
+ if err != nil {
+ glog.Errorf("failed to parse webhook event: %v", err)
+ w.WriteHeader(http.StatusInternalServerError)
+ fmt.Fprint(w, err.Error())
+ return
+ }
+
+ // response avoids gitee timeout 5s
+ fmt.Fprint(w, "handle webhook event successfully")
+ var client http.Client
+ client.Do(r)
+
+ // handle events
+ switch event.(type) {
+ case *gitee.NoteEvent:
+ glog.Info("received a note event")
+ go s.HandleNoteEvent(event.(*gitee.NoteEvent))
+ case *gitee.PushEvent:
+ glog.Info("received a push event")
+ go s.HandlePushEvent(event.(*gitee.PushEvent))
+ case *gitee.IssueEvent:
+ glog.Info("received a issue event")
+ go s.HandleIssueEvent(event.(*gitee.IssueEvent))
+ case *gitee.PullRequestEvent:
+ glog.Info("received a pull request event")
+ go s.HandlePullRequestEvent(event.(*gitee.PullRequestEvent))
+ case *gitee.TagPushEvent:
+ glog.Info("received a tag push event")
+ }
+}
diff --git a/pkg/cibot/sighandler.go b/pkg/cibot/sighandler.go
new file mode 100644
index 0000000000000000000000000000000000000000..b9144e74dd1d47abcc91208c78fb283e80538986
--- /dev/null
+++ b/pkg/cibot/sighandler.go
@@ -0,0 +1,441 @@
+package cibot
+
+import (
+ "context"
+ "encoding/base64"
+ "strconv"
+ "time"
+
+ "gitee.com/openeuler/ci-bot/pkg/cibot/config"
+ "gitee.com/openeuler/ci-bot/pkg/cibot/database"
+ "gitee.com/openeuler/go-gitee/gitee"
+ "github.com/antihax/optional"
+ "github.com/golang/glog"
+ "gopkg.in/yaml.v2"
+)
+
+type SigHandler struct {
+ Config config.Config
+ Context context.Context
+ GiteeClient *gitee.APIClient
+}
+
+type SigsYaml struct {
+ Sigs []Sig `yaml:"sigs"`
+}
+
+type Sig struct {
+ Name string `yaml:"name"`
+ Repositories []string `yaml:"repositories"`
+}
+
+// Serve
+func (handler *SigHandler) Serve() {
+ // init sha
+ err := handler.initSha()
+ if err != nil {
+ glog.Errorf("unable to initSha in sig: %v", err)
+ return
+ }
+ // watch database
+ handler.watch()
+}
+
+// initSha init sha
+func (handler *SigHandler) initSha() error {
+ if len(handler.Config.WatchSigFiles) == 0 {
+ return nil
+ }
+
+ for _, wf := range handler.Config.WatchSigFiles {
+ // get params
+ watchOwner := wf.WatchSigFileOwner
+ watchRepo := wf.WatchSigFileRepo
+ watchPath := wf.WatchSigFilePath
+ watchRef := wf.WatchSigFileRef
+
+ // invoke api to get file contents
+ localVarOptionals := &gitee.GetV5ReposOwnerRepoContentsPathOpts{}
+ localVarOptionals.AccessToken = optional.NewString(handler.Config.GiteeToken)
+ localVarOptionals.Ref = optional.NewString(watchRef)
+
+ // get contents
+ contents, _, err := handler.GiteeClient.RepositoriesApi.GetV5ReposOwnerRepoContentsPath(
+ handler.Context, watchOwner, watchRepo, watchPath, localVarOptionals)
+ if err != nil {
+ glog.Errorf("unable to get repository content in sig: %v", err)
+ return err
+ }
+ // Check sig file
+ var lenSigFiles int
+ err = database.DBConnection.Model(&database.SigFiles{}).
+ Where("owner = ? and repo = ? and path = ? and ref = ?", watchOwner, watchRepo, watchPath, watchRef).
+ Count(&lenSigFiles).Error
+ if err != nil {
+ glog.Errorf("unable to get sig files: %v", err)
+ return err
+ }
+ if lenSigFiles > 0 {
+ glog.Infof("sig file is exist: %s", contents.Sha)
+ // Check sha in database
+ updatesf := database.SigFiles{}
+ err = database.DBConnection.
+ Where("owner = ? and repo = ? and path = ? and ref = ?", watchOwner, watchRepo, watchPath, watchRef).
+ First(&updatesf).Error
+ if err != nil {
+ glog.Errorf("unable to get sig files: %v", err)
+ return err
+ }
+ // write sha in waitingsha
+ updatesf.WaitingSha = contents.Sha
+ // init targetsha
+ updatesf.TargetSha = ""
+ err = database.DBConnection.Save(&updatesf).Error
+ if err != nil {
+ glog.Errorf("unable to get sig files: %v", err)
+ return err
+ }
+
+ } else {
+ glog.Infof("sig file is non-exist: %s", contents.Sha)
+ // add sig file
+ addsf := database.SigFiles{
+ Owner: watchOwner,
+ Repo: watchRepo,
+ Path: watchPath,
+ Ref: watchRef,
+ WaitingSha: contents.Sha,
+ }
+
+ // create sig file
+ err = database.DBConnection.Create(&addsf).Error
+ if err != nil {
+ glog.Errorf("unable to create sig files: %v", err)
+ return err
+ }
+ glog.Infof("add sig file successfully: %s", contents.Sha)
+ }
+ }
+ return nil
+}
+
+// watch database
+func (handler *SigHandler) watch() {
+ if len(handler.Config.WatchSigFiles) == 0 {
+ return
+ }
+
+ for {
+ watchDuration := handler.Config.WatchSigFileDuration
+ for _, wf := range handler.Config.WatchSigFiles {
+ // get params
+ watchOwner := wf.WatchSigFileOwner
+ watchRepo := wf.WatchSigFileRepo
+ watchPath := wf.WatchSigFilePath
+ watchRef := wf.WatchSigFileRef
+
+ glog.Infof("begin to serve in sig. watchOwner: %s watchRepo: %s watchPath: %s watchRef: %s watchDuration: %d",
+ watchOwner, watchRepo, watchPath, watchRef, watchDuration)
+
+ // get sig file
+ sf := database.SigFiles{}
+ err := database.DBConnection.
+ Where("owner = ? and repo = ? and path = ? and ref = ?", watchOwner, watchRepo, watchPath, watchRef).
+ First(&sf).Error
+ if err != nil {
+ glog.Errorf("unable to get sig files: %v", err)
+ } else {
+ glog.Infof("init handler current sha: %v target sha: %v waiting sha: %v in sig",
+ sf.CurrentSha, sf.TargetSha, sf.WaitingSha)
+ if sf.TargetSha != "" {
+ // skip when there is executing target sha
+ glog.Infof("there is executing target sha: %v in sig", sf.TargetSha)
+ } else {
+ if sf.WaitingSha != "" && sf.CurrentSha != sf.WaitingSha {
+ // waiting -> target
+ sf.TargetSha = sf.WaitingSha
+ err = database.DBConnection.Save(&sf).Error
+ if err != nil {
+ glog.Errorf("unable to save sig files: %v", err)
+ } else {
+ // define update sf
+ updatesf := &database.SigFiles{}
+ updatesf.ID = sf.ID
+
+ // get file content from target sha
+ glog.Infof("get target sha blob: %v", sf.TargetSha)
+ localVarOptionals := &gitee.GetV5ReposOwnerRepoGitBlobsShaOpts{}
+ localVarOptionals.AccessToken = optional.NewString(handler.Config.GiteeToken)
+ blob, _, err := handler.GiteeClient.GitDataApi.GetV5ReposOwnerRepoGitBlobsSha(
+ handler.Context, watchOwner, watchRepo, sf.TargetSha, localVarOptionals)
+ if err != nil {
+ glog.Errorf("unable to get blob: %v", err)
+ } else {
+ // base64 decode
+ glog.Infof("decode target sha blob: %v", sf.TargetSha)
+ decodeBytes, err := base64.StdEncoding.DecodeString(blob.Content)
+ if err != nil {
+ glog.Errorf("decode content with error: %v", err)
+ } else {
+ // unmarshal owners file
+ glog.Infof("unmarshal target sha blob: %v", sf.TargetSha)
+ var sy SigsYaml
+ err = yaml.Unmarshal(decodeBytes, &sy)
+ if err != nil {
+ glog.Errorf("failed to unmarshal sigs: %v", err)
+ } else {
+ glog.Infof("get blob result: %v", sy)
+ result := true
+ // handle sigs
+ err = handler.handleSigs(sy)
+ if err != nil {
+ glog.Errorf("failed to handle sig: %v", err)
+ result = false
+ }
+ glog.Infof("running result: %v", result)
+ if result {
+ err = database.DBConnection.Model(updatesf).Update("CurrentSha", sf.TargetSha).Error
+ if err != nil {
+ glog.Errorf("unable to update current sha in sig: %v", err)
+ }
+ }
+ }
+ }
+ }
+
+ // at last update target sha
+ err = database.DBConnection.Model(updatesf).Update("TargetSha", "").Error
+ if err != nil {
+ glog.Errorf("unable to update target sha in sig: %v", err)
+ }
+ glog.Info("update sha successfully in sig")
+ }
+ } else {
+ glog.Infof("no waiting sha in sig: %v", sf.WaitingSha)
+ }
+ }
+ }
+ }
+
+ // watch duration
+ glog.Info("end to serve in sig")
+ time.Sleep(time.Duration(watchDuration) * time.Second)
+ }
+}
+
+// handleSigs handle sig
+func (handler *SigHandler) handleSigs(sy SigsYaml) error {
+ // handle sig repos
+ for i := 0; i < len(sy.Sigs); i++ {
+ // handle sig repos
+ err := handler.handleSigRepos(sy.Sigs[i])
+ if err != nil {
+ glog.Errorf("failed to handle sig repos: %v", err)
+ return err
+ }
+ }
+
+ mapSigs := make(map[string]string)
+ if len(sy.Sigs) > 0 {
+ for _, s := range sy.Sigs {
+ mapSigs[s.Name] = s.Name
+ }
+ }
+
+ // get sigs from DB
+ var srs []database.SigRecords
+ err := database.DBConnection.Model(&database.SigRecords{}).Find(&srs).Error
+ if err != nil {
+ glog.Errorf("unable to get sig repos: %v", err)
+ return err
+ }
+ mapSigsInDB := make(map[string]string)
+ for _, sr := range srs {
+ mapSigsInDB[sr.Name] = strconv.Itoa(int(sr.ID))
+ }
+
+ // remove
+ err = handler.removeSigs(mapSigs, mapSigsInDB)
+ if err != nil {
+ glog.Errorf("unable to remove sig: %v", err)
+ }
+
+ // add
+ err = handler.addSigs(mapSigs, mapSigsInDB)
+ if err != nil {
+ glog.Errorf("unable to add sig: %v", err)
+ }
+
+ return nil
+}
+
+// removeSigs
+func (handler *SigHandler) removeSigs(mapSigs, mapSigsInDB map[string]string) error {
+ listOfRemove := make([]string, 0)
+
+ for k := range mapSigsInDB {
+ if _, exists := mapSigs[k]; !exists {
+ listOfRemove = append(listOfRemove, k)
+ }
+ }
+ glog.Infof("list of remove sigs: %v", listOfRemove)
+
+ if len(listOfRemove) > 0 {
+ glog.Info("begin to remove sigs")
+ for _, v := range listOfRemove {
+ // remove from DB
+ id, _ := strconv.Atoi(mapSigsInDB[v])
+ sr := database.SigRecords{}
+ sr.ID = uint(id)
+ err := database.DBConnection.Delete(&sr).Error
+ if err != nil {
+ glog.Errorf("failed to remove sig in database: %v", err)
+ }
+
+ glog.Infof("begin to remove sig repos for %s", v)
+ database.DBConnection.Where(database.SigRepositories{Name: v}).Delete(database.SigRepositories{})
+ glog.Infof("end to remove sig repo for %s", v)
+ }
+ glog.Info("end to remove sigs")
+ }
+
+ return nil
+}
+
+// addSigs
+func (handler *SigHandler) addSigs(mapSigs, mapSigsInDB map[string]string) error {
+ listOfAdd := make([]string, 0)
+
+ for k := range mapSigs {
+ if _, exits := mapSigsInDB[k]; !exits {
+ listOfAdd = append(listOfAdd, k)
+ }
+ }
+ glog.Infof("list of add sigs: %v", listOfAdd)
+
+ if len(listOfAdd) > 0 {
+ glog.Info("begin to add sigs")
+ for _, v := range listOfAdd {
+ // add sig
+ sr := database.SigRecords{
+ Name: v,
+ }
+ err := database.DBConnection.Create(&sr).Error
+ if err != nil {
+ glog.Errorf("failed to add sigs in database: %v", err)
+ }
+ }
+ glog.Info("end to add sigs")
+ }
+
+ return nil
+}
+
+// getSigsLength get sigs length
+func (handler *SigHandler) getSigsLength(name string) (int, error) {
+ // Check sigs file
+ var lenSigs int
+ err := database.DBConnection.Model(&database.SigRecords{}).
+ Where("name = ?", name).
+ Count(&lenSigs).Error
+ if err != nil {
+ glog.Errorf("unable to get sig length: %v", err)
+ }
+ return lenSigs, err
+}
+
+// handleSigRepos handle sig repos
+func (handler *SigHandler) handleSigRepos(sig Sig) error {
+ mapSigRepos := make(map[string]string)
+
+ if len(sig.Repositories) > 0 {
+ for _, sr := range sig.Repositories {
+ mapSigRepos[sr] = sr
+ }
+ }
+
+ // get sig repos from DB
+ var srs []database.SigRepositories
+ err := database.DBConnection.Model(&database.SigRepositories{}).
+ Where("name = ?", sig.Name).Find(&srs).Error
+ if err != nil {
+ glog.Errorf("unable to get sig repos: %v", err)
+ return err
+ }
+ mapSigReposInDB := make(map[string]string)
+ for _, sr := range srs {
+ mapSigReposInDB[sr.RepoName] = strconv.Itoa(int(sr.ID))
+ }
+
+ // remove
+ err = handler.removeSigRepos(sig, mapSigRepos, mapSigReposInDB)
+ if err != nil {
+ glog.Errorf("unable to remove sig repos: %v", err)
+ }
+
+ // add
+ err = handler.addSigRepos(sig, mapSigRepos, mapSigReposInDB)
+ if err != nil {
+ glog.Errorf("unable to add sig repos: %v", err)
+ }
+
+ return nil
+}
+
+// removeSigRepos
+func (handler *SigHandler) removeSigRepos(sig Sig, mapSigRepos, mapSigReposInDB map[string]string) error {
+ listOfRemove := make([]string, 0)
+
+ for k := range mapSigReposInDB {
+ if _, exists := mapSigRepos[k]; !exists {
+ listOfRemove = append(listOfRemove, k)
+ }
+ }
+ glog.Infof("list of remove sig repos: %v", listOfRemove)
+
+ if len(listOfRemove) > 0 {
+ glog.Infof("begin to remove sig repos for %s", sig.Name)
+ for _, v := range listOfRemove {
+ // remove from DB
+ id, _ := strconv.Atoi(mapSigReposInDB[v])
+ sr := database.SigRepositories{}
+ sr.ID = uint(id)
+ err := database.DBConnection.Delete(&sr).Error
+ if err != nil {
+ glog.Errorf("failed to remove sig repo in database: %v", err)
+ }
+ }
+ glog.Infof("end to remove sig repo for %s", sig.Name)
+ }
+
+ return nil
+}
+
+// addSigRepos
+func (handler *SigHandler) addSigRepos(sig Sig, mapSigRepos, mapSigReposInDB map[string]string) error {
+ listOfAdd := make([]string, 0)
+
+ for k := range mapSigRepos {
+ if _, exits := mapSigReposInDB[k]; !exits {
+ listOfAdd = append(listOfAdd, k)
+ }
+ }
+ glog.Infof("list of add sig repos: %v", listOfAdd)
+
+ if len(listOfAdd) > 0 {
+ glog.Infof("begin to add sig repos for %s", sig.Name)
+ for _, v := range listOfAdd {
+ sr := database.SigRepositories{
+ Name: sig.Name,
+ RepoName: v,
+ }
+ err := database.DBConnection.Create(&sr).Error
+ if err != nil {
+ glog.Errorf("failed to add sig repos in database: %v", err)
+ }
+ }
+ glog.Infof("end to add sig repos for %s", sig.Name)
+ }
+
+ return nil
+}
diff --git a/pkg/cibot/unassign.go b/pkg/cibot/unassign.go
new file mode 100644
index 0000000000000000000000000000000000000000..96e5512f6e60d8c001b3e7abfdea294ac4c1c255
--- /dev/null
+++ b/pkg/cibot/unassign.go
@@ -0,0 +1,93 @@
+package cibot
+
+import (
+ "fmt"
+ "strings"
+
+ "gitee.com/openeuler/go-gitee/gitee"
+ "github.com/golang/glog"
+)
+
+const (
+ issueUnAssignMessage = `***@%s*** is unassigned from this issue.`
+ issueCanNotUnAssignMessage = `***@%s*** can not be unassigned from this issue.
+please try to unassign the assignee from this issue.`
+)
+
+// UnAssign a collaborator for issue
+func (s *Server) UnAssign(event *gitee.NoteEvent) error {
+ if *event.NoteableType == "Issue" {
+ // handle open
+ if event.Issue.State == "open" {
+ // get basic informations
+ comment := event.Comment.Body
+ owner := event.Repository.Namespace
+ repo := event.Repository.Name
+ issueNumber := event.Issue.Number
+ issueAuthor := event.Issue.User.Login
+ commentAuthor := event.Comment.User.Login
+ glog.Infof("unassign started. comment: %s owner: %s repo: %s issueNumber: %s issueAuthor: %s commentAuthor: %s",
+ comment, owner, repo, issueNumber, issueAuthor, commentAuthor)
+
+ // split the assignees and operation to be performed.
+ substrings := strings.Split(comment, "@")
+ // default is comment author
+ unassignee := commentAuthor
+ if len(substrings) > 1 {
+ unassignee = strings.TrimSpace(substrings[1])
+ }
+
+ // if issue assignee is the same with unassignee
+ issueAssignee := ""
+ if event.Issue.Assignee != nil {
+ issueAssignee = event.Issue.Assignee.Login
+ }
+ if issueAssignee == unassignee {
+ body := gitee.IssueUpdateParam{}
+ body.Repo = repo
+ // set " " to empty the assignee by gitee
+ body.Assignee = " "
+ body.AccessToken = s.Config.GiteeToken
+ // build label string
+ var strLabel string
+ for _, l := range event.Issue.Labels {
+ strLabel += l.Name + ","
+ }
+ strLabel = strings.TrimRight(strLabel, ",")
+ if strLabel == "" {
+ strLabel = ","
+ }
+ body.Labels = strLabel
+ glog.Infof("invoke api to unassign: %s", issueNumber)
+
+ // patch assignee
+ _, _, err := s.GiteeClient.IssuesApi.PatchV5ReposOwnerIssuesNumber(s.Context, owner, issueNumber, body)
+ if err != nil {
+ glog.Errorf("unable to unassign: %s err: %v", issueNumber, err)
+ return err
+ }
+ glog.Infof("unassign successfully: %v", issueNumber)
+
+ // add comment
+ bodyComment := gitee.IssueCommentPostParam{}
+ bodyComment.AccessToken = s.Config.GiteeToken
+ bodyComment.Body = fmt.Sprintf(issueUnAssignMessage, unassignee)
+ _, _, err = s.GiteeClient.IssuesApi.PostV5ReposOwnerRepoIssuesNumberComments(s.Context, owner, repo, issueNumber, bodyComment)
+ if err != nil {
+ glog.Errorf("unable to add comment in issue: %v", err)
+ }
+ } else {
+ glog.Infof("can not unassign: %v", issueNumber)
+ // add comment
+ body := gitee.IssueCommentPostParam{}
+ body.AccessToken = s.Config.GiteeToken
+ body.Body = fmt.Sprintf(issueCanNotUnAssignMessage, unassignee)
+ _, _, err := s.GiteeClient.IssuesApi.PostV5ReposOwnerRepoIssuesNumberComments(s.Context, owner, repo, issueNumber, body)
+ if err != nil {
+ glog.Errorf("unable to add comment in issue: %v", err)
+ }
+ }
+ }
+ }
+ return nil
+}
diff --git a/pkg/cibot/utils.go b/pkg/cibot/utils.go
new file mode 100644
index 0000000000000000000000000000000000000000..446d117e56dfd49702eaa17e7b6962ca54cadb89
--- /dev/null
+++ b/pkg/cibot/utils.go
@@ -0,0 +1,131 @@
+package cibot
+
+import (
+ "fmt"
+ "regexp"
+ "strings"
+
+ "gitee.com/openeuler/go-gitee/gitee"
+ "github.com/antihax/optional"
+ "github.com/golang/glog"
+)
+
+const (
+ kind = "/kind"
+ RemoveKind = "/remove-kind"
+ AddClaYes = "/%s-cla yes"
+ AddClaNo = "/%s-cla no"
+ RemoveClaYes = "/remove-%s-cla yes"
+ RemoveClaNo = "/remove-%s-cla no"
+ LabelNameLgtm = "lgtm"
+ LabelLgtmWithCommenter = "lgtm-%s"
+ LabelNameApproved = "approved"
+ LabelHiddenValue = ""
+ tipBotMessage = `Hey ***@%s***, Welcome to %s Community.
+All of the projects in %s Community are maintained by ***@%s***.
+That means the developers can comment below every pull request or issue to trigger Bot Commands.
+Please follow instructions at <%s> to find the details.`
+)
+
+var (
+ // RegAddLabel
+ RegAddLabel = regexp.MustCompile(`(?mi)^/(kind|priority|sig)\s*(.*)$`)
+ // RegRemoveLabel
+ RegRemoveLabel = regexp.MustCompile(`(?mi)^/remove-(kind|priority|sig)\s*(.*)$`)
+ // RegCheckCLA
+ RegCheckCLA = regexp.MustCompile(`(?mi)^/check-cla\s*$`)
+ // RegAddLgtm
+ RegAddLgtm = regexp.MustCompile(`(?mi)^/lgtm\s*$`)
+ // RegRemoveLgtm
+ RegRemoveLgtm = regexp.MustCompile(`(?mi)^/lgtm cancel\s*$`)
+ // RegAddApprove
+ RegAddApprove = regexp.MustCompile(`(?mi)^/approve\s*$`)
+ // RegRemoveApprove
+ RegRemoveApprove = regexp.MustCompile(`(?mi)^/approve cancel\s*$`)
+ // RegClose
+ RegClose = regexp.MustCompile(`(?mi)^/close\s*$`)
+ // RegReOpen
+ RegReOpen = regexp.MustCompile(`(?mi)^/reopen\s*$`)
+ // RegBotAddLgtm
+ RegBotAddLgtm = regexp.MustCompile(fmt.Sprintf(LabelHiddenValue, "(.*)"))
+ // RegAssign
+ RegAssign = regexp.MustCompile(`(?mi)^/assign(( @?[-\w]+?)*)\s*$`)
+ // RegUnAssign
+ RegUnAssign = regexp.MustCompile(`(?mi)^/unassign(( @?[-\w]+?)*)\s*$`)
+)
+
+// UrlEncode replcae special chars in url
+func UrlEncode(str string) string {
+ str = strings.Replace(str, "/", "%2F", -1)
+ return str
+}
+
+// canCommentPrIncludingSigDirectory
+func canCommentPrIncludingSigDirectory(server *Server, owner string, repo string, prNumber int32, commentUser string) (int32, error) {
+ // only check community
+ if repo != "community" {
+ return -1, nil
+ }
+
+ // get pr files
+ files, _, err := server.GiteeClient.PullRequestsApi.GetV5ReposOwnerRepoPullsNumberFiles(
+ server.Context, owner, repo, prNumber, &gitee.GetV5ReposOwnerRepoPullsNumberFilesOpts{
+ AccessToken: optional.NewString(server.Config.GiteeToken),
+ })
+ if err != nil {
+ glog.Infof("read pr files failed: %v", err)
+ return -1, err
+ }
+
+ sigFilePathHeadPattern, err := regexp.Compile("^sig/[a-zA-Z0-9_-]+/")
+ if err != nil {
+ return -1, err
+ }
+
+ sigFilePathPattern, _ := regexp.Compile(sigFilePathHeadPattern.String() + ".+")
+ targetSigPath := make(map[string]bool)
+
+ for _, file := range files {
+ // TODO test: use file.RawUrl instead?
+ glog.Infof("get files log, RawUrl=%v, filename=%v\n", file.RawUrl, file.Filename)
+ if !sigFilePathPattern.MatchString(file.Filename) {
+ glog.Info("file name pattern log: not match")
+ return -1, nil
+ }
+ targetSigPath[sigFilePathHeadPattern.FindString(file.Filename)] = true
+ }
+
+ glog.Infof("targetSigPath=%v", targetSigPath)
+
+ for path, _ := range targetSigPath {
+ content, _, err := server.GiteeClient.RepositoriesApi.GetV5ReposOwnerRepoContentsPath(
+ server.Context, owner, repo, path+"OWNERS", &gitee.GetV5ReposOwnerRepoContentsPathOpts{
+ AccessToken: optional.NewString(server.Config.GiteeToken),
+ })
+ glog.Infof("read file=%v, err=%v", path, err)
+ // TODO the file is not exist. for example: this pr create OWNERS.
+ if err != nil {
+ // TODO if read OWNERS failed, return nil to allow TC to approve this pr temporarily.
+ return -1, nil
+ }
+
+ owners := DecodeOwners(content.Content)
+ glog.Infof("owners=%v, commenturser=%v", owners, commentUser)
+ if owners == nil {
+ return 0, nil
+ }
+
+ bingo := false
+ for _, owner := range owners {
+ glog.Infof("owner=%v", owner)
+ if owner == commentUser {
+ bingo = true
+ break
+ }
+ }
+ if !bingo {
+ return 0, nil
+ }
+ }
+ return 1, nil
+}
diff --git a/pkg/cibot/webhook.go b/pkg/cibot/webhook.go
new file mode 100644
index 0000000000000000000000000000000000000000..857157bb082bb1a08bdb73b4f41704ac8f07a4f3
--- /dev/null
+++ b/pkg/cibot/webhook.go
@@ -0,0 +1,133 @@
+package cibot
+
+import (
+ "context"
+ "flag"
+ "io/ioutil"
+ "net/http"
+ "strconv"
+
+ "gitee.com/openeuler/ci-bot/pkg/cibot/config"
+ "gitee.com/openeuler/ci-bot/pkg/cibot/database"
+ "gitee.com/openeuler/go-gitee/gitee"
+ "github.com/golang/glog"
+ "github.com/spf13/pflag"
+ "golang.org/x/oauth2"
+ "gopkg.in/yaml.v2"
+)
+
+type Webhook struct {
+ Address string
+ Port int64
+ ConfigFile string
+}
+
+func NewWebHook() *Webhook {
+ return &Webhook{
+ Address: "0.0.0.0",
+ Port: 8888,
+ ConfigFile: "config.yaml",
+ }
+}
+
+func (s *Webhook) AddFlags(fs *pflag.FlagSet) {
+ fs.StringVar(&s.Address, "address", s.Address, "ip address to serve, 0.0.0.0 by default.")
+ fs.Int64Var(&s.Port, "port", s.Port, "port to listen on, 8888 by default.")
+ fs.StringVar(&s.ConfigFile, "configfile", s.ConfigFile, "config file.")
+
+ // See https://github.com/spf13/pflag#supporting-go-flags-when-using-pflag
+ fs.AddGoFlagSet(flag.CommandLine)
+ pflag.Parse()
+}
+
+func (s *Webhook) Run() {
+ // Flush flushes all pending log I/O.
+ defer glog.Flush()
+
+ // read file
+ configContent, err := ioutil.ReadFile(s.ConfigFile)
+ if err != nil {
+ glog.Fatalf("could not read config file: %v", err)
+ }
+
+ // unmarshal config file
+ var config config.Config
+ err = yaml.Unmarshal(configContent, &config)
+ if err != nil {
+ glog.Fatalf("fail to unmarshal: %v", err)
+ }
+
+ // oauth
+ oauthSecret := config.GiteeToken
+ ctx := context.Background()
+ ts := oauth2.StaticTokenSource(
+ &oauth2.Token{AccessToken: string(oauthSecret)},
+ )
+
+ // configuration
+ giteeConf := gitee.NewConfiguration()
+ giteeConf.HTTPClient = oauth2.NewClient(ctx, ts)
+
+ // git client
+ giteeClient := gitee.NewAPIClient(giteeConf)
+
+ err = database.New(config)
+ if err != nil {
+ glog.Errorf("init back database error: %v", err)
+ }
+
+ /* setting init handler
+ initHandler := InitHandler{
+ Config: config,
+ Context: ctx,
+ GiteeClient: giteeClient,
+ }
+ go initHandler.Serve()*/
+
+ // setting repo handler
+ repoHandler := RepoHandler{
+ Config: config,
+ Context: ctx,
+ GiteeClient: giteeClient,
+ }
+ go repoHandler.Serve()
+
+ // setting sig handler
+ sigHandler := SigHandler{
+ Config: config,
+ Context: ctx,
+ GiteeClient: giteeClient,
+ }
+ go sigHandler.Serve()
+
+ // setting owner handler
+ ownerHandler := OwnerHandler{
+ Config: config,
+ Context: ctx,
+ GiteeClient: giteeClient,
+ }
+ go ownerHandler.Serve()
+
+ // return 200 for health check
+ http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {})
+
+ // setting webhook handler
+ webHookHandler := Server{
+ Config: config,
+ Context: ctx,
+ GiteeClient: giteeClient,
+ }
+ http.HandleFunc("/webhook", webHookHandler.ServeHTTP)
+
+ // setting cla handler
+ claHandler := CLAHandler{
+ Context: ctx,
+ }
+ http.HandleFunc("/cla", claHandler.ServeHTTP)
+
+ //starting server
+ address := s.Address + ":" + strconv.FormatInt(s.Port, 10)
+ if err := http.ListenAndServe(address, nil); err != nil {
+ glog.Error(err)
+ }
+}
diff --git a/projects.yaml b/projects.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..09be048d98b79e55694412847a6c666120c29451
--- /dev/null
+++ b/projects.yaml
@@ -0,0 +1,18 @@
+community:
+ name: openeuler
+ managers:
+ - edisontest
+ developers:
+ - edisontest
+ viewers:
+ - edisontest
+repositories:
+ - name: edisontest
+ description: "this is test from edison"
+ type: private
+ managers:
+ - edisontest
+ developers:
+ - edisontest
+ viewers:
+ - edisontest
diff --git a/script/coverage b/script/coverage
new file mode 100644
index 0000000000000000000000000000000000000000..3efa81ba5aea4e5ae8f24a50beaab0606c03d8cb
--- /dev/null
+++ b/script/coverage
@@ -0,0 +1,12 @@
+#!/bin/bash
+
+set -e
+
+n=1
+for testpkg in $(go list ./testing ./.../testing); do
+ covpkg="${testpkg/"/testing"/}"
+ go test -covermode count -coverprofile "testing_"$n.coverprofile -coverpkg $covpkg $testpkg 2>/dev/null
+ n=$((n+1))
+done
+gocovmerge `ls *.coverprofile` > cover.out
+rm *.coverprofile
diff --git a/vendor/gitee.com/openeuler/go-gitee/LICENSE b/vendor/gitee.com/openeuler/go-gitee/LICENSE
new file mode 100644
index 0000000000000000000000000000000000000000..a10985f0870b66a8385e18df5fe94ec35ff5919a
--- /dev/null
+++ b/vendor/gitee.com/openeuler/go-gitee/LICENSE
@@ -0,0 +1,122 @@
+木兰宽松许可证, 第1版
+
+2019年8月 http://license.coscl.org.cn/MulanPSL
+
+您对“软件”的复制、使用、修改及分发受木兰宽松许可证,第1版(“本许可证”)的如下条款的约束:
+
+0. 定义
+
+“软件”是指由“贡献”构成的许可在“本许可证”下的程序和相关文档的集合。
+
+“贡献者”是指将受版权法保护的作品许可在“本许可证”下的自然人或“法人实体”。
+
+“法人实体”是指提交贡献的机构及其“关联实体”。
+
+“关联实体”是指,对“本许可证”下的一方而言,控制、受控制或与其共同受控制的机构,此处的控制是指有受控方或共同受控方至少50%直接或间接的投票权、资金或其他有价证券。
+
+“贡献”是指由任一“贡献者”许可在“本许可证”下的受版权法保护的作品。
+
+1. 授予版权许可
+
+每个“贡献者”根据“本许可证”授予您永久性的、全球性的、免费的、非独占的、不可撤销的版权许可,您可以复制、使用、修改、分发其“贡献”,不论修改与否。
+
+2. 授予专利许可
+
+每个“贡献者”根据“本许可证”授予您永久性的、全球性的、免费的、非独占的、不可撤销的(根据本条规定撤销除外)专利许可,供您制造、委托制造、使用、许诺销售、销售、进口其“贡献”或以其他方式转移其“贡献”。前述专利许可仅限于“贡献者”现在或将来拥有或控制的其“贡献”本身或其“贡献”与许可“贡献”时的“软件”结合而将必然会侵犯的专利权利要求,不包括仅因您或他人修改“贡献”或其他结合而将必然会侵犯到的专利权利要求。如您或您的“关联实体”直接或间接地(包括通过代理、专利被许可人或受让人),就“软件”或其中的“贡献”对任何人发起专利侵权诉讼(包括反诉或交叉诉讼)或其他专利维权行动,指控其侵犯专利权,则“本许可证”授予您对“软件”的专利许可自您提起诉讼或发起维权行动之日终止。
+
+3. 无商标许可
+
+“本许可证”不提供对“贡献者”的商品名称、商标、服务标志或产品名称的商标许可,但您为满足第4条规定的声明义务而必须使用除外。
+
+4. 分发限制
+
+您可以在任何媒介中将“软件”以源程序形式或可执行形式重新分发,不论修改与否,但您必须向接收者提供“本许可证”的副本,并保留“软件”中的版权、商标、专利及免责声明。
+
+5. 免责声明与责任限制
+
+“软件”及其中的“贡献”在提供时不带任何明示或默示的担保。在任何情况下,“贡献者”或版权所有者不对任何人因使用“软件”或其中的“贡献”而引发的任何直接或间接损失承担责任,不论因何种原因导致或者基于何种法律理论,即使其曾被建议有此种损失的可能性。
+
+条款结束
+
+如何将木兰宽松许可证,第1版,应用到您的软件
+
+如果您希望将木兰宽松许可证,第1版,应用到您的新软件,为了方便接收者查阅,建议您完成如下三步:
+
+1, 请您补充如下声明中的空白,包括软件名、软件的首次发表年份以及您作为版权人的名字;
+
+2, 请您在软件包的一级目录下创建以“LICENSE”为名的文件,将整个许可证文本放入该文件中;
+
+3, 请将如下声明文本放入每个源文件的头部注释中。
+
+Copyright (c) [2019] [name of copyright holder]
+[Software Name] is licensed under the Mulan PSL v1.
+You can use this software according to the terms and conditions of the Mulan PSL v1.
+You may obtain a copy of Mulan PSL v1 at:
+ http://license.coscl.org.cn/MulanPSL
+THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR
+PURPOSE.
+See the Mulan PSL v1 for more details.
+
+
+
+Mulan Permissive Software License,Version 1
+
+Mulan Permissive Software License,Version 1 (Mulan PSL v1)
+
+August 2019 http://license.coscl.org.cn/MulanPSL
+
+Your reproduction, use, modification and distribution of the Software shall be subject to Mulan PSL v1 (this License) with following terms and conditions:
+
+0. Definition
+
+Software means the program and related documents which are comprised of those Contribution and licensed under this License.
+
+Contributor means the Individual or Legal Entity who licenses its copyrightable work under this License.
+
+Legal Entity means the entity making a Contribution and all its Affiliates.
+
+Affiliates means entities that control, or are controlled by, or are under common control with a party to this License, ‘control’ means direct or indirect ownership of at least fifty percent (50%) of the voting power, capital or other securities of controlled or commonly controlled entity.
+
+Contribution means the copyrightable work licensed by a particular Contributor under this License.
+
+1. Grant of Copyright License
+
+Subject to the terms and conditions of this License, each Contributor hereby grants to you a perpetual, worldwide, royalty-free, non-exclusive, irrevocable copyright license to reproduce, use, modify, or distribute its Contribution, with modification or not.
+
+2. Grant of Patent License
+
+Subject to the terms and conditions of this License, each Contributor hereby grants to you a perpetual, worldwide, royalty-free, non-exclusive, irrevocable (except for revocation under this Section) patent license to make, have made, use, offer for sale, sell, import or otherwise transfer its Contribution where such patent license is only limited to the patent claims owned or controlled by such Contributor now or in future which will be necessarily infringed by its Contribution alone, or by combination of the Contribution with the Software to which the Contribution was contributed, excluding of any patent claims solely be infringed by your or others’ modification or other combinations. If you or your Affiliates directly or indirectly (including through an agent, patent licensee or assignee), institute patent litigation (including a cross claim or counterclaim in a litigation) or other patent enforcement activities against any individual or entity by alleging that the Software or any Contribution in it infringes patents, then any patent license granted to you under this License for the Software shall terminate as of the date such litigation or activity is filed or taken.
+
+3. No Trademark License
+
+No trademark license is granted to use the trade names, trademarks, service marks, or product names of Contributor, except as required to fulfill notice requirements in section 4.
+
+4. Distribution Restriction
+
+You may distribute the Software in any medium with or without modification, whether in source or executable forms, provided that you provide recipients with a copy of this License and retain copyright, patent, trademark and disclaimer statements in the Software.
+
+5. Disclaimer of Warranty and Limitation of Liability
+
+The Software and Contribution in it are provided without warranties of any kind, either express or implied. In no event shall any Contributor or copyright holder be liable to you for any damages, including, but not limited to any direct, or indirect, special or consequential damages arising from your use or inability to use the Software or the Contribution in it, no matter how it’s caused or based on which legal theory, even if advised of the possibility of such damages.
+
+End of the Terms and Conditions
+
+How to apply the Mulan Permissive Software License,Version 1 (Mulan PSL v1) to your software
+
+To apply the Mulan PSL v1 to your work, for easy identification by recipients, you are suggested to complete following three steps:
+
+1. Fill in the blanks in following statement, including insert your software name, the year of the first publication of your software, and your name identified as the copyright owner;
+2. Create a file named “LICENSE” which contains the whole context of this License in the first directory of your software package;
+3. Attach the statement to the appropriate annotated syntax at the beginning of each source file.
+
+Copyright (c) [2019] [name of copyright holder]
+[Software Name] is licensed under the Mulan PSL v1.
+You can use this software according to the terms and conditions of the Mulan PSL v1.
+You may obtain a copy of Mulan PSL v1 at:
+ http://license.coscl.org.cn/MulanPSL
+THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR
+PURPOSE.
+See the Mulan PSL v1 for more details.
+
diff --git a/vendor/gitee.com/openeuler/go-gitee/gitee/api_activity.go b/vendor/gitee.com/openeuler/go-gitee/gitee/api_activity.go
new file mode 100644
index 0000000000000000000000000000000000000000..cdb82d1eeb5a1dba12c1b959cbbad62cdecbdb68
--- /dev/null
+++ b/vendor/gitee.com/openeuler/go-gitee/gitee/api_activity.go
@@ -0,0 +1,3409 @@
+/*
+ * 码云 Open API
+ *
+ * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen)
+ *
+ * API version: 5.3.2
+ * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
+ */
+
+package gitee
+
+import (
+ "context"
+ "fmt"
+ "io/ioutil"
+ "net/http"
+ "net/url"
+ "strings"
+
+ "github.com/antihax/optional"
+)
+
+// Linger please
+var (
+ _ context.Context
+)
+
+type ActivityApiService service
+
+/*
+ActivityApiService 取消 star 一个仓库
+取消 star 一个仓库
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param owner 仓库所属空间地址(企业、组织或个人的地址path)
+ * @param repo 仓库路径(path)
+ * @param optional nil or *DeleteV5UserStarredOwnerRepoOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+
+
+*/
+
+type DeleteV5UserStarredOwnerRepoOpts struct {
+ AccessToken optional.String
+}
+
+func (a *ActivityApiService) DeleteV5UserStarredOwnerRepo(ctx context.Context, owner string, repo string, localVarOptionals *DeleteV5UserStarredOwnerRepoOpts) (*http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Delete")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/user/starred/{owner}/{repo}"
+ localVarPath = strings.Replace(localVarPath, "{"+"owner"+"}", fmt.Sprintf("%v", owner), -1)
+ localVarPath = strings.Replace(localVarPath, "{"+"repo"+"}", fmt.Sprintf("%v", repo), -1)
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarQueryParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ return localVarHttpResponse, newErr
+ }
+
+ return localVarHttpResponse, nil
+}
+
+/*
+ActivityApiService 取消 watch 一个仓库
+取消 watch 一个仓库
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param owner 仓库所属空间地址(企业、组织或个人的地址path)
+ * @param repo 仓库路径(path)
+ * @param optional nil or *DeleteV5UserSubscriptionsOwnerRepoOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+
+
+*/
+
+type DeleteV5UserSubscriptionsOwnerRepoOpts struct {
+ AccessToken optional.String
+}
+
+func (a *ActivityApiService) DeleteV5UserSubscriptionsOwnerRepo(ctx context.Context, owner string, repo string, localVarOptionals *DeleteV5UserSubscriptionsOwnerRepoOpts) (*http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Delete")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/user/subscriptions/{owner}/{repo}"
+ localVarPath = strings.Replace(localVarPath, "{"+"owner"+"}", fmt.Sprintf("%v", owner), -1)
+ localVarPath = strings.Replace(localVarPath, "{"+"repo"+"}", fmt.Sprintf("%v", repo), -1)
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarQueryParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ return localVarHttpResponse, newErr
+ }
+
+ return localVarHttpResponse, nil
+}
+
+/*
+ActivityApiService 获取站内所有公开动态
+获取站内所有公开动态
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param optional nil or *GetV5EventsOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+ * @param "Page" (optional.Int32) - 当前的页码
+ * @param "PerPage" (optional.Int32) - 每页的数量,最大为 100
+
+@return []Event
+*/
+
+type GetV5EventsOpts struct {
+ AccessToken optional.String
+ Page optional.Int32
+ PerPage optional.Int32
+}
+
+func (a *ActivityApiService) GetV5Events(ctx context.Context, localVarOptionals *GetV5EventsOpts) ([]Event, *http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Get")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ localVarReturnValue []Event
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/events"
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarQueryParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Page.IsSet() {
+ localVarQueryParams.Add("page", parameterToString(localVarOptionals.Page.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.PerPage.IsSet() {
+ localVarQueryParams.Add("per_page", parameterToString(localVarOptionals.PerPage.Value(), ""))
+ }
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return localVarReturnValue, nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode < 300 {
+ // If we succeed, return the data, otherwise pass on to decode error.
+ err = a.client.decode(&localVarReturnValue, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ if localVarHttpResponse.StatusCode == 200 {
+ var v []Event
+ err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err != nil {
+ newErr.error = err.Error()
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+ newErr.model = v
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, nil
+}
+
+/*
+ActivityApiService 列出仓库的所有公开动态
+列出仓库的所有公开动态
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param owner 仓库所属空间地址(企业、组织或个人的地址path)
+ * @param repo 仓库路径(path)
+ * @param optional nil or *GetV5NetworksOwnerRepoEventsOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+ * @param "Page" (optional.Int32) - 当前的页码
+ * @param "PerPage" (optional.Int32) - 每页的数量,最大为 100
+
+@return []Event
+*/
+
+type GetV5NetworksOwnerRepoEventsOpts struct {
+ AccessToken optional.String
+ Page optional.Int32
+ PerPage optional.Int32
+}
+
+func (a *ActivityApiService) GetV5NetworksOwnerRepoEvents(ctx context.Context, owner string, repo string, localVarOptionals *GetV5NetworksOwnerRepoEventsOpts) ([]Event, *http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Get")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ localVarReturnValue []Event
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/networks/{owner}/{repo}/events"
+ localVarPath = strings.Replace(localVarPath, "{"+"owner"+"}", fmt.Sprintf("%v", owner), -1)
+ localVarPath = strings.Replace(localVarPath, "{"+"repo"+"}", fmt.Sprintf("%v", repo), -1)
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarQueryParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Page.IsSet() {
+ localVarQueryParams.Add("page", parameterToString(localVarOptionals.Page.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.PerPage.IsSet() {
+ localVarQueryParams.Add("per_page", parameterToString(localVarOptionals.PerPage.Value(), ""))
+ }
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return localVarReturnValue, nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode < 300 {
+ // If we succeed, return the data, otherwise pass on to decode error.
+ err = a.client.decode(&localVarReturnValue, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ if localVarHttpResponse.StatusCode == 200 {
+ var v []Event
+ err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err != nil {
+ newErr.error = err.Error()
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+ newErr.model = v
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, nil
+}
+
+/*
+ActivityApiService 获取授权用户的通知数
+获取授权用户的通知数
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param optional nil or *GetV5NotificationsCountOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+ * @param "Unread" (optional.Bool) - 是否只获取未读消息,默认:否
+
+@return UserNotificationCount
+*/
+
+type GetV5NotificationsCountOpts struct {
+ AccessToken optional.String
+ Unread optional.Bool
+}
+
+func (a *ActivityApiService) GetV5NotificationsCount(ctx context.Context, localVarOptionals *GetV5NotificationsCountOpts) (UserNotificationCount, *http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Get")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ localVarReturnValue UserNotificationCount
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/notifications/count"
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarQueryParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Unread.IsSet() {
+ localVarQueryParams.Add("unread", parameterToString(localVarOptionals.Unread.Value(), ""))
+ }
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return localVarReturnValue, nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode < 300 {
+ // If we succeed, return the data, otherwise pass on to decode error.
+ err = a.client.decode(&localVarReturnValue, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ if localVarHttpResponse.StatusCode == 200 {
+ var v UserNotificationCount
+ err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err != nil {
+ newErr.error = err.Error()
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+ newErr.model = v
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, nil
+}
+
+/*
+ActivityApiService 列出授权用户的所有私信
+列出授权用户的所有私信
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param optional nil or *GetV5NotificationsMessagesOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+ * @param "Unread" (optional.Bool) - 是否只显示未读私信,默认:否
+ * @param "Since" (optional.String) - 只获取在给定时间后更新的私信,要求时间格式为 ISO 8601
+ * @param "Before" (optional.String) - 只获取在给定时间前更新的私信,要求时间格式为 ISO 8601
+ * @param "Ids" (optional.String) - 指定一组私信 ID,以 , 分隔
+ * @param "Page" (optional.Int32) - 当前的页码
+ * @param "PerPage" (optional.Int32) - 每页的数量,最大为 100
+
+@return []UserMessageList
+*/
+
+type GetV5NotificationsMessagesOpts struct {
+ AccessToken optional.String
+ Unread optional.Bool
+ Since optional.String
+ Before optional.String
+ Ids optional.String
+ Page optional.Int32
+ PerPage optional.Int32
+}
+
+func (a *ActivityApiService) GetV5NotificationsMessages(ctx context.Context, localVarOptionals *GetV5NotificationsMessagesOpts) ([]UserMessageList, *http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Get")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ localVarReturnValue []UserMessageList
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/notifications/messages"
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarQueryParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Unread.IsSet() {
+ localVarQueryParams.Add("unread", parameterToString(localVarOptionals.Unread.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Since.IsSet() {
+ localVarQueryParams.Add("since", parameterToString(localVarOptionals.Since.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Before.IsSet() {
+ localVarQueryParams.Add("before", parameterToString(localVarOptionals.Before.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Ids.IsSet() {
+ localVarQueryParams.Add("ids", parameterToString(localVarOptionals.Ids.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Page.IsSet() {
+ localVarQueryParams.Add("page", parameterToString(localVarOptionals.Page.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.PerPage.IsSet() {
+ localVarQueryParams.Add("per_page", parameterToString(localVarOptionals.PerPage.Value(), ""))
+ }
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return localVarReturnValue, nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode < 300 {
+ // If we succeed, return the data, otherwise pass on to decode error.
+ err = a.client.decode(&localVarReturnValue, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ if localVarHttpResponse.StatusCode == 200 {
+ var v []UserMessageList
+ err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err != nil {
+ newErr.error = err.Error()
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+ newErr.model = v
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, nil
+}
+
+/*
+ActivityApiService 获取一条私信
+获取一条私信
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param id 私信的 ID
+ * @param optional nil or *GetV5NotificationsMessagesIdOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+
+@return UserMessage
+*/
+
+type GetV5NotificationsMessagesIdOpts struct {
+ AccessToken optional.String
+}
+
+func (a *ActivityApiService) GetV5NotificationsMessagesId(ctx context.Context, id string, localVarOptionals *GetV5NotificationsMessagesIdOpts) (UserMessage, *http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Get")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ localVarReturnValue UserMessage
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/notifications/messages/{id}"
+ localVarPath = strings.Replace(localVarPath, "{"+"id"+"}", fmt.Sprintf("%v", id), -1)
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarQueryParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return localVarReturnValue, nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode < 300 {
+ // If we succeed, return the data, otherwise pass on to decode error.
+ err = a.client.decode(&localVarReturnValue, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ if localVarHttpResponse.StatusCode == 200 {
+ var v UserMessage
+ err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err != nil {
+ newErr.error = err.Error()
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+ newErr.model = v
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, nil
+}
+
+/*
+ActivityApiService 列出授权用户的所有通知
+列出授权用户的所有通知
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param optional nil or *GetV5NotificationsThreadsOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+ * @param "Unread" (optional.Bool) - 是否只获取未读消息,默认:否
+ * @param "Participating" (optional.Bool) - 是否只获取自己直接参与的消息,默认:否
+ * @param "Type_" (optional.String) - 筛选指定类型的通知,all:所有,event:事件通知,referer:@ 通知
+ * @param "Since" (optional.String) - 只获取在给定时间后更新的消息,要求时间格式为 ISO 8601
+ * @param "Before" (optional.String) - 只获取在给定时间前更新的消息,要求时间格式为 ISO 8601
+ * @param "Ids" (optional.String) - 指定一组通知 ID,以 , 分隔
+ * @param "Page" (optional.Int32) - 当前的页码
+ * @param "PerPage" (optional.Int32) - 每页的数量,最大为 100
+
+@return []UserNotificationList
+*/
+
+type GetV5NotificationsThreadsOpts struct {
+ AccessToken optional.String
+ Unread optional.Bool
+ Participating optional.Bool
+ Type_ optional.String
+ Since optional.String
+ Before optional.String
+ Ids optional.String
+ Page optional.Int32
+ PerPage optional.Int32
+}
+
+func (a *ActivityApiService) GetV5NotificationsThreads(ctx context.Context, localVarOptionals *GetV5NotificationsThreadsOpts) ([]UserNotificationList, *http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Get")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ localVarReturnValue []UserNotificationList
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/notifications/threads"
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarQueryParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Unread.IsSet() {
+ localVarQueryParams.Add("unread", parameterToString(localVarOptionals.Unread.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Participating.IsSet() {
+ localVarQueryParams.Add("participating", parameterToString(localVarOptionals.Participating.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Type_.IsSet() {
+ localVarQueryParams.Add("type", parameterToString(localVarOptionals.Type_.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Since.IsSet() {
+ localVarQueryParams.Add("since", parameterToString(localVarOptionals.Since.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Before.IsSet() {
+ localVarQueryParams.Add("before", parameterToString(localVarOptionals.Before.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Ids.IsSet() {
+ localVarQueryParams.Add("ids", parameterToString(localVarOptionals.Ids.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Page.IsSet() {
+ localVarQueryParams.Add("page", parameterToString(localVarOptionals.Page.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.PerPage.IsSet() {
+ localVarQueryParams.Add("per_page", parameterToString(localVarOptionals.PerPage.Value(), ""))
+ }
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return localVarReturnValue, nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode < 300 {
+ // If we succeed, return the data, otherwise pass on to decode error.
+ err = a.client.decode(&localVarReturnValue, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ if localVarHttpResponse.StatusCode == 200 {
+ var v []UserNotificationList
+ err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err != nil {
+ newErr.error = err.Error()
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+ newErr.model = v
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, nil
+}
+
+/*
+ActivityApiService 获取一条通知
+获取一条通知
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param id 通知的 ID
+ * @param optional nil or *GetV5NotificationsThreadsIdOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+
+@return UserNotification
+*/
+
+type GetV5NotificationsThreadsIdOpts struct {
+ AccessToken optional.String
+}
+
+func (a *ActivityApiService) GetV5NotificationsThreadsId(ctx context.Context, id string, localVarOptionals *GetV5NotificationsThreadsIdOpts) (UserNotification, *http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Get")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ localVarReturnValue UserNotification
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/notifications/threads/{id}"
+ localVarPath = strings.Replace(localVarPath, "{"+"id"+"}", fmt.Sprintf("%v", id), -1)
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarQueryParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return localVarReturnValue, nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode < 300 {
+ // If we succeed, return the data, otherwise pass on to decode error.
+ err = a.client.decode(&localVarReturnValue, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ if localVarHttpResponse.StatusCode == 200 {
+ var v UserNotification
+ err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err != nil {
+ newErr.error = err.Error()
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+ newErr.model = v
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, nil
+}
+
+/*
+ActivityApiService 列出组织的公开动态
+列出组织的公开动态
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param org 组织的路径(path/login)
+ * @param optional nil or *GetV5OrgsOrgEventsOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+ * @param "Page" (optional.Int32) - 当前的页码
+ * @param "PerPage" (optional.Int32) - 每页的数量,最大为 100
+
+@return []Event
+*/
+
+type GetV5OrgsOrgEventsOpts struct {
+ AccessToken optional.String
+ Page optional.Int32
+ PerPage optional.Int32
+}
+
+func (a *ActivityApiService) GetV5OrgsOrgEvents(ctx context.Context, org string, localVarOptionals *GetV5OrgsOrgEventsOpts) ([]Event, *http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Get")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ localVarReturnValue []Event
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/orgs/{org}/events"
+ localVarPath = strings.Replace(localVarPath, "{"+"org"+"}", fmt.Sprintf("%v", org), -1)
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarQueryParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Page.IsSet() {
+ localVarQueryParams.Add("page", parameterToString(localVarOptionals.Page.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.PerPage.IsSet() {
+ localVarQueryParams.Add("per_page", parameterToString(localVarOptionals.PerPage.Value(), ""))
+ }
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return localVarReturnValue, nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode < 300 {
+ // If we succeed, return the data, otherwise pass on to decode error.
+ err = a.client.decode(&localVarReturnValue, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ if localVarHttpResponse.StatusCode == 200 {
+ var v []Event
+ err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err != nil {
+ newErr.error = err.Error()
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+ newErr.model = v
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, nil
+}
+
+/*
+ActivityApiService 列出仓库的所有动态
+列出仓库的所有动态
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param owner 仓库所属空间地址(企业、组织或个人的地址path)
+ * @param repo 仓库路径(path)
+ * @param optional nil or *GetV5ReposOwnerRepoEventsOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+ * @param "Page" (optional.Int32) - 当前的页码
+ * @param "PerPage" (optional.Int32) - 每页的数量,最大为 100
+
+@return []Event
+*/
+
+type GetV5ReposOwnerRepoEventsOpts struct {
+ AccessToken optional.String
+ Page optional.Int32
+ PerPage optional.Int32
+}
+
+func (a *ActivityApiService) GetV5ReposOwnerRepoEvents(ctx context.Context, owner string, repo string, localVarOptionals *GetV5ReposOwnerRepoEventsOpts) ([]Event, *http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Get")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ localVarReturnValue []Event
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/repos/{owner}/{repo}/events"
+ localVarPath = strings.Replace(localVarPath, "{"+"owner"+"}", fmt.Sprintf("%v", owner), -1)
+ localVarPath = strings.Replace(localVarPath, "{"+"repo"+"}", fmt.Sprintf("%v", repo), -1)
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarQueryParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Page.IsSet() {
+ localVarQueryParams.Add("page", parameterToString(localVarOptionals.Page.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.PerPage.IsSet() {
+ localVarQueryParams.Add("per_page", parameterToString(localVarOptionals.PerPage.Value(), ""))
+ }
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return localVarReturnValue, nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode < 300 {
+ // If we succeed, return the data, otherwise pass on to decode error.
+ err = a.client.decode(&localVarReturnValue, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ if localVarHttpResponse.StatusCode == 200 {
+ var v []Event
+ err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err != nil {
+ newErr.error = err.Error()
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+ newErr.model = v
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, nil
+}
+
+/*
+ActivityApiService 列出一个仓库里的通知
+列出一个仓库里的通知
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param owner 仓库所属空间地址(企业、组织或个人的地址path)
+ * @param repo 仓库路径(path)
+ * @param optional nil or *GetV5ReposOwnerRepoNotificationsOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+ * @param "Unread" (optional.Bool) - 是否只获取未读消息,默认:否
+ * @param "Participating" (optional.Bool) - 是否只获取自己直接参与的消息,默认:否
+ * @param "Type_" (optional.String) - 筛选指定类型的通知,all:所有,event:事件通知,referer:@ 通知
+ * @param "Since" (optional.String) - 只获取在给定时间后更新的消息,要求时间格式为 ISO 8601
+ * @param "Before" (optional.String) - 只获取在给定时间前更新的消息,要求时间格式为 ISO 8601
+ * @param "Ids" (optional.String) - 指定一组通知 ID,以 , 分隔
+ * @param "Page" (optional.Int32) - 当前的页码
+ * @param "PerPage" (optional.Int32) - 每页的数量,最大为 100
+
+@return []UserNotificationList
+*/
+
+type GetV5ReposOwnerRepoNotificationsOpts struct {
+ AccessToken optional.String
+ Unread optional.Bool
+ Participating optional.Bool
+ Type_ optional.String
+ Since optional.String
+ Before optional.String
+ Ids optional.String
+ Page optional.Int32
+ PerPage optional.Int32
+}
+
+func (a *ActivityApiService) GetV5ReposOwnerRepoNotifications(ctx context.Context, owner string, repo string, localVarOptionals *GetV5ReposOwnerRepoNotificationsOpts) ([]UserNotificationList, *http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Get")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ localVarReturnValue []UserNotificationList
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/repos/{owner}/{repo}/notifications"
+ localVarPath = strings.Replace(localVarPath, "{"+"owner"+"}", fmt.Sprintf("%v", owner), -1)
+ localVarPath = strings.Replace(localVarPath, "{"+"repo"+"}", fmt.Sprintf("%v", repo), -1)
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarQueryParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Unread.IsSet() {
+ localVarQueryParams.Add("unread", parameterToString(localVarOptionals.Unread.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Participating.IsSet() {
+ localVarQueryParams.Add("participating", parameterToString(localVarOptionals.Participating.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Type_.IsSet() {
+ localVarQueryParams.Add("type", parameterToString(localVarOptionals.Type_.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Since.IsSet() {
+ localVarQueryParams.Add("since", parameterToString(localVarOptionals.Since.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Before.IsSet() {
+ localVarQueryParams.Add("before", parameterToString(localVarOptionals.Before.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Ids.IsSet() {
+ localVarQueryParams.Add("ids", parameterToString(localVarOptionals.Ids.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Page.IsSet() {
+ localVarQueryParams.Add("page", parameterToString(localVarOptionals.Page.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.PerPage.IsSet() {
+ localVarQueryParams.Add("per_page", parameterToString(localVarOptionals.PerPage.Value(), ""))
+ }
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return localVarReturnValue, nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode < 300 {
+ // If we succeed, return the data, otherwise pass on to decode error.
+ err = a.client.decode(&localVarReturnValue, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ if localVarHttpResponse.StatusCode == 200 {
+ var v []UserNotificationList
+ err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err != nil {
+ newErr.error = err.Error()
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+ newErr.model = v
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, nil
+}
+
+/*
+ActivityApiService 列出 star 了仓库的用户
+列出 star 了仓库的用户
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param owner 仓库所属空间地址(企业、组织或个人的地址path)
+ * @param repo 仓库路径(path)
+ * @param optional nil or *GetV5ReposOwnerRepoStargazersOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+ * @param "Page" (optional.Int32) - 当前的页码
+ * @param "PerPage" (optional.Int32) - 每页的数量,最大为 100
+
+@return []UserBasic
+*/
+
+type GetV5ReposOwnerRepoStargazersOpts struct {
+ AccessToken optional.String
+ Page optional.Int32
+ PerPage optional.Int32
+}
+
+func (a *ActivityApiService) GetV5ReposOwnerRepoStargazers(ctx context.Context, owner string, repo string, localVarOptionals *GetV5ReposOwnerRepoStargazersOpts) ([]UserBasic, *http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Get")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ localVarReturnValue []UserBasic
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/repos/{owner}/{repo}/stargazers"
+ localVarPath = strings.Replace(localVarPath, "{"+"owner"+"}", fmt.Sprintf("%v", owner), -1)
+ localVarPath = strings.Replace(localVarPath, "{"+"repo"+"}", fmt.Sprintf("%v", repo), -1)
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarQueryParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Page.IsSet() {
+ localVarQueryParams.Add("page", parameterToString(localVarOptionals.Page.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.PerPage.IsSet() {
+ localVarQueryParams.Add("per_page", parameterToString(localVarOptionals.PerPage.Value(), ""))
+ }
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return localVarReturnValue, nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode < 300 {
+ // If we succeed, return the data, otherwise pass on to decode error.
+ err = a.client.decode(&localVarReturnValue, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ if localVarHttpResponse.StatusCode == 200 {
+ var v []UserBasic
+ err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err != nil {
+ newErr.error = err.Error()
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+ newErr.model = v
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, nil
+}
+
+/*
+ActivityApiService 列出 watch 了仓库的用户
+列出 watch 了仓库的用户
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param owner 仓库所属空间地址(企业、组织或个人的地址path)
+ * @param repo 仓库路径(path)
+ * @param optional nil or *GetV5ReposOwnerRepoSubscribersOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+ * @param "Page" (optional.Int32) - 当前的页码
+ * @param "PerPage" (optional.Int32) - 每页的数量,最大为 100
+
+@return []UserBasic
+*/
+
+type GetV5ReposOwnerRepoSubscribersOpts struct {
+ AccessToken optional.String
+ Page optional.Int32
+ PerPage optional.Int32
+}
+
+func (a *ActivityApiService) GetV5ReposOwnerRepoSubscribers(ctx context.Context, owner string, repo string, localVarOptionals *GetV5ReposOwnerRepoSubscribersOpts) ([]UserBasic, *http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Get")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ localVarReturnValue []UserBasic
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/repos/{owner}/{repo}/subscribers"
+ localVarPath = strings.Replace(localVarPath, "{"+"owner"+"}", fmt.Sprintf("%v", owner), -1)
+ localVarPath = strings.Replace(localVarPath, "{"+"repo"+"}", fmt.Sprintf("%v", repo), -1)
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarQueryParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Page.IsSet() {
+ localVarQueryParams.Add("page", parameterToString(localVarOptionals.Page.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.PerPage.IsSet() {
+ localVarQueryParams.Add("per_page", parameterToString(localVarOptionals.PerPage.Value(), ""))
+ }
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return localVarReturnValue, nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode < 300 {
+ // If we succeed, return the data, otherwise pass on to decode error.
+ err = a.client.decode(&localVarReturnValue, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ if localVarHttpResponse.StatusCode == 200 {
+ var v []UserBasic
+ err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err != nil {
+ newErr.error = err.Error()
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+ newErr.model = v
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, nil
+}
+
+/*
+ActivityApiService 列出授权用户 star 了的仓库
+列出授权用户 star 了的仓库
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param optional nil or *GetV5UserStarredOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+ * @param "Sort" (optional.String) - 根据仓库创建时间(created)或最后推送时间(updated)进行排序,默认:创建时间
+ * @param "Direction" (optional.String) - 按递增(asc)或递减(desc)排序,默认:递减
+ * @param "Page" (optional.Int32) - 当前的页码
+ * @param "PerPage" (optional.Int32) - 每页的数量,最大为 100
+
+@return []Project
+*/
+
+type GetV5UserStarredOpts struct {
+ AccessToken optional.String
+ Sort optional.String
+ Direction optional.String
+ Page optional.Int32
+ PerPage optional.Int32
+}
+
+func (a *ActivityApiService) GetV5UserStarred(ctx context.Context, localVarOptionals *GetV5UserStarredOpts) ([]Project, *http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Get")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ localVarReturnValue []Project
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/user/starred"
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarQueryParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Sort.IsSet() {
+ localVarQueryParams.Add("sort", parameterToString(localVarOptionals.Sort.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Direction.IsSet() {
+ localVarQueryParams.Add("direction", parameterToString(localVarOptionals.Direction.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Page.IsSet() {
+ localVarQueryParams.Add("page", parameterToString(localVarOptionals.Page.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.PerPage.IsSet() {
+ localVarQueryParams.Add("per_page", parameterToString(localVarOptionals.PerPage.Value(), ""))
+ }
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return localVarReturnValue, nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode < 300 {
+ // If we succeed, return the data, otherwise pass on to decode error.
+ err = a.client.decode(&localVarReturnValue, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ if localVarHttpResponse.StatusCode == 200 {
+ var v []Project
+ err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err != nil {
+ newErr.error = err.Error()
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+ newErr.model = v
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, nil
+}
+
+/*
+ActivityApiService 检查授权用户是否 star 了一个仓库
+检查授权用户是否 star 了一个仓库
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param owner 仓库所属空间地址(企业、组织或个人的地址path)
+ * @param repo 仓库路径(path)
+ * @param optional nil or *GetV5UserStarredOwnerRepoOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+
+
+*/
+
+type GetV5UserStarredOwnerRepoOpts struct {
+ AccessToken optional.String
+}
+
+func (a *ActivityApiService) GetV5UserStarredOwnerRepo(ctx context.Context, owner string, repo string, localVarOptionals *GetV5UserStarredOwnerRepoOpts) (*http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Get")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/user/starred/{owner}/{repo}"
+ localVarPath = strings.Replace(localVarPath, "{"+"owner"+"}", fmt.Sprintf("%v", owner), -1)
+ localVarPath = strings.Replace(localVarPath, "{"+"repo"+"}", fmt.Sprintf("%v", repo), -1)
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarQueryParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ return localVarHttpResponse, newErr
+ }
+
+ return localVarHttpResponse, nil
+}
+
+/*
+ActivityApiService 列出授权用户 watch 了的仓库
+列出授权用户 watch 了的仓库
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param optional nil or *GetV5UserSubscriptionsOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+ * @param "Sort" (optional.String) - 根据仓库创建时间(created)或最后推送时间(updated)进行排序,默认:创建时间
+ * @param "Direction" (optional.String) - 按递增(asc)或递减(desc)排序,默认:递减
+ * @param "Page" (optional.Int32) - 当前的页码
+ * @param "PerPage" (optional.Int32) - 每页的数量,最大为 100
+
+@return []Project
+*/
+
+type GetV5UserSubscriptionsOpts struct {
+ AccessToken optional.String
+ Sort optional.String
+ Direction optional.String
+ Page optional.Int32
+ PerPage optional.Int32
+}
+
+func (a *ActivityApiService) GetV5UserSubscriptions(ctx context.Context, localVarOptionals *GetV5UserSubscriptionsOpts) ([]Project, *http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Get")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ localVarReturnValue []Project
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/user/subscriptions"
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarQueryParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Sort.IsSet() {
+ localVarQueryParams.Add("sort", parameterToString(localVarOptionals.Sort.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Direction.IsSet() {
+ localVarQueryParams.Add("direction", parameterToString(localVarOptionals.Direction.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Page.IsSet() {
+ localVarQueryParams.Add("page", parameterToString(localVarOptionals.Page.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.PerPage.IsSet() {
+ localVarQueryParams.Add("per_page", parameterToString(localVarOptionals.PerPage.Value(), ""))
+ }
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return localVarReturnValue, nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode < 300 {
+ // If we succeed, return the data, otherwise pass on to decode error.
+ err = a.client.decode(&localVarReturnValue, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ if localVarHttpResponse.StatusCode == 200 {
+ var v []Project
+ err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err != nil {
+ newErr.error = err.Error()
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+ newErr.model = v
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, nil
+}
+
+/*
+ActivityApiService 检查授权用户是否 watch 了一个仓库
+检查授权用户是否 watch 了一个仓库
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param owner 仓库所属空间地址(企业、组织或个人的地址path)
+ * @param repo 仓库路径(path)
+ * @param optional nil or *GetV5UserSubscriptionsOwnerRepoOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+
+
+*/
+
+type GetV5UserSubscriptionsOwnerRepoOpts struct {
+ AccessToken optional.String
+}
+
+func (a *ActivityApiService) GetV5UserSubscriptionsOwnerRepo(ctx context.Context, owner string, repo string, localVarOptionals *GetV5UserSubscriptionsOwnerRepoOpts) (*http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Get")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/user/subscriptions/{owner}/{repo}"
+ localVarPath = strings.Replace(localVarPath, "{"+"owner"+"}", fmt.Sprintf("%v", owner), -1)
+ localVarPath = strings.Replace(localVarPath, "{"+"repo"+"}", fmt.Sprintf("%v", repo), -1)
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarQueryParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ return localVarHttpResponse, newErr
+ }
+
+ return localVarHttpResponse, nil
+}
+
+/*
+ActivityApiService 列出用户的动态
+列出用户的动态
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param username 用户名(username/login)
+ * @param optional nil or *GetV5UsersUsernameEventsOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+ * @param "Page" (optional.Int32) - 当前的页码
+ * @param "PerPage" (optional.Int32) - 每页的数量,最大为 100
+
+@return []Event
+*/
+
+type GetV5UsersUsernameEventsOpts struct {
+ AccessToken optional.String
+ Page optional.Int32
+ PerPage optional.Int32
+}
+
+func (a *ActivityApiService) GetV5UsersUsernameEvents(ctx context.Context, username string, localVarOptionals *GetV5UsersUsernameEventsOpts) ([]Event, *http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Get")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ localVarReturnValue []Event
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/users/{username}/events"
+ localVarPath = strings.Replace(localVarPath, "{"+"username"+"}", fmt.Sprintf("%v", username), -1)
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarQueryParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Page.IsSet() {
+ localVarQueryParams.Add("page", parameterToString(localVarOptionals.Page.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.PerPage.IsSet() {
+ localVarQueryParams.Add("per_page", parameterToString(localVarOptionals.PerPage.Value(), ""))
+ }
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return localVarReturnValue, nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode < 300 {
+ // If we succeed, return the data, otherwise pass on to decode error.
+ err = a.client.decode(&localVarReturnValue, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ if localVarHttpResponse.StatusCode == 200 {
+ var v []Event
+ err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err != nil {
+ newErr.error = err.Error()
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+ newErr.model = v
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, nil
+}
+
+/*
+ActivityApiService 列出用户所属组织的动态
+列出用户所属组织的动态
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param username 用户名(username/login)
+ * @param org 组织的路径(path/login)
+ * @param optional nil or *GetV5UsersUsernameEventsOrgsOrgOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+ * @param "Page" (optional.Int32) - 当前的页码
+ * @param "PerPage" (optional.Int32) - 每页的数量,最大为 100
+
+@return []Event
+*/
+
+type GetV5UsersUsernameEventsOrgsOrgOpts struct {
+ AccessToken optional.String
+ Page optional.Int32
+ PerPage optional.Int32
+}
+
+func (a *ActivityApiService) GetV5UsersUsernameEventsOrgsOrg(ctx context.Context, username string, org string, localVarOptionals *GetV5UsersUsernameEventsOrgsOrgOpts) ([]Event, *http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Get")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ localVarReturnValue []Event
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/users/{username}/events/orgs/{org}"
+ localVarPath = strings.Replace(localVarPath, "{"+"username"+"}", fmt.Sprintf("%v", username), -1)
+ localVarPath = strings.Replace(localVarPath, "{"+"org"+"}", fmt.Sprintf("%v", org), -1)
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarQueryParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Page.IsSet() {
+ localVarQueryParams.Add("page", parameterToString(localVarOptionals.Page.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.PerPage.IsSet() {
+ localVarQueryParams.Add("per_page", parameterToString(localVarOptionals.PerPage.Value(), ""))
+ }
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return localVarReturnValue, nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode < 300 {
+ // If we succeed, return the data, otherwise pass on to decode error.
+ err = a.client.decode(&localVarReturnValue, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ if localVarHttpResponse.StatusCode == 200 {
+ var v []Event
+ err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err != nil {
+ newErr.error = err.Error()
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+ newErr.model = v
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, nil
+}
+
+/*
+ActivityApiService 列出用户的公开动态
+列出用户的公开动态
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param username 用户名(username/login)
+ * @param optional nil or *GetV5UsersUsernameEventsPublicOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+ * @param "Page" (optional.Int32) - 当前的页码
+ * @param "PerPage" (optional.Int32) - 每页的数量,最大为 100
+
+@return []Event
+*/
+
+type GetV5UsersUsernameEventsPublicOpts struct {
+ AccessToken optional.String
+ Page optional.Int32
+ PerPage optional.Int32
+}
+
+func (a *ActivityApiService) GetV5UsersUsernameEventsPublic(ctx context.Context, username string, localVarOptionals *GetV5UsersUsernameEventsPublicOpts) ([]Event, *http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Get")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ localVarReturnValue []Event
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/users/{username}/events/public"
+ localVarPath = strings.Replace(localVarPath, "{"+"username"+"}", fmt.Sprintf("%v", username), -1)
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarQueryParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Page.IsSet() {
+ localVarQueryParams.Add("page", parameterToString(localVarOptionals.Page.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.PerPage.IsSet() {
+ localVarQueryParams.Add("per_page", parameterToString(localVarOptionals.PerPage.Value(), ""))
+ }
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return localVarReturnValue, nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode < 300 {
+ // If we succeed, return the data, otherwise pass on to decode error.
+ err = a.client.decode(&localVarReturnValue, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ if localVarHttpResponse.StatusCode == 200 {
+ var v []Event
+ err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err != nil {
+ newErr.error = err.Error()
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+ newErr.model = v
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, nil
+}
+
+/*
+ActivityApiService 列出一个用户收到的动态
+列出一个用户收到的动态
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param username 用户名(username/login)
+ * @param optional nil or *GetV5UsersUsernameReceivedEventsOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+ * @param "Page" (optional.Int32) - 当前的页码
+ * @param "PerPage" (optional.Int32) - 每页的数量,最大为 100
+
+@return []Event
+*/
+
+type GetV5UsersUsernameReceivedEventsOpts struct {
+ AccessToken optional.String
+ Page optional.Int32
+ PerPage optional.Int32
+}
+
+func (a *ActivityApiService) GetV5UsersUsernameReceivedEvents(ctx context.Context, username string, localVarOptionals *GetV5UsersUsernameReceivedEventsOpts) ([]Event, *http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Get")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ localVarReturnValue []Event
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/users/{username}/received_events"
+ localVarPath = strings.Replace(localVarPath, "{"+"username"+"}", fmt.Sprintf("%v", username), -1)
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarQueryParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Page.IsSet() {
+ localVarQueryParams.Add("page", parameterToString(localVarOptionals.Page.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.PerPage.IsSet() {
+ localVarQueryParams.Add("per_page", parameterToString(localVarOptionals.PerPage.Value(), ""))
+ }
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return localVarReturnValue, nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode < 300 {
+ // If we succeed, return the data, otherwise pass on to decode error.
+ err = a.client.decode(&localVarReturnValue, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ if localVarHttpResponse.StatusCode == 200 {
+ var v []Event
+ err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err != nil {
+ newErr.error = err.Error()
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+ newErr.model = v
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, nil
+}
+
+/*
+ActivityApiService 列出一个用户收到的公开动态
+列出一个用户收到的公开动态
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param username 用户名(username/login)
+ * @param optional nil or *GetV5UsersUsernameReceivedEventsPublicOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+ * @param "Page" (optional.Int32) - 当前的页码
+ * @param "PerPage" (optional.Int32) - 每页的数量,最大为 100
+
+@return []Event
+*/
+
+type GetV5UsersUsernameReceivedEventsPublicOpts struct {
+ AccessToken optional.String
+ Page optional.Int32
+ PerPage optional.Int32
+}
+
+func (a *ActivityApiService) GetV5UsersUsernameReceivedEventsPublic(ctx context.Context, username string, localVarOptionals *GetV5UsersUsernameReceivedEventsPublicOpts) ([]Event, *http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Get")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ localVarReturnValue []Event
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/users/{username}/received_events/public"
+ localVarPath = strings.Replace(localVarPath, "{"+"username"+"}", fmt.Sprintf("%v", username), -1)
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarQueryParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Page.IsSet() {
+ localVarQueryParams.Add("page", parameterToString(localVarOptionals.Page.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.PerPage.IsSet() {
+ localVarQueryParams.Add("per_page", parameterToString(localVarOptionals.PerPage.Value(), ""))
+ }
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return localVarReturnValue, nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode < 300 {
+ // If we succeed, return the data, otherwise pass on to decode error.
+ err = a.client.decode(&localVarReturnValue, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ if localVarHttpResponse.StatusCode == 200 {
+ var v []Event
+ err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err != nil {
+ newErr.error = err.Error()
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+ newErr.model = v
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, nil
+}
+
+/*
+ActivityApiService 列出用户 star 了的仓库
+列出用户 star 了的仓库
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param username 用户名(username/login)
+ * @param optional nil or *GetV5UsersUsernameStarredOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+ * @param "Page" (optional.Int32) - 当前的页码
+ * @param "PerPage" (optional.Int32) - 每页的数量,最大为 100
+ * @param "Sort" (optional.String) - 根据仓库创建时间(created)或最后推送时间(updated)进行排序,默认:创建时间
+ * @param "Direction" (optional.String) - 按递增(asc)或递减(desc)排序,默认:递减
+
+@return []Project
+*/
+
+type GetV5UsersUsernameStarredOpts struct {
+ AccessToken optional.String
+ Page optional.Int32
+ PerPage optional.Int32
+ Sort optional.String
+ Direction optional.String
+}
+
+func (a *ActivityApiService) GetV5UsersUsernameStarred(ctx context.Context, username string, localVarOptionals *GetV5UsersUsernameStarredOpts) ([]Project, *http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Get")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ localVarReturnValue []Project
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/users/{username}/starred"
+ localVarPath = strings.Replace(localVarPath, "{"+"username"+"}", fmt.Sprintf("%v", username), -1)
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarQueryParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Page.IsSet() {
+ localVarQueryParams.Add("page", parameterToString(localVarOptionals.Page.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.PerPage.IsSet() {
+ localVarQueryParams.Add("per_page", parameterToString(localVarOptionals.PerPage.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Sort.IsSet() {
+ localVarQueryParams.Add("sort", parameterToString(localVarOptionals.Sort.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Direction.IsSet() {
+ localVarQueryParams.Add("direction", parameterToString(localVarOptionals.Direction.Value(), ""))
+ }
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return localVarReturnValue, nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode < 300 {
+ // If we succeed, return the data, otherwise pass on to decode error.
+ err = a.client.decode(&localVarReturnValue, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ if localVarHttpResponse.StatusCode == 200 {
+ var v []Project
+ err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err != nil {
+ newErr.error = err.Error()
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+ newErr.model = v
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, nil
+}
+
+/*
+ActivityApiService 列出用户 watch 了的仓库
+列出用户 watch 了的仓库
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param username 用户名(username/login)
+ * @param optional nil or *GetV5UsersUsernameSubscriptionsOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+ * @param "Page" (optional.Int32) - 当前的页码
+ * @param "PerPage" (optional.Int32) - 每页的数量,最大为 100
+ * @param "Sort" (optional.String) - 根据仓库创建时间(created)或最后推送时间(updated)进行排序,默认:创建时间
+ * @param "Direction" (optional.String) - 按递增(asc)或递减(desc)排序,默认:递减
+
+@return []Project
+*/
+
+type GetV5UsersUsernameSubscriptionsOpts struct {
+ AccessToken optional.String
+ Page optional.Int32
+ PerPage optional.Int32
+ Sort optional.String
+ Direction optional.String
+}
+
+func (a *ActivityApiService) GetV5UsersUsernameSubscriptions(ctx context.Context, username string, localVarOptionals *GetV5UsersUsernameSubscriptionsOpts) ([]Project, *http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Get")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ localVarReturnValue []Project
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/users/{username}/subscriptions"
+ localVarPath = strings.Replace(localVarPath, "{"+"username"+"}", fmt.Sprintf("%v", username), -1)
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarQueryParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Page.IsSet() {
+ localVarQueryParams.Add("page", parameterToString(localVarOptionals.Page.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.PerPage.IsSet() {
+ localVarQueryParams.Add("per_page", parameterToString(localVarOptionals.PerPage.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Sort.IsSet() {
+ localVarQueryParams.Add("sort", parameterToString(localVarOptionals.Sort.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Direction.IsSet() {
+ localVarQueryParams.Add("direction", parameterToString(localVarOptionals.Direction.Value(), ""))
+ }
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return localVarReturnValue, nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode < 300 {
+ // If we succeed, return the data, otherwise pass on to decode error.
+ err = a.client.decode(&localVarReturnValue, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ if localVarHttpResponse.StatusCode == 200 {
+ var v []Project
+ err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err != nil {
+ newErr.error = err.Error()
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+ newErr.model = v
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, nil
+}
+
+/*
+ActivityApiService 标记一条私信为已读
+标记一条私信为已读
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param id 私信的 ID
+ * @param optional nil or *PatchV5NotificationsMessagesIdOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+
+
+*/
+
+type PatchV5NotificationsMessagesIdOpts struct {
+ AccessToken optional.String
+}
+
+func (a *ActivityApiService) PatchV5NotificationsMessagesId(ctx context.Context, id string, localVarOptionals *PatchV5NotificationsMessagesIdOpts) (*http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Patch")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/notifications/messages/{id}"
+ localVarPath = strings.Replace(localVarPath, "{"+"id"+"}", fmt.Sprintf("%v", id), -1)
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarFormParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ return localVarHttpResponse, newErr
+ }
+
+ return localVarHttpResponse, nil
+}
+
+/*
+ActivityApiService 标记一条通知为已读
+标记一条通知为已读
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param id 通知的 ID
+ * @param optional nil or *PatchV5NotificationsThreadsIdOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+
+
+*/
+
+type PatchV5NotificationsThreadsIdOpts struct {
+ AccessToken optional.String
+}
+
+func (a *ActivityApiService) PatchV5NotificationsThreadsId(ctx context.Context, id string, localVarOptionals *PatchV5NotificationsThreadsIdOpts) (*http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Patch")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/notifications/threads/{id}"
+ localVarPath = strings.Replace(localVarPath, "{"+"id"+"}", fmt.Sprintf("%v", id), -1)
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarFormParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ return localVarHttpResponse, newErr
+ }
+
+ return localVarHttpResponse, nil
+}
+
+/*
+ActivityApiService 发送私信给指定用户
+发送私信给指定用户
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param username 用户名(username/login)
+ * @param content 私信内容
+ * @param optional nil or *PostV5NotificationsMessagesOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+
+@return UserMessage
+*/
+
+type PostV5NotificationsMessagesOpts struct {
+ AccessToken optional.String
+}
+
+func (a *ActivityApiService) PostV5NotificationsMessages(ctx context.Context, username string, content string, localVarOptionals *PostV5NotificationsMessagesOpts) (UserMessage, *http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Post")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ localVarReturnValue UserMessage
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/notifications/messages"
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarFormParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ localVarFormParams.Add("username", parameterToString(username, ""))
+ localVarFormParams.Add("content", parameterToString(content, ""))
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return localVarReturnValue, nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode < 300 {
+ // If we succeed, return the data, otherwise pass on to decode error.
+ err = a.client.decode(&localVarReturnValue, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ if localVarHttpResponse.StatusCode == 201 {
+ var v UserMessage
+ err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err != nil {
+ newErr.error = err.Error()
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+ newErr.model = v
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, nil
+}
+
+/*
+ActivityApiService 标记所有私信为已读
+标记所有私信为已读
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param optional nil or *PutV5NotificationsMessagesOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+ * @param "Ids" (optional.String) - 指定一组私信 ID,以 , 分隔
+
+
+*/
+
+type PutV5NotificationsMessagesOpts struct {
+ AccessToken optional.String
+ Ids optional.String
+}
+
+func (a *ActivityApiService) PutV5NotificationsMessages(ctx context.Context, localVarOptionals *PutV5NotificationsMessagesOpts) (*http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Put")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/notifications/messages"
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarFormParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Ids.IsSet() {
+ localVarFormParams.Add("ids", parameterToString(localVarOptionals.Ids.Value(), ""))
+ }
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ return localVarHttpResponse, newErr
+ }
+
+ return localVarHttpResponse, nil
+}
+
+/*
+ActivityApiService 标记所有通知为已读
+标记所有通知为已读
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param optional nil or *PutV5NotificationsThreadsOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+ * @param "Ids" (optional.String) - 指定一组通知 ID,以 , 分隔
+
+
+*/
+
+type PutV5NotificationsThreadsOpts struct {
+ AccessToken optional.String
+ Ids optional.String
+}
+
+func (a *ActivityApiService) PutV5NotificationsThreads(ctx context.Context, localVarOptionals *PutV5NotificationsThreadsOpts) (*http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Put")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/notifications/threads"
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarFormParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Ids.IsSet() {
+ localVarFormParams.Add("ids", parameterToString(localVarOptionals.Ids.Value(), ""))
+ }
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ return localVarHttpResponse, newErr
+ }
+
+ return localVarHttpResponse, nil
+}
+
+/*
+ActivityApiService 标记一个仓库里的通知为已读
+标记一个仓库里的通知为已读
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param owner 仓库所属空间地址(企业、组织或个人的地址path)
+ * @param repo 仓库路径(path)
+ * @param optional nil or *PutV5ReposOwnerRepoNotificationsOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+ * @param "Ids" (optional.String) - 指定一组通知 ID,以 , 分隔
+
+
+*/
+
+type PutV5ReposOwnerRepoNotificationsOpts struct {
+ AccessToken optional.String
+ Ids optional.String
+}
+
+func (a *ActivityApiService) PutV5ReposOwnerRepoNotifications(ctx context.Context, owner string, repo string, localVarOptionals *PutV5ReposOwnerRepoNotificationsOpts) (*http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Put")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/repos/{owner}/{repo}/notifications"
+ localVarPath = strings.Replace(localVarPath, "{"+"owner"+"}", fmt.Sprintf("%v", owner), -1)
+ localVarPath = strings.Replace(localVarPath, "{"+"repo"+"}", fmt.Sprintf("%v", repo), -1)
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarFormParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Ids.IsSet() {
+ localVarFormParams.Add("ids", parameterToString(localVarOptionals.Ids.Value(), ""))
+ }
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ return localVarHttpResponse, newErr
+ }
+
+ return localVarHttpResponse, nil
+}
+
+/*
+ActivityApiService star 一个仓库
+star 一个仓库
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param owner 仓库所属空间地址(企业、组织或个人的地址path)
+ * @param repo 仓库路径(path)
+ * @param optional nil or *PutV5UserStarredOwnerRepoOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+
+
+*/
+
+type PutV5UserStarredOwnerRepoOpts struct {
+ AccessToken optional.String
+}
+
+func (a *ActivityApiService) PutV5UserStarredOwnerRepo(ctx context.Context, owner string, repo string, localVarOptionals *PutV5UserStarredOwnerRepoOpts) (*http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Put")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/user/starred/{owner}/{repo}"
+ localVarPath = strings.Replace(localVarPath, "{"+"owner"+"}", fmt.Sprintf("%v", owner), -1)
+ localVarPath = strings.Replace(localVarPath, "{"+"repo"+"}", fmt.Sprintf("%v", repo), -1)
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarFormParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ return localVarHttpResponse, newErr
+ }
+
+ return localVarHttpResponse, nil
+}
+
+/*
+ActivityApiService watch 一个仓库
+watch 一个仓库
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param owner 仓库所属空间地址(企业、组织或个人的地址path)
+ * @param repo 仓库路径(path)
+ * @param watchType watch策略, watching: 关注所有动态, releases_only: 仅关注版本发行动态, ignoring: 关注但不提醒动态
+ * @param optional nil or *PutV5UserSubscriptionsOwnerRepoOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+
+
+*/
+
+type PutV5UserSubscriptionsOwnerRepoOpts struct {
+ AccessToken optional.String
+}
+
+func (a *ActivityApiService) PutV5UserSubscriptionsOwnerRepo(ctx context.Context, owner string, repo string, watchType string, localVarOptionals *PutV5UserSubscriptionsOwnerRepoOpts) (*http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Put")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/user/subscriptions/{owner}/{repo}"
+ localVarPath = strings.Replace(localVarPath, "{"+"owner"+"}", fmt.Sprintf("%v", owner), -1)
+ localVarPath = strings.Replace(localVarPath, "{"+"repo"+"}", fmt.Sprintf("%v", repo), -1)
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarFormParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ localVarFormParams.Add("watch_type", parameterToString(watchType, ""))
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ return localVarHttpResponse, newErr
+ }
+
+ return localVarHttpResponse, nil
+}
diff --git a/vendor/gitee.com/openeuler/go-gitee/gitee/api_emails.go b/vendor/gitee.com/openeuler/go-gitee/gitee/api_emails.go
new file mode 100644
index 0000000000000000000000000000000000000000..57500fbf1716ceb84a9bc8a488246eba2493f1c5
--- /dev/null
+++ b/vendor/gitee.com/openeuler/go-gitee/gitee/api_emails.go
@@ -0,0 +1,123 @@
+/*
+ * 码云 Open API
+ *
+ * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen)
+ *
+ * API version: 5.3.2
+ * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
+ */
+
+package gitee
+
+import (
+ "context"
+ "github.com/antihax/optional"
+ "io/ioutil"
+ "net/http"
+ "net/url"
+ "strings"
+)
+
+// Linger please
+var (
+ _ context.Context
+)
+
+type EmailsApiService service
+
+/*
+EmailsApiService 获取授权用户的所有邮箱
+获取授权用户的所有邮箱
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param optional nil or *GetV5EmailsOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+
+@return []Email
+*/
+
+type GetV5EmailsOpts struct {
+ AccessToken optional.String
+}
+
+func (a *EmailsApiService) GetV5Emails(ctx context.Context, localVarOptionals *GetV5EmailsOpts) ([]Email, *http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Get")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ localVarReturnValue []Email
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/emails"
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarQueryParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return localVarReturnValue, nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode < 300 {
+ // If we succeed, return the data, otherwise pass on to decode error.
+ err = a.client.decode(&localVarReturnValue, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ if localVarHttpResponse.StatusCode == 200 {
+ var v []Email
+ err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err != nil {
+ newErr.error = err.Error()
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+ newErr.model = v
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, nil
+}
diff --git a/vendor/gitee.com/openeuler/go-gitee/gitee/api_enterprises.go b/vendor/gitee.com/openeuler/go-gitee/gitee/api_enterprises.go
new file mode 100644
index 0000000000000000000000000000000000000000..0c53273fcc9c2e79ef843618c1c1d5026d45f928
--- /dev/null
+++ b/vendor/gitee.com/openeuler/go-gitee/gitee/api_enterprises.go
@@ -0,0 +1,1603 @@
+/*
+ * 码云 Open API
+ *
+ * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen)
+ *
+ * API version: 5.3.2
+ * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
+ */
+
+package gitee
+
+import (
+ "context"
+ "fmt"
+ "io/ioutil"
+ "net/http"
+ "net/url"
+ "strings"
+
+ "github.com/antihax/optional"
+)
+
+// Linger please
+var (
+ _ context.Context
+)
+
+type EnterprisesApiService service
+
+/*
+EnterprisesApiService 移除企业成员
+移除企业成员
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param enterprise 企业的路径(path/login)
+ * @param username 用户名(username/login)
+ * @param optional nil or *DeleteV5EnterprisesEnterpriseMembersUsernameOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+
+
+*/
+
+type DeleteV5EnterprisesEnterpriseMembersUsernameOpts struct {
+ AccessToken optional.String
+}
+
+func (a *EnterprisesApiService) DeleteV5EnterprisesEnterpriseMembersUsername(ctx context.Context, enterprise string, username string, localVarOptionals *DeleteV5EnterprisesEnterpriseMembersUsernameOpts) (*http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Delete")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/enterprises/{enterprise}/members/{username}"
+ localVarPath = strings.Replace(localVarPath, "{"+"enterprise"+"}", fmt.Sprintf("%v", enterprise), -1)
+ localVarPath = strings.Replace(localVarPath, "{"+"username"+"}", fmt.Sprintf("%v", username), -1)
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarQueryParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ return localVarHttpResponse, newErr
+ }
+
+ return localVarHttpResponse, nil
+}
+
+/*
+EnterprisesApiService 删除周报某个评论
+删除周报某个评论
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param enterprise 企业的路径(path/login)
+ * @param reportId 周报ID
+ * @param id 评论ID
+ * @param optional nil or *DeleteV5EnterprisesEnterpriseWeekReportsReportIdCommentsIdOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+
+
+*/
+
+type DeleteV5EnterprisesEnterpriseWeekReportsReportIdCommentsIdOpts struct {
+ AccessToken optional.String
+}
+
+func (a *EnterprisesApiService) DeleteV5EnterprisesEnterpriseWeekReportsReportIdCommentsId(ctx context.Context, enterprise string, reportId int32, id int32, localVarOptionals *DeleteV5EnterprisesEnterpriseWeekReportsReportIdCommentsIdOpts) (*http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Delete")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/enterprises/{enterprise}/week_reports/{report_id}/comments/{id}"
+ localVarPath = strings.Replace(localVarPath, "{"+"enterprise"+"}", fmt.Sprintf("%v", enterprise), -1)
+ localVarPath = strings.Replace(localVarPath, "{"+"report_id"+"}", fmt.Sprintf("%v", reportId), -1)
+ localVarPath = strings.Replace(localVarPath, "{"+"id"+"}", fmt.Sprintf("%v", id), -1)
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarQueryParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ return localVarHttpResponse, newErr
+ }
+
+ return localVarHttpResponse, nil
+}
+
+/*
+EnterprisesApiService 获取一个企业
+获取一个企业
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param enterprise 企业的路径(path/login)
+ * @param optional nil or *GetV5EnterprisesEnterpriseOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+
+@return EnterpriseBasic
+*/
+
+type GetV5EnterprisesEnterpriseOpts struct {
+ AccessToken optional.String
+}
+
+func (a *EnterprisesApiService) GetV5EnterprisesEnterprise(ctx context.Context, enterprise string, localVarOptionals *GetV5EnterprisesEnterpriseOpts) (EnterpriseBasic, *http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Get")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ localVarReturnValue EnterpriseBasic
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/enterprises/{enterprise}"
+ localVarPath = strings.Replace(localVarPath, "{"+"enterprise"+"}", fmt.Sprintf("%v", enterprise), -1)
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarQueryParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return localVarReturnValue, nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode < 300 {
+ // If we succeed, return the data, otherwise pass on to decode error.
+ err = a.client.decode(&localVarReturnValue, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ if localVarHttpResponse.StatusCode == 200 {
+ var v EnterpriseBasic
+ err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err != nil {
+ newErr.error = err.Error()
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+ newErr.model = v
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, nil
+}
+
+/*
+EnterprisesApiService 列出企业的所有成员
+列出企业的所有成员
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param enterprise 企业的路径(path/login)
+ * @param optional nil or *GetV5EnterprisesEnterpriseMembersOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+ * @param "Role" (optional.String) - 根据角色筛选成员
+
+@return []EnterpriseMember
+*/
+
+type GetV5EnterprisesEnterpriseMembersOpts struct {
+ AccessToken optional.String
+ Role optional.String
+}
+
+func (a *EnterprisesApiService) GetV5EnterprisesEnterpriseMembers(ctx context.Context, enterprise string, localVarOptionals *GetV5EnterprisesEnterpriseMembersOpts) ([]EnterpriseMember, *http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Get")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ localVarReturnValue []EnterpriseMember
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/enterprises/{enterprise}/members"
+ localVarPath = strings.Replace(localVarPath, "{"+"enterprise"+"}", fmt.Sprintf("%v", enterprise), -1)
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarQueryParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Role.IsSet() {
+ localVarQueryParams.Add("role", parameterToString(localVarOptionals.Role.Value(), ""))
+ }
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return localVarReturnValue, nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode < 300 {
+ // If we succeed, return the data, otherwise pass on to decode error.
+ err = a.client.decode(&localVarReturnValue, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ if localVarHttpResponse.StatusCode == 200 {
+ var v []EnterpriseMember
+ err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err != nil {
+ newErr.error = err.Error()
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+ newErr.model = v
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, nil
+}
+
+/*
+EnterprisesApiService 获取企业的一个成员
+获取企业的一个成员
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param enterprise 企业的路径(path/login)
+ * @param username 用户名(username/login)
+ * @param optional nil or *GetV5EnterprisesEnterpriseMembersUsernameOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+
+@return EnterpriseMember
+*/
+
+type GetV5EnterprisesEnterpriseMembersUsernameOpts struct {
+ AccessToken optional.String
+}
+
+func (a *EnterprisesApiService) GetV5EnterprisesEnterpriseMembersUsername(ctx context.Context, enterprise string, username string, localVarOptionals *GetV5EnterprisesEnterpriseMembersUsernameOpts) (EnterpriseMember, *http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Get")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ localVarReturnValue EnterpriseMember
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/enterprises/{enterprise}/members/{username}"
+ localVarPath = strings.Replace(localVarPath, "{"+"enterprise"+"}", fmt.Sprintf("%v", enterprise), -1)
+ localVarPath = strings.Replace(localVarPath, "{"+"username"+"}", fmt.Sprintf("%v", username), -1)
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarQueryParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return localVarReturnValue, nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode < 300 {
+ // If we succeed, return the data, otherwise pass on to decode error.
+ err = a.client.decode(&localVarReturnValue, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ if localVarHttpResponse.StatusCode == 200 {
+ var v EnterpriseMember
+ err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err != nil {
+ newErr.error = err.Error()
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+ newErr.model = v
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, nil
+}
+
+/*
+EnterprisesApiService 个人周报列表
+个人周报列表
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param enterprise 企业的路径(path/login)
+ * @param username 用户名(username/login)
+ * @param optional nil or *GetV5EnterprisesEnterpriseUsersUsernameWeekReportsOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+ * @param "Page" (optional.Int32) - 当前的页码
+ * @param "PerPage" (optional.Int32) - 每页的数量,最大为 100
+
+@return []WeekReport
+*/
+
+type GetV5EnterprisesEnterpriseUsersUsernameWeekReportsOpts struct {
+ AccessToken optional.String
+ Page optional.Int32
+ PerPage optional.Int32
+}
+
+func (a *EnterprisesApiService) GetV5EnterprisesEnterpriseUsersUsernameWeekReports(ctx context.Context, enterprise string, username string, localVarOptionals *GetV5EnterprisesEnterpriseUsersUsernameWeekReportsOpts) ([]WeekReport, *http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Get")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ localVarReturnValue []WeekReport
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/enterprises/{enterprise}/users/{username}/week_reports"
+ localVarPath = strings.Replace(localVarPath, "{"+"enterprise"+"}", fmt.Sprintf("%v", enterprise), -1)
+ localVarPath = strings.Replace(localVarPath, "{"+"username"+"}", fmt.Sprintf("%v", username), -1)
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarQueryParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Page.IsSet() {
+ localVarQueryParams.Add("page", parameterToString(localVarOptionals.Page.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.PerPage.IsSet() {
+ localVarQueryParams.Add("per_page", parameterToString(localVarOptionals.PerPage.Value(), ""))
+ }
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return localVarReturnValue, nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode < 300 {
+ // If we succeed, return the data, otherwise pass on to decode error.
+ err = a.client.decode(&localVarReturnValue, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ if localVarHttpResponse.StatusCode == 200 {
+ var v []WeekReport
+ err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err != nil {
+ newErr.error = err.Error()
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+ newErr.model = v
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, nil
+}
+
+/*
+EnterprisesApiService 企业成员周报列表
+企业成员周报列表
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param enterprise 企业的路径(path/login)
+ * @param optional nil or *GetV5EnterprisesEnterpriseWeekReportsOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+ * @param "Page" (optional.Int32) - 当前的页码
+ * @param "PerPage" (optional.Int32) - 每页的数量,最大为 100
+ * @param "Username" (optional.String) - 用户名(username/login)
+ * @param "Year" (optional.Int32) - 周报所属年
+ * @param "WeekIndex" (optional.Int32) - 周报所属周
+ * @param "Date" (optional.String) - 周报日期(格式:2019-03-25)
+
+@return []WeekReport
+*/
+
+type GetV5EnterprisesEnterpriseWeekReportsOpts struct {
+ AccessToken optional.String
+ Page optional.Int32
+ PerPage optional.Int32
+ Username optional.String
+ Year optional.Int32
+ WeekIndex optional.Int32
+ Date optional.String
+}
+
+func (a *EnterprisesApiService) GetV5EnterprisesEnterpriseWeekReports(ctx context.Context, enterprise string, localVarOptionals *GetV5EnterprisesEnterpriseWeekReportsOpts) ([]WeekReport, *http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Get")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ localVarReturnValue []WeekReport
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/enterprises/{enterprise}/week_reports"
+ localVarPath = strings.Replace(localVarPath, "{"+"enterprise"+"}", fmt.Sprintf("%v", enterprise), -1)
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarQueryParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Page.IsSet() {
+ localVarQueryParams.Add("page", parameterToString(localVarOptionals.Page.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.PerPage.IsSet() {
+ localVarQueryParams.Add("per_page", parameterToString(localVarOptionals.PerPage.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Username.IsSet() {
+ localVarQueryParams.Add("username", parameterToString(localVarOptionals.Username.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Year.IsSet() {
+ localVarQueryParams.Add("year", parameterToString(localVarOptionals.Year.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.WeekIndex.IsSet() {
+ localVarQueryParams.Add("week_index", parameterToString(localVarOptionals.WeekIndex.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Date.IsSet() {
+ localVarQueryParams.Add("date", parameterToString(localVarOptionals.Date.Value(), ""))
+ }
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return localVarReturnValue, nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode < 300 {
+ // If we succeed, return the data, otherwise pass on to decode error.
+ err = a.client.decode(&localVarReturnValue, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ if localVarHttpResponse.StatusCode == 200 {
+ var v []WeekReport
+ err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err != nil {
+ newErr.error = err.Error()
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+ newErr.model = v
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, nil
+}
+
+/*
+EnterprisesApiService 周报详情
+周报详情
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param enterprise 企业的路径(path/login)
+ * @param id 周报ID
+ * @param optional nil or *GetV5EnterprisesEnterpriseWeekReportsIdOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+
+@return WeekReport
+*/
+
+type GetV5EnterprisesEnterpriseWeekReportsIdOpts struct {
+ AccessToken optional.String
+}
+
+func (a *EnterprisesApiService) GetV5EnterprisesEnterpriseWeekReportsId(ctx context.Context, enterprise string, id int32, localVarOptionals *GetV5EnterprisesEnterpriseWeekReportsIdOpts) (WeekReport, *http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Get")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ localVarReturnValue WeekReport
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/enterprises/{enterprise}/week_reports/{id}"
+ localVarPath = strings.Replace(localVarPath, "{"+"enterprise"+"}", fmt.Sprintf("%v", enterprise), -1)
+ localVarPath = strings.Replace(localVarPath, "{"+"id"+"}", fmt.Sprintf("%v", id), -1)
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarQueryParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return localVarReturnValue, nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode < 300 {
+ // If we succeed, return the data, otherwise pass on to decode error.
+ err = a.client.decode(&localVarReturnValue, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ if localVarHttpResponse.StatusCode == 200 {
+ var v WeekReport
+ err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err != nil {
+ newErr.error = err.Error()
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+ newErr.model = v
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, nil
+}
+
+/*
+EnterprisesApiService 某个周报评论列表
+某个周报评论列表
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param enterprise 企业的路径(path/login)
+ * @param id 周报ID
+ * @param optional nil or *GetV5EnterprisesEnterpriseWeekReportsIdCommentsOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+ * @param "Page" (optional.Int32) - 当前的页码
+ * @param "PerPage" (optional.Int32) - 每页的数量,最大为 100
+
+@return []Note
+*/
+
+type GetV5EnterprisesEnterpriseWeekReportsIdCommentsOpts struct {
+ AccessToken optional.String
+ Page optional.Int32
+ PerPage optional.Int32
+}
+
+func (a *EnterprisesApiService) GetV5EnterprisesEnterpriseWeekReportsIdComments(ctx context.Context, enterprise string, id int32, localVarOptionals *GetV5EnterprisesEnterpriseWeekReportsIdCommentsOpts) ([]Note, *http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Get")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ localVarReturnValue []Note
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/enterprises/{enterprise}/week_reports/{id}/comments"
+ localVarPath = strings.Replace(localVarPath, "{"+"enterprise"+"}", fmt.Sprintf("%v", enterprise), -1)
+ localVarPath = strings.Replace(localVarPath, "{"+"id"+"}", fmt.Sprintf("%v", id), -1)
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarQueryParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Page.IsSet() {
+ localVarQueryParams.Add("page", parameterToString(localVarOptionals.Page.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.PerPage.IsSet() {
+ localVarQueryParams.Add("per_page", parameterToString(localVarOptionals.PerPage.Value(), ""))
+ }
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return localVarReturnValue, nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode < 300 {
+ // If we succeed, return the data, otherwise pass on to decode error.
+ err = a.client.decode(&localVarReturnValue, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ if localVarHttpResponse.StatusCode == 200 {
+ var v []Note
+ err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err != nil {
+ newErr.error = err.Error()
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+ newErr.model = v
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, nil
+}
+
+/*
+EnterprisesApiService 列出授权用户所属的企业
+列出授权用户所属的企业
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param optional nil or *GetV5UserEnterprisesOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+ * @param "Page" (optional.Int32) - 当前的页码
+ * @param "PerPage" (optional.Int32) - 每页的数量,最大为 100
+ * @param "Admin" (optional.Bool) - 只列出授权用户管理的企业
+
+@return []EnterpriseBasic
+*/
+
+type GetV5UserEnterprisesOpts struct {
+ AccessToken optional.String
+ Page optional.Int32
+ PerPage optional.Int32
+ Admin optional.Bool
+}
+
+func (a *EnterprisesApiService) GetV5UserEnterprises(ctx context.Context, localVarOptionals *GetV5UserEnterprisesOpts) ([]EnterpriseBasic, *http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Get")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ localVarReturnValue []EnterpriseBasic
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/user/enterprises"
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarQueryParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Page.IsSet() {
+ localVarQueryParams.Add("page", parameterToString(localVarOptionals.Page.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.PerPage.IsSet() {
+ localVarQueryParams.Add("per_page", parameterToString(localVarOptionals.PerPage.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Admin.IsSet() {
+ localVarQueryParams.Add("admin", parameterToString(localVarOptionals.Admin.Value(), ""))
+ }
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return localVarReturnValue, nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode < 300 {
+ // If we succeed, return the data, otherwise pass on to decode error.
+ err = a.client.decode(&localVarReturnValue, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ if localVarHttpResponse.StatusCode == 200 {
+ var v []EnterpriseBasic
+ err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err != nil {
+ newErr.error = err.Error()
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+ newErr.model = v
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, nil
+}
+
+/*
+EnterprisesApiService 编辑周报
+编辑周报
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param enterprise 企业的路径(path/login)
+ * @param id 周报ID
+ * @param content 周报内容
+ * @param optional nil or *PatchV5EnterprisesEnterpriseWeekReportIdOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+
+@return WeekReport
+*/
+
+type PatchV5EnterprisesEnterpriseWeekReportIdOpts struct {
+ AccessToken optional.String
+}
+
+func (a *EnterprisesApiService) PatchV5EnterprisesEnterpriseWeekReportId(ctx context.Context, enterprise string, id int32, content string, localVarOptionals *PatchV5EnterprisesEnterpriseWeekReportIdOpts) (WeekReport, *http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Patch")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ localVarReturnValue WeekReport
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/enterprises/{enterprise}/week_report/{id}"
+ localVarPath = strings.Replace(localVarPath, "{"+"enterprise"+"}", fmt.Sprintf("%v", enterprise), -1)
+ localVarPath = strings.Replace(localVarPath, "{"+"id"+"}", fmt.Sprintf("%v", id), -1)
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarFormParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ localVarFormParams.Add("content", parameterToString(content, ""))
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return localVarReturnValue, nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode < 300 {
+ // If we succeed, return the data, otherwise pass on to decode error.
+ err = a.client.decode(&localVarReturnValue, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ if localVarHttpResponse.StatusCode == 200 {
+ var v WeekReport
+ err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err != nil {
+ newErr.error = err.Error()
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+ newErr.model = v
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, nil
+}
+
+/*
+EnterprisesApiService 添加或邀请企业成员
+添加或邀请企业成员
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param enterprise 企业的路径(path/login)
+ * @param optional nil or *PostV5EnterprisesEnterpriseMembersOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+ * @param "Username" (optional.String) - 需要邀请的码云用户名(username/login),username,email至少填写一个
+ * @param "Email" (optional.String) - 要添加邮箱地址,若该邮箱未注册则自动创建帐号。username,email至少填写一个
+ * @param "Outsourced" (optional.Bool) - 是否企业外包成员,默认:否
+ * @param "Role" (optional.String) - 企业角色,默认普通成员
+ * @param "Name" (optional.String) - 企业成员真实姓名(备注)
+
+
+*/
+
+type PostV5EnterprisesEnterpriseMembersOpts struct {
+ AccessToken optional.String
+ Username optional.String
+ Email optional.String
+ Outsourced optional.Bool
+ Role optional.String
+ Name optional.String
+}
+
+func (a *EnterprisesApiService) PostV5EnterprisesEnterpriseMembers(ctx context.Context, enterprise string, localVarOptionals *PostV5EnterprisesEnterpriseMembersOpts) (*http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Post")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/enterprises/{enterprise}/members"
+ localVarPath = strings.Replace(localVarPath, "{"+"enterprise"+"}", fmt.Sprintf("%v", enterprise), -1)
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarFormParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Username.IsSet() {
+ localVarFormParams.Add("username", parameterToString(localVarOptionals.Username.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Email.IsSet() {
+ localVarFormParams.Add("email", parameterToString(localVarOptionals.Email.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Outsourced.IsSet() {
+ localVarFormParams.Add("outsourced", parameterToString(localVarOptionals.Outsourced.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Role.IsSet() {
+ localVarFormParams.Add("role", parameterToString(localVarOptionals.Role.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Name.IsSet() {
+ localVarFormParams.Add("name", parameterToString(localVarOptionals.Name.Value(), ""))
+ }
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ return localVarHttpResponse, newErr
+ }
+
+ return localVarHttpResponse, nil
+}
+
+/*
+EnterprisesApiService 新建周报
+新建周报
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param enterprise 企业的路径(path/login)
+ * @param year 周报所属年
+ * @param content 周报内容
+ * @param weekIndex 周报所属周
+ * @param username 用户名(username/login)
+ * @param optional nil or *PostV5EnterprisesEnterpriseWeekReportOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+ * @param "Date" (optional.String) - 周报日期(格式:2019-03-25)
+
+@return WeekReport
+*/
+
+type PostV5EnterprisesEnterpriseWeekReportOpts struct {
+ AccessToken optional.String
+ Date optional.String
+}
+
+func (a *EnterprisesApiService) PostV5EnterprisesEnterpriseWeekReport(ctx context.Context, enterprise string, year int32, content string, weekIndex int32, username string, localVarOptionals *PostV5EnterprisesEnterpriseWeekReportOpts) (WeekReport, *http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Post")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ localVarReturnValue WeekReport
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/enterprises/{enterprise}/week_report"
+ localVarPath = strings.Replace(localVarPath, "{"+"enterprise"+"}", fmt.Sprintf("%v", enterprise), -1)
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarFormParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ localVarFormParams.Add("year", parameterToString(year, ""))
+ localVarFormParams.Add("content", parameterToString(content, ""))
+ localVarFormParams.Add("week_index", parameterToString(weekIndex, ""))
+ localVarFormParams.Add("username", parameterToString(username, ""))
+ if localVarOptionals != nil && localVarOptionals.Date.IsSet() {
+ localVarFormParams.Add("date", parameterToString(localVarOptionals.Date.Value(), ""))
+ }
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return localVarReturnValue, nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode < 300 {
+ // If we succeed, return the data, otherwise pass on to decode error.
+ err = a.client.decode(&localVarReturnValue, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ if localVarHttpResponse.StatusCode == 201 {
+ var v WeekReport
+ err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err != nil {
+ newErr.error = err.Error()
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+ newErr.model = v
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, nil
+}
+
+/*
+EnterprisesApiService 评论周报
+评论周报
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param enterprise 企业的路径(path/login)
+ * @param id 周报ID
+ * @param body 评论的内容
+ * @param optional nil or *PostV5EnterprisesEnterpriseWeekReportsIdCommentOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+
+@return Note
+*/
+
+type PostV5EnterprisesEnterpriseWeekReportsIdCommentOpts struct {
+ AccessToken optional.String
+}
+
+func (a *EnterprisesApiService) PostV5EnterprisesEnterpriseWeekReportsIdComment(ctx context.Context, enterprise string, id int32, body string, localVarOptionals *PostV5EnterprisesEnterpriseWeekReportsIdCommentOpts) (Note, *http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Post")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ localVarReturnValue Note
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/enterprises/{enterprise}/week_reports/{id}/comment"
+ localVarPath = strings.Replace(localVarPath, "{"+"enterprise"+"}", fmt.Sprintf("%v", enterprise), -1)
+ localVarPath = strings.Replace(localVarPath, "{"+"id"+"}", fmt.Sprintf("%v", id), -1)
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarFormParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ localVarFormParams.Add("body", parameterToString(body, ""))
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return localVarReturnValue, nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode < 300 {
+ // If we succeed, return the data, otherwise pass on to decode error.
+ err = a.client.decode(&localVarReturnValue, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ if localVarHttpResponse.StatusCode == 201 {
+ var v Note
+ err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err != nil {
+ newErr.error = err.Error()
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+ newErr.model = v
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, nil
+}
+
+/*
+EnterprisesApiService 修改企业成员权限或备注
+修改企业成员权限或备注
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param enterprise 企业的路径(path/login)
+ * @param username 用户名(username/login)
+ * @param optional nil or *PutV5EnterprisesEnterpriseMembersUsernameOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+ * @param "Outsourced" (optional.Bool) - 是否企业外包成员,默认:否
+ * @param "Role" (optional.String) - 企业角色,默认普通成员
+ * @param "Active" (optional.Bool) - 是否可访问企业资源,默认:是。(若选否则禁止该用户访问企业资源)
+ * @param "Name" (optional.String) - 企业成员真实姓名(备注)
+
+@return EnterpriseMember
+*/
+
+type PutV5EnterprisesEnterpriseMembersUsernameOpts struct {
+ AccessToken optional.String
+ Outsourced optional.Bool
+ Role optional.String
+ Active optional.Bool
+ Name optional.String
+}
+
+func (a *EnterprisesApiService) PutV5EnterprisesEnterpriseMembersUsername(ctx context.Context, enterprise string, username string, localVarOptionals *PutV5EnterprisesEnterpriseMembersUsernameOpts) (EnterpriseMember, *http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Put")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ localVarReturnValue EnterpriseMember
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/enterprises/{enterprise}/members/{username}"
+ localVarPath = strings.Replace(localVarPath, "{"+"enterprise"+"}", fmt.Sprintf("%v", enterprise), -1)
+ localVarPath = strings.Replace(localVarPath, "{"+"username"+"}", fmt.Sprintf("%v", username), -1)
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarFormParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Outsourced.IsSet() {
+ localVarFormParams.Add("outsourced", parameterToString(localVarOptionals.Outsourced.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Role.IsSet() {
+ localVarFormParams.Add("role", parameterToString(localVarOptionals.Role.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Active.IsSet() {
+ localVarFormParams.Add("active", parameterToString(localVarOptionals.Active.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Name.IsSet() {
+ localVarFormParams.Add("name", parameterToString(localVarOptionals.Name.Value(), ""))
+ }
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return localVarReturnValue, nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode < 300 {
+ // If we succeed, return the data, otherwise pass on to decode error.
+ err = a.client.decode(&localVarReturnValue, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ if localVarHttpResponse.StatusCode == 200 {
+ var v EnterpriseMember
+ err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err != nil {
+ newErr.error = err.Error()
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+ newErr.model = v
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, nil
+}
diff --git a/vendor/gitee.com/openeuler/go-gitee/gitee/api_gists.go b/vendor/gitee.com/openeuler/go-gitee/gitee/api_gists.go
new file mode 100644
index 0000000000000000000000000000000000000000..41d7c5d05315871b802b5f46c2bd2b2b799e2038
--- /dev/null
+++ b/vendor/gitee.com/openeuler/go-gitee/gitee/api_gists.go
@@ -0,0 +1,1908 @@
+/*
+ * 码云 Open API
+ *
+ * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen)
+ *
+ * API version: 5.3.2
+ * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
+ */
+
+package gitee
+
+import (
+ "context"
+ "fmt"
+ "io/ioutil"
+ "net/http"
+ "net/url"
+ "os"
+ "strings"
+
+ "github.com/antihax/optional"
+)
+
+// Linger please
+var (
+ _ context.Context
+)
+
+type GistsApiService service
+
+/*
+GistsApiService 删除代码片段的评论
+删除代码片段的评论
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param gistId 代码片段的ID
+ * @param id 评论的ID
+ * @param optional nil or *DeleteV5GistsGistIdCommentsIdOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+
+
+*/
+
+type DeleteV5GistsGistIdCommentsIdOpts struct {
+ AccessToken optional.String
+}
+
+func (a *GistsApiService) DeleteV5GistsGistIdCommentsId(ctx context.Context, gistId string, id int32, localVarOptionals *DeleteV5GistsGistIdCommentsIdOpts) (*http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Delete")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/gists/{gist_id}/comments/{id}"
+ localVarPath = strings.Replace(localVarPath, "{"+"gist_id"+"}", fmt.Sprintf("%v", gistId), -1)
+ localVarPath = strings.Replace(localVarPath, "{"+"id"+"}", fmt.Sprintf("%v", id), -1)
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarQueryParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ return localVarHttpResponse, newErr
+ }
+
+ return localVarHttpResponse, nil
+}
+
+/*
+GistsApiService 删除指定代码片段
+删除指定代码片段
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param id 代码片段的ID
+ * @param optional nil or *DeleteV5GistsIdOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+
+
+*/
+
+type DeleteV5GistsIdOpts struct {
+ AccessToken optional.String
+}
+
+func (a *GistsApiService) DeleteV5GistsId(ctx context.Context, id string, localVarOptionals *DeleteV5GistsIdOpts) (*http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Delete")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/gists/{id}"
+ localVarPath = strings.Replace(localVarPath, "{"+"id"+"}", fmt.Sprintf("%v", id), -1)
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarQueryParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ return localVarHttpResponse, newErr
+ }
+
+ return localVarHttpResponse, nil
+}
+
+/*
+GistsApiService 取消Star代码片段
+取消Star代码片段
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param id 代码片段的ID
+ * @param optional nil or *DeleteV5GistsIdStarOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+
+
+*/
+
+type DeleteV5GistsIdStarOpts struct {
+ AccessToken optional.String
+}
+
+func (a *GistsApiService) DeleteV5GistsIdStar(ctx context.Context, id string, localVarOptionals *DeleteV5GistsIdStarOpts) (*http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Delete")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/gists/{id}/star"
+ localVarPath = strings.Replace(localVarPath, "{"+"id"+"}", fmt.Sprintf("%v", id), -1)
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarQueryParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ return localVarHttpResponse, newErr
+ }
+
+ return localVarHttpResponse, nil
+}
+
+/*
+GistsApiService 获取代码片段
+获取代码片段
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param optional nil or *GetV5GistsOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+ * @param "Since" (optional.String) - 起始的更新时间,要求时间格式为 ISO 8601
+ * @param "Page" (optional.Int32) - 当前的页码
+ * @param "PerPage" (optional.Int32) - 每页的数量,最大为 100
+
+@return []Code
+*/
+
+type GetV5GistsOpts struct {
+ AccessToken optional.String
+ Since optional.String
+ Page optional.Int32
+ PerPage optional.Int32
+}
+
+func (a *GistsApiService) GetV5Gists(ctx context.Context, localVarOptionals *GetV5GistsOpts) ([]Code, *http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Get")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ localVarReturnValue []Code
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/gists"
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarQueryParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Since.IsSet() {
+ localVarQueryParams.Add("since", parameterToString(localVarOptionals.Since.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Page.IsSet() {
+ localVarQueryParams.Add("page", parameterToString(localVarOptionals.Page.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.PerPage.IsSet() {
+ localVarQueryParams.Add("per_page", parameterToString(localVarOptionals.PerPage.Value(), ""))
+ }
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return localVarReturnValue, nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode < 300 {
+ // If we succeed, return the data, otherwise pass on to decode error.
+ err = a.client.decode(&localVarReturnValue, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ if localVarHttpResponse.StatusCode == 200 {
+ var v []Code
+ err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err != nil {
+ newErr.error = err.Error()
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+ newErr.model = v
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, nil
+}
+
+/*
+GistsApiService 获取代码片段的评论
+获取代码片段的评论
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param gistId 代码片段的ID
+ * @param optional nil or *GetV5GistsGistIdCommentsOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+ * @param "Page" (optional.Int32) - 当前的页码
+ * @param "PerPage" (optional.Int32) - 每页的数量,最大为 100
+
+@return []CodeComment
+*/
+
+type GetV5GistsGistIdCommentsOpts struct {
+ AccessToken optional.String
+ Page optional.Int32
+ PerPage optional.Int32
+}
+
+func (a *GistsApiService) GetV5GistsGistIdComments(ctx context.Context, gistId string, localVarOptionals *GetV5GistsGistIdCommentsOpts) ([]CodeComment, *http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Get")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ localVarReturnValue []CodeComment
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/gists/{gist_id}/comments"
+ localVarPath = strings.Replace(localVarPath, "{"+"gist_id"+"}", fmt.Sprintf("%v", gistId), -1)
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarQueryParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Page.IsSet() {
+ localVarQueryParams.Add("page", parameterToString(localVarOptionals.Page.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.PerPage.IsSet() {
+ localVarQueryParams.Add("per_page", parameterToString(localVarOptionals.PerPage.Value(), ""))
+ }
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return localVarReturnValue, nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode < 300 {
+ // If we succeed, return the data, otherwise pass on to decode error.
+ err = a.client.decode(&localVarReturnValue, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ if localVarHttpResponse.StatusCode == 200 {
+ var v []CodeComment
+ err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err != nil {
+ newErr.error = err.Error()
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+ newErr.model = v
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, nil
+}
+
+/*
+GistsApiService 获取单条代码片段的评论
+获取单条代码片段的评论
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param gistId 代码片段的ID
+ * @param id 评论的ID
+ * @param optional nil or *GetV5GistsGistIdCommentsIdOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+
+@return CodeComment
+*/
+
+type GetV5GistsGistIdCommentsIdOpts struct {
+ AccessToken optional.String
+}
+
+func (a *GistsApiService) GetV5GistsGistIdCommentsId(ctx context.Context, gistId string, id int32, localVarOptionals *GetV5GistsGistIdCommentsIdOpts) (CodeComment, *http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Get")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ localVarReturnValue CodeComment
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/gists/{gist_id}/comments/{id}"
+ localVarPath = strings.Replace(localVarPath, "{"+"gist_id"+"}", fmt.Sprintf("%v", gistId), -1)
+ localVarPath = strings.Replace(localVarPath, "{"+"id"+"}", fmt.Sprintf("%v", id), -1)
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarQueryParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return localVarReturnValue, nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode < 300 {
+ // If we succeed, return the data, otherwise pass on to decode error.
+ err = a.client.decode(&localVarReturnValue, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ if localVarHttpResponse.StatusCode == 200 {
+ var v CodeComment
+ err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err != nil {
+ newErr.error = err.Error()
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+ newErr.model = v
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, nil
+}
+
+/*
+GistsApiService 获取单条代码片段
+获取单条代码片段
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param id 代码片段的ID
+ * @param optional nil or *GetV5GistsIdOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+
+@return CodeForksHistory
+*/
+
+type GetV5GistsIdOpts struct {
+ AccessToken optional.String
+}
+
+func (a *GistsApiService) GetV5GistsId(ctx context.Context, id string, localVarOptionals *GetV5GistsIdOpts) (CodeForksHistory, *http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Get")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ localVarReturnValue CodeForksHistory
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/gists/{id}"
+ localVarPath = strings.Replace(localVarPath, "{"+"id"+"}", fmt.Sprintf("%v", id), -1)
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarQueryParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return localVarReturnValue, nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode < 300 {
+ // If we succeed, return the data, otherwise pass on to decode error.
+ err = a.client.decode(&localVarReturnValue, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ if localVarHttpResponse.StatusCode == 200 {
+ var v CodeForksHistory
+ err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err != nil {
+ newErr.error = err.Error()
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+ newErr.model = v
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, nil
+}
+
+/*
+GistsApiService 获取代码片段的commit
+获取代码片段的commit
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param id 代码片段的ID
+ * @param optional nil or *GetV5GistsIdCommitsOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+
+@return CodeForksHistory
+*/
+
+type GetV5GistsIdCommitsOpts struct {
+ AccessToken optional.String
+}
+
+func (a *GistsApiService) GetV5GistsIdCommits(ctx context.Context, id string, localVarOptionals *GetV5GistsIdCommitsOpts) (CodeForksHistory, *http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Get")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ localVarReturnValue CodeForksHistory
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/gists/{id}/commits"
+ localVarPath = strings.Replace(localVarPath, "{"+"id"+"}", fmt.Sprintf("%v", id), -1)
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarQueryParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return localVarReturnValue, nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode < 300 {
+ // If we succeed, return the data, otherwise pass on to decode error.
+ err = a.client.decode(&localVarReturnValue, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ if localVarHttpResponse.StatusCode == 200 {
+ var v CodeForksHistory
+ err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err != nil {
+ newErr.error = err.Error()
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+ newErr.model = v
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, nil
+}
+
+/*
+GistsApiService 获取 Fork 了指定代码片段的列表
+获取 Fork 了指定代码片段的列表
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param id 代码片段的ID
+ * @param optional nil or *GetV5GistsIdForksOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+ * @param "Page" (optional.Int32) - 当前的页码
+ * @param "PerPage" (optional.Int32) - 每页的数量,最大为 100
+
+@return CodeForks
+*/
+
+type GetV5GistsIdForksOpts struct {
+ AccessToken optional.String
+ Page optional.Int32
+ PerPage optional.Int32
+}
+
+func (a *GistsApiService) GetV5GistsIdForks(ctx context.Context, id string, localVarOptionals *GetV5GistsIdForksOpts) (CodeForks, *http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Get")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ localVarReturnValue CodeForks
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/gists/{id}/forks"
+ localVarPath = strings.Replace(localVarPath, "{"+"id"+"}", fmt.Sprintf("%v", id), -1)
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarQueryParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Page.IsSet() {
+ localVarQueryParams.Add("page", parameterToString(localVarOptionals.Page.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.PerPage.IsSet() {
+ localVarQueryParams.Add("per_page", parameterToString(localVarOptionals.PerPage.Value(), ""))
+ }
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return localVarReturnValue, nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode < 300 {
+ // If we succeed, return the data, otherwise pass on to decode error.
+ err = a.client.decode(&localVarReturnValue, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ if localVarHttpResponse.StatusCode == 200 {
+ var v CodeForks
+ err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err != nil {
+ newErr.error = err.Error()
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+ newErr.model = v
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, nil
+}
+
+/*
+GistsApiService 判断代码片段是否已Star
+判断代码片段是否已Star
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param id 代码片段的ID
+ * @param optional nil or *GetV5GistsIdStarOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+
+
+*/
+
+type GetV5GistsIdStarOpts struct {
+ AccessToken optional.String
+}
+
+func (a *GistsApiService) GetV5GistsIdStar(ctx context.Context, id string, localVarOptionals *GetV5GistsIdStarOpts) (*http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Get")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/gists/{id}/star"
+ localVarPath = strings.Replace(localVarPath, "{"+"id"+"}", fmt.Sprintf("%v", id), -1)
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarQueryParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ return localVarHttpResponse, newErr
+ }
+
+ return localVarHttpResponse, nil
+}
+
+/*
+GistsApiService 获取公开的代码片段
+获取公开的代码片段
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param optional nil or *GetV5GistsPublicOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+ * @param "Since" (optional.String) - 起始的更新时间,要求时间格式为 ISO 8601
+ * @param "Page" (optional.Int32) - 当前的页码
+ * @param "PerPage" (optional.Int32) - 每页的数量,最大为 100
+
+@return []Code
+*/
+
+type GetV5GistsPublicOpts struct {
+ AccessToken optional.String
+ Since optional.String
+ Page optional.Int32
+ PerPage optional.Int32
+}
+
+func (a *GistsApiService) GetV5GistsPublic(ctx context.Context, localVarOptionals *GetV5GistsPublicOpts) ([]Code, *http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Get")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ localVarReturnValue []Code
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/gists/public"
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarQueryParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Since.IsSet() {
+ localVarQueryParams.Add("since", parameterToString(localVarOptionals.Since.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Page.IsSet() {
+ localVarQueryParams.Add("page", parameterToString(localVarOptionals.Page.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.PerPage.IsSet() {
+ localVarQueryParams.Add("per_page", parameterToString(localVarOptionals.PerPage.Value(), ""))
+ }
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return localVarReturnValue, nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode < 300 {
+ // If we succeed, return the data, otherwise pass on to decode error.
+ err = a.client.decode(&localVarReturnValue, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ if localVarHttpResponse.StatusCode == 200 {
+ var v []Code
+ err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err != nil {
+ newErr.error = err.Error()
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+ newErr.model = v
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, nil
+}
+
+/*
+GistsApiService 获取用户Star的代码片段
+获取用户Star的代码片段
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param optional nil or *GetV5GistsStarredOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+ * @param "Since" (optional.String) - 起始的更新时间,要求时间格式为 ISO 8601
+ * @param "Page" (optional.Int32) - 当前的页码
+ * @param "PerPage" (optional.Int32) - 每页的数量,最大为 100
+
+@return []Code
+*/
+
+type GetV5GistsStarredOpts struct {
+ AccessToken optional.String
+ Since optional.String
+ Page optional.Int32
+ PerPage optional.Int32
+}
+
+func (a *GistsApiService) GetV5GistsStarred(ctx context.Context, localVarOptionals *GetV5GistsStarredOpts) ([]Code, *http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Get")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ localVarReturnValue []Code
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/gists/starred"
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarQueryParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Since.IsSet() {
+ localVarQueryParams.Add("since", parameterToString(localVarOptionals.Since.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Page.IsSet() {
+ localVarQueryParams.Add("page", parameterToString(localVarOptionals.Page.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.PerPage.IsSet() {
+ localVarQueryParams.Add("per_page", parameterToString(localVarOptionals.PerPage.Value(), ""))
+ }
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return localVarReturnValue, nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode < 300 {
+ // If we succeed, return the data, otherwise pass on to decode error.
+ err = a.client.decode(&localVarReturnValue, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ if localVarHttpResponse.StatusCode == 200 {
+ var v []Code
+ err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err != nil {
+ newErr.error = err.Error()
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+ newErr.model = v
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, nil
+}
+
+/*
+GistsApiService 获取指定用户的公开代码片段
+获取指定用户的公开代码片段
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param username 用户名(username/login)
+ * @param optional nil or *GetV5UsersUsernameGistsOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+ * @param "Page" (optional.Int32) - 当前的页码
+ * @param "PerPage" (optional.Int32) - 每页的数量,最大为 100
+
+@return []Code
+*/
+
+type GetV5UsersUsernameGistsOpts struct {
+ AccessToken optional.String
+ Page optional.Int32
+ PerPage optional.Int32
+}
+
+func (a *GistsApiService) GetV5UsersUsernameGists(ctx context.Context, username string, localVarOptionals *GetV5UsersUsernameGistsOpts) ([]Code, *http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Get")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ localVarReturnValue []Code
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/users/{username}/gists"
+ localVarPath = strings.Replace(localVarPath, "{"+"username"+"}", fmt.Sprintf("%v", username), -1)
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarQueryParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Page.IsSet() {
+ localVarQueryParams.Add("page", parameterToString(localVarOptionals.Page.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.PerPage.IsSet() {
+ localVarQueryParams.Add("per_page", parameterToString(localVarOptionals.PerPage.Value(), ""))
+ }
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return localVarReturnValue, nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode < 300 {
+ // If we succeed, return the data, otherwise pass on to decode error.
+ err = a.client.decode(&localVarReturnValue, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ if localVarHttpResponse.StatusCode == 200 {
+ var v []Code
+ err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err != nil {
+ newErr.error = err.Error()
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+ newErr.model = v
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, nil
+}
+
+/*
+GistsApiService 修改代码片段的评论
+修改代码片段的评论
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param gistId 代码片段的ID
+ * @param id 评论的ID
+ * @param body 评论内容
+ * @param optional nil or *PatchV5GistsGistIdCommentsIdOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+
+@return CodeComment
+*/
+
+type PatchV5GistsGistIdCommentsIdOpts struct {
+ AccessToken optional.String
+}
+
+func (a *GistsApiService) PatchV5GistsGistIdCommentsId(ctx context.Context, gistId string, id int32, body string, localVarOptionals *PatchV5GistsGistIdCommentsIdOpts) (CodeComment, *http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Patch")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ localVarReturnValue CodeComment
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/gists/{gist_id}/comments/{id}"
+ localVarPath = strings.Replace(localVarPath, "{"+"gist_id"+"}", fmt.Sprintf("%v", gistId), -1)
+ localVarPath = strings.Replace(localVarPath, "{"+"id"+"}", fmt.Sprintf("%v", id), -1)
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarFormParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ localVarFormParams.Add("body", parameterToString(body, ""))
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return localVarReturnValue, nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode < 300 {
+ // If we succeed, return the data, otherwise pass on to decode error.
+ err = a.client.decode(&localVarReturnValue, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ if localVarHttpResponse.StatusCode == 200 {
+ var v CodeComment
+ err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err != nil {
+ newErr.error = err.Error()
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+ newErr.model = v
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, nil
+}
+
+/*
+GistsApiService 修改代码片段
+修改代码片段
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param id 代码片段的ID
+ * @param optional nil or *PatchV5GistsIdOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+ * @param "Files" (optional.Interface of *os.File) - Hash形式的代码片段文件名以及文件内容。如: { \"file1.txt\": { \"content\": \"String file contents\" } }
+ * @param "Description" (optional.String) - 代码片段描述,1~30个字符
+ * @param "Public" (optional.Bool) - 公开/私有,默认: 私有
+
+@return CodeForksHistory
+*/
+
+type PatchV5GistsIdOpts struct {
+ AccessToken optional.String
+ Files optional.Interface
+ Description optional.String
+ Public optional.Bool
+}
+
+func (a *GistsApiService) PatchV5GistsId(ctx context.Context, id string, localVarOptionals *PatchV5GistsIdOpts) (CodeForksHistory, *http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Patch")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ localVarReturnValue CodeForksHistory
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/gists/{id}"
+ localVarPath = strings.Replace(localVarPath, "{"+"id"+"}", fmt.Sprintf("%v", id), -1)
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarFormParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ var localVarFile *os.File
+ if localVarOptionals != nil && localVarOptionals.Files.IsSet() {
+ localVarFileOk := false
+ localVarFile, localVarFileOk = localVarOptionals.Files.Value().(*os.File)
+ if !localVarFileOk {
+ return localVarReturnValue, nil, reportError("files should be *os.File")
+ }
+ }
+ if localVarFile != nil {
+ fbs, _ := ioutil.ReadAll(localVarFile)
+ localVarFileBytes = fbs
+ localVarFileName = localVarFile.Name()
+ localVarFile.Close()
+ }
+ if localVarOptionals != nil && localVarOptionals.Description.IsSet() {
+ localVarFormParams.Add("description", parameterToString(localVarOptionals.Description.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Public.IsSet() {
+ localVarFormParams.Add("public", parameterToString(localVarOptionals.Public.Value(), ""))
+ }
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return localVarReturnValue, nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode < 300 {
+ // If we succeed, return the data, otherwise pass on to decode error.
+ err = a.client.decode(&localVarReturnValue, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ if localVarHttpResponse.StatusCode == 200 {
+ var v CodeForksHistory
+ err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err != nil {
+ newErr.error = err.Error()
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+ newErr.model = v
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, nil
+}
+
+/*
+GistsApiService 创建代码片段
+创建代码片段
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param files Hash形式的代码片段文件名以及文件内容。如: { \"file1.txt\": { \"content\": \"String file contents\" } }
+ * @param description 代码片段描述,1~30个字符
+ * @param optional nil or *PostV5GistsOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+ * @param "Public" (optional.Bool) - 公开/私有,默认: 私有
+
+@return []CodeForksHistory
+*/
+
+type PostV5GistsOpts struct {
+ AccessToken optional.String
+ Public optional.Bool
+}
+
+func (a *GistsApiService) PostV5Gists(ctx context.Context, files *os.File, description string, localVarOptionals *PostV5GistsOpts) ([]CodeForksHistory, *http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Post")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ localVarReturnValue []CodeForksHistory
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/gists"
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarFormParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ /* TODO: fix localVarFile issue
+ if localVarFile != nil {
+ fbs, _ := ioutil.ReadAll(localVarFile)
+ localVarFileBytes = fbs
+ localVarFileName = localVarFile.Name()
+ localVarFile.Close()
+ }*/
+ localVarFormParams.Add("description", parameterToString(description, ""))
+ if localVarOptionals != nil && localVarOptionals.Public.IsSet() {
+ localVarFormParams.Add("public", parameterToString(localVarOptionals.Public.Value(), ""))
+ }
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return localVarReturnValue, nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode < 300 {
+ // If we succeed, return the data, otherwise pass on to decode error.
+ err = a.client.decode(&localVarReturnValue, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ if localVarHttpResponse.StatusCode == 201 {
+ var v []CodeForksHistory
+ err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err != nil {
+ newErr.error = err.Error()
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+ newErr.model = v
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, nil
+}
+
+/*
+GistsApiService 增加代码片段的评论
+增加代码片段的评论
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param gistId 代码片段的ID
+ * @param body 评论内容
+ * @param optional nil or *PostV5GistsGistIdCommentsOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+
+@return CodeComment
+*/
+
+type PostV5GistsGistIdCommentsOpts struct {
+ AccessToken optional.String
+}
+
+func (a *GistsApiService) PostV5GistsGistIdComments(ctx context.Context, gistId string, body string, localVarOptionals *PostV5GistsGistIdCommentsOpts) (CodeComment, *http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Post")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ localVarReturnValue CodeComment
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/gists/{gist_id}/comments"
+ localVarPath = strings.Replace(localVarPath, "{"+"gist_id"+"}", fmt.Sprintf("%v", gistId), -1)
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarFormParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ localVarFormParams.Add("body", parameterToString(body, ""))
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return localVarReturnValue, nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode < 300 {
+ // If we succeed, return the data, otherwise pass on to decode error.
+ err = a.client.decode(&localVarReturnValue, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ if localVarHttpResponse.StatusCode == 201 {
+ var v CodeComment
+ err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err != nil {
+ newErr.error = err.Error()
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+ newErr.model = v
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, nil
+}
+
+/*
+GistsApiService Fork代码片段
+Fork代码片段
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param id 代码片段的ID
+ * @param optional nil or *PostV5GistsIdForksOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+
+
+*/
+
+type PostV5GistsIdForksOpts struct {
+ AccessToken optional.String
+}
+
+func (a *GistsApiService) PostV5GistsIdForks(ctx context.Context, id string, localVarOptionals *PostV5GistsIdForksOpts) (*http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Post")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/gists/{id}/forks"
+ localVarPath = strings.Replace(localVarPath, "{"+"id"+"}", fmt.Sprintf("%v", id), -1)
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarFormParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ return localVarHttpResponse, newErr
+ }
+
+ return localVarHttpResponse, nil
+}
+
+/*
+GistsApiService Star代码片段
+Star代码片段
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param id 代码片段的ID
+ * @param optional nil or *PutV5GistsIdStarOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+
+
+*/
+
+type PutV5GistsIdStarOpts struct {
+ AccessToken optional.String
+}
+
+func (a *GistsApiService) PutV5GistsIdStar(ctx context.Context, id string, localVarOptionals *PutV5GistsIdStarOpts) (*http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Put")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/gists/{id}/star"
+ localVarPath = strings.Replace(localVarPath, "{"+"id"+"}", fmt.Sprintf("%v", id), -1)
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarFormParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ return localVarHttpResponse, newErr
+ }
+
+ return localVarHttpResponse, nil
+}
diff --git a/vendor/gitee.com/openeuler/go-gitee/gitee/api_git_data.go b/vendor/gitee.com/openeuler/go-gitee/gitee/api_git_data.go
new file mode 100644
index 0000000000000000000000000000000000000000..536a68ba67bcba891068a41f75d746531d8e461b
--- /dev/null
+++ b/vendor/gitee.com/openeuler/go-gitee/gitee/api_git_data.go
@@ -0,0 +1,239 @@
+/*
+ * 码云 Open API
+ *
+ * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen)
+ *
+ * API version: 5.3.2
+ * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
+ */
+
+package gitee
+
+import (
+ "context"
+ "fmt"
+ "io/ioutil"
+ "net/http"
+ "net/url"
+ "strings"
+
+ "github.com/antihax/optional"
+)
+
+// Linger please
+var (
+ _ context.Context
+)
+
+type GitDataApiService service
+
+/*
+GitDataApiService 获取文件Blob
+获取文件Blob
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param owner 仓库所属空间地址(企业、组织或个人的地址path)
+ * @param repo 仓库路径(path)
+ * @param sha 文件的 Blob SHA,可通过 [获取仓库具体路径下的内容] API 获取
+ * @param optional nil or *GetV5ReposOwnerRepoGitBlobsShaOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+
+@return Blob
+*/
+
+type GetV5ReposOwnerRepoGitBlobsShaOpts struct {
+ AccessToken optional.String
+}
+
+func (a *GitDataApiService) GetV5ReposOwnerRepoGitBlobsSha(ctx context.Context, owner string, repo string, sha string, localVarOptionals *GetV5ReposOwnerRepoGitBlobsShaOpts) (Blob, *http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Get")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ localVarReturnValue Blob
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/repos/{owner}/{repo}/git/blobs/{sha}"
+ localVarPath = strings.Replace(localVarPath, "{"+"owner"+"}", fmt.Sprintf("%v", owner), -1)
+ localVarPath = strings.Replace(localVarPath, "{"+"repo"+"}", fmt.Sprintf("%v", repo), -1)
+ localVarPath = strings.Replace(localVarPath, "{"+"sha"+"}", fmt.Sprintf("%v", sha), -1)
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarQueryParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return localVarReturnValue, nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode < 300 {
+ // If we succeed, return the data, otherwise pass on to decode error.
+ err = a.client.decode(&localVarReturnValue, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ if localVarHttpResponse.StatusCode == 200 {
+ var v Blob
+ err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err != nil {
+ newErr.error = err.Error()
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+ newErr.model = v
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, nil
+}
+
+/*
+GitDataApiService 获取目录Tree
+获取目录Tree
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param owner 仓库所属空间地址(企业、组织或个人的地址path)
+ * @param repo 仓库路径(path)
+ * @param sha 可以是分支名(如master)、Commit或者目录Tree的SHA值
+ * @param optional nil or *GetV5ReposOwnerRepoGitTreesShaOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+ * @param "Recursive" (optional.Int32) - 赋值为1递归获取目录
+
+@return Tree
+*/
+
+type GetV5ReposOwnerRepoGitTreesShaOpts struct {
+ AccessToken optional.String
+ Recursive optional.Int32
+}
+
+func (a *GitDataApiService) GetV5ReposOwnerRepoGitTreesSha(ctx context.Context, owner string, repo string, sha string, localVarOptionals *GetV5ReposOwnerRepoGitTreesShaOpts) (Tree, *http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Get")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ localVarReturnValue Tree
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/repos/{owner}/{repo}/git/trees/{sha}"
+ localVarPath = strings.Replace(localVarPath, "{"+"owner"+"}", fmt.Sprintf("%v", owner), -1)
+ localVarPath = strings.Replace(localVarPath, "{"+"repo"+"}", fmt.Sprintf("%v", repo), -1)
+ localVarPath = strings.Replace(localVarPath, "{"+"sha"+"}", fmt.Sprintf("%v", sha), -1)
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarQueryParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Recursive.IsSet() {
+ localVarQueryParams.Add("recursive", parameterToString(localVarOptionals.Recursive.Value(), ""))
+ }
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return localVarReturnValue, nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode < 300 {
+ // If we succeed, return the data, otherwise pass on to decode error.
+ err = a.client.decode(&localVarReturnValue, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ if localVarHttpResponse.StatusCode == 200 {
+ var v Tree
+ err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err != nil {
+ newErr.error = err.Error()
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+ newErr.model = v
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, nil
+}
diff --git a/vendor/gitee.com/openeuler/go-gitee/gitee/api_issues.go b/vendor/gitee.com/openeuler/go-gitee/gitee/api_issues.go
new file mode 100644
index 0000000000000000000000000000000000000000..ddf7b4d501ad903272a51c13ec429627374f93a7
--- /dev/null
+++ b/vendor/gitee.com/openeuler/go-gitee/gitee/api_issues.go
@@ -0,0 +1,2248 @@
+/*
+ * 码云 Open API
+ *
+ * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen)
+ *
+ * API version: 5.3.2
+ * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
+ */
+
+package gitee
+
+import (
+ "context"
+ "fmt"
+ "github.com/antihax/optional"
+ "io/ioutil"
+ "net/http"
+ "net/url"
+ "strings"
+)
+
+// Linger please
+var (
+ _ context.Context
+)
+
+type IssuesApiService service
+
+/*
+IssuesApiService 删除Issue某条评论
+删除Issue某条评论
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param owner 仓库所属空间地址(企业、组织或个人的地址path)
+ * @param repo 仓库路径(path)
+ * @param id 评论的ID
+ * @param optional nil or *DeleteV5ReposOwnerRepoIssuesCommentsIdOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+
+
+*/
+
+type DeleteV5ReposOwnerRepoIssuesCommentsIdOpts struct {
+ AccessToken optional.String
+}
+
+func (a *IssuesApiService) DeleteV5ReposOwnerRepoIssuesCommentsId(ctx context.Context, owner string, repo string, id int32, localVarOptionals *DeleteV5ReposOwnerRepoIssuesCommentsIdOpts) (*http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Delete")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/repos/{owner}/{repo}/issues/comments/{id}"
+ localVarPath = strings.Replace(localVarPath, "{"+"owner"+"}", fmt.Sprintf("%v", owner), -1)
+ localVarPath = strings.Replace(localVarPath, "{"+"repo"+"}", fmt.Sprintf("%v", repo), -1)
+ localVarPath = strings.Replace(localVarPath, "{"+"id"+"}", fmt.Sprintf("%v", id), -1)
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarQueryParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ return localVarHttpResponse, newErr
+ }
+
+ return localVarHttpResponse, nil
+}
+
+/*
+IssuesApiService 获取某个企业的所有Issues
+获取某个企业的所有Issues
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param enterprise 企业的路径(path/login)
+ * @param optional nil or *GetV5EnterprisesEnterpriseIssuesOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+ * @param "State" (optional.String) - Issue的状态: open(开启的), progressing(进行中), closed(关闭的), rejected(拒绝的)。 默认: open
+ * @param "Labels" (optional.String) - 用逗号分开的标签。如: bug,performance
+ * @param "Sort" (optional.String) - 排序依据: 创建时间(created),更新时间(updated_at)。默认: created_at
+ * @param "Direction" (optional.String) - 排序方式: 升序(asc),降序(desc)。默认: desc
+ * @param "Since" (optional.String) - 起始的更新时间,要求时间格式为 ISO 8601
+ * @param "Page" (optional.Int32) - 当前的页码
+ * @param "PerPage" (optional.Int32) - 每页的数量,最大为 100
+ * @param "Schedule" (optional.String) - 计划开始日期,格式:20181006T173008+80-20181007T173008+80(区间),或者 -20181007T173008+80(小于20181007T173008+80),或者 20181006T173008+80-(大于20181006T173008+80),要求时间格式为20181006T173008+80
+ * @param "Deadline" (optional.String) - 计划截止日期,格式同上
+ * @param "CreatedAt" (optional.String) - 任务创建时间,格式同上
+ * @param "FinishedAt" (optional.String) - 任务完成时间,即任务最后一次转为已完成状态的时间点。格式同上
+ * @param "Milestone" (optional.String) - 根据里程碑标题。none为没里程碑的,*为所有带里程碑的
+ * @param "Assignee" (optional.String) - 用户的username。 none为没指派者, *为所有带有指派者的
+ * @param "Creator" (optional.String) - 创建Issues的用户username
+ * @param "Program" (optional.String) - 所属项目名称。none为没所属有项目的,*为所有带所属项目的
+
+@return []Issue
+*/
+
+type GetV5EnterprisesEnterpriseIssuesOpts struct {
+ AccessToken optional.String
+ State optional.String
+ Labels optional.String
+ Sort optional.String
+ Direction optional.String
+ Since optional.String
+ Page optional.Int32
+ PerPage optional.Int32
+ Schedule optional.String
+ Deadline optional.String
+ CreatedAt optional.String
+ FinishedAt optional.String
+ Milestone optional.String
+ Assignee optional.String
+ Creator optional.String
+ Program optional.String
+}
+
+func (a *IssuesApiService) GetV5EnterprisesEnterpriseIssues(ctx context.Context, enterprise string, localVarOptionals *GetV5EnterprisesEnterpriseIssuesOpts) ([]Issue, *http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Get")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ localVarReturnValue []Issue
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/enterprises/{enterprise}/issues"
+ localVarPath = strings.Replace(localVarPath, "{"+"enterprise"+"}", fmt.Sprintf("%v", enterprise), -1)
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarQueryParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.State.IsSet() {
+ localVarQueryParams.Add("state", parameterToString(localVarOptionals.State.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Labels.IsSet() {
+ localVarQueryParams.Add("labels", parameterToString(localVarOptionals.Labels.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Sort.IsSet() {
+ localVarQueryParams.Add("sort", parameterToString(localVarOptionals.Sort.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Direction.IsSet() {
+ localVarQueryParams.Add("direction", parameterToString(localVarOptionals.Direction.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Since.IsSet() {
+ localVarQueryParams.Add("since", parameterToString(localVarOptionals.Since.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Page.IsSet() {
+ localVarQueryParams.Add("page", parameterToString(localVarOptionals.Page.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.PerPage.IsSet() {
+ localVarQueryParams.Add("per_page", parameterToString(localVarOptionals.PerPage.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Schedule.IsSet() {
+ localVarQueryParams.Add("schedule", parameterToString(localVarOptionals.Schedule.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Deadline.IsSet() {
+ localVarQueryParams.Add("deadline", parameterToString(localVarOptionals.Deadline.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.CreatedAt.IsSet() {
+ localVarQueryParams.Add("created_at", parameterToString(localVarOptionals.CreatedAt.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.FinishedAt.IsSet() {
+ localVarQueryParams.Add("finished_at", parameterToString(localVarOptionals.FinishedAt.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Milestone.IsSet() {
+ localVarQueryParams.Add("milestone", parameterToString(localVarOptionals.Milestone.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Assignee.IsSet() {
+ localVarQueryParams.Add("assignee", parameterToString(localVarOptionals.Assignee.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Creator.IsSet() {
+ localVarQueryParams.Add("creator", parameterToString(localVarOptionals.Creator.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Program.IsSet() {
+ localVarQueryParams.Add("program", parameterToString(localVarOptionals.Program.Value(), ""))
+ }
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return localVarReturnValue, nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode < 300 {
+ // If we succeed, return the data, otherwise pass on to decode error.
+ err = a.client.decode(&localVarReturnValue, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ if localVarHttpResponse.StatusCode == 200 {
+ var v []Issue
+ err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err != nil {
+ newErr.error = err.Error()
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+ newErr.model = v
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, nil
+}
+
+/*
+IssuesApiService 获取企业的某个Issue
+获取企业的某个Issue
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param enterprise 企业的路径(path/login)
+ * @param number Issue 编号(区分大小写,无需添加 # 号)
+ * @param optional nil or *GetV5EnterprisesEnterpriseIssuesNumberOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+
+@return Issue
+*/
+
+type GetV5EnterprisesEnterpriseIssuesNumberOpts struct {
+ AccessToken optional.String
+}
+
+func (a *IssuesApiService) GetV5EnterprisesEnterpriseIssuesNumber(ctx context.Context, enterprise string, number string, localVarOptionals *GetV5EnterprisesEnterpriseIssuesNumberOpts) (Issue, *http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Get")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ localVarReturnValue Issue
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/enterprises/{enterprise}/issues/{number}"
+ localVarPath = strings.Replace(localVarPath, "{"+"enterprise"+"}", fmt.Sprintf("%v", enterprise), -1)
+ localVarPath = strings.Replace(localVarPath, "{"+"number"+"}", fmt.Sprintf("%v", number), -1)
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarQueryParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return localVarReturnValue, nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode < 300 {
+ // If we succeed, return the data, otherwise pass on to decode error.
+ err = a.client.decode(&localVarReturnValue, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ if localVarHttpResponse.StatusCode == 200 {
+ var v Issue
+ err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err != nil {
+ newErr.error = err.Error()
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+ newErr.model = v
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, nil
+}
+
+/*
+IssuesApiService 获取企业某个Issue所有评论
+获取企业某个Issue所有评论
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param enterprise 企业的路径(path/login)
+ * @param number Issue 编号(区分大小写,无需添加 # 号)
+ * @param optional nil or *GetV5EnterprisesEnterpriseIssuesNumberCommentsOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+ * @param "Page" (optional.Int32) - 当前的页码
+ * @param "PerPage" (optional.Int32) - 每页的数量,最大为 100
+
+@return []Note
+*/
+
+type GetV5EnterprisesEnterpriseIssuesNumberCommentsOpts struct {
+ AccessToken optional.String
+ Page optional.Int32
+ PerPage optional.Int32
+}
+
+func (a *IssuesApiService) GetV5EnterprisesEnterpriseIssuesNumberComments(ctx context.Context, enterprise string, number string, localVarOptionals *GetV5EnterprisesEnterpriseIssuesNumberCommentsOpts) ([]Note, *http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Get")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ localVarReturnValue []Note
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/enterprises/{enterprise}/issues/{number}/comments"
+ localVarPath = strings.Replace(localVarPath, "{"+"enterprise"+"}", fmt.Sprintf("%v", enterprise), -1)
+ localVarPath = strings.Replace(localVarPath, "{"+"number"+"}", fmt.Sprintf("%v", number), -1)
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarQueryParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Page.IsSet() {
+ localVarQueryParams.Add("page", parameterToString(localVarOptionals.Page.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.PerPage.IsSet() {
+ localVarQueryParams.Add("per_page", parameterToString(localVarOptionals.PerPage.Value(), ""))
+ }
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return localVarReturnValue, nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode < 300 {
+ // If we succeed, return the data, otherwise pass on to decode error.
+ err = a.client.decode(&localVarReturnValue, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ if localVarHttpResponse.StatusCode == 200 {
+ var v []Note
+ err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err != nil {
+ newErr.error = err.Error()
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+ newErr.model = v
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, nil
+}
+
+/*
+IssuesApiService 获取企业某个Issue所有标签
+获取企业某个Issue所有标签
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param enterprise 企业的路径(path/login)
+ * @param number Issue 编号(区分大小写,无需添加 # 号)
+ * @param optional nil or *GetV5EnterprisesEnterpriseIssuesNumberLabelsOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+ * @param "Page" (optional.Int32) - 当前的页码
+ * @param "PerPage" (optional.Int32) - 每页的数量,最大为 100
+
+@return []Label
+*/
+
+type GetV5EnterprisesEnterpriseIssuesNumberLabelsOpts struct {
+ AccessToken optional.String
+ Page optional.Int32
+ PerPage optional.Int32
+}
+
+func (a *IssuesApiService) GetV5EnterprisesEnterpriseIssuesNumberLabels(ctx context.Context, enterprise string, number string, localVarOptionals *GetV5EnterprisesEnterpriseIssuesNumberLabelsOpts) ([]Label, *http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Get")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ localVarReturnValue []Label
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/enterprises/{enterprise}/issues/{number}/labels"
+ localVarPath = strings.Replace(localVarPath, "{"+"enterprise"+"}", fmt.Sprintf("%v", enterprise), -1)
+ localVarPath = strings.Replace(localVarPath, "{"+"number"+"}", fmt.Sprintf("%v", number), -1)
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarQueryParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Page.IsSet() {
+ localVarQueryParams.Add("page", parameterToString(localVarOptionals.Page.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.PerPage.IsSet() {
+ localVarQueryParams.Add("per_page", parameterToString(localVarOptionals.PerPage.Value(), ""))
+ }
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return localVarReturnValue, nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode < 300 {
+ // If we succeed, return the data, otherwise pass on to decode error.
+ err = a.client.decode(&localVarReturnValue, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ if localVarHttpResponse.StatusCode == 200 {
+ var v []Label
+ err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err != nil {
+ newErr.error = err.Error()
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+ newErr.model = v
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, nil
+}
+
+/*
+IssuesApiService 获取当前授权用户的所有Issues
+获取当前授权用户的所有Issues
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param optional nil or *GetV5IssuesOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+ * @param "Filter" (optional.String) - 筛选参数: 授权用户负责的(assigned),授权用户创建的(created),包含前两者的(all)。默认: assigned
+ * @param "State" (optional.String) - Issue的状态: open(开启的), progressing(进行中), closed(关闭的), rejected(拒绝的)。 默认: open
+ * @param "Labels" (optional.String) - 用逗号分开的标签。如: bug,performance
+ * @param "Sort" (optional.String) - 排序依据: 创建时间(created),更新时间(updated_at)。默认: created_at
+ * @param "Direction" (optional.String) - 排序方式: 升序(asc),降序(desc)。默认: desc
+ * @param "Since" (optional.String) - 起始的更新时间,要求时间格式为 ISO 8601
+ * @param "Page" (optional.Int32) - 当前的页码
+ * @param "PerPage" (optional.Int32) - 每页的数量,最大为 100
+ * @param "Schedule" (optional.String) - 计划开始日期,格式:20181006T173008+80-20181007T173008+80(区间),或者 -20181007T173008+80(小于20181007T173008+80),或者 20181006T173008+80-(大于20181006T173008+80),要求时间格式为20181006T173008+80
+ * @param "Deadline" (optional.String) - 计划截止日期,格式同上
+ * @param "CreatedAt" (optional.String) - 任务创建时间,格式同上
+ * @param "FinishedAt" (optional.String) - 任务完成时间,即任务最后一次转为已完成状态的时间点。格式同上
+
+@return []Issue
+*/
+
+type GetV5IssuesOpts struct {
+ AccessToken optional.String
+ Filter optional.String
+ State optional.String
+ Labels optional.String
+ Sort optional.String
+ Direction optional.String
+ Since optional.String
+ Page optional.Int32
+ PerPage optional.Int32
+ Schedule optional.String
+ Deadline optional.String
+ CreatedAt optional.String
+ FinishedAt optional.String
+}
+
+func (a *IssuesApiService) GetV5Issues(ctx context.Context, localVarOptionals *GetV5IssuesOpts) ([]Issue, *http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Get")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ localVarReturnValue []Issue
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/issues"
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarQueryParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Filter.IsSet() {
+ localVarQueryParams.Add("filter", parameterToString(localVarOptionals.Filter.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.State.IsSet() {
+ localVarQueryParams.Add("state", parameterToString(localVarOptionals.State.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Labels.IsSet() {
+ localVarQueryParams.Add("labels", parameterToString(localVarOptionals.Labels.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Sort.IsSet() {
+ localVarQueryParams.Add("sort", parameterToString(localVarOptionals.Sort.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Direction.IsSet() {
+ localVarQueryParams.Add("direction", parameterToString(localVarOptionals.Direction.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Since.IsSet() {
+ localVarQueryParams.Add("since", parameterToString(localVarOptionals.Since.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Page.IsSet() {
+ localVarQueryParams.Add("page", parameterToString(localVarOptionals.Page.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.PerPage.IsSet() {
+ localVarQueryParams.Add("per_page", parameterToString(localVarOptionals.PerPage.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Schedule.IsSet() {
+ localVarQueryParams.Add("schedule", parameterToString(localVarOptionals.Schedule.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Deadline.IsSet() {
+ localVarQueryParams.Add("deadline", parameterToString(localVarOptionals.Deadline.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.CreatedAt.IsSet() {
+ localVarQueryParams.Add("created_at", parameterToString(localVarOptionals.CreatedAt.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.FinishedAt.IsSet() {
+ localVarQueryParams.Add("finished_at", parameterToString(localVarOptionals.FinishedAt.Value(), ""))
+ }
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return localVarReturnValue, nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode < 300 {
+ // If we succeed, return the data, otherwise pass on to decode error.
+ err = a.client.decode(&localVarReturnValue, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ if localVarHttpResponse.StatusCode == 200 {
+ var v []Issue
+ err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err != nil {
+ newErr.error = err.Error()
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+ newErr.model = v
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, nil
+}
+
+/*
+IssuesApiService 获取当前用户某个组织的Issues
+获取当前用户某个组织的Issues
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param org 组织的路径(path/login)
+ * @param optional nil or *GetV5OrgsOrgIssuesOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+ * @param "Filter" (optional.String) - 筛选参数: 授权用户负责的(assigned),授权用户创建的(created),包含前两者的(all)。默认: assigned
+ * @param "State" (optional.String) - Issue的状态: open(开启的), progressing(进行中), closed(关闭的), rejected(拒绝的)。 默认: open
+ * @param "Labels" (optional.String) - 用逗号分开的标签。如: bug,performance
+ * @param "Sort" (optional.String) - 排序依据: 创建时间(created),更新时间(updated_at)。默认: created_at
+ * @param "Direction" (optional.String) - 排序方式: 升序(asc),降序(desc)。默认: desc
+ * @param "Since" (optional.String) - 起始的更新时间,要求时间格式为 ISO 8601
+ * @param "Page" (optional.Int32) - 当前的页码
+ * @param "PerPage" (optional.Int32) - 每页的数量,最大为 100
+ * @param "Schedule" (optional.String) - 计划开始日期,格式:20181006T173008+80-20181007T173008+80(区间),或者 -20181007T173008+80(小于20181007T173008+80),或者 20181006T173008+80-(大于20181006T173008+80),要求时间格式为20181006T173008+80
+ * @param "Deadline" (optional.String) - 计划截止日期,格式同上
+ * @param "CreatedAt" (optional.String) - 任务创建时间,格式同上
+ * @param "FinishedAt" (optional.String) - 任务完成时间,即任务最后一次转为已完成状态的时间点。格式同上
+
+@return []Issue
+*/
+
+type GetV5OrgsOrgIssuesOpts struct {
+ AccessToken optional.String
+ Filter optional.String
+ State optional.String
+ Labels optional.String
+ Sort optional.String
+ Direction optional.String
+ Since optional.String
+ Page optional.Int32
+ PerPage optional.Int32
+ Schedule optional.String
+ Deadline optional.String
+ CreatedAt optional.String
+ FinishedAt optional.String
+}
+
+func (a *IssuesApiService) GetV5OrgsOrgIssues(ctx context.Context, org string, localVarOptionals *GetV5OrgsOrgIssuesOpts) ([]Issue, *http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Get")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ localVarReturnValue []Issue
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/orgs/{org}/issues"
+ localVarPath = strings.Replace(localVarPath, "{"+"org"+"}", fmt.Sprintf("%v", org), -1)
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarQueryParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Filter.IsSet() {
+ localVarQueryParams.Add("filter", parameterToString(localVarOptionals.Filter.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.State.IsSet() {
+ localVarQueryParams.Add("state", parameterToString(localVarOptionals.State.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Labels.IsSet() {
+ localVarQueryParams.Add("labels", parameterToString(localVarOptionals.Labels.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Sort.IsSet() {
+ localVarQueryParams.Add("sort", parameterToString(localVarOptionals.Sort.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Direction.IsSet() {
+ localVarQueryParams.Add("direction", parameterToString(localVarOptionals.Direction.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Since.IsSet() {
+ localVarQueryParams.Add("since", parameterToString(localVarOptionals.Since.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Page.IsSet() {
+ localVarQueryParams.Add("page", parameterToString(localVarOptionals.Page.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.PerPage.IsSet() {
+ localVarQueryParams.Add("per_page", parameterToString(localVarOptionals.PerPage.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Schedule.IsSet() {
+ localVarQueryParams.Add("schedule", parameterToString(localVarOptionals.Schedule.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Deadline.IsSet() {
+ localVarQueryParams.Add("deadline", parameterToString(localVarOptionals.Deadline.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.CreatedAt.IsSet() {
+ localVarQueryParams.Add("created_at", parameterToString(localVarOptionals.CreatedAt.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.FinishedAt.IsSet() {
+ localVarQueryParams.Add("finished_at", parameterToString(localVarOptionals.FinishedAt.Value(), ""))
+ }
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return localVarReturnValue, nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode < 300 {
+ // If we succeed, return the data, otherwise pass on to decode error.
+ err = a.client.decode(&localVarReturnValue, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ if localVarHttpResponse.StatusCode == 200 {
+ var v []Issue
+ err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err != nil {
+ newErr.error = err.Error()
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+ newErr.model = v
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, nil
+}
+
+/*
+IssuesApiService 获取某个Issue下的操作日志
+获取某个Issue下的操作日志
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param owner 仓库所属空间地址(企业、组织或个人的地址path)
+ * @param number Issue 编号(区分大小写,无需添加 # 号)
+ * @param optional nil or *GetV5ReposOwnerIssuesNumberOperateLogsOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+ * @param "Repo" (optional.String) - 仓库路径(path)
+ * @param "Sort" (optional.String) - 按递增(asc)或递减(desc)排序,默认:递减
+
+@return []OperateLog
+*/
+
+type GetV5ReposOwnerIssuesNumberOperateLogsOpts struct {
+ AccessToken optional.String
+ Repo optional.String
+ Sort optional.String
+}
+
+func (a *IssuesApiService) GetV5ReposOwnerIssuesNumberOperateLogs(ctx context.Context, owner string, number string, localVarOptionals *GetV5ReposOwnerIssuesNumberOperateLogsOpts) ([]OperateLog, *http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Get")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ localVarReturnValue []OperateLog
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/repos/{owner}/issues/{number}/operate_logs"
+ localVarPath = strings.Replace(localVarPath, "{"+"owner"+"}", fmt.Sprintf("%v", owner), -1)
+ localVarPath = strings.Replace(localVarPath, "{"+"number"+"}", fmt.Sprintf("%v", number), -1)
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarQueryParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Repo.IsSet() {
+ localVarQueryParams.Add("repo", parameterToString(localVarOptionals.Repo.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Sort.IsSet() {
+ localVarQueryParams.Add("sort", parameterToString(localVarOptionals.Sort.Value(), ""))
+ }
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return localVarReturnValue, nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode < 300 {
+ // If we succeed, return the data, otherwise pass on to decode error.
+ err = a.client.decode(&localVarReturnValue, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ if localVarHttpResponse.StatusCode == 200 {
+ var v []OperateLog
+ err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err != nil {
+ newErr.error = err.Error()
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+ newErr.model = v
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, nil
+}
+
+/*
+IssuesApiService 仓库的所有Issues
+仓库的所有Issues
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param owner 仓库所属空间地址(企业、组织或个人的地址path)
+ * @param repo 仓库路径(path)
+ * @param optional nil or *GetV5ReposOwnerRepoIssuesOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+ * @param "State" (optional.String) - Issue的状态: open(开启的), progressing(进行中), closed(关闭的), rejected(拒绝的)。 默认: open
+ * @param "Labels" (optional.String) - 用逗号分开的标签。如: bug,performance
+ * @param "Sort" (optional.String) - 排序依据: 创建时间(created),更新时间(updated_at)。默认: created_at
+ * @param "Direction" (optional.String) - 排序方式: 升序(asc),降序(desc)。默认: desc
+ * @param "Since" (optional.String) - 起始的更新时间,要求时间格式为 ISO 8601
+ * @param "Page" (optional.Int32) - 当前的页码
+ * @param "PerPage" (optional.Int32) - 每页的数量,最大为 100
+ * @param "Schedule" (optional.String) - 计划开始日期,格式:20181006T173008+80-20181007T173008+80(区间),或者 -20181007T173008+80(小于20181007T173008+80),或者 20181006T173008+80-(大于20181006T173008+80),要求时间格式为20181006T173008+80
+ * @param "Deadline" (optional.String) - 计划截止日期,格式同上
+ * @param "CreatedAt" (optional.String) - 任务创建时间,格式同上
+ * @param "FinishedAt" (optional.String) - 任务完成时间,即任务最后一次转为已完成状态的时间点。格式同上
+ * @param "Milestone" (optional.String) - 根据里程碑标题。none为没里程碑的,*为所有带里程碑的
+ * @param "Assignee" (optional.String) - 用户的username。 none为没指派者, *为所有带有指派者的
+ * @param "Creator" (optional.String) - 创建Issues的用户username
+ * @param "Program" (optional.String) - 所属项目名称。none为没有所属项目,*为所有带所属项目的
+
+@return []Issue
+*/
+
+type GetV5ReposOwnerRepoIssuesOpts struct {
+ AccessToken optional.String
+ State optional.String
+ Labels optional.String
+ Sort optional.String
+ Direction optional.String
+ Since optional.String
+ Page optional.Int32
+ PerPage optional.Int32
+ Schedule optional.String
+ Deadline optional.String
+ CreatedAt optional.String
+ FinishedAt optional.String
+ Milestone optional.String
+ Assignee optional.String
+ Creator optional.String
+ Program optional.String
+}
+
+func (a *IssuesApiService) GetV5ReposOwnerRepoIssues(ctx context.Context, owner string, repo string, localVarOptionals *GetV5ReposOwnerRepoIssuesOpts) ([]Issue, *http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Get")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ localVarReturnValue []Issue
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/repos/{owner}/{repo}/issues"
+ localVarPath = strings.Replace(localVarPath, "{"+"owner"+"}", fmt.Sprintf("%v", owner), -1)
+ localVarPath = strings.Replace(localVarPath, "{"+"repo"+"}", fmt.Sprintf("%v", repo), -1)
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarQueryParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.State.IsSet() {
+ localVarQueryParams.Add("state", parameterToString(localVarOptionals.State.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Labels.IsSet() {
+ localVarQueryParams.Add("labels", parameterToString(localVarOptionals.Labels.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Sort.IsSet() {
+ localVarQueryParams.Add("sort", parameterToString(localVarOptionals.Sort.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Direction.IsSet() {
+ localVarQueryParams.Add("direction", parameterToString(localVarOptionals.Direction.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Since.IsSet() {
+ localVarQueryParams.Add("since", parameterToString(localVarOptionals.Since.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Page.IsSet() {
+ localVarQueryParams.Add("page", parameterToString(localVarOptionals.Page.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.PerPage.IsSet() {
+ localVarQueryParams.Add("per_page", parameterToString(localVarOptionals.PerPage.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Schedule.IsSet() {
+ localVarQueryParams.Add("schedule", parameterToString(localVarOptionals.Schedule.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Deadline.IsSet() {
+ localVarQueryParams.Add("deadline", parameterToString(localVarOptionals.Deadline.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.CreatedAt.IsSet() {
+ localVarQueryParams.Add("created_at", parameterToString(localVarOptionals.CreatedAt.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.FinishedAt.IsSet() {
+ localVarQueryParams.Add("finished_at", parameterToString(localVarOptionals.FinishedAt.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Milestone.IsSet() {
+ localVarQueryParams.Add("milestone", parameterToString(localVarOptionals.Milestone.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Assignee.IsSet() {
+ localVarQueryParams.Add("assignee", parameterToString(localVarOptionals.Assignee.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Creator.IsSet() {
+ localVarQueryParams.Add("creator", parameterToString(localVarOptionals.Creator.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Program.IsSet() {
+ localVarQueryParams.Add("program", parameterToString(localVarOptionals.Program.Value(), ""))
+ }
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return localVarReturnValue, nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode < 300 {
+ // If we succeed, return the data, otherwise pass on to decode error.
+ err = a.client.decode(&localVarReturnValue, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ if localVarHttpResponse.StatusCode == 200 {
+ var v []Issue
+ err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err != nil {
+ newErr.error = err.Error()
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+ newErr.model = v
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, nil
+}
+
+/*
+IssuesApiService 获取仓库所有Issue的评论
+获取仓库所有Issue的评论
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param owner 仓库所属空间地址(企业、组织或个人的地址path)
+ * @param repo 仓库路径(path)
+ * @param optional nil or *GetV5ReposOwnerRepoIssuesCommentsOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+ * @param "Sort" (optional.String) - Either created or updated. Default: created
+ * @param "Direction" (optional.String) - Either asc or desc. Ignored without the sort parameter.
+ * @param "Since" (optional.String) - Only comments updated at or after this time are returned. This is a timestamp in ISO 8601 format: YYYY-MM-DDTHH:MM:SSZ
+ * @param "Page" (optional.Int32) - 当前的页码
+ * @param "PerPage" (optional.Int32) - 每页的数量,最大为 100
+
+@return Note
+*/
+
+type GetV5ReposOwnerRepoIssuesCommentsOpts struct {
+ AccessToken optional.String
+ Sort optional.String
+ Direction optional.String
+ Since optional.String
+ Page optional.Int32
+ PerPage optional.Int32
+}
+
+func (a *IssuesApiService) GetV5ReposOwnerRepoIssuesComments(ctx context.Context, owner string, repo string, localVarOptionals *GetV5ReposOwnerRepoIssuesCommentsOpts) (Note, *http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Get")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ localVarReturnValue Note
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/repos/{owner}/{repo}/issues/comments"
+ localVarPath = strings.Replace(localVarPath, "{"+"owner"+"}", fmt.Sprintf("%v", owner), -1)
+ localVarPath = strings.Replace(localVarPath, "{"+"repo"+"}", fmt.Sprintf("%v", repo), -1)
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarQueryParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Sort.IsSet() {
+ localVarQueryParams.Add("sort", parameterToString(localVarOptionals.Sort.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Direction.IsSet() {
+ localVarQueryParams.Add("direction", parameterToString(localVarOptionals.Direction.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Since.IsSet() {
+ localVarQueryParams.Add("since", parameterToString(localVarOptionals.Since.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Page.IsSet() {
+ localVarQueryParams.Add("page", parameterToString(localVarOptionals.Page.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.PerPage.IsSet() {
+ localVarQueryParams.Add("per_page", parameterToString(localVarOptionals.PerPage.Value(), ""))
+ }
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return localVarReturnValue, nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode < 300 {
+ // If we succeed, return the data, otherwise pass on to decode error.
+ err = a.client.decode(&localVarReturnValue, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ if localVarHttpResponse.StatusCode == 200 {
+ var v Note
+ err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err != nil {
+ newErr.error = err.Error()
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+ newErr.model = v
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, nil
+}
+
+/*
+IssuesApiService 获取仓库Issue某条评论
+获取仓库Issue某条评论
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param owner 仓库所属空间地址(企业、组织或个人的地址path)
+ * @param repo 仓库路径(path)
+ * @param id 评论的ID
+ * @param optional nil or *GetV5ReposOwnerRepoIssuesCommentsIdOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+
+@return Note
+*/
+
+type GetV5ReposOwnerRepoIssuesCommentsIdOpts struct {
+ AccessToken optional.String
+}
+
+func (a *IssuesApiService) GetV5ReposOwnerRepoIssuesCommentsId(ctx context.Context, owner string, repo string, id int32, localVarOptionals *GetV5ReposOwnerRepoIssuesCommentsIdOpts) (Note, *http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Get")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ localVarReturnValue Note
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/repos/{owner}/{repo}/issues/comments/{id}"
+ localVarPath = strings.Replace(localVarPath, "{"+"owner"+"}", fmt.Sprintf("%v", owner), -1)
+ localVarPath = strings.Replace(localVarPath, "{"+"repo"+"}", fmt.Sprintf("%v", repo), -1)
+ localVarPath = strings.Replace(localVarPath, "{"+"id"+"}", fmt.Sprintf("%v", id), -1)
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarQueryParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return localVarReturnValue, nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode < 300 {
+ // If we succeed, return the data, otherwise pass on to decode error.
+ err = a.client.decode(&localVarReturnValue, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ if localVarHttpResponse.StatusCode == 200 {
+ var v Note
+ err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err != nil {
+ newErr.error = err.Error()
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+ newErr.model = v
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, nil
+}
+
+/*
+IssuesApiService 仓库的某个Issue
+仓库的某个Issue
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param owner 仓库所属空间地址(企业、组织或个人的地址path)
+ * @param repo 仓库路径(path)
+ * @param number Issue 编号(区分大小写,无需添加 # 号)
+ * @param optional nil or *GetV5ReposOwnerRepoIssuesNumberOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+
+@return Issue
+*/
+
+type GetV5ReposOwnerRepoIssuesNumberOpts struct {
+ AccessToken optional.String
+}
+
+func (a *IssuesApiService) GetV5ReposOwnerRepoIssuesNumber(ctx context.Context, owner string, repo string, number string, localVarOptionals *GetV5ReposOwnerRepoIssuesNumberOpts) (Issue, *http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Get")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ localVarReturnValue Issue
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/repos/{owner}/{repo}/issues/{number}"
+ localVarPath = strings.Replace(localVarPath, "{"+"owner"+"}", fmt.Sprintf("%v", owner), -1)
+ localVarPath = strings.Replace(localVarPath, "{"+"repo"+"}", fmt.Sprintf("%v", repo), -1)
+ localVarPath = strings.Replace(localVarPath, "{"+"number"+"}", fmt.Sprintf("%v", number), -1)
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarQueryParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return localVarReturnValue, nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode < 300 {
+ // If we succeed, return the data, otherwise pass on to decode error.
+ err = a.client.decode(&localVarReturnValue, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ if localVarHttpResponse.StatusCode == 200 {
+ var v Issue
+ err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err != nil {
+ newErr.error = err.Error()
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+ newErr.model = v
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, nil
+}
+
+/*
+IssuesApiService 获取仓库某个Issue所有的评论
+获取仓库某个Issue所有的评论
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param owner 仓库所属空间地址(企业、组织或个人的地址path)
+ * @param repo 仓库路径(path)
+ * @param number Issue 编号(区分大小写,无需添加 # 号)
+ * @param optional nil or *GetV5ReposOwnerRepoIssuesNumberCommentsOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+ * @param "Since" (optional.String) - Only comments updated at or after this time are returned. This is a timestamp in ISO 8601 format: YYYY-MM-DDTHH:MM:SSZ
+ * @param "Page" (optional.Int32) - 当前的页码
+ * @param "PerPage" (optional.Int32) - 每页的数量,最大为 100
+
+@return Note
+*/
+
+type GetV5ReposOwnerRepoIssuesNumberCommentsOpts struct {
+ AccessToken optional.String
+ Since optional.String
+ Page optional.Int32
+ PerPage optional.Int32
+}
+
+func (a *IssuesApiService) GetV5ReposOwnerRepoIssuesNumberComments(ctx context.Context, owner string, repo string, number string, localVarOptionals *GetV5ReposOwnerRepoIssuesNumberCommentsOpts) (Note, *http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Get")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ localVarReturnValue Note
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/repos/{owner}/{repo}/issues/{number}/comments"
+ localVarPath = strings.Replace(localVarPath, "{"+"owner"+"}", fmt.Sprintf("%v", owner), -1)
+ localVarPath = strings.Replace(localVarPath, "{"+"repo"+"}", fmt.Sprintf("%v", repo), -1)
+ localVarPath = strings.Replace(localVarPath, "{"+"number"+"}", fmt.Sprintf("%v", number), -1)
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarQueryParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Since.IsSet() {
+ localVarQueryParams.Add("since", parameterToString(localVarOptionals.Since.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Page.IsSet() {
+ localVarQueryParams.Add("page", parameterToString(localVarOptionals.Page.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.PerPage.IsSet() {
+ localVarQueryParams.Add("per_page", parameterToString(localVarOptionals.PerPage.Value(), ""))
+ }
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return localVarReturnValue, nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode < 300 {
+ // If we succeed, return the data, otherwise pass on to decode error.
+ err = a.client.decode(&localVarReturnValue, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ if localVarHttpResponse.StatusCode == 200 {
+ var v Note
+ err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err != nil {
+ newErr.error = err.Error()
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+ newErr.model = v
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, nil
+}
+
+/*
+IssuesApiService 获取授权用户的所有Issues
+获取授权用户的所有Issues
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param optional nil or *GetV5UserIssuesOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+ * @param "Filter" (optional.String) - 筛选参数: 授权用户负责的(assigned),授权用户创建的(created),包含前两者的(all)。默认: assigned
+ * @param "State" (optional.String) - Issue的状态: open(开启的), progressing(进行中), closed(关闭的), rejected(拒绝的)。 默认: open
+ * @param "Labels" (optional.String) - 用逗号分开的标签。如: bug,performance
+ * @param "Sort" (optional.String) - 排序依据: 创建时间(created),更新时间(updated_at)。默认: created_at
+ * @param "Direction" (optional.String) - 排序方式: 升序(asc),降序(desc)。默认: desc
+ * @param "Since" (optional.String) - 起始的更新时间,要求时间格式为 ISO 8601
+ * @param "Page" (optional.Int32) - 当前的页码
+ * @param "PerPage" (optional.Int32) - 每页的数量,最大为 100
+ * @param "Schedule" (optional.String) - 计划开始日期,格式:20181006T173008+80-20181007T173008+80(区间),或者 -20181007T173008+80(小于20181007T173008+80),或者 20181006T173008+80-(大于20181006T173008+80),要求时间格式为20181006T173008+80
+ * @param "Deadline" (optional.String) - 计划截止日期,格式同上
+ * @param "CreatedAt" (optional.String) - 任务创建时间,格式同上
+ * @param "FinishedAt" (optional.String) - 任务完成时间,即任务最后一次转为已完成状态的时间点。格式同上
+
+@return []Issue
+*/
+
+type GetV5UserIssuesOpts struct {
+ AccessToken optional.String
+ Filter optional.String
+ State optional.String
+ Labels optional.String
+ Sort optional.String
+ Direction optional.String
+ Since optional.String
+ Page optional.Int32
+ PerPage optional.Int32
+ Schedule optional.String
+ Deadline optional.String
+ CreatedAt optional.String
+ FinishedAt optional.String
+}
+
+func (a *IssuesApiService) GetV5UserIssues(ctx context.Context, localVarOptionals *GetV5UserIssuesOpts) ([]Issue, *http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Get")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ localVarReturnValue []Issue
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/user/issues"
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarQueryParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Filter.IsSet() {
+ localVarQueryParams.Add("filter", parameterToString(localVarOptionals.Filter.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.State.IsSet() {
+ localVarQueryParams.Add("state", parameterToString(localVarOptionals.State.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Labels.IsSet() {
+ localVarQueryParams.Add("labels", parameterToString(localVarOptionals.Labels.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Sort.IsSet() {
+ localVarQueryParams.Add("sort", parameterToString(localVarOptionals.Sort.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Direction.IsSet() {
+ localVarQueryParams.Add("direction", parameterToString(localVarOptionals.Direction.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Since.IsSet() {
+ localVarQueryParams.Add("since", parameterToString(localVarOptionals.Since.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Page.IsSet() {
+ localVarQueryParams.Add("page", parameterToString(localVarOptionals.Page.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.PerPage.IsSet() {
+ localVarQueryParams.Add("per_page", parameterToString(localVarOptionals.PerPage.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Schedule.IsSet() {
+ localVarQueryParams.Add("schedule", parameterToString(localVarOptionals.Schedule.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Deadline.IsSet() {
+ localVarQueryParams.Add("deadline", parameterToString(localVarOptionals.Deadline.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.CreatedAt.IsSet() {
+ localVarQueryParams.Add("created_at", parameterToString(localVarOptionals.CreatedAt.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.FinishedAt.IsSet() {
+ localVarQueryParams.Add("finished_at", parameterToString(localVarOptionals.FinishedAt.Value(), ""))
+ }
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return localVarReturnValue, nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode < 300 {
+ // If we succeed, return the data, otherwise pass on to decode error.
+ err = a.client.decode(&localVarReturnValue, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ if localVarHttpResponse.StatusCode == 200 {
+ var v []Issue
+ err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err != nil {
+ newErr.error = err.Error()
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+ newErr.model = v
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, nil
+}
+
+/*
+IssuesApiService 更新Issue
+更新Issue
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param owner 仓库所属空间地址(企业、组织或个人的地址path)
+ * @param number Issue 编号(区分大小写,无需添加 # 号)
+ * @param body 可选。Issue 内容
+
+@return Issue
+*/
+func (a *IssuesApiService) PatchV5ReposOwnerIssuesNumber(ctx context.Context, owner string, number string, body IssueUpdateParam) (Issue, *http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Patch")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ localVarReturnValue Issue
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/repos/{owner}/issues/{number}"
+ localVarPath = strings.Replace(localVarPath, "{"+"owner"+"}", fmt.Sprintf("%v", owner), -1)
+ localVarPath = strings.Replace(localVarPath, "{"+"number"+"}", fmt.Sprintf("%v", number), -1)
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ // body params
+ localVarPostBody = &body
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return localVarReturnValue, nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode < 300 {
+ // If we succeed, return the data, otherwise pass on to decode error.
+ err = a.client.decode(&localVarReturnValue, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ if localVarHttpResponse.StatusCode == 200 {
+ var v Issue
+ err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err != nil {
+ newErr.error = err.Error()
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+ newErr.model = v
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, nil
+}
+
+/*
+IssuesApiService 更新Issue某条评论
+更新Issue某条评论
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param owner 仓库所属空间地址(企业、组织或个人的地址path)
+ * @param repo 仓库路径(path)
+ * @param id 评论的ID
+ * @param body The contents of the comment.
+ * @param optional nil or *PatchV5ReposOwnerRepoIssuesCommentsIdOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+
+@return Note
+*/
+
+type PatchV5ReposOwnerRepoIssuesCommentsIdOpts struct {
+ AccessToken optional.String
+}
+
+func (a *IssuesApiService) PatchV5ReposOwnerRepoIssuesCommentsId(ctx context.Context, owner string, repo string, id int32, body string, localVarOptionals *PatchV5ReposOwnerRepoIssuesCommentsIdOpts) (Note, *http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Patch")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ localVarReturnValue Note
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/repos/{owner}/{repo}/issues/comments/{id}"
+ localVarPath = strings.Replace(localVarPath, "{"+"owner"+"}", fmt.Sprintf("%v", owner), -1)
+ localVarPath = strings.Replace(localVarPath, "{"+"repo"+"}", fmt.Sprintf("%v", repo), -1)
+ localVarPath = strings.Replace(localVarPath, "{"+"id"+"}", fmt.Sprintf("%v", id), -1)
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarFormParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ localVarFormParams.Add("body", parameterToString(body, ""))
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return localVarReturnValue, nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode < 300 {
+ // If we succeed, return the data, otherwise pass on to decode error.
+ err = a.client.decode(&localVarReturnValue, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ if localVarHttpResponse.StatusCode == 200 {
+ var v Note
+ err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err != nil {
+ newErr.error = err.Error()
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+ newErr.model = v
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, nil
+}
+
+/*
+IssuesApiService 创建Issue
+创建Issue
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param owner 仓库所属空间地址(企业、组织或个人的地址path)
+ * @param title Issue标题
+ * @param optional nil or *PostV5ReposOwnerIssuesOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+ * @param "Repo" (optional.String) - 仓库路径(path)
+ * @param "IssueType" (optional.String) - 企业自定义任务类型,非企业默认任务类型为“任务”
+ * @param "Body" (optional.String) - Issue描述
+ * @param "Assignee" (optional.String) - Issue负责人的username
+ * @param "Milestone" (optional.Int32) - 里程碑序号
+ * @param "Labels" (optional.String) - 用逗号分开的标签,名称要求长度在 2-20 之间且非特殊字符。如: bug,performance
+ * @param "Program" (optional.String) - 项目ID
+
+@return Issue
+*/
+
+type PostV5ReposOwnerIssuesOpts struct {
+ AccessToken optional.String
+ Repo optional.String
+ IssueType optional.String
+ Body optional.String
+ Assignee optional.String
+ Milestone optional.Int32
+ Labels optional.String
+ Program optional.String
+}
+
+func (a *IssuesApiService) PostV5ReposOwnerIssues(ctx context.Context, owner string, title string, localVarOptionals *PostV5ReposOwnerIssuesOpts) (Issue, *http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Post")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ localVarReturnValue Issue
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/repos/{owner}/issues"
+ localVarPath = strings.Replace(localVarPath, "{"+"owner"+"}", fmt.Sprintf("%v", owner), -1)
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarFormParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Repo.IsSet() {
+ localVarFormParams.Add("repo", parameterToString(localVarOptionals.Repo.Value(), ""))
+ }
+ localVarFormParams.Add("title", parameterToString(title, ""))
+ if localVarOptionals != nil && localVarOptionals.IssueType.IsSet() {
+ localVarFormParams.Add("issue_type", parameterToString(localVarOptionals.IssueType.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Body.IsSet() {
+ localVarFormParams.Add("body", parameterToString(localVarOptionals.Body.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Assignee.IsSet() {
+ localVarFormParams.Add("assignee", parameterToString(localVarOptionals.Assignee.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Milestone.IsSet() {
+ localVarFormParams.Add("milestone", parameterToString(localVarOptionals.Milestone.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Labels.IsSet() {
+ localVarFormParams.Add("labels", parameterToString(localVarOptionals.Labels.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Program.IsSet() {
+ localVarFormParams.Add("program", parameterToString(localVarOptionals.Program.Value(), ""))
+ }
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return localVarReturnValue, nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode < 300 {
+ // If we succeed, return the data, otherwise pass on to decode error.
+ err = a.client.decode(&localVarReturnValue, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ if localVarHttpResponse.StatusCode == 201 {
+ var v Issue
+ err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err != nil {
+ newErr.error = err.Error()
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+ newErr.model = v
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, nil
+}
+
+/*
+IssuesApiService 创建某个Issue评论
+创建某个Issue评论
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param owner 仓库所属空间地址(企业、组织或个人的地址path)
+ * @param repo 仓库路径(path)
+ * @param number Issue 编号(区分大小写,无需添加 # 号)
+ * @param body Issue comment内容
+
+@return Note
+*/
+func (a *IssuesApiService) PostV5ReposOwnerRepoIssuesNumberComments(ctx context.Context, owner string, repo string, number string, body IssueCommentPostParam) (Note, *http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Post")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ localVarReturnValue Note
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/repos/{owner}/{repo}/issues/{number}/comments"
+ localVarPath = strings.Replace(localVarPath, "{"+"owner"+"}", fmt.Sprintf("%v", owner), -1)
+ localVarPath = strings.Replace(localVarPath, "{"+"repo"+"}", fmt.Sprintf("%v", repo), -1)
+ localVarPath = strings.Replace(localVarPath, "{"+"number"+"}", fmt.Sprintf("%v", number), -1)
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ // body params
+ localVarPostBody = &body
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return localVarReturnValue, nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode < 300 {
+ // If we succeed, return the data, otherwise pass on to decode error.
+ err = a.client.decode(&localVarReturnValue, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ if localVarHttpResponse.StatusCode == 201 {
+ var v Note
+ err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err != nil {
+ newErr.error = err.Error()
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+ newErr.model = v
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, nil
+}
diff --git a/vendor/gitee.com/openeuler/go-gitee/gitee/api_labels.go b/vendor/gitee.com/openeuler/go-gitee/gitee/api_labels.go
new file mode 100644
index 0000000000000000000000000000000000000000..2e42f83841a77761c465aa9e7c5a95ac16066967
--- /dev/null
+++ b/vendor/gitee.com/openeuler/go-gitee/gitee/api_labels.go
@@ -0,0 +1,1209 @@
+/*
+ * 码云 Open API
+ *
+ * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen)
+ *
+ * API version: 5.3.2
+ * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
+ */
+
+package gitee
+
+import (
+ "context"
+ "fmt"
+ "io/ioutil"
+ "net/http"
+ "net/url"
+ "strings"
+
+ "github.com/antihax/optional"
+)
+
+// Linger please
+var (
+ _ context.Context
+)
+
+type LabelsApiService service
+
+/*
+LabelsApiService 删除Issue所有标签
+删除Issue所有标签
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param owner 仓库所属空间地址(企业、组织或个人的地址path)
+ * @param repo 仓库路径(path)
+ * @param number Issue 编号(区分大小写,无需添加 # 号)
+ * @param optional nil or *DeleteV5ReposOwnerRepoIssuesNumberLabelsOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+
+
+*/
+
+type DeleteV5ReposOwnerRepoIssuesNumberLabelsOpts struct {
+ AccessToken optional.String
+}
+
+func (a *LabelsApiService) DeleteV5ReposOwnerRepoIssuesNumberLabels(ctx context.Context, owner string, repo string, number string, localVarOptionals *DeleteV5ReposOwnerRepoIssuesNumberLabelsOpts) (*http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Delete")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/repos/{owner}/{repo}/issues/{number}/labels"
+ localVarPath = strings.Replace(localVarPath, "{"+"owner"+"}", fmt.Sprintf("%v", owner), -1)
+ localVarPath = strings.Replace(localVarPath, "{"+"repo"+"}", fmt.Sprintf("%v", repo), -1)
+ localVarPath = strings.Replace(localVarPath, "{"+"number"+"}", fmt.Sprintf("%v", number), -1)
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarQueryParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ return localVarHttpResponse, newErr
+ }
+
+ return localVarHttpResponse, nil
+}
+
+/*
+LabelsApiService 删除Issue标签
+删除Issue标签
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param owner 仓库所属空间地址(企业、组织或个人的地址path)
+ * @param repo 仓库路径(path)
+ * @param number Issue 编号(区分大小写,无需添加 # 号)
+ * @param name 标签名称
+ * @param optional nil or *DeleteV5ReposOwnerRepoIssuesNumberLabelsNameOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+
+
+*/
+
+type DeleteV5ReposOwnerRepoIssuesNumberLabelsNameOpts struct {
+ AccessToken optional.String
+}
+
+func (a *LabelsApiService) DeleteV5ReposOwnerRepoIssuesNumberLabelsName(ctx context.Context, owner string, repo string, number string, name string, localVarOptionals *DeleteV5ReposOwnerRepoIssuesNumberLabelsNameOpts) (*http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Delete")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/repos/{owner}/{repo}/issues/{number}/labels/{name}"
+ localVarPath = strings.Replace(localVarPath, "{"+"owner"+"}", fmt.Sprintf("%v", owner), -1)
+ localVarPath = strings.Replace(localVarPath, "{"+"repo"+"}", fmt.Sprintf("%v", repo), -1)
+ localVarPath = strings.Replace(localVarPath, "{"+"number"+"}", fmt.Sprintf("%v", number), -1)
+ localVarPath = strings.Replace(localVarPath, "{"+"name"+"}", fmt.Sprintf("%v", name), -1)
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarQueryParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ return localVarHttpResponse, newErr
+ }
+
+ return localVarHttpResponse, nil
+}
+
+/*
+LabelsApiService 删除一个仓库任务标签
+删除一个仓库任务标签
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param owner 仓库所属空间地址(企业、组织或个人的地址path)
+ * @param repo 仓库路径(path)
+ * @param name 标签名称
+ * @param optional nil or *DeleteV5ReposOwnerRepoLabelsNameOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+
+
+*/
+
+type DeleteV5ReposOwnerRepoLabelsNameOpts struct {
+ AccessToken optional.String
+}
+
+func (a *LabelsApiService) DeleteV5ReposOwnerRepoLabelsName(ctx context.Context, owner string, repo string, name string, localVarOptionals *DeleteV5ReposOwnerRepoLabelsNameOpts) (*http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Delete")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/repos/{owner}/{repo}/labels/{name}"
+ localVarPath = strings.Replace(localVarPath, "{"+"owner"+"}", fmt.Sprintf("%v", owner), -1)
+ localVarPath = strings.Replace(localVarPath, "{"+"repo"+"}", fmt.Sprintf("%v", repo), -1)
+ localVarPath = strings.Replace(localVarPath, "{"+"name"+"}", fmt.Sprintf("%v", name), -1)
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarQueryParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ return localVarHttpResponse, newErr
+ }
+
+ return localVarHttpResponse, nil
+}
+
+/*
+LabelsApiService 获取企业所有标签
+获取企业所有标签
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param enterprise 企业的路径(path/login)
+ * @param optional nil or *GetV5EnterprisesEnterpriseLabelsOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+
+@return []Label
+*/
+
+type GetV5EnterprisesEnterpriseLabelsOpts struct {
+ AccessToken optional.String
+}
+
+func (a *LabelsApiService) GetV5EnterprisesEnterpriseLabels(ctx context.Context, enterprise string, localVarOptionals *GetV5EnterprisesEnterpriseLabelsOpts) ([]Label, *http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Get")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ localVarReturnValue []Label
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/enterprises/{enterprise}/labels"
+ localVarPath = strings.Replace(localVarPath, "{"+"enterprise"+"}", fmt.Sprintf("%v", enterprise), -1)
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarQueryParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return localVarReturnValue, nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode < 300 {
+ // If we succeed, return the data, otherwise pass on to decode error.
+ err = a.client.decode(&localVarReturnValue, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ if localVarHttpResponse.StatusCode == 200 {
+ var v []Label
+ err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err != nil {
+ newErr.error = err.Error()
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+ newErr.model = v
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, nil
+}
+
+/*
+LabelsApiService 获取企业某个标签
+获取企业某个标签
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param enterprise 企业的路径(path/login)
+ * @param name 标签名称
+ * @param optional nil or *GetV5EnterprisesEnterpriseLabelsNameOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+
+@return Label
+*/
+
+type GetV5EnterprisesEnterpriseLabelsNameOpts struct {
+ AccessToken optional.String
+}
+
+func (a *LabelsApiService) GetV5EnterprisesEnterpriseLabelsName(ctx context.Context, enterprise string, name string, localVarOptionals *GetV5EnterprisesEnterpriseLabelsNameOpts) (Label, *http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Get")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ localVarReturnValue Label
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/enterprises/{enterprise}/labels/{name}"
+ localVarPath = strings.Replace(localVarPath, "{"+"enterprise"+"}", fmt.Sprintf("%v", enterprise), -1)
+ localVarPath = strings.Replace(localVarPath, "{"+"name"+"}", fmt.Sprintf("%v", name), -1)
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarQueryParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return localVarReturnValue, nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode < 300 {
+ // If we succeed, return the data, otherwise pass on to decode error.
+ err = a.client.decode(&localVarReturnValue, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ if localVarHttpResponse.StatusCode == 200 {
+ var v Label
+ err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err != nil {
+ newErr.error = err.Error()
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+ newErr.model = v
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, nil
+}
+
+/*
+LabelsApiService 获取仓库任务的所有标签
+获取仓库任务的所有标签
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param owner 仓库所属空间地址(企业、组织或个人的地址path)
+ * @param repo 仓库路径(path)
+ * @param number Issue 编号(区分大小写,无需添加 # 号)
+ * @param optional nil or *GetV5ReposOwnerRepoIssuesNumberLabelsOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+
+@return []Label
+*/
+
+type GetV5ReposOwnerRepoIssuesNumberLabelsOpts struct {
+ AccessToken optional.String
+}
+
+func (a *LabelsApiService) GetV5ReposOwnerRepoIssuesNumberLabels(ctx context.Context, owner string, repo string, number string, localVarOptionals *GetV5ReposOwnerRepoIssuesNumberLabelsOpts) ([]Label, *http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Get")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ localVarReturnValue []Label
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/repos/{owner}/{repo}/issues/{number}/labels"
+ localVarPath = strings.Replace(localVarPath, "{"+"owner"+"}", fmt.Sprintf("%v", owner), -1)
+ localVarPath = strings.Replace(localVarPath, "{"+"repo"+"}", fmt.Sprintf("%v", repo), -1)
+ localVarPath = strings.Replace(localVarPath, "{"+"number"+"}", fmt.Sprintf("%v", number), -1)
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarQueryParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return localVarReturnValue, nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode < 300 {
+ // If we succeed, return the data, otherwise pass on to decode error.
+ err = a.client.decode(&localVarReturnValue, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ if localVarHttpResponse.StatusCode == 200 {
+ var v []Label
+ err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err != nil {
+ newErr.error = err.Error()
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+ newErr.model = v
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, nil
+}
+
+/*
+LabelsApiService 获取仓库所有任务标签
+获取仓库所有任务标签
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param owner 仓库所属空间地址(企业、组织或个人的地址path)
+ * @param repo 仓库路径(path)
+ * @param optional nil or *GetV5ReposOwnerRepoLabelsOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+
+@return []Label
+*/
+
+type GetV5ReposOwnerRepoLabelsOpts struct {
+ AccessToken optional.String
+}
+
+func (a *LabelsApiService) GetV5ReposOwnerRepoLabels(ctx context.Context, owner string, repo string, localVarOptionals *GetV5ReposOwnerRepoLabelsOpts) ([]Label, *http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Get")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ localVarReturnValue []Label
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/repos/{owner}/{repo}/labels"
+ localVarPath = strings.Replace(localVarPath, "{"+"owner"+"}", fmt.Sprintf("%v", owner), -1)
+ localVarPath = strings.Replace(localVarPath, "{"+"repo"+"}", fmt.Sprintf("%v", repo), -1)
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarQueryParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return localVarReturnValue, nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode < 300 {
+ // If we succeed, return the data, otherwise pass on to decode error.
+ err = a.client.decode(&localVarReturnValue, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ if localVarHttpResponse.StatusCode == 200 {
+ var v []Label
+ err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err != nil {
+ newErr.error = err.Error()
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+ newErr.model = v
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, nil
+}
+
+/*
+LabelsApiService 根据标签名称获取单个标签
+根据标签名称获取单个标签
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param owner 仓库所属空间地址(企业、组织或个人的地址path)
+ * @param repo 仓库路径(path)
+ * @param name 标签名称
+ * @param optional nil or *GetV5ReposOwnerRepoLabelsNameOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+
+@return Label
+*/
+
+type GetV5ReposOwnerRepoLabelsNameOpts struct {
+ AccessToken optional.String
+}
+
+func (a *LabelsApiService) GetV5ReposOwnerRepoLabelsName(ctx context.Context, owner string, repo string, name string, localVarOptionals *GetV5ReposOwnerRepoLabelsNameOpts) (Label, *http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Get")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ localVarReturnValue Label
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/repos/{owner}/{repo}/labels/{name}"
+ localVarPath = strings.Replace(localVarPath, "{"+"owner"+"}", fmt.Sprintf("%v", owner), -1)
+ localVarPath = strings.Replace(localVarPath, "{"+"repo"+"}", fmt.Sprintf("%v", repo), -1)
+ localVarPath = strings.Replace(localVarPath, "{"+"name"+"}", fmt.Sprintf("%v", name), -1)
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarQueryParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return localVarReturnValue, nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode < 300 {
+ // If we succeed, return the data, otherwise pass on to decode error.
+ err = a.client.decode(&localVarReturnValue, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ if localVarHttpResponse.StatusCode == 200 {
+ var v Label
+ err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err != nil {
+ newErr.error = err.Error()
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+ newErr.model = v
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, nil
+}
+
+/*
+LabelsApiService 更新一个仓库任务标签
+更新一个仓库任务标签
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param owner 仓库所属空间地址(企业、组织或个人的地址path)
+ * @param repo 仓库路径(path)
+ * @param originalName 标签原有名称
+ * @param optional nil or *PatchV5ReposOwnerRepoLabelsOriginalNameOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+ * @param "Name" (optional.String) - 标签新名称
+ * @param "Color" (optional.String) - 标签新颜色
+
+@return Label
+*/
+
+type PatchV5ReposOwnerRepoLabelsOriginalNameOpts struct {
+ AccessToken optional.String
+ Name optional.String
+ Color optional.String
+}
+
+func (a *LabelsApiService) PatchV5ReposOwnerRepoLabelsOriginalName(ctx context.Context, owner string, repo string, originalName string, localVarOptionals *PatchV5ReposOwnerRepoLabelsOriginalNameOpts) (Label, *http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Patch")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ localVarReturnValue Label
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/repos/{owner}/{repo}/labels/{original_name}"
+ localVarPath = strings.Replace(localVarPath, "{"+"owner"+"}", fmt.Sprintf("%v", owner), -1)
+ localVarPath = strings.Replace(localVarPath, "{"+"repo"+"}", fmt.Sprintf("%v", repo), -1)
+ localVarPath = strings.Replace(localVarPath, "{"+"original_name"+"}", fmt.Sprintf("%v", originalName), -1)
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarFormParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Name.IsSet() {
+ localVarFormParams.Add("name", parameterToString(localVarOptionals.Name.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Color.IsSet() {
+ localVarFormParams.Add("color", parameterToString(localVarOptionals.Color.Value(), ""))
+ }
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return localVarReturnValue, nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode < 300 {
+ // If we succeed, return the data, otherwise pass on to decode error.
+ err = a.client.decode(&localVarReturnValue, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ if localVarHttpResponse.StatusCode == 200 {
+ var v Label
+ err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err != nil {
+ newErr.error = err.Error()
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+ newErr.model = v
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, nil
+}
+
+/*
+LabelsApiService 创建Issue标签
+创建Issue标签 需要在请求的body里填上数组,元素为标签的名字。如: [\"performance\", \"bug\"]
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param owner 仓库所属空间地址(企业、组织或个人的地址path)
+ * @param repo 仓库路径(path)
+ * @param number Issue 编号(区分大小写,无需添加 # 号)
+ * @param optional nil or *PostV5ReposOwnerRepoIssuesNumberLabelsOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+ * @param "Body" (optional.Interface of []string) - 标签名数组,如: [\"feat\", \"bug\"]
+
+@return Label
+*/
+
+type PostV5ReposOwnerRepoIssuesNumberLabelsOpts struct {
+ AccessToken optional.String
+ Body optional.Interface
+}
+
+func (a *LabelsApiService) PostV5ReposOwnerRepoIssuesNumberLabels(ctx context.Context, owner string, repo string, number string, localVarOptionals *PostV5ReposOwnerRepoIssuesNumberLabelsOpts) (Label, *http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Post")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ localVarReturnValue Label
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/repos/{owner}/{repo}/issues/{number}/labels"
+ localVarPath = strings.Replace(localVarPath, "{"+"owner"+"}", fmt.Sprintf("%v", owner), -1)
+ localVarPath = strings.Replace(localVarPath, "{"+"repo"+"}", fmt.Sprintf("%v", repo), -1)
+ localVarPath = strings.Replace(localVarPath, "{"+"number"+"}", fmt.Sprintf("%v", number), -1)
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarFormParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Body.IsSet() {
+ localVarFormParams.Add("body", parameterToString(localVarOptionals.Body.Value(), "multi"))
+ }
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return localVarReturnValue, nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode < 300 {
+ // If we succeed, return the data, otherwise pass on to decode error.
+ err = a.client.decode(&localVarReturnValue, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ if localVarHttpResponse.StatusCode == 201 {
+ var v Label
+ err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err != nil {
+ newErr.error = err.Error()
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+ newErr.model = v
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, nil
+}
+
+/*
+LabelsApiService 创建仓库任务标签
+创建仓库任务标签
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param owner 仓库所属空间地址(企业、组织或个人的地址path)
+ * @param repo 仓库路径(path)
+ * @param body 必选,标签的内容
+
+@return Label
+*/
+func (a *LabelsApiService) PostV5ReposOwnerRepoLabels(ctx context.Context, owner string, repo string, body LabelPostParam) (Label, *http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Post")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ localVarReturnValue Label
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/repos/{owner}/{repo}/labels"
+ localVarPath = strings.Replace(localVarPath, "{"+"owner"+"}", fmt.Sprintf("%v", owner), -1)
+ localVarPath = strings.Replace(localVarPath, "{"+"repo"+"}", fmt.Sprintf("%v", repo), -1)
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ // body params
+ localVarPostBody = &body
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return localVarReturnValue, nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode < 300 {
+ // If we succeed, return the data, otherwise pass on to decode error.
+ err = a.client.decode(&localVarReturnValue, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ if localVarHttpResponse.StatusCode == 201 {
+ var v Label
+ err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err != nil {
+ newErr.error = err.Error()
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+ newErr.model = v
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, nil
+}
+
+/*
+LabelsApiService 替换Issue所有标签
+替换Issue所有标签 需要在请求的body里填上数组,元素为标签的名字。如: [\"performance\", \"bug\"]
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param owner 仓库所属空间地址(企业、组织或个人的地址path)
+ * @param repo 仓库路径(path)
+ * @param number Issue 编号(区分大小写,无需添加 # 号)
+ * @param optional nil or *PutV5ReposOwnerRepoIssuesNumberLabelsOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+ * @param "Body" (optional.Interface of []string) - 标签名数组,如: [\"feat\", \"bug\"]
+
+@return Label
+*/
+
+type PutV5ReposOwnerRepoIssuesNumberLabelsOpts struct {
+ AccessToken optional.String
+ Body optional.Interface
+}
+
+func (a *LabelsApiService) PutV5ReposOwnerRepoIssuesNumberLabels(ctx context.Context, owner string, repo string, number string, localVarOptionals *PutV5ReposOwnerRepoIssuesNumberLabelsOpts) (Label, *http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Put")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ localVarReturnValue Label
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/repos/{owner}/{repo}/issues/{number}/labels"
+ localVarPath = strings.Replace(localVarPath, "{"+"owner"+"}", fmt.Sprintf("%v", owner), -1)
+ localVarPath = strings.Replace(localVarPath, "{"+"repo"+"}", fmt.Sprintf("%v", repo), -1)
+ localVarPath = strings.Replace(localVarPath, "{"+"number"+"}", fmt.Sprintf("%v", number), -1)
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarFormParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Body.IsSet() {
+ localVarFormParams.Add("body", parameterToString(localVarOptionals.Body.Value(), "multi"))
+ }
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return localVarReturnValue, nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode < 300 {
+ // If we succeed, return the data, otherwise pass on to decode error.
+ err = a.client.decode(&localVarReturnValue, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ if localVarHttpResponse.StatusCode == 200 {
+ var v Label
+ err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err != nil {
+ newErr.error = err.Error()
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+ newErr.model = v
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, nil
+}
diff --git a/vendor/gitee.com/openeuler/go-gitee/gitee/api_milestones.go b/vendor/gitee.com/openeuler/go-gitee/gitee/api_milestones.go
new file mode 100644
index 0000000000000000000000000000000000000000..21145cdf21ab4aba7b47cd97d0fc3104c4ef6ff3
--- /dev/null
+++ b/vendor/gitee.com/openeuler/go-gitee/gitee/api_milestones.go
@@ -0,0 +1,572 @@
+/*
+ * 码云 Open API
+ *
+ * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen)
+ *
+ * API version: 5.3.2
+ * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
+ */
+
+package gitee
+
+import (
+ "context"
+ "fmt"
+ "io/ioutil"
+ "net/http"
+ "net/url"
+ "strings"
+
+ "github.com/antihax/optional"
+)
+
+// Linger please
+var (
+ _ context.Context
+)
+
+type MilestonesApiService service
+
+/*
+MilestonesApiService 删除仓库单个里程碑
+删除仓库单个里程碑
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param owner 仓库所属空间地址(企业、组织或个人的地址path)
+ * @param repo 仓库路径(path)
+ * @param number 里程碑序号(id)
+ * @param optional nil or *DeleteV5ReposOwnerRepoMilestonesNumberOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+
+
+*/
+
+type DeleteV5ReposOwnerRepoMilestonesNumberOpts struct {
+ AccessToken optional.String
+}
+
+func (a *MilestonesApiService) DeleteV5ReposOwnerRepoMilestonesNumber(ctx context.Context, owner string, repo string, number int32, localVarOptionals *DeleteV5ReposOwnerRepoMilestonesNumberOpts) (*http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Delete")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/repos/{owner}/{repo}/milestones/{number}"
+ localVarPath = strings.Replace(localVarPath, "{"+"owner"+"}", fmt.Sprintf("%v", owner), -1)
+ localVarPath = strings.Replace(localVarPath, "{"+"repo"+"}", fmt.Sprintf("%v", repo), -1)
+ localVarPath = strings.Replace(localVarPath, "{"+"number"+"}", fmt.Sprintf("%v", number), -1)
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarQueryParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ return localVarHttpResponse, newErr
+ }
+
+ return localVarHttpResponse, nil
+}
+
+/*
+MilestonesApiService 获取仓库所有里程碑
+获取仓库所有里程碑
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param owner 仓库所属空间地址(企业、组织或个人的地址path)
+ * @param repo 仓库路径(path)
+ * @param optional nil or *GetV5ReposOwnerRepoMilestonesOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+ * @param "State" (optional.String) - 里程碑状态: open, closed, all。默认: open
+ * @param "Sort" (optional.String) - 排序方式: due_on
+ * @param "Direction" (optional.String) - 升序(asc)或是降序(desc)。默认: asc
+ * @param "Page" (optional.Int32) - 当前的页码
+ * @param "PerPage" (optional.Int32) - 每页的数量,最大为 100
+
+@return []Milestone
+*/
+
+type GetV5ReposOwnerRepoMilestonesOpts struct {
+ AccessToken optional.String
+ State optional.String
+ Sort optional.String
+ Direction optional.String
+ Page optional.Int32
+ PerPage optional.Int32
+}
+
+func (a *MilestonesApiService) GetV5ReposOwnerRepoMilestones(ctx context.Context, owner string, repo string, localVarOptionals *GetV5ReposOwnerRepoMilestonesOpts) ([]Milestone, *http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Get")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ localVarReturnValue []Milestone
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/repos/{owner}/{repo}/milestones"
+ localVarPath = strings.Replace(localVarPath, "{"+"owner"+"}", fmt.Sprintf("%v", owner), -1)
+ localVarPath = strings.Replace(localVarPath, "{"+"repo"+"}", fmt.Sprintf("%v", repo), -1)
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarQueryParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.State.IsSet() {
+ localVarQueryParams.Add("state", parameterToString(localVarOptionals.State.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Sort.IsSet() {
+ localVarQueryParams.Add("sort", parameterToString(localVarOptionals.Sort.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Direction.IsSet() {
+ localVarQueryParams.Add("direction", parameterToString(localVarOptionals.Direction.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Page.IsSet() {
+ localVarQueryParams.Add("page", parameterToString(localVarOptionals.Page.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.PerPage.IsSet() {
+ localVarQueryParams.Add("per_page", parameterToString(localVarOptionals.PerPage.Value(), ""))
+ }
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return localVarReturnValue, nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode < 300 {
+ // If we succeed, return the data, otherwise pass on to decode error.
+ err = a.client.decode(&localVarReturnValue, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ if localVarHttpResponse.StatusCode == 200 {
+ var v []Milestone
+ err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err != nil {
+ newErr.error = err.Error()
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+ newErr.model = v
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, nil
+}
+
+/*
+MilestonesApiService 获取仓库单个里程碑
+获取仓库单个里程碑
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param owner 仓库所属空间地址(企业、组织或个人的地址path)
+ * @param repo 仓库路径(path)
+ * @param number 里程碑序号(id)
+ * @param optional nil or *GetV5ReposOwnerRepoMilestonesNumberOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+
+@return Milestone
+*/
+
+type GetV5ReposOwnerRepoMilestonesNumberOpts struct {
+ AccessToken optional.String
+}
+
+func (a *MilestonesApiService) GetV5ReposOwnerRepoMilestonesNumber(ctx context.Context, owner string, repo string, number int32, localVarOptionals *GetV5ReposOwnerRepoMilestonesNumberOpts) (Milestone, *http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Get")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ localVarReturnValue Milestone
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/repos/{owner}/{repo}/milestones/{number}"
+ localVarPath = strings.Replace(localVarPath, "{"+"owner"+"}", fmt.Sprintf("%v", owner), -1)
+ localVarPath = strings.Replace(localVarPath, "{"+"repo"+"}", fmt.Sprintf("%v", repo), -1)
+ localVarPath = strings.Replace(localVarPath, "{"+"number"+"}", fmt.Sprintf("%v", number), -1)
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarQueryParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return localVarReturnValue, nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode < 300 {
+ // If we succeed, return the data, otherwise pass on to decode error.
+ err = a.client.decode(&localVarReturnValue, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ if localVarHttpResponse.StatusCode == 200 {
+ var v Milestone
+ err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err != nil {
+ newErr.error = err.Error()
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+ newErr.model = v
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, nil
+}
+
+/*
+MilestonesApiService 更新仓库里程碑
+更新仓库里程碑
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param owner 仓库所属空间地址(企业、组织或个人的地址path)
+ * @param repo 仓库路径(path)
+ * @param number 里程碑序号(id)
+ * @param title 里程碑标题
+ * @param dueOn 里程碑的截止日期
+ * @param optional nil or *PatchV5ReposOwnerRepoMilestonesNumberOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+ * @param "State" (optional.String) - 里程碑状态: open, closed, all。默认: open
+ * @param "Description" (optional.String) - 里程碑具体描述
+
+@return Milestone
+*/
+
+type PatchV5ReposOwnerRepoMilestonesNumberOpts struct {
+ AccessToken optional.String
+ State optional.String
+ Description optional.String
+}
+
+func (a *MilestonesApiService) PatchV5ReposOwnerRepoMilestonesNumber(ctx context.Context, owner string, repo string, number int32, title string, dueOn string, localVarOptionals *PatchV5ReposOwnerRepoMilestonesNumberOpts) (Milestone, *http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Patch")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ localVarReturnValue Milestone
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/repos/{owner}/{repo}/milestones/{number}"
+ localVarPath = strings.Replace(localVarPath, "{"+"owner"+"}", fmt.Sprintf("%v", owner), -1)
+ localVarPath = strings.Replace(localVarPath, "{"+"repo"+"}", fmt.Sprintf("%v", repo), -1)
+ localVarPath = strings.Replace(localVarPath, "{"+"number"+"}", fmt.Sprintf("%v", number), -1)
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarFormParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ localVarFormParams.Add("title", parameterToString(title, ""))
+ if localVarOptionals != nil && localVarOptionals.State.IsSet() {
+ localVarFormParams.Add("state", parameterToString(localVarOptionals.State.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Description.IsSet() {
+ localVarFormParams.Add("description", parameterToString(localVarOptionals.Description.Value(), ""))
+ }
+ localVarFormParams.Add("due_on", parameterToString(dueOn, ""))
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return localVarReturnValue, nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode < 300 {
+ // If we succeed, return the data, otherwise pass on to decode error.
+ err = a.client.decode(&localVarReturnValue, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ if localVarHttpResponse.StatusCode == 200 {
+ var v Milestone
+ err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err != nil {
+ newErr.error = err.Error()
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+ newErr.model = v
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, nil
+}
+
+/*
+MilestonesApiService 创建仓库里程碑
+创建仓库里程碑
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param owner 仓库所属空间地址(企业、组织或个人的地址path)
+ * @param repo 仓库路径(path)
+ * @param title 里程碑标题
+ * @param dueOn 里程碑的截止日期
+ * @param optional nil or *PostV5ReposOwnerRepoMilestonesOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+ * @param "State" (optional.String) - 里程碑状态: open, closed, all。默认: open
+ * @param "Description" (optional.String) - 里程碑具体描述
+
+@return Milestone
+*/
+
+type PostV5ReposOwnerRepoMilestonesOpts struct {
+ AccessToken optional.String
+ State optional.String
+ Description optional.String
+}
+
+func (a *MilestonesApiService) PostV5ReposOwnerRepoMilestones(ctx context.Context, owner string, repo string, title string, dueOn string, localVarOptionals *PostV5ReposOwnerRepoMilestonesOpts) (Milestone, *http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Post")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ localVarReturnValue Milestone
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/repos/{owner}/{repo}/milestones"
+ localVarPath = strings.Replace(localVarPath, "{"+"owner"+"}", fmt.Sprintf("%v", owner), -1)
+ localVarPath = strings.Replace(localVarPath, "{"+"repo"+"}", fmt.Sprintf("%v", repo), -1)
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarFormParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ localVarFormParams.Add("title", parameterToString(title, ""))
+ if localVarOptionals != nil && localVarOptionals.State.IsSet() {
+ localVarFormParams.Add("state", parameterToString(localVarOptionals.State.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Description.IsSet() {
+ localVarFormParams.Add("description", parameterToString(localVarOptionals.Description.Value(), ""))
+ }
+ localVarFormParams.Add("due_on", parameterToString(dueOn, ""))
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return localVarReturnValue, nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode < 300 {
+ // If we succeed, return the data, otherwise pass on to decode error.
+ err = a.client.decode(&localVarReturnValue, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ if localVarHttpResponse.StatusCode == 201 {
+ var v Milestone
+ err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err != nil {
+ newErr.error = err.Error()
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+ newErr.model = v
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, nil
+}
diff --git a/vendor/gitee.com/openeuler/go-gitee/gitee/api_miscellaneous.go b/vendor/gitee.com/openeuler/go-gitee/gitee/api_miscellaneous.go
new file mode 100644
index 0000000000000000000000000000000000000000..e96caead7f65ee18e269e305ed24e529713df8c2
--- /dev/null
+++ b/vendor/gitee.com/openeuler/go-gitee/gitee/api_miscellaneous.go
@@ -0,0 +1,735 @@
+/*
+ * 码云 Open API
+ *
+ * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen)
+ *
+ * API version: 5.3.2
+ * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
+ */
+
+package gitee
+
+import (
+ "context"
+ "fmt"
+ "io/ioutil"
+ "net/http"
+ "net/url"
+ "strings"
+
+ "github.com/antihax/optional"
+)
+
+// Linger please
+var (
+ _ context.Context
+)
+
+type MiscellaneousApiService service
+
+/*
+MiscellaneousApiService 列出可使用的 Emoji
+列出可使用的 Emoji
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param optional nil or *GetV5EmojisOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+
+
+*/
+
+type GetV5EmojisOpts struct {
+ AccessToken optional.String
+}
+
+func (a *MiscellaneousApiService) GetV5Emojis(ctx context.Context, localVarOptionals *GetV5EmojisOpts) (*http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Get")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/emojis"
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarQueryParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ return localVarHttpResponse, newErr
+ }
+
+ return localVarHttpResponse, nil
+}
+
+/*
+MiscellaneousApiService 列出可使用的 .gitignore 模板
+列出可使用的 .gitignore 模板
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param optional nil or *GetV5GitignoreTemplatesOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+
+
+*/
+
+type GetV5GitignoreTemplatesOpts struct {
+ AccessToken optional.String
+}
+
+func (a *MiscellaneousApiService) GetV5GitignoreTemplates(ctx context.Context, localVarOptionals *GetV5GitignoreTemplatesOpts) (*http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Get")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/gitignore/templates"
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarQueryParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ return localVarHttpResponse, newErr
+ }
+
+ return localVarHttpResponse, nil
+}
+
+/*
+MiscellaneousApiService 获取一个 .gitignore 模板
+获取一个 .gitignore 模板
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param name .gitignore 模板名
+ * @param optional nil or *GetV5GitignoreTemplatesNameOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+
+
+*/
+
+type GetV5GitignoreTemplatesNameOpts struct {
+ AccessToken optional.String
+}
+
+func (a *MiscellaneousApiService) GetV5GitignoreTemplatesName(ctx context.Context, name string, localVarOptionals *GetV5GitignoreTemplatesNameOpts) (*http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Get")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/gitignore/templates/{name}"
+ localVarPath = strings.Replace(localVarPath, "{"+"name"+"}", fmt.Sprintf("%v", name), -1)
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarQueryParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ return localVarHttpResponse, newErr
+ }
+
+ return localVarHttpResponse, nil
+}
+
+/*
+MiscellaneousApiService 获取一个 .gitignore 模板原始文件
+获取一个 .gitignore 模板原始文件
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param name .gitignore 模板名
+ * @param optional nil or *GetV5GitignoreTemplatesNameRawOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+
+
+*/
+
+type GetV5GitignoreTemplatesNameRawOpts struct {
+ AccessToken optional.String
+}
+
+func (a *MiscellaneousApiService) GetV5GitignoreTemplatesNameRaw(ctx context.Context, name string, localVarOptionals *GetV5GitignoreTemplatesNameRawOpts) (*http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Get")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/gitignore/templates/{name}/raw"
+ localVarPath = strings.Replace(localVarPath, "{"+"name"+"}", fmt.Sprintf("%v", name), -1)
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarQueryParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ return localVarHttpResponse, newErr
+ }
+
+ return localVarHttpResponse, nil
+}
+
+/*
+MiscellaneousApiService 列出可使用的开源许可协议
+列出可使用的开源许可协议
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param optional nil or *GetV5LicensesOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+
+
+*/
+
+type GetV5LicensesOpts struct {
+ AccessToken optional.String
+}
+
+func (a *MiscellaneousApiService) GetV5Licenses(ctx context.Context, localVarOptionals *GetV5LicensesOpts) (*http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Get")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/licenses"
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarQueryParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ return localVarHttpResponse, newErr
+ }
+
+ return localVarHttpResponse, nil
+}
+
+/*
+MiscellaneousApiService 获取一个开源许可协议
+获取一个开源许可协议
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param license 协议名称
+ * @param optional nil or *GetV5LicensesLicenseOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+
+
+*/
+
+type GetV5LicensesLicenseOpts struct {
+ AccessToken optional.String
+}
+
+func (a *MiscellaneousApiService) GetV5LicensesLicense(ctx context.Context, license string, localVarOptionals *GetV5LicensesLicenseOpts) (*http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Get")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/licenses/{license}"
+ localVarPath = strings.Replace(localVarPath, "{"+"license"+"}", fmt.Sprintf("%v", license), -1)
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarQueryParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ return localVarHttpResponse, newErr
+ }
+
+ return localVarHttpResponse, nil
+}
+
+/*
+MiscellaneousApiService 获取一个开源许可协议原始文件
+获取一个开源许可协议原始文件
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param license 协议名称
+ * @param optional nil or *GetV5LicensesLicenseRawOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+
+
+*/
+
+type GetV5LicensesLicenseRawOpts struct {
+ AccessToken optional.String
+}
+
+func (a *MiscellaneousApiService) GetV5LicensesLicenseRaw(ctx context.Context, license string, localVarOptionals *GetV5LicensesLicenseRawOpts) (*http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Get")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/licenses/{license}/raw"
+ localVarPath = strings.Replace(localVarPath, "{"+"license"+"}", fmt.Sprintf("%v", license), -1)
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarQueryParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ return localVarHttpResponse, newErr
+ }
+
+ return localVarHttpResponse, nil
+}
+
+/*
+MiscellaneousApiService 获取一个仓库使用的开源许可协议
+获取一个仓库使用的开源许可协议
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param owner 仓库所属空间地址(企业、组织或个人的地址path)
+ * @param repo 仓库路径(path)
+ * @param optional nil or *GetV5ReposOwnerRepoLicenseOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+
+
+*/
+
+type GetV5ReposOwnerRepoLicenseOpts struct {
+ AccessToken optional.String
+}
+
+func (a *MiscellaneousApiService) GetV5ReposOwnerRepoLicense(ctx context.Context, owner string, repo string, localVarOptionals *GetV5ReposOwnerRepoLicenseOpts) (*http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Get")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/repos/{owner}/{repo}/license"
+ localVarPath = strings.Replace(localVarPath, "{"+"owner"+"}", fmt.Sprintf("%v", owner), -1)
+ localVarPath = strings.Replace(localVarPath, "{"+"repo"+"}", fmt.Sprintf("%v", repo), -1)
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarQueryParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ return localVarHttpResponse, newErr
+ }
+
+ return localVarHttpResponse, nil
+}
+
+/*
+MiscellaneousApiService 渲染 Markdown 文本
+渲染 Markdown 文本
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param text Markdown 文本
+ * @param optional nil or *PostV5MarkdownOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+
+
+*/
+
+type PostV5MarkdownOpts struct {
+ AccessToken optional.String
+}
+
+func (a *MiscellaneousApiService) PostV5Markdown(ctx context.Context, text string, localVarOptionals *PostV5MarkdownOpts) (*http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Post")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/markdown"
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarFormParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ localVarFormParams.Add("text", parameterToString(text, ""))
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ return localVarHttpResponse, newErr
+ }
+
+ return localVarHttpResponse, nil
+}
diff --git a/vendor/gitee.com/openeuler/go-gitee/gitee/api_organizations.go b/vendor/gitee.com/openeuler/go-gitee/gitee/api_organizations.go
new file mode 100644
index 0000000000000000000000000000000000000000..6c74cb02712b066d247e872ff8b3b1d75bb6cded
--- /dev/null
+++ b/vendor/gitee.com/openeuler/go-gitee/gitee/api_organizations.go
@@ -0,0 +1,1374 @@
+/*
+ * 码云 Open API
+ *
+ * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen)
+ *
+ * API version: 5.3.2
+ * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
+ */
+
+package gitee
+
+import (
+ "context"
+ "fmt"
+ "io/ioutil"
+ "net/http"
+ "net/url"
+ "strings"
+
+ "github.com/antihax/optional"
+)
+
+// Linger please
+var (
+ _ context.Context
+)
+
+type OrganizationsApiService service
+
+/*
+OrganizationsApiService 移除授权用户所管理组织中的成员
+移除授权用户所管理组织中的成员
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param org 组织的路径(path/login)
+ * @param username 用户名(username/login)
+ * @param optional nil or *DeleteV5OrgsOrgMembershipsUsernameOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+
+
+*/
+
+type DeleteV5OrgsOrgMembershipsUsernameOpts struct {
+ AccessToken optional.String
+}
+
+func (a *OrganizationsApiService) DeleteV5OrgsOrgMembershipsUsername(ctx context.Context, org string, username string, localVarOptionals *DeleteV5OrgsOrgMembershipsUsernameOpts) (*http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Delete")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/orgs/{org}/memberships/{username}"
+ localVarPath = strings.Replace(localVarPath, "{"+"org"+"}", fmt.Sprintf("%v", org), -1)
+ localVarPath = strings.Replace(localVarPath, "{"+"username"+"}", fmt.Sprintf("%v", username), -1)
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarQueryParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ return localVarHttpResponse, newErr
+ }
+
+ return localVarHttpResponse, nil
+}
+
+/*
+OrganizationsApiService 退出一个组织
+退出一个组织
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param org 组织的路径(path/login)
+ * @param optional nil or *DeleteV5UserMembershipsOrgsOrgOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+
+
+*/
+
+type DeleteV5UserMembershipsOrgsOrgOpts struct {
+ AccessToken optional.String
+}
+
+func (a *OrganizationsApiService) DeleteV5UserMembershipsOrgsOrg(ctx context.Context, org string, localVarOptionals *DeleteV5UserMembershipsOrgsOrgOpts) (*http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Delete")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/user/memberships/orgs/{org}"
+ localVarPath = strings.Replace(localVarPath, "{"+"org"+"}", fmt.Sprintf("%v", org), -1)
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarQueryParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ return localVarHttpResponse, newErr
+ }
+
+ return localVarHttpResponse, nil
+}
+
+/*
+OrganizationsApiService 获取一个组织
+获取一个组织
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param org 组织的路径(path/login)
+ * @param optional nil or *GetV5OrgsOrgOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+
+@return Group
+*/
+
+type GetV5OrgsOrgOpts struct {
+ AccessToken optional.String
+}
+
+func (a *OrganizationsApiService) GetV5OrgsOrg(ctx context.Context, org string, localVarOptionals *GetV5OrgsOrgOpts) (Group, *http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Get")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ localVarReturnValue Group
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/orgs/{org}"
+ localVarPath = strings.Replace(localVarPath, "{"+"org"+"}", fmt.Sprintf("%v", org), -1)
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarQueryParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return localVarReturnValue, nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode < 300 {
+ // If we succeed, return the data, otherwise pass on to decode error.
+ err = a.client.decode(&localVarReturnValue, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ if localVarHttpResponse.StatusCode == 200 {
+ var v Group
+ err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err != nil {
+ newErr.error = err.Error()
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+ newErr.model = v
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, nil
+}
+
+/*
+OrganizationsApiService 列出一个组织的所有成员
+列出一个组织的所有成员
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param org 组织的路径(path/login)
+ * @param optional nil or *GetV5OrgsOrgMembersOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+ * @param "Page" (optional.Int32) - 当前的页码
+ * @param "PerPage" (optional.Int32) - 每页的数量,最大为 100
+ * @param "Role" (optional.String) - 根据角色筛选成员
+
+@return []UserBasic
+*/
+
+type GetV5OrgsOrgMembersOpts struct {
+ AccessToken optional.String
+ Page optional.Int32
+ PerPage optional.Int32
+ Role optional.String
+}
+
+func (a *OrganizationsApiService) GetV5OrgsOrgMembers(ctx context.Context, org string, localVarOptionals *GetV5OrgsOrgMembersOpts) ([]UserBasic, *http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Get")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ localVarReturnValue []UserBasic
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/orgs/{org}/members"
+ localVarPath = strings.Replace(localVarPath, "{"+"org"+"}", fmt.Sprintf("%v", org), -1)
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarQueryParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Page.IsSet() {
+ localVarQueryParams.Add("page", parameterToString(localVarOptionals.Page.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.PerPage.IsSet() {
+ localVarQueryParams.Add("per_page", parameterToString(localVarOptionals.PerPage.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Role.IsSet() {
+ localVarQueryParams.Add("role", parameterToString(localVarOptionals.Role.Value(), ""))
+ }
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return localVarReturnValue, nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode < 300 {
+ // If we succeed, return the data, otherwise pass on to decode error.
+ err = a.client.decode(&localVarReturnValue, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ if localVarHttpResponse.StatusCode == 200 {
+ var v []UserBasic
+ err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err != nil {
+ newErr.error = err.Error()
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+ newErr.model = v
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, nil
+}
+
+/*
+OrganizationsApiService 获取授权用户所属组织的一个成员
+获取授权用户所属组织的一个成员
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param org 组织的路径(path/login)
+ * @param username 用户名(username/login)
+ * @param optional nil or *GetV5OrgsOrgMembershipsUsernameOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+
+@return GroupMember
+*/
+
+type GetV5OrgsOrgMembershipsUsernameOpts struct {
+ AccessToken optional.String
+}
+
+func (a *OrganizationsApiService) GetV5OrgsOrgMembershipsUsername(ctx context.Context, org string, username string, localVarOptionals *GetV5OrgsOrgMembershipsUsernameOpts) (GroupMember, *http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Get")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ localVarReturnValue GroupMember
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/orgs/{org}/memberships/{username}"
+ localVarPath = strings.Replace(localVarPath, "{"+"org"+"}", fmt.Sprintf("%v", org), -1)
+ localVarPath = strings.Replace(localVarPath, "{"+"username"+"}", fmt.Sprintf("%v", username), -1)
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarQueryParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return localVarReturnValue, nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode < 300 {
+ // If we succeed, return the data, otherwise pass on to decode error.
+ err = a.client.decode(&localVarReturnValue, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ if localVarHttpResponse.StatusCode == 200 {
+ var v GroupMember
+ err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err != nil {
+ newErr.error = err.Error()
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+ newErr.model = v
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, nil
+}
+
+/*
+OrganizationsApiService 列出授权用户在所属组织的成员资料
+列出授权用户在所属组织的成员资料
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param optional nil or *GetV5UserMembershipsOrgsOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+ * @param "Active" (optional.Bool) - 根据成员是否已激活进行筛选资料,缺省返回所有资料
+ * @param "Page" (optional.Int32) - 当前的页码
+ * @param "PerPage" (optional.Int32) - 每页的数量,最大为 100
+
+@return []GroupMember
+*/
+
+type GetV5UserMembershipsOrgsOpts struct {
+ AccessToken optional.String
+ Active optional.Bool
+ Page optional.Int32
+ PerPage optional.Int32
+}
+
+func (a *OrganizationsApiService) GetV5UserMembershipsOrgs(ctx context.Context, localVarOptionals *GetV5UserMembershipsOrgsOpts) ([]GroupMember, *http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Get")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ localVarReturnValue []GroupMember
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/user/memberships/orgs"
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarQueryParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Active.IsSet() {
+ localVarQueryParams.Add("active", parameterToString(localVarOptionals.Active.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Page.IsSet() {
+ localVarQueryParams.Add("page", parameterToString(localVarOptionals.Page.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.PerPage.IsSet() {
+ localVarQueryParams.Add("per_page", parameterToString(localVarOptionals.PerPage.Value(), ""))
+ }
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return localVarReturnValue, nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode < 300 {
+ // If we succeed, return the data, otherwise pass on to decode error.
+ err = a.client.decode(&localVarReturnValue, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ if localVarHttpResponse.StatusCode == 200 {
+ var v []GroupMember
+ err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err != nil {
+ newErr.error = err.Error()
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+ newErr.model = v
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, nil
+}
+
+/*
+OrganizationsApiService 获取授权用户在一个组织的成员资料
+获取授权用户在一个组织的成员资料
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param org 组织的路径(path/login)
+ * @param optional nil or *GetV5UserMembershipsOrgsOrgOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+
+@return GroupMember
+*/
+
+type GetV5UserMembershipsOrgsOrgOpts struct {
+ AccessToken optional.String
+}
+
+func (a *OrganizationsApiService) GetV5UserMembershipsOrgsOrg(ctx context.Context, org string, localVarOptionals *GetV5UserMembershipsOrgsOrgOpts) (GroupMember, *http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Get")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ localVarReturnValue GroupMember
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/user/memberships/orgs/{org}"
+ localVarPath = strings.Replace(localVarPath, "{"+"org"+"}", fmt.Sprintf("%v", org), -1)
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarQueryParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return localVarReturnValue, nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode < 300 {
+ // If we succeed, return the data, otherwise pass on to decode error.
+ err = a.client.decode(&localVarReturnValue, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ if localVarHttpResponse.StatusCode == 200 {
+ var v GroupMember
+ err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err != nil {
+ newErr.error = err.Error()
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+ newErr.model = v
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, nil
+}
+
+/*
+OrganizationsApiService 列出授权用户所属的组织
+列出授权用户所属的组织
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param optional nil or *GetV5UserOrgsOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+ * @param "Page" (optional.Int32) - 当前的页码
+ * @param "PerPage" (optional.Int32) - 每页的数量,最大为 100
+ * @param "Admin" (optional.Bool) - 只列出授权用户管理的组织
+
+@return []Group
+*/
+
+type GetV5UserOrgsOpts struct {
+ AccessToken optional.String
+ Page optional.Int32
+ PerPage optional.Int32
+ Admin optional.Bool
+}
+
+func (a *OrganizationsApiService) GetV5UserOrgs(ctx context.Context, localVarOptionals *GetV5UserOrgsOpts) ([]Group, *http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Get")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ localVarReturnValue []Group
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/user/orgs"
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarQueryParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Page.IsSet() {
+ localVarQueryParams.Add("page", parameterToString(localVarOptionals.Page.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.PerPage.IsSet() {
+ localVarQueryParams.Add("per_page", parameterToString(localVarOptionals.PerPage.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Admin.IsSet() {
+ localVarQueryParams.Add("admin", parameterToString(localVarOptionals.Admin.Value(), ""))
+ }
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return localVarReturnValue, nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode < 300 {
+ // If we succeed, return the data, otherwise pass on to decode error.
+ err = a.client.decode(&localVarReturnValue, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ if localVarHttpResponse.StatusCode == 200 {
+ var v []Group
+ err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err != nil {
+ newErr.error = err.Error()
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+ newErr.model = v
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, nil
+}
+
+/*
+OrganizationsApiService 列出用户所属的组织
+列出用户所属的组织
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param username 用户名(username/login)
+ * @param optional nil or *GetV5UsersUsernameOrgsOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+ * @param "Page" (optional.Int32) - 当前的页码
+ * @param "PerPage" (optional.Int32) - 每页的数量,最大为 100
+
+@return []Group
+*/
+
+type GetV5UsersUsernameOrgsOpts struct {
+ AccessToken optional.String
+ Page optional.Int32
+ PerPage optional.Int32
+}
+
+func (a *OrganizationsApiService) GetV5UsersUsernameOrgs(ctx context.Context, username string, localVarOptionals *GetV5UsersUsernameOrgsOpts) ([]Group, *http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Get")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ localVarReturnValue []Group
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/users/{username}/orgs"
+ localVarPath = strings.Replace(localVarPath, "{"+"username"+"}", fmt.Sprintf("%v", username), -1)
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarQueryParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Page.IsSet() {
+ localVarQueryParams.Add("page", parameterToString(localVarOptionals.Page.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.PerPage.IsSet() {
+ localVarQueryParams.Add("per_page", parameterToString(localVarOptionals.PerPage.Value(), ""))
+ }
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return localVarReturnValue, nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode < 300 {
+ // If we succeed, return the data, otherwise pass on to decode error.
+ err = a.client.decode(&localVarReturnValue, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ if localVarHttpResponse.StatusCode == 200 {
+ var v []Group
+ err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err != nil {
+ newErr.error = err.Error()
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+ newErr.model = v
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, nil
+}
+
+/*
+OrganizationsApiService 更新授权用户所管理的组织资料
+更新授权用户所管理的组织资料
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param org 组织的路径(path/login)
+ * @param optional nil or *PatchV5OrgsOrgOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+ * @param "Email" (optional.String) - 组织公开的邮箱地址
+ * @param "Location" (optional.String) - 组织所在地
+ * @param "Name" (optional.String) - 组织名称
+ * @param "Description" (optional.String) - 组织简介
+ * @param "HtmlUrl" (optional.String) - 组织站点
+
+@return GroupDetail
+*/
+
+type PatchV5OrgsOrgOpts struct {
+ AccessToken optional.String
+ Email optional.String
+ Location optional.String
+ Name optional.String
+ Description optional.String
+ HtmlUrl optional.String
+}
+
+func (a *OrganizationsApiService) PatchV5OrgsOrg(ctx context.Context, org string, localVarOptionals *PatchV5OrgsOrgOpts) (GroupDetail, *http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Patch")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ localVarReturnValue GroupDetail
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/orgs/{org}"
+ localVarPath = strings.Replace(localVarPath, "{"+"org"+"}", fmt.Sprintf("%v", org), -1)
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarFormParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Email.IsSet() {
+ localVarFormParams.Add("email", parameterToString(localVarOptionals.Email.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Location.IsSet() {
+ localVarFormParams.Add("location", parameterToString(localVarOptionals.Location.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Name.IsSet() {
+ localVarFormParams.Add("name", parameterToString(localVarOptionals.Name.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Description.IsSet() {
+ localVarFormParams.Add("description", parameterToString(localVarOptionals.Description.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.HtmlUrl.IsSet() {
+ localVarFormParams.Add("html_url", parameterToString(localVarOptionals.HtmlUrl.Value(), ""))
+ }
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return localVarReturnValue, nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode < 300 {
+ // If we succeed, return the data, otherwise pass on to decode error.
+ err = a.client.decode(&localVarReturnValue, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ if localVarHttpResponse.StatusCode == 200 {
+ var v GroupDetail
+ err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err != nil {
+ newErr.error = err.Error()
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+ newErr.model = v
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, nil
+}
+
+/*
+OrganizationsApiService 更新授权用户在一个组织的成员资料
+更新授权用户在一个组织的成员资料
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param org 组织的路径(path/login)
+ * @param optional nil or *PatchV5UserMembershipsOrgsOrgOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+ * @param "Remark" (optional.String) - 在组织中的备注信息
+
+@return GroupMember
+*/
+
+type PatchV5UserMembershipsOrgsOrgOpts struct {
+ AccessToken optional.String
+ Remark optional.String
+}
+
+func (a *OrganizationsApiService) PatchV5UserMembershipsOrgsOrg(ctx context.Context, org string, localVarOptionals *PatchV5UserMembershipsOrgsOrgOpts) (GroupMember, *http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Patch")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ localVarReturnValue GroupMember
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/user/memberships/orgs/{org}"
+ localVarPath = strings.Replace(localVarPath, "{"+"org"+"}", fmt.Sprintf("%v", org), -1)
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarFormParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Remark.IsSet() {
+ localVarFormParams.Add("remark", parameterToString(localVarOptionals.Remark.Value(), ""))
+ }
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return localVarReturnValue, nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode < 300 {
+ // If we succeed, return the data, otherwise pass on to decode error.
+ err = a.client.decode(&localVarReturnValue, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ if localVarHttpResponse.StatusCode == 200 {
+ var v GroupMember
+ err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err != nil {
+ newErr.error = err.Error()
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+ newErr.model = v
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, nil
+}
+
+/*
+OrganizationsApiService 创建组织
+创建组织
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param name 组织名称
+ * @param org 组织的路径(path/login)
+ * @param optional nil or *PostV5UsersOrganizationOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+ * @param "Description" (optional.String) - 组织描述
+
+@return Group
+*/
+
+type PostV5UsersOrganizationOpts struct {
+ AccessToken optional.String
+ Description optional.String
+}
+
+func (a *OrganizationsApiService) PostV5UsersOrganization(ctx context.Context, name string, org string, localVarOptionals *PostV5UsersOrganizationOpts) (Group, *http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Post")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ localVarReturnValue Group
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/users/organization"
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarFormParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ localVarFormParams.Add("name", parameterToString(name, ""))
+ localVarFormParams.Add("org", parameterToString(org, ""))
+ if localVarOptionals != nil && localVarOptionals.Description.IsSet() {
+ localVarFormParams.Add("description", parameterToString(localVarOptionals.Description.Value(), ""))
+ }
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return localVarReturnValue, nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode < 300 {
+ // If we succeed, return the data, otherwise pass on to decode error.
+ err = a.client.decode(&localVarReturnValue, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ if localVarHttpResponse.StatusCode == 201 {
+ var v Group
+ err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err != nil {
+ newErr.error = err.Error()
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+ newErr.model = v
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, nil
+}
+
+/*
+OrganizationsApiService 增加或更新授权用户所管理组织的成员
+增加或更新授权用户所管理组织的成员
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param org 组织的路径(path/login)
+ * @param username 用户名(username/login)
+ * @param optional nil or *PutV5OrgsOrgMembershipsUsernameOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+ * @param "Role" (optional.String) - 设置用户在组织的角色
+
+@return GroupMember
+*/
+
+type PutV5OrgsOrgMembershipsUsernameOpts struct {
+ AccessToken optional.String
+ Role optional.String
+}
+
+func (a *OrganizationsApiService) PutV5OrgsOrgMembershipsUsername(ctx context.Context, org string, username string, localVarOptionals *PutV5OrgsOrgMembershipsUsernameOpts) (GroupMember, *http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Put")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ localVarReturnValue GroupMember
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/orgs/{org}/memberships/{username}"
+ localVarPath = strings.Replace(localVarPath, "{"+"org"+"}", fmt.Sprintf("%v", org), -1)
+ localVarPath = strings.Replace(localVarPath, "{"+"username"+"}", fmt.Sprintf("%v", username), -1)
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarFormParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Role.IsSet() {
+ localVarFormParams.Add("role", parameterToString(localVarOptionals.Role.Value(), ""))
+ }
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return localVarReturnValue, nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode < 300 {
+ // If we succeed, return the data, otherwise pass on to decode error.
+ err = a.client.decode(&localVarReturnValue, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ if localVarHttpResponse.StatusCode == 200 {
+ var v GroupMember
+ err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err != nil {
+ newErr.error = err.Error()
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+ newErr.model = v
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, nil
+}
diff --git a/vendor/gitee.com/openeuler/go-gitee/gitee/api_pull_requests.go b/vendor/gitee.com/openeuler/go-gitee/gitee/api_pull_requests.go
new file mode 100644
index 0000000000000000000000000000000000000000..8eb1c324189f17ff9a1a9501fb30b5ddb2081504
--- /dev/null
+++ b/vendor/gitee.com/openeuler/go-gitee/gitee/api_pull_requests.go
@@ -0,0 +1,2033 @@
+/*
+ * 码云 Open API
+ *
+ * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen)
+ *
+ * API version: 5.3.2
+ * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
+ */
+
+package gitee
+
+import (
+ "context"
+ "fmt"
+ "github.com/antihax/optional"
+ "io/ioutil"
+ "net/http"
+ "net/url"
+ "strings"
+)
+
+// Linger please
+var (
+ _ context.Context
+)
+
+type PullRequestsApiService service
+
+/*
+PullRequestsApiService 删除评论
+删除评论
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param owner 仓库所属空间地址(企业、组织或个人的地址path)
+ * @param repo 仓库路径(path)
+ * @param id 评论的ID
+ * @param optional nil or *DeleteV5ReposOwnerRepoPullsCommentsIdOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+
+
+*/
+
+type DeleteV5ReposOwnerRepoPullsCommentsIdOpts struct {
+ AccessToken optional.String
+}
+
+func (a *PullRequestsApiService) DeleteV5ReposOwnerRepoPullsCommentsId(ctx context.Context, owner string, repo string, id int32, localVarOptionals *DeleteV5ReposOwnerRepoPullsCommentsIdOpts) (*http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Delete")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/repos/{owner}/{repo}/pulls/comments/{id}"
+ localVarPath = strings.Replace(localVarPath, "{"+"owner"+"}", fmt.Sprintf("%v", owner), -1)
+ localVarPath = strings.Replace(localVarPath, "{"+"repo"+"}", fmt.Sprintf("%v", repo), -1)
+ localVarPath = strings.Replace(localVarPath, "{"+"id"+"}", fmt.Sprintf("%v", id), -1)
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarQueryParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ return localVarHttpResponse, newErr
+ }
+
+ return localVarHttpResponse, nil
+}
+
+/*
+PullRequestsApiService 取消用户审查 Pull Request
+取消用户审查 Pull Request
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param owner 仓库所属空间地址(企业、组织或个人的地址path)
+ * @param repo 仓库路径(path)
+ * @param number 第几个PR,即本仓库PR的序数
+ * @param assignees 用户的个人空间地址, 以 , 分隔
+ * @param optional nil or *DeleteV5ReposOwnerRepoPullsNumberAssigneesOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+
+@return PullRequest
+*/
+
+type DeleteV5ReposOwnerRepoPullsNumberAssigneesOpts struct {
+ AccessToken optional.String
+}
+
+func (a *PullRequestsApiService) DeleteV5ReposOwnerRepoPullsNumberAssignees(ctx context.Context, owner string, repo string, number int32, assignees string, localVarOptionals *DeleteV5ReposOwnerRepoPullsNumberAssigneesOpts) (PullRequest, *http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Delete")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ localVarReturnValue PullRequest
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/repos/{owner}/{repo}/pulls/{number}/assignees"
+ localVarPath = strings.Replace(localVarPath, "{"+"owner"+"}", fmt.Sprintf("%v", owner), -1)
+ localVarPath = strings.Replace(localVarPath, "{"+"repo"+"}", fmt.Sprintf("%v", repo), -1)
+ localVarPath = strings.Replace(localVarPath, "{"+"number"+"}", fmt.Sprintf("%v", number), -1)
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarQueryParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ localVarQueryParams.Add("assignees", parameterToString(assignees, ""))
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return localVarReturnValue, nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode < 300 {
+ // If we succeed, return the data, otherwise pass on to decode error.
+ err = a.client.decode(&localVarReturnValue, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ if localVarHttpResponse.StatusCode == 200 {
+ var v PullRequest
+ err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err != nil {
+ newErr.error = err.Error()
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+ newErr.model = v
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, nil
+}
+
+/*
+PullRequestsApiService 取消用户测试 Pull Request
+取消用户测试 Pull Request
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param owner 仓库所属空间地址(企业、组织或个人的地址path)
+ * @param repo 仓库路径(path)
+ * @param number 第几个PR,即本仓库PR的序数
+ * @param testers 用户的个人空间地址, 以 , 分隔
+ * @param optional nil or *DeleteV5ReposOwnerRepoPullsNumberTestersOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+
+@return PullRequest
+*/
+
+type DeleteV5ReposOwnerRepoPullsNumberTestersOpts struct {
+ AccessToken optional.String
+}
+
+func (a *PullRequestsApiService) DeleteV5ReposOwnerRepoPullsNumberTesters(ctx context.Context, owner string, repo string, number int32, testers string, localVarOptionals *DeleteV5ReposOwnerRepoPullsNumberTestersOpts) (PullRequest, *http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Delete")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ localVarReturnValue PullRequest
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/repos/{owner}/{repo}/pulls/{number}/testers"
+ localVarPath = strings.Replace(localVarPath, "{"+"owner"+"}", fmt.Sprintf("%v", owner), -1)
+ localVarPath = strings.Replace(localVarPath, "{"+"repo"+"}", fmt.Sprintf("%v", repo), -1)
+ localVarPath = strings.Replace(localVarPath, "{"+"number"+"}", fmt.Sprintf("%v", number), -1)
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarQueryParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ localVarQueryParams.Add("testers", parameterToString(testers, ""))
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return localVarReturnValue, nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode < 300 {
+ // If we succeed, return the data, otherwise pass on to decode error.
+ err = a.client.decode(&localVarReturnValue, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ if localVarHttpResponse.StatusCode == 200 {
+ var v PullRequest
+ err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err != nil {
+ newErr.error = err.Error()
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+ newErr.model = v
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, nil
+}
+
+/*
+PullRequestsApiService 获取Pull Request列表
+获取Pull Request列表
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param owner 仓库所属空间地址(企业、组织或个人的地址path)
+ * @param repo 仓库路径(path)
+ * @param optional nil or *GetV5ReposOwnerRepoPullsOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+ * @param "State" (optional.String) - 可选。Pull Request 状态
+ * @param "Head" (optional.String) - 可选。Pull Request 提交的源分支。格式:branch 或者:username:branch
+ * @param "Base" (optional.String) - 可选。Pull Request 提交目标分支的名称。
+ * @param "Sort" (optional.String) - 可选。排序字段,默认按创建时间
+ * @param "Direction" (optional.String) - 可选。升序/降序
+ * @param "MilestoneNumber" (optional.Int32) - 可选。里程碑序号(id)
+ * @param "Labels" (optional.String) - 用逗号分开的标签。如: bug,performance
+ * @param "Page" (optional.Int32) - 当前的页码
+ * @param "PerPage" (optional.Int32) - 每页的数量,最大为 100
+
+@return []PullRequest
+*/
+
+type GetV5ReposOwnerRepoPullsOpts struct {
+ AccessToken optional.String
+ State optional.String
+ Head optional.String
+ Base optional.String
+ Sort optional.String
+ Direction optional.String
+ MilestoneNumber optional.Int32
+ Labels optional.String
+ Page optional.Int32
+ PerPage optional.Int32
+}
+
+func (a *PullRequestsApiService) GetV5ReposOwnerRepoPulls(ctx context.Context, owner string, repo string, localVarOptionals *GetV5ReposOwnerRepoPullsOpts) ([]PullRequest, *http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Get")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ localVarReturnValue []PullRequest
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/repos/{owner}/{repo}/pulls"
+ localVarPath = strings.Replace(localVarPath, "{"+"owner"+"}", fmt.Sprintf("%v", owner), -1)
+ localVarPath = strings.Replace(localVarPath, "{"+"repo"+"}", fmt.Sprintf("%v", repo), -1)
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarQueryParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.State.IsSet() {
+ localVarQueryParams.Add("state", parameterToString(localVarOptionals.State.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Head.IsSet() {
+ localVarQueryParams.Add("head", parameterToString(localVarOptionals.Head.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Base.IsSet() {
+ localVarQueryParams.Add("base", parameterToString(localVarOptionals.Base.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Sort.IsSet() {
+ localVarQueryParams.Add("sort", parameterToString(localVarOptionals.Sort.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Direction.IsSet() {
+ localVarQueryParams.Add("direction", parameterToString(localVarOptionals.Direction.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.MilestoneNumber.IsSet() {
+ localVarQueryParams.Add("milestone_number", parameterToString(localVarOptionals.MilestoneNumber.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Labels.IsSet() {
+ localVarQueryParams.Add("labels", parameterToString(localVarOptionals.Labels.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Page.IsSet() {
+ localVarQueryParams.Add("page", parameterToString(localVarOptionals.Page.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.PerPage.IsSet() {
+ localVarQueryParams.Add("per_page", parameterToString(localVarOptionals.PerPage.Value(), ""))
+ }
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return localVarReturnValue, nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode < 300 {
+ // If we succeed, return the data, otherwise pass on to decode error.
+ err = a.client.decode(&localVarReturnValue, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ if localVarHttpResponse.StatusCode == 200 {
+ var v []PullRequest
+ err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err != nil {
+ newErr.error = err.Error()
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+ newErr.model = v
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, nil
+}
+
+/*
+PullRequestsApiService 获取该仓库下的所有Pull Request评论
+获取该仓库下的所有Pull Request评论
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param owner 仓库所属空间地址(企业、组织或个人的地址path)
+ * @param repo 仓库路径(path)
+ * @param optional nil or *GetV5ReposOwnerRepoPullsCommentsOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+ * @param "Sort" (optional.String) - 可选。按创建时间/更新时间排序
+ * @param "Direction" (optional.String) - 可选。升序/降序
+ * @param "Since" (optional.String) - 起始的更新时间,要求时间格式为 ISO 8601
+ * @param "Page" (optional.Int32) - 当前的页码
+ * @param "PerPage" (optional.Int32) - 每页的数量,最大为 100
+
+@return []PullRequestComments
+*/
+
+type GetV5ReposOwnerRepoPullsCommentsOpts struct {
+ AccessToken optional.String
+ Sort optional.String
+ Direction optional.String
+ Since optional.String
+ Page optional.Int32
+ PerPage optional.Int32
+}
+
+func (a *PullRequestsApiService) GetV5ReposOwnerRepoPullsComments(ctx context.Context, owner string, repo string, localVarOptionals *GetV5ReposOwnerRepoPullsCommentsOpts) ([]PullRequestComments, *http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Get")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ localVarReturnValue []PullRequestComments
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/repos/{owner}/{repo}/pulls/comments"
+ localVarPath = strings.Replace(localVarPath, "{"+"owner"+"}", fmt.Sprintf("%v", owner), -1)
+ localVarPath = strings.Replace(localVarPath, "{"+"repo"+"}", fmt.Sprintf("%v", repo), -1)
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarQueryParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Sort.IsSet() {
+ localVarQueryParams.Add("sort", parameterToString(localVarOptionals.Sort.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Direction.IsSet() {
+ localVarQueryParams.Add("direction", parameterToString(localVarOptionals.Direction.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Since.IsSet() {
+ localVarQueryParams.Add("since", parameterToString(localVarOptionals.Since.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Page.IsSet() {
+ localVarQueryParams.Add("page", parameterToString(localVarOptionals.Page.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.PerPage.IsSet() {
+ localVarQueryParams.Add("per_page", parameterToString(localVarOptionals.PerPage.Value(), ""))
+ }
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return localVarReturnValue, nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode < 300 {
+ // If we succeed, return the data, otherwise pass on to decode error.
+ err = a.client.decode(&localVarReturnValue, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ if localVarHttpResponse.StatusCode == 200 {
+ var v []PullRequestComments
+ err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err != nil {
+ newErr.error = err.Error()
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+ newErr.model = v
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, nil
+}
+
+/*
+PullRequestsApiService 获取Pull Request的某个评论
+获取Pull Request的某个评论
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param owner 仓库所属空间地址(企业、组织或个人的地址path)
+ * @param repo 仓库路径(path)
+ * @param id
+ * @param optional nil or *GetV5ReposOwnerRepoPullsCommentsIdOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+
+@return PullRequestComments
+*/
+
+type GetV5ReposOwnerRepoPullsCommentsIdOpts struct {
+ AccessToken optional.String
+}
+
+func (a *PullRequestsApiService) GetV5ReposOwnerRepoPullsCommentsId(ctx context.Context, owner string, repo string, id int32, localVarOptionals *GetV5ReposOwnerRepoPullsCommentsIdOpts) (PullRequestComments, *http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Get")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ localVarReturnValue PullRequestComments
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/repos/{owner}/{repo}/pulls/comments/{id}"
+ localVarPath = strings.Replace(localVarPath, "{"+"owner"+"}", fmt.Sprintf("%v", owner), -1)
+ localVarPath = strings.Replace(localVarPath, "{"+"repo"+"}", fmt.Sprintf("%v", repo), -1)
+ localVarPath = strings.Replace(localVarPath, "{"+"id"+"}", fmt.Sprintf("%v", id), -1)
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarQueryParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return localVarReturnValue, nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode < 300 {
+ // If we succeed, return the data, otherwise pass on to decode error.
+ err = a.client.decode(&localVarReturnValue, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ if localVarHttpResponse.StatusCode == 200 {
+ var v PullRequestComments
+ err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err != nil {
+ newErr.error = err.Error()
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+ newErr.model = v
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, nil
+}
+
+/*
+PullRequestsApiService 获取单个Pull Request
+获取单个Pull Request
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param owner 仓库所属空间地址(企业、组织或个人的地址path)
+ * @param repo 仓库路径(path)
+ * @param number 第几个PR,即本仓库PR的序数
+ * @param optional nil or *GetV5ReposOwnerRepoPullsNumberOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+
+@return PullRequest
+*/
+
+type GetV5ReposOwnerRepoPullsNumberOpts struct {
+ AccessToken optional.String
+}
+
+func (a *PullRequestsApiService) GetV5ReposOwnerRepoPullsNumber(ctx context.Context, owner string, repo string, number int32, localVarOptionals *GetV5ReposOwnerRepoPullsNumberOpts) (PullRequest, *http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Get")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ localVarReturnValue PullRequest
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/repos/{owner}/{repo}/pulls/{number}"
+ localVarPath = strings.Replace(localVarPath, "{"+"owner"+"}", fmt.Sprintf("%v", owner), -1)
+ localVarPath = strings.Replace(localVarPath, "{"+"repo"+"}", fmt.Sprintf("%v", repo), -1)
+ localVarPath = strings.Replace(localVarPath, "{"+"number"+"}", fmt.Sprintf("%v", number), -1)
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarQueryParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return localVarReturnValue, nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode < 300 {
+ // If we succeed, return the data, otherwise pass on to decode error.
+ err = a.client.decode(&localVarReturnValue, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ if localVarHttpResponse.StatusCode == 200 {
+ var v PullRequest
+ err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err != nil {
+ newErr.error = err.Error()
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+ newErr.model = v
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, nil
+}
+
+/*
+PullRequestsApiService 获取某个Pull Request的所有评论
+获取某个Pull Request的所有评论
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param owner 仓库所属空间地址(企业、组织或个人的地址path)
+ * @param repo 仓库路径(path)
+ * @param number 第几个PR,即本仓库PR的序数
+ * @param optional nil or *GetV5ReposOwnerRepoPullsNumberCommentsOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+ * @param "Page" (optional.Int32) - 当前的页码
+ * @param "PerPage" (optional.Int32) - 每页的数量,最大为 100
+
+@return []PullRequestComments
+*/
+
+type GetV5ReposOwnerRepoPullsNumberCommentsOpts struct {
+ AccessToken optional.String
+ Page optional.Int32
+ PerPage optional.Int32
+}
+
+func (a *PullRequestsApiService) GetV5ReposOwnerRepoPullsNumberComments(ctx context.Context, owner string, repo string, number int32, localVarOptionals *GetV5ReposOwnerRepoPullsNumberCommentsOpts) ([]PullRequestComments, *http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Get")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ localVarReturnValue []PullRequestComments
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/repos/{owner}/{repo}/pulls/{number}/comments"
+ localVarPath = strings.Replace(localVarPath, "{"+"owner"+"}", fmt.Sprintf("%v", owner), -1)
+ localVarPath = strings.Replace(localVarPath, "{"+"repo"+"}", fmt.Sprintf("%v", repo), -1)
+ localVarPath = strings.Replace(localVarPath, "{"+"number"+"}", fmt.Sprintf("%v", number), -1)
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarQueryParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Page.IsSet() {
+ localVarQueryParams.Add("page", parameterToString(localVarOptionals.Page.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.PerPage.IsSet() {
+ localVarQueryParams.Add("per_page", parameterToString(localVarOptionals.PerPage.Value(), ""))
+ }
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return localVarReturnValue, nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode < 300 {
+ // If we succeed, return the data, otherwise pass on to decode error.
+ err = a.client.decode(&localVarReturnValue, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ if localVarHttpResponse.StatusCode == 200 {
+ var v []PullRequestComments
+ err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err != nil {
+ newErr.error = err.Error()
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+ newErr.model = v
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, nil
+}
+
+/*
+PullRequestsApiService 获取某Pull Request的所有Commit信息。最多显示250条Commit
+获取某Pull Request的所有Commit信息。最多显示250条Commit
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param owner 仓库所属空间地址(企业、组织或个人的地址path)
+ * @param repo 仓库路径(path)
+ * @param number 第几个PR,即本仓库PR的序数
+ * @param optional nil or *GetV5ReposOwnerRepoPullsNumberCommitsOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+
+@return []PullRequestCommits
+*/
+
+type GetV5ReposOwnerRepoPullsNumberCommitsOpts struct {
+ AccessToken optional.String
+}
+
+func (a *PullRequestsApiService) GetV5ReposOwnerRepoPullsNumberCommits(ctx context.Context, owner string, repo string, number int32, localVarOptionals *GetV5ReposOwnerRepoPullsNumberCommitsOpts) ([]PullRequestCommits, *http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Get")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ localVarReturnValue []PullRequestCommits
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/repos/{owner}/{repo}/pulls/{number}/commits"
+ localVarPath = strings.Replace(localVarPath, "{"+"owner"+"}", fmt.Sprintf("%v", owner), -1)
+ localVarPath = strings.Replace(localVarPath, "{"+"repo"+"}", fmt.Sprintf("%v", repo), -1)
+ localVarPath = strings.Replace(localVarPath, "{"+"number"+"}", fmt.Sprintf("%v", number), -1)
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarQueryParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return localVarReturnValue, nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode < 300 {
+ // If we succeed, return the data, otherwise pass on to decode error.
+ err = a.client.decode(&localVarReturnValue, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ if localVarHttpResponse.StatusCode == 200 {
+ var v []PullRequestCommits
+ err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err != nil {
+ newErr.error = err.Error()
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+ newErr.model = v
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, nil
+}
+
+/*
+PullRequestsApiService Pull Request Commit文件列表。最多显示300条diff
+Pull Request Commit文件列表。最多显示300条diff
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param owner 仓库所属空间地址(企业、组织或个人的地址path)
+ * @param repo 仓库路径(path)
+ * @param number 第几个PR,即本仓库PR的序数
+ * @param optional nil or *GetV5ReposOwnerRepoPullsNumberFilesOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+
+@return []PullRequestFiles
+*/
+
+type GetV5ReposOwnerRepoPullsNumberFilesOpts struct {
+ AccessToken optional.String
+}
+
+func (a *PullRequestsApiService) GetV5ReposOwnerRepoPullsNumberFiles(ctx context.Context, owner string, repo string, number int32, localVarOptionals *GetV5ReposOwnerRepoPullsNumberFilesOpts) ([]PullRequestFiles, *http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Get")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ localVarReturnValue []PullRequestFiles
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/repos/{owner}/{repo}/pulls/{number}/files"
+ localVarPath = strings.Replace(localVarPath, "{"+"owner"+"}", fmt.Sprintf("%v", owner), -1)
+ localVarPath = strings.Replace(localVarPath, "{"+"repo"+"}", fmt.Sprintf("%v", repo), -1)
+ localVarPath = strings.Replace(localVarPath, "{"+"number"+"}", fmt.Sprintf("%v", number), -1)
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarQueryParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return localVarReturnValue, nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode < 300 {
+ // If we succeed, return the data, otherwise pass on to decode error.
+ err = a.client.decode(&localVarReturnValue, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ if localVarHttpResponse.StatusCode == 200 {
+ var v []PullRequestFiles
+ err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err != nil {
+ newErr.error = err.Error()
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+ newErr.model = v
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, nil
+}
+
+/*
+PullRequestsApiService 判断Pull Request是否已经合并
+判断Pull Request是否已经合并
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param owner 仓库所属空间地址(企业、组织或个人的地址path)
+ * @param repo 仓库路径(path)
+ * @param number 第几个PR,即本仓库PR的序数
+ * @param optional nil or *GetV5ReposOwnerRepoPullsNumberMergeOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+
+
+*/
+
+type GetV5ReposOwnerRepoPullsNumberMergeOpts struct {
+ AccessToken optional.String
+}
+
+func (a *PullRequestsApiService) GetV5ReposOwnerRepoPullsNumberMerge(ctx context.Context, owner string, repo string, number int32, localVarOptionals *GetV5ReposOwnerRepoPullsNumberMergeOpts) (*http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Get")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/repos/{owner}/{repo}/pulls/{number}/merge"
+ localVarPath = strings.Replace(localVarPath, "{"+"owner"+"}", fmt.Sprintf("%v", owner), -1)
+ localVarPath = strings.Replace(localVarPath, "{"+"repo"+"}", fmt.Sprintf("%v", repo), -1)
+ localVarPath = strings.Replace(localVarPath, "{"+"number"+"}", fmt.Sprintf("%v", number), -1)
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarQueryParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ return localVarHttpResponse, newErr
+ }
+
+ return localVarHttpResponse, nil
+}
+
+/*
+PullRequestsApiService 获取某个Pull Request的操作日志
+获取某个Pull Request的操作日志
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param owner 仓库所属空间地址(企业、组织或个人的地址path)
+ * @param repo 仓库路径(path)
+ * @param number 第几个PR,即本仓库PR的序数
+ * @param optional nil or *GetV5ReposOwnerRepoPullsNumberOperateLogsOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+ * @param "Sort" (optional.String) - 按递增(asc)或递减(desc)排序,默认:递减
+
+@return OperateLog
+*/
+
+type GetV5ReposOwnerRepoPullsNumberOperateLogsOpts struct {
+ AccessToken optional.String
+ Sort optional.String
+}
+
+func (a *PullRequestsApiService) GetV5ReposOwnerRepoPullsNumberOperateLogs(ctx context.Context, owner string, repo string, number int32, localVarOptionals *GetV5ReposOwnerRepoPullsNumberOperateLogsOpts) (OperateLog, *http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Get")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ localVarReturnValue OperateLog
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/repos/{owner}/{repo}/pulls/{number}/operate_logs"
+ localVarPath = strings.Replace(localVarPath, "{"+"owner"+"}", fmt.Sprintf("%v", owner), -1)
+ localVarPath = strings.Replace(localVarPath, "{"+"repo"+"}", fmt.Sprintf("%v", repo), -1)
+ localVarPath = strings.Replace(localVarPath, "{"+"number"+"}", fmt.Sprintf("%v", number), -1)
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarQueryParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Sort.IsSet() {
+ localVarQueryParams.Add("sort", parameterToString(localVarOptionals.Sort.Value(), ""))
+ }
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return localVarReturnValue, nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode < 300 {
+ // If we succeed, return the data, otherwise pass on to decode error.
+ err = a.client.decode(&localVarReturnValue, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ if localVarHttpResponse.StatusCode == 200 {
+ var v OperateLog
+ err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err != nil {
+ newErr.error = err.Error()
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+ newErr.model = v
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, nil
+}
+
+/*
+PullRequestsApiService 编辑评论
+编辑评论
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param owner 仓库所属空间地址(企业、组织或个人的地址path)
+ * @param repo 仓库路径(path)
+ * @param id 评论的ID
+ * @param body 必填。评论内容
+ * @param optional nil or *PatchV5ReposOwnerRepoPullsCommentsIdOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+
+@return PullRequestComments
+*/
+
+type PatchV5ReposOwnerRepoPullsCommentsIdOpts struct {
+ AccessToken optional.String
+}
+
+func (a *PullRequestsApiService) PatchV5ReposOwnerRepoPullsCommentsId(ctx context.Context, owner string, repo string, id int32, body string, localVarOptionals *PatchV5ReposOwnerRepoPullsCommentsIdOpts) (PullRequestComments, *http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Patch")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ localVarReturnValue PullRequestComments
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/repos/{owner}/{repo}/pulls/comments/{id}"
+ localVarPath = strings.Replace(localVarPath, "{"+"owner"+"}", fmt.Sprintf("%v", owner), -1)
+ localVarPath = strings.Replace(localVarPath, "{"+"repo"+"}", fmt.Sprintf("%v", repo), -1)
+ localVarPath = strings.Replace(localVarPath, "{"+"id"+"}", fmt.Sprintf("%v", id), -1)
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarFormParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ localVarFormParams.Add("body", parameterToString(body, ""))
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return localVarReturnValue, nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode < 300 {
+ // If we succeed, return the data, otherwise pass on to decode error.
+ err = a.client.decode(&localVarReturnValue, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ if localVarHttpResponse.StatusCode == 200 {
+ var v PullRequestComments
+ err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err != nil {
+ newErr.error = err.Error()
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+ newErr.model = v
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, nil
+}
+
+/*
+PullRequestsApiService 更新Pull Request信息
+更新Pull Request信息
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param owner 仓库所属空间地址(企业、组织或个人的地址path)
+ * @param repo 仓库路径(path)
+ * @param number 第几个PR,即本仓库PR的序数
+ * @param body 可选。Pull Request 内容
+
+@return PullRequest
+*/
+func (a *PullRequestsApiService) PatchV5ReposOwnerRepoPullsNumber(ctx context.Context, owner string, repo string, number int32, body PullRequestUpdateParam) (PullRequest, *http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Patch")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ localVarReturnValue PullRequest
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/repos/{owner}/{repo}/pulls/{number}"
+ localVarPath = strings.Replace(localVarPath, "{"+"owner"+"}", fmt.Sprintf("%v", owner), -1)
+ localVarPath = strings.Replace(localVarPath, "{"+"repo"+"}", fmt.Sprintf("%v", repo), -1)
+ localVarPath = strings.Replace(localVarPath, "{"+"number"+"}", fmt.Sprintf("%v", number), -1)
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ // body params
+ localVarPostBody = &body
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return localVarReturnValue, nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode < 300 {
+ // If we succeed, return the data, otherwise pass on to decode error.
+ err = a.client.decode(&localVarReturnValue, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ if localVarHttpResponse.StatusCode == 200 {
+ var v PullRequest
+ err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err != nil {
+ newErr.error = err.Error()
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+ newErr.model = v
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, nil
+}
+
+/*
+PullRequestsApiService 创建Pull Request
+创建Pull Request
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param owner 仓库所属空间地址(企业、组织或个人的地址path)
+ * @param repo 仓库路径(path)
+ * @param title 必填。Pull Request 标题
+ * @param head 必填。Pull Request 提交的源分支。格式:branch 或者:username:branch
+ * @param base 必填。Pull Request 提交目标分支的名称
+ * @param optional nil or *PostV5ReposOwnerRepoPullsOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+ * @param "Body" (optional.String) - 可选。Pull Request 内容
+ * @param "MilestoneNumber" (optional.Int32) - 可选。里程碑序号(id)
+ * @param "Labels" (optional.String) - 用逗号分开的标签,名称要求长度在 2-20 之间且非特殊字符。如: bug,performance
+ * @param "Issue" (optional.String) - 可选。Pull Request的标题和内容可以根据指定的Issue Id自动填充
+ * @param "Assignees" (optional.String) - 可选。审查人员username,可多个,半角逗号分隔,如:(username1,username2)
+ * @param "Testers" (optional.String) - 可选。测试人员username,可多个,半角逗号分隔,如:(username1,username2)
+ * @param "PruneSourceBranch" (optional.Bool) - 可选。合并PR后是否删除源分支,默认false(不删除)
+
+@return PullRequest
+*/
+
+type PostV5ReposOwnerRepoPullsOpts struct {
+ AccessToken optional.String
+ Body optional.String
+ MilestoneNumber optional.Int32
+ Labels optional.String
+ Issue optional.String
+ Assignees optional.String
+ Testers optional.String
+ PruneSourceBranch optional.Bool
+}
+
+func (a *PullRequestsApiService) PostV5ReposOwnerRepoPulls(ctx context.Context, owner string, repo string, title string, head string, base string, localVarOptionals *PostV5ReposOwnerRepoPullsOpts) (PullRequest, *http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Post")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ localVarReturnValue PullRequest
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/repos/{owner}/{repo}/pulls"
+ localVarPath = strings.Replace(localVarPath, "{"+"owner"+"}", fmt.Sprintf("%v", owner), -1)
+ localVarPath = strings.Replace(localVarPath, "{"+"repo"+"}", fmt.Sprintf("%v", repo), -1)
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarFormParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ localVarFormParams.Add("title", parameterToString(title, ""))
+ localVarFormParams.Add("head", parameterToString(head, ""))
+ localVarFormParams.Add("base", parameterToString(base, ""))
+ if localVarOptionals != nil && localVarOptionals.Body.IsSet() {
+ localVarFormParams.Add("body", parameterToString(localVarOptionals.Body.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.MilestoneNumber.IsSet() {
+ localVarFormParams.Add("milestone_number", parameterToString(localVarOptionals.MilestoneNumber.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Labels.IsSet() {
+ localVarFormParams.Add("labels", parameterToString(localVarOptionals.Labels.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Issue.IsSet() {
+ localVarFormParams.Add("issue", parameterToString(localVarOptionals.Issue.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Assignees.IsSet() {
+ localVarFormParams.Add("assignees", parameterToString(localVarOptionals.Assignees.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Testers.IsSet() {
+ localVarFormParams.Add("testers", parameterToString(localVarOptionals.Testers.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.PruneSourceBranch.IsSet() {
+ localVarFormParams.Add("prune_source_branch", parameterToString(localVarOptionals.PruneSourceBranch.Value(), ""))
+ }
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return localVarReturnValue, nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode < 300 {
+ // If we succeed, return the data, otherwise pass on to decode error.
+ err = a.client.decode(&localVarReturnValue, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ if localVarHttpResponse.StatusCode == 201 {
+ var v PullRequest
+ err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err != nil {
+ newErr.error = err.Error()
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+ newErr.model = v
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, nil
+}
+
+/*
+PullRequestsApiService 指派用户审查 Pull Request
+指派用户审查 Pull Request
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param owner 仓库所属空间地址(企业、组织或个人的地址path)
+ * @param repo 仓库路径(path)
+ * @param number 第几个PR,即本仓库PR的序数
+ * @param assignees 用户的个人空间地址, 以 , 分隔
+ * @param optional nil or *PostV5ReposOwnerRepoPullsNumberAssigneesOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+
+@return PullRequest
+*/
+
+type PostV5ReposOwnerRepoPullsNumberAssigneesOpts struct {
+ AccessToken optional.String
+}
+
+func (a *PullRequestsApiService) PostV5ReposOwnerRepoPullsNumberAssignees(ctx context.Context, owner string, repo string, number int32, assignees string, localVarOptionals *PostV5ReposOwnerRepoPullsNumberAssigneesOpts) (PullRequest, *http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Post")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ localVarReturnValue PullRequest
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/repos/{owner}/{repo}/pulls/{number}/assignees"
+ localVarPath = strings.Replace(localVarPath, "{"+"owner"+"}", fmt.Sprintf("%v", owner), -1)
+ localVarPath = strings.Replace(localVarPath, "{"+"repo"+"}", fmt.Sprintf("%v", repo), -1)
+ localVarPath = strings.Replace(localVarPath, "{"+"number"+"}", fmt.Sprintf("%v", number), -1)
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarFormParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ localVarFormParams.Add("assignees", parameterToString(assignees, ""))
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return localVarReturnValue, nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode < 300 {
+ // If we succeed, return the data, otherwise pass on to decode error.
+ err = a.client.decode(&localVarReturnValue, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ if localVarHttpResponse.StatusCode == 201 {
+ var v PullRequest
+ err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err != nil {
+ newErr.error = err.Error()
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+ newErr.model = v
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, nil
+}
+
+/*
+PullRequestsApiService 提交Pull Request评论
+提交Pull Request评论
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param owner 仓库所属空间地址(企业、组织或个人的地址path)
+ * @param repo 仓库路径(path)
+ * @param number 第几个PR,即本仓库PR的序数
+ * @param body 评论内容
+
+@return PullRequestComments
+*/
+func (a *PullRequestsApiService) PostV5ReposOwnerRepoPullsNumberComments(ctx context.Context, owner string, repo string, number int32, body PullRequestCommentPostParam) (PullRequestComments, *http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Post")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ localVarReturnValue PullRequestComments
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/repos/{owner}/{repo}/pulls/{number}/comments"
+ localVarPath = strings.Replace(localVarPath, "{"+"owner"+"}", fmt.Sprintf("%v", owner), -1)
+ localVarPath = strings.Replace(localVarPath, "{"+"repo"+"}", fmt.Sprintf("%v", repo), -1)
+ localVarPath = strings.Replace(localVarPath, "{"+"number"+"}", fmt.Sprintf("%v", number), -1)
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ // body params
+ localVarPostBody = &body
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return localVarReturnValue, nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode < 300 {
+ // If we succeed, return the data, otherwise pass on to decode error.
+ err = a.client.decode(&localVarReturnValue, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ if localVarHttpResponse.StatusCode == 201 {
+ var v PullRequestComments
+ err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err != nil {
+ newErr.error = err.Error()
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+ newErr.model = v
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, nil
+}
+
+/*
+PullRequestsApiService 指派用户测试 Pull Request
+指派用户测试 Pull Request
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param owner 仓库所属空间地址(企业、组织或个人的地址path)
+ * @param repo 仓库路径(path)
+ * @param number 第几个PR,即本仓库PR的序数
+ * @param testers 用户的个人空间地址, 以 , 分隔
+ * @param optional nil or *PostV5ReposOwnerRepoPullsNumberTestersOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+
+@return PullRequest
+*/
+
+type PostV5ReposOwnerRepoPullsNumberTestersOpts struct {
+ AccessToken optional.String
+}
+
+func (a *PullRequestsApiService) PostV5ReposOwnerRepoPullsNumberTesters(ctx context.Context, owner string, repo string, number int32, testers string, localVarOptionals *PostV5ReposOwnerRepoPullsNumberTestersOpts) (PullRequest, *http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Post")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ localVarReturnValue PullRequest
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/repos/{owner}/{repo}/pulls/{number}/testers"
+ localVarPath = strings.Replace(localVarPath, "{"+"owner"+"}", fmt.Sprintf("%v", owner), -1)
+ localVarPath = strings.Replace(localVarPath, "{"+"repo"+"}", fmt.Sprintf("%v", repo), -1)
+ localVarPath = strings.Replace(localVarPath, "{"+"number"+"}", fmt.Sprintf("%v", number), -1)
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarFormParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ localVarFormParams.Add("testers", parameterToString(testers, ""))
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return localVarReturnValue, nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode < 300 {
+ // If we succeed, return the data, otherwise pass on to decode error.
+ err = a.client.decode(&localVarReturnValue, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ if localVarHttpResponse.StatusCode == 201 {
+ var v PullRequest
+ err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err != nil {
+ newErr.error = err.Error()
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+ newErr.model = v
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, nil
+}
+
+/*
+PullRequestsApiService 合并Pull Request
+合并Pull Request
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param owner 仓库所属空间地址(企业、组织或个人的地址path)
+ * @param repo 仓库路径(path)
+ * @param number 第几个PR,即本仓库PR的序数
+ * @param body PullRequest合入参数
+
+
+*/
+func (a *PullRequestsApiService) PutV5ReposOwnerRepoPullsNumberMerge(ctx context.Context, owner string, repo string, number int32, body PullRequestMergePutParam) (*http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Put")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/repos/{owner}/{repo}/pulls/{number}/merge"
+ localVarPath = strings.Replace(localVarPath, "{"+"owner"+"}", fmt.Sprintf("%v", owner), -1)
+ localVarPath = strings.Replace(localVarPath, "{"+"repo"+"}", fmt.Sprintf("%v", repo), -1)
+ localVarPath = strings.Replace(localVarPath, "{"+"number"+"}", fmt.Sprintf("%v", number), -1)
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ // body params
+ localVarPostBody = &body
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ return localVarHttpResponse, newErr
+ }
+
+ return localVarHttpResponse, nil
+}
diff --git a/vendor/gitee.com/openeuler/go-gitee/gitee/api_repositories.go b/vendor/gitee.com/openeuler/go-gitee/gitee/api_repositories.go
new file mode 100644
index 0000000000000000000000000000000000000000..6df47f65b0729b41dc47b175d58372470382eb52
--- /dev/null
+++ b/vendor/gitee.com/openeuler/go-gitee/gitee/api_repositories.go
@@ -0,0 +1,5804 @@
+/*
+ * 码云 Open API
+ *
+ * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen)
+ *
+ * API version: 5.3.2
+ * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
+ */
+
+package gitee
+
+import (
+ "context"
+ "fmt"
+ "github.com/antihax/optional"
+ "io/ioutil"
+ "net/http"
+ "net/url"
+ "strings"
+)
+
+// Linger please
+var (
+ _ context.Context
+)
+
+type RepositoriesApiService service
+
+/*
+RepositoriesApiService 删除一个仓库
+删除一个仓库
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param owner 仓库所属空间地址(企业、组织或个人的地址path)
+ * @param repo 仓库路径(path)
+ * @param optional nil or *DeleteV5ReposOwnerRepoOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+
+
+*/
+
+type DeleteV5ReposOwnerRepoOpts struct {
+ AccessToken optional.String
+}
+
+func (a *RepositoriesApiService) DeleteV5ReposOwnerRepo(ctx context.Context, owner string, repo string, localVarOptionals *DeleteV5ReposOwnerRepoOpts) (*http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Delete")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/repos/{owner}/{repo}"
+ localVarPath = strings.Replace(localVarPath, "{"+"owner"+"}", fmt.Sprintf("%v", owner), -1)
+ localVarPath = strings.Replace(localVarPath, "{"+"repo"+"}", fmt.Sprintf("%v", repo), -1)
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarQueryParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ return localVarHttpResponse, newErr
+ }
+
+ return localVarHttpResponse, nil
+}
+
+/*
+RepositoriesApiService 取消保护分支的设置
+取消保护分支的设置
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param owner 仓库所属空间地址(企业、组织或个人的地址path)
+ * @param repo 仓库路径(path)
+ * @param branch 分支名称
+ * @param optional nil or *DeleteV5ReposOwnerRepoBranchesBranchProtectionOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+
+
+*/
+
+type DeleteV5ReposOwnerRepoBranchesBranchProtectionOpts struct {
+ AccessToken optional.String
+}
+
+func (a *RepositoriesApiService) DeleteV5ReposOwnerRepoBranchesBranchProtection(ctx context.Context, owner string, repo string, branch string, localVarOptionals *DeleteV5ReposOwnerRepoBranchesBranchProtectionOpts) (*http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Delete")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/repos/{owner}/{repo}/branches/{branch}/protection"
+ localVarPath = strings.Replace(localVarPath, "{"+"owner"+"}", fmt.Sprintf("%v", owner), -1)
+ localVarPath = strings.Replace(localVarPath, "{"+"repo"+"}", fmt.Sprintf("%v", repo), -1)
+ localVarPath = strings.Replace(localVarPath, "{"+"branch"+"}", fmt.Sprintf("%v", branch), -1)
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarQueryParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ return localVarHttpResponse, newErr
+ }
+
+ return localVarHttpResponse, nil
+}
+
+/*
+RepositoriesApiService 移除仓库成员
+移除仓库成员
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param owner 仓库所属空间地址(企业、组织或个人的地址path)
+ * @param repo 仓库路径(path)
+ * @param username 用户名(username/login)
+ * @param optional nil or *DeleteV5ReposOwnerRepoCollaboratorsUsernameOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+
+
+*/
+
+type DeleteV5ReposOwnerRepoCollaboratorsUsernameOpts struct {
+ AccessToken optional.String
+}
+
+func (a *RepositoriesApiService) DeleteV5ReposOwnerRepoCollaboratorsUsername(ctx context.Context, owner string, repo string, username string, localVarOptionals *DeleteV5ReposOwnerRepoCollaboratorsUsernameOpts) (*http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Delete")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/repos/{owner}/{repo}/collaborators/{username}"
+ localVarPath = strings.Replace(localVarPath, "{"+"owner"+"}", fmt.Sprintf("%v", owner), -1)
+ localVarPath = strings.Replace(localVarPath, "{"+"repo"+"}", fmt.Sprintf("%v", repo), -1)
+ localVarPath = strings.Replace(localVarPath, "{"+"username"+"}", fmt.Sprintf("%v", username), -1)
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarQueryParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ return localVarHttpResponse, newErr
+ }
+
+ return localVarHttpResponse, nil
+}
+
+/*
+RepositoriesApiService 删除Commit评论
+删除Commit评论
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param owner 仓库所属空间地址(企业、组织或个人的地址path)
+ * @param repo 仓库路径(path)
+ * @param id 评论的ID
+ * @param optional nil or *DeleteV5ReposOwnerRepoCommentsIdOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+
+
+*/
+
+type DeleteV5ReposOwnerRepoCommentsIdOpts struct {
+ AccessToken optional.String
+}
+
+func (a *RepositoriesApiService) DeleteV5ReposOwnerRepoCommentsId(ctx context.Context, owner string, repo string, id int32, localVarOptionals *DeleteV5ReposOwnerRepoCommentsIdOpts) (*http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Delete")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/repos/{owner}/{repo}/comments/{id}"
+ localVarPath = strings.Replace(localVarPath, "{"+"owner"+"}", fmt.Sprintf("%v", owner), -1)
+ localVarPath = strings.Replace(localVarPath, "{"+"repo"+"}", fmt.Sprintf("%v", repo), -1)
+ localVarPath = strings.Replace(localVarPath, "{"+"id"+"}", fmt.Sprintf("%v", id), -1)
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarQueryParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ return localVarHttpResponse, newErr
+ }
+
+ return localVarHttpResponse, nil
+}
+
+/*
+RepositoriesApiService 删除文件
+删除文件
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param owner 仓库所属空间地址(企业、组织或个人的地址path)
+ * @param repo 仓库路径(path)
+ * @param path 文件的路径
+ * @param sha 文件的 Blob SHA,可通过 [获取仓库具体路径下的内容] API 获取
+ * @param message 提交信息
+ * @param optional nil or *DeleteV5ReposOwnerRepoContentsPathOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+ * @param "Branch" (optional.String) - 分支名称。默认为仓库对默认分支
+ * @param "CommitterName" (optional.String) - Committer的名字,默认为当前用户的名字
+ * @param "CommitterEmail" (optional.String) - Committer的邮箱,默认为当前用户的邮箱
+ * @param "AuthorName" (optional.String) - Author的名字,默认为当前用户的名字
+ * @param "AuthorEmail" (optional.String) - Author的邮箱,默认为当前用户的邮箱
+
+@return CommitContent
+*/
+
+type DeleteV5ReposOwnerRepoContentsPathOpts struct {
+ AccessToken optional.String
+ Branch optional.String
+ CommitterName optional.String
+ CommitterEmail optional.String
+ AuthorName optional.String
+ AuthorEmail optional.String
+}
+
+func (a *RepositoriesApiService) DeleteV5ReposOwnerRepoContentsPath(ctx context.Context, owner string, repo string, path string, sha string, message string, localVarOptionals *DeleteV5ReposOwnerRepoContentsPathOpts) (CommitContent, *http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Delete")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ localVarReturnValue CommitContent
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/repos/{owner}/{repo}/contents/{path}"
+ localVarPath = strings.Replace(localVarPath, "{"+"owner"+"}", fmt.Sprintf("%v", owner), -1)
+ localVarPath = strings.Replace(localVarPath, "{"+"repo"+"}", fmt.Sprintf("%v", repo), -1)
+ localVarPath = strings.Replace(localVarPath, "{"+"path"+"}", fmt.Sprintf("%v", path), -1)
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarQueryParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ localVarQueryParams.Add("sha", parameterToString(sha, ""))
+ localVarQueryParams.Add("message", parameterToString(message, ""))
+ if localVarOptionals != nil && localVarOptionals.Branch.IsSet() {
+ localVarQueryParams.Add("branch", parameterToString(localVarOptionals.Branch.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.CommitterName.IsSet() {
+ localVarQueryParams.Add("committer[name]", parameterToString(localVarOptionals.CommitterName.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.CommitterEmail.IsSet() {
+ localVarQueryParams.Add("committer[email]", parameterToString(localVarOptionals.CommitterEmail.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.AuthorName.IsSet() {
+ localVarQueryParams.Add("author[name]", parameterToString(localVarOptionals.AuthorName.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.AuthorEmail.IsSet() {
+ localVarQueryParams.Add("author[email]", parameterToString(localVarOptionals.AuthorEmail.Value(), ""))
+ }
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return localVarReturnValue, nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode < 300 {
+ // If we succeed, return the data, otherwise pass on to decode error.
+ err = a.client.decode(&localVarReturnValue, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ if localVarHttpResponse.StatusCode == 200 {
+ var v CommitContent
+ err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err != nil {
+ newErr.error = err.Error()
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+ newErr.model = v
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, nil
+}
+
+/*
+RepositoriesApiService 停用仓库公钥
+停用仓库公钥
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param owner 仓库所属空间地址(企业、组织或个人的地址path)
+ * @param repo 仓库路径(path)
+ * @param id 公钥 ID
+ * @param optional nil or *DeleteV5ReposOwnerRepoKeysEnableIdOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+
+
+*/
+
+type DeleteV5ReposOwnerRepoKeysEnableIdOpts struct {
+ AccessToken optional.String
+}
+
+func (a *RepositoriesApiService) DeleteV5ReposOwnerRepoKeysEnableId(ctx context.Context, owner string, repo string, id int32, localVarOptionals *DeleteV5ReposOwnerRepoKeysEnableIdOpts) (*http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Delete")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/repos/{owner}/{repo}/keys/enable/{id}"
+ localVarPath = strings.Replace(localVarPath, "{"+"owner"+"}", fmt.Sprintf("%v", owner), -1)
+ localVarPath = strings.Replace(localVarPath, "{"+"repo"+"}", fmt.Sprintf("%v", repo), -1)
+ localVarPath = strings.Replace(localVarPath, "{"+"id"+"}", fmt.Sprintf("%v", id), -1)
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarQueryParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ return localVarHttpResponse, newErr
+ }
+
+ return localVarHttpResponse, nil
+}
+
+/*
+RepositoriesApiService 删除一个仓库公钥
+删除一个仓库公钥
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param owner 仓库所属空间地址(企业、组织或个人的地址path)
+ * @param repo 仓库路径(path)
+ * @param id 公钥 ID
+ * @param optional nil or *DeleteV5ReposOwnerRepoKeysIdOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+
+
+*/
+
+type DeleteV5ReposOwnerRepoKeysIdOpts struct {
+ AccessToken optional.String
+}
+
+func (a *RepositoriesApiService) DeleteV5ReposOwnerRepoKeysId(ctx context.Context, owner string, repo string, id int32, localVarOptionals *DeleteV5ReposOwnerRepoKeysIdOpts) (*http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Delete")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/repos/{owner}/{repo}/keys/{id}"
+ localVarPath = strings.Replace(localVarPath, "{"+"owner"+"}", fmt.Sprintf("%v", owner), -1)
+ localVarPath = strings.Replace(localVarPath, "{"+"repo"+"}", fmt.Sprintf("%v", repo), -1)
+ localVarPath = strings.Replace(localVarPath, "{"+"id"+"}", fmt.Sprintf("%v", id), -1)
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarQueryParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ return localVarHttpResponse, newErr
+ }
+
+ return localVarHttpResponse, nil
+}
+
+/*
+RepositoriesApiService 删除仓库Release
+删除仓库Release
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param owner 仓库所属空间地址(企业、组织或个人的地址path)
+ * @param repo 仓库路径(path)
+ * @param id
+ * @param optional nil or *DeleteV5ReposOwnerRepoReleasesIdOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+
+
+*/
+
+type DeleteV5ReposOwnerRepoReleasesIdOpts struct {
+ AccessToken optional.String
+}
+
+func (a *RepositoriesApiService) DeleteV5ReposOwnerRepoReleasesId(ctx context.Context, owner string, repo string, id int32, localVarOptionals *DeleteV5ReposOwnerRepoReleasesIdOpts) (*http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Delete")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/repos/{owner}/{repo}/releases/{id}"
+ localVarPath = strings.Replace(localVarPath, "{"+"owner"+"}", fmt.Sprintf("%v", owner), -1)
+ localVarPath = strings.Replace(localVarPath, "{"+"repo"+"}", fmt.Sprintf("%v", repo), -1)
+ localVarPath = strings.Replace(localVarPath, "{"+"id"+"}", fmt.Sprintf("%v", id), -1)
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarQueryParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ return localVarHttpResponse, newErr
+ }
+
+ return localVarHttpResponse, nil
+}
+
+/*
+RepositoriesApiService 获取企业的所有仓库
+获取企业的所有仓库
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param enterprise 企业的路径(path/login)
+ * @param optional nil or *GetV5EnterprisesEnterpriseReposOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+ * @param "Type_" (optional.String) - 筛选仓库的类型,可以是 all, public, internal, private。默认: all
+ * @param "Direct" (optional.Bool) - 只获取直属仓库,默认: false
+ * @param "Page" (optional.Int32) - 当前的页码
+ * @param "PerPage" (optional.Int32) - 每页的数量,最大为 100
+
+@return Project
+*/
+
+type GetV5EnterprisesEnterpriseReposOpts struct {
+ AccessToken optional.String
+ Type_ optional.String
+ Direct optional.Bool
+ Page optional.Int32
+ PerPage optional.Int32
+}
+
+func (a *RepositoriesApiService) GetV5EnterprisesEnterpriseRepos(ctx context.Context, enterprise string, localVarOptionals *GetV5EnterprisesEnterpriseReposOpts) (Project, *http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Get")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ localVarReturnValue Project
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/enterprises/{enterprise}/repos"
+ localVarPath = strings.Replace(localVarPath, "{"+"enterprise"+"}", fmt.Sprintf("%v", enterprise), -1)
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarQueryParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Type_.IsSet() {
+ localVarQueryParams.Add("type", parameterToString(localVarOptionals.Type_.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Direct.IsSet() {
+ localVarQueryParams.Add("direct", parameterToString(localVarOptionals.Direct.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Page.IsSet() {
+ localVarQueryParams.Add("page", parameterToString(localVarOptionals.Page.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.PerPage.IsSet() {
+ localVarQueryParams.Add("per_page", parameterToString(localVarOptionals.PerPage.Value(), ""))
+ }
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return localVarReturnValue, nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode < 300 {
+ // If we succeed, return the data, otherwise pass on to decode error.
+ err = a.client.decode(&localVarReturnValue, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ if localVarHttpResponse.StatusCode == 200 {
+ var v Project
+ err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err != nil {
+ newErr.error = err.Error()
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+ newErr.model = v
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, nil
+}
+
+/*
+RepositoriesApiService 获取一个组织的仓库
+获取一个组织的仓库
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param org 组织的路径(path/login)
+ * @param optional nil or *GetV5OrgsOrgReposOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+ * @param "Type_" (optional.String) - 筛选仓库的类型,可以是 all, public, private。默认: all
+ * @param "Page" (optional.Int32) - 当前的页码
+ * @param "PerPage" (optional.Int32) - 每页的数量,最大为 100
+
+@return []Project
+*/
+
+type GetV5OrgsOrgReposOpts struct {
+ AccessToken optional.String
+ Type_ optional.String
+ Page optional.Int32
+ PerPage optional.Int32
+}
+
+func (a *RepositoriesApiService) GetV5OrgsOrgRepos(ctx context.Context, org string, localVarOptionals *GetV5OrgsOrgReposOpts) ([]Project, *http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Get")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ localVarReturnValue []Project
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/orgs/{org}/repos"
+ localVarPath = strings.Replace(localVarPath, "{"+"org"+"}", fmt.Sprintf("%v", org), -1)
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarQueryParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Type_.IsSet() {
+ localVarQueryParams.Add("type", parameterToString(localVarOptionals.Type_.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Page.IsSet() {
+ localVarQueryParams.Add("page", parameterToString(localVarOptionals.Page.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.PerPage.IsSet() {
+ localVarQueryParams.Add("per_page", parameterToString(localVarOptionals.PerPage.Value(), ""))
+ }
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return localVarReturnValue, nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode < 300 {
+ // If we succeed, return the data, otherwise pass on to decode error.
+ err = a.client.decode(&localVarReturnValue, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ if localVarHttpResponse.StatusCode == 200 {
+ var v []Project
+ err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err != nil {
+ newErr.error = err.Error()
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+ newErr.model = v
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, nil
+}
+
+/*
+RepositoriesApiService 获取用户的某个仓库
+获取用户的某个仓库
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param owner 仓库所属空间地址(企业、组织或个人的地址path)
+ * @param repo 仓库路径(path)
+ * @param optional nil or *GetV5ReposOwnerRepoOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+
+@return Project
+*/
+
+type GetV5ReposOwnerRepoOpts struct {
+ AccessToken optional.String
+}
+
+func (a *RepositoriesApiService) GetV5ReposOwnerRepo(ctx context.Context, owner string, repo string, localVarOptionals *GetV5ReposOwnerRepoOpts) (Project, *http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Get")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ localVarReturnValue Project
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/repos/{owner}/{repo}"
+ localVarPath = strings.Replace(localVarPath, "{"+"owner"+"}", fmt.Sprintf("%v", owner), -1)
+ localVarPath = strings.Replace(localVarPath, "{"+"repo"+"}", fmt.Sprintf("%v", repo), -1)
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarQueryParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return localVarReturnValue, nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode < 300 {
+ // If we succeed, return the data, otherwise pass on to decode error.
+ err = a.client.decode(&localVarReturnValue, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ if localVarHttpResponse.StatusCode == 200 {
+ var v Project
+ err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err != nil {
+ newErr.error = err.Error()
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+ newErr.model = v
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, nil
+}
+
+/*
+RepositoriesApiService 获取所有分支
+获取所有分支
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param owner 仓库所属空间地址(企业、组织或个人的地址path)
+ * @param repo 仓库路径(path)
+ * @param optional nil or *GetV5ReposOwnerRepoBranchesOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+
+@return []Branch
+*/
+
+type GetV5ReposOwnerRepoBranchesOpts struct {
+ AccessToken optional.String
+}
+
+func (a *RepositoriesApiService) GetV5ReposOwnerRepoBranches(ctx context.Context, owner string, repo string, localVarOptionals *GetV5ReposOwnerRepoBranchesOpts) ([]Branch, *http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Get")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ localVarReturnValue []Branch
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/repos/{owner}/{repo}/branches"
+ localVarPath = strings.Replace(localVarPath, "{"+"owner"+"}", fmt.Sprintf("%v", owner), -1)
+ localVarPath = strings.Replace(localVarPath, "{"+"repo"+"}", fmt.Sprintf("%v", repo), -1)
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarQueryParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return localVarReturnValue, nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode < 300 {
+ // If we succeed, return the data, otherwise pass on to decode error.
+ err = a.client.decode(&localVarReturnValue, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ if localVarHttpResponse.StatusCode == 200 {
+ var v []Branch
+ err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err != nil {
+ newErr.error = err.Error()
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+ newErr.model = v
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, nil
+}
+
+/*
+RepositoriesApiService 获取单个分支
+获取单个分支
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param owner 仓库所属空间地址(企业、组织或个人的地址path)
+ * @param repo 仓库路径(path)
+ * @param branch 分支名称
+ * @param optional nil or *GetV5ReposOwnerRepoBranchesBranchOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+
+@return CompleteBranch
+*/
+
+type GetV5ReposOwnerRepoBranchesBranchOpts struct {
+ AccessToken optional.String
+}
+
+func (a *RepositoriesApiService) GetV5ReposOwnerRepoBranchesBranch(ctx context.Context, owner string, repo string, branch string, localVarOptionals *GetV5ReposOwnerRepoBranchesBranchOpts) (CompleteBranch, *http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Get")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ localVarReturnValue CompleteBranch
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/repos/{owner}/{repo}/branches/{branch}"
+ localVarPath = strings.Replace(localVarPath, "{"+"owner"+"}", fmt.Sprintf("%v", owner), -1)
+ localVarPath = strings.Replace(localVarPath, "{"+"repo"+"}", fmt.Sprintf("%v", repo), -1)
+ localVarPath = strings.Replace(localVarPath, "{"+"branch"+"}", fmt.Sprintf("%v", branch), -1)
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarQueryParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return localVarReturnValue, nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode < 300 {
+ // If we succeed, return the data, otherwise pass on to decode error.
+ err = a.client.decode(&localVarReturnValue, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ if localVarHttpResponse.StatusCode == 200 {
+ var v CompleteBranch
+ err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err != nil {
+ newErr.error = err.Error()
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+ newErr.model = v
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, nil
+}
+
+/*
+RepositoriesApiService 获取仓库的所有成员
+获取仓库的所有成员
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param owner 仓库所属空间地址(企业、组织或个人的地址path)
+ * @param repo 仓库路径(path)
+ * @param optional nil or *GetV5ReposOwnerRepoCollaboratorsOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+
+@return ProjectMember
+*/
+
+type GetV5ReposOwnerRepoCollaboratorsOpts struct {
+ AccessToken optional.String
+}
+
+func (a *RepositoriesApiService) GetV5ReposOwnerRepoCollaborators(ctx context.Context, owner string, repo string, localVarOptionals *GetV5ReposOwnerRepoCollaboratorsOpts) (ProjectMember, *http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Get")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ localVarReturnValue ProjectMember
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/repos/{owner}/{repo}/collaborators"
+ localVarPath = strings.Replace(localVarPath, "{"+"owner"+"}", fmt.Sprintf("%v", owner), -1)
+ localVarPath = strings.Replace(localVarPath, "{"+"repo"+"}", fmt.Sprintf("%v", repo), -1)
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarQueryParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return localVarReturnValue, nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode < 300 {
+ // If we succeed, return the data, otherwise pass on to decode error.
+ err = a.client.decode(&localVarReturnValue, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ if localVarHttpResponse.StatusCode == 200 {
+ var v ProjectMember
+ err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err != nil {
+ newErr.error = err.Error()
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+ newErr.model = v
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, nil
+}
+
+/*
+RepositoriesApiService 判断用户是否为仓库成员
+判断用户是否为仓库成员
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param owner 仓库所属空间地址(企业、组织或个人的地址path)
+ * @param repo 仓库路径(path)
+ * @param username 用户名(username/login)
+ * @param optional nil or *GetV5ReposOwnerRepoCollaboratorsUsernameOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+
+
+*/
+
+type GetV5ReposOwnerRepoCollaboratorsUsernameOpts struct {
+ AccessToken optional.String
+}
+
+func (a *RepositoriesApiService) GetV5ReposOwnerRepoCollaboratorsUsername(ctx context.Context, owner string, repo string, username string, localVarOptionals *GetV5ReposOwnerRepoCollaboratorsUsernameOpts) (*http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Get")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/repos/{owner}/{repo}/collaborators/{username}"
+ localVarPath = strings.Replace(localVarPath, "{"+"owner"+"}", fmt.Sprintf("%v", owner), -1)
+ localVarPath = strings.Replace(localVarPath, "{"+"repo"+"}", fmt.Sprintf("%v", repo), -1)
+ localVarPath = strings.Replace(localVarPath, "{"+"username"+"}", fmt.Sprintf("%v", username), -1)
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarQueryParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ return localVarHttpResponse, newErr
+ }
+
+ return localVarHttpResponse, nil
+}
+
+/*
+RepositoriesApiService 查看仓库成员的权限
+查看仓库成员的权限
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param owner 仓库所属空间地址(企业、组织或个人的地址path)
+ * @param repo 仓库路径(path)
+ * @param username 用户名(username/login)
+ * @param optional nil or *GetV5ReposOwnerRepoCollaboratorsUsernamePermissionOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+
+@return ProjectMemberPermission
+*/
+
+type GetV5ReposOwnerRepoCollaboratorsUsernamePermissionOpts struct {
+ AccessToken optional.String
+}
+
+func (a *RepositoriesApiService) GetV5ReposOwnerRepoCollaboratorsUsernamePermission(ctx context.Context, owner string, repo string, username string, localVarOptionals *GetV5ReposOwnerRepoCollaboratorsUsernamePermissionOpts) (ProjectMemberPermission, *http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Get")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ localVarReturnValue ProjectMemberPermission
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/repos/{owner}/{repo}/collaborators/{username}/permission"
+ localVarPath = strings.Replace(localVarPath, "{"+"owner"+"}", fmt.Sprintf("%v", owner), -1)
+ localVarPath = strings.Replace(localVarPath, "{"+"repo"+"}", fmt.Sprintf("%v", repo), -1)
+ localVarPath = strings.Replace(localVarPath, "{"+"username"+"}", fmt.Sprintf("%v", username), -1)
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarQueryParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return localVarReturnValue, nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode < 300 {
+ // If we succeed, return the data, otherwise pass on to decode error.
+ err = a.client.decode(&localVarReturnValue, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ if localVarHttpResponse.StatusCode == 200 {
+ var v ProjectMemberPermission
+ err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err != nil {
+ newErr.error = err.Error()
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+ newErr.model = v
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, nil
+}
+
+/*
+RepositoriesApiService 获取仓库的Commit评论
+获取仓库的Commit评论
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param owner 仓库所属空间地址(企业、组织或个人的地址path)
+ * @param repo 仓库路径(path)
+ * @param optional nil or *GetV5ReposOwnerRepoCommentsOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+ * @param "Page" (optional.Int32) - 当前的页码
+ * @param "PerPage" (optional.Int32) - 每页的数量,最大为 100
+
+@return Note
+*/
+
+type GetV5ReposOwnerRepoCommentsOpts struct {
+ AccessToken optional.String
+ Page optional.Int32
+ PerPage optional.Int32
+}
+
+func (a *RepositoriesApiService) GetV5ReposOwnerRepoComments(ctx context.Context, owner string, repo string, localVarOptionals *GetV5ReposOwnerRepoCommentsOpts) (Note, *http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Get")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ localVarReturnValue Note
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/repos/{owner}/{repo}/comments"
+ localVarPath = strings.Replace(localVarPath, "{"+"owner"+"}", fmt.Sprintf("%v", owner), -1)
+ localVarPath = strings.Replace(localVarPath, "{"+"repo"+"}", fmt.Sprintf("%v", repo), -1)
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarQueryParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Page.IsSet() {
+ localVarQueryParams.Add("page", parameterToString(localVarOptionals.Page.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.PerPage.IsSet() {
+ localVarQueryParams.Add("per_page", parameterToString(localVarOptionals.PerPage.Value(), ""))
+ }
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return localVarReturnValue, nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode < 300 {
+ // If we succeed, return the data, otherwise pass on to decode error.
+ err = a.client.decode(&localVarReturnValue, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ if localVarHttpResponse.StatusCode == 200 {
+ var v Note
+ err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err != nil {
+ newErr.error = err.Error()
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+ newErr.model = v
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, nil
+}
+
+/*
+RepositoriesApiService 获取仓库的某条Commit评论
+获取仓库的某条Commit评论
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param owner 仓库所属空间地址(企业、组织或个人的地址path)
+ * @param repo 仓库路径(path)
+ * @param id 评论的ID
+ * @param optional nil or *GetV5ReposOwnerRepoCommentsIdOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+
+@return Note
+*/
+
+type GetV5ReposOwnerRepoCommentsIdOpts struct {
+ AccessToken optional.String
+}
+
+func (a *RepositoriesApiService) GetV5ReposOwnerRepoCommentsId(ctx context.Context, owner string, repo string, id int32, localVarOptionals *GetV5ReposOwnerRepoCommentsIdOpts) (Note, *http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Get")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ localVarReturnValue Note
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/repos/{owner}/{repo}/comments/{id}"
+ localVarPath = strings.Replace(localVarPath, "{"+"owner"+"}", fmt.Sprintf("%v", owner), -1)
+ localVarPath = strings.Replace(localVarPath, "{"+"repo"+"}", fmt.Sprintf("%v", repo), -1)
+ localVarPath = strings.Replace(localVarPath, "{"+"id"+"}", fmt.Sprintf("%v", id), -1)
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarQueryParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return localVarReturnValue, nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode < 300 {
+ // If we succeed, return the data, otherwise pass on to decode error.
+ err = a.client.decode(&localVarReturnValue, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ if localVarHttpResponse.StatusCode == 200 {
+ var v Note
+ err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err != nil {
+ newErr.error = err.Error()
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+ newErr.model = v
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, nil
+}
+
+/*
+RepositoriesApiService 仓库的所有提交
+仓库的所有提交
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param owner 仓库所属空间地址(企业、组织或个人的地址path)
+ * @param repo 仓库路径(path)
+ * @param optional nil or *GetV5ReposOwnerRepoCommitsOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+ * @param "Sha" (optional.String) - 提交起始的SHA值或者分支名. 默认: 仓库的默认分支
+ * @param "Path" (optional.String) - 包含该文件的提交
+ * @param "Author" (optional.String) - 提交作者的邮箱或个人空间地址(username/login)
+ * @param "Since" (optional.String) - 提交的起始时间,时间格式为 ISO 8601
+ * @param "Until" (optional.String) - 提交的最后时间,时间格式为 ISO 8601
+ * @param "Page" (optional.Int32) - 当前的页码
+ * @param "PerPage" (optional.Int32) - 每页的数量,最大为 100
+
+@return []RepoCommit
+*/
+
+type GetV5ReposOwnerRepoCommitsOpts struct {
+ AccessToken optional.String
+ Sha optional.String
+ Path optional.String
+ Author optional.String
+ Since optional.String
+ Until optional.String
+ Page optional.Int32
+ PerPage optional.Int32
+}
+
+func (a *RepositoriesApiService) GetV5ReposOwnerRepoCommits(ctx context.Context, owner string, repo string, localVarOptionals *GetV5ReposOwnerRepoCommitsOpts) ([]RepoCommit, *http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Get")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ localVarReturnValue []RepoCommit
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/repos/{owner}/{repo}/commits"
+ localVarPath = strings.Replace(localVarPath, "{"+"owner"+"}", fmt.Sprintf("%v", owner), -1)
+ localVarPath = strings.Replace(localVarPath, "{"+"repo"+"}", fmt.Sprintf("%v", repo), -1)
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarQueryParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Sha.IsSet() {
+ localVarQueryParams.Add("sha", parameterToString(localVarOptionals.Sha.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Path.IsSet() {
+ localVarQueryParams.Add("path", parameterToString(localVarOptionals.Path.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Author.IsSet() {
+ localVarQueryParams.Add("author", parameterToString(localVarOptionals.Author.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Since.IsSet() {
+ localVarQueryParams.Add("since", parameterToString(localVarOptionals.Since.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Until.IsSet() {
+ localVarQueryParams.Add("until", parameterToString(localVarOptionals.Until.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Page.IsSet() {
+ localVarQueryParams.Add("page", parameterToString(localVarOptionals.Page.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.PerPage.IsSet() {
+ localVarQueryParams.Add("per_page", parameterToString(localVarOptionals.PerPage.Value(), ""))
+ }
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return localVarReturnValue, nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode < 300 {
+ // If we succeed, return the data, otherwise pass on to decode error.
+ err = a.client.decode(&localVarReturnValue, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ if localVarHttpResponse.StatusCode == 200 {
+ var v []RepoCommit
+ err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err != nil {
+ newErr.error = err.Error()
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+ newErr.model = v
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, nil
+}
+
+/*
+RepositoriesApiService 获取单个Commit的评论
+获取单个Commit的评论
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param owner 仓库所属空间地址(企业、组织或个人的地址path)
+ * @param repo 仓库路径(path)
+ * @param ref Commit的Reference
+ * @param optional nil or *GetV5ReposOwnerRepoCommitsRefCommentsOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+ * @param "Page" (optional.Int32) - 当前的页码
+ * @param "PerPage" (optional.Int32) - 每页的数量,最大为 100
+
+@return Note
+*/
+
+type GetV5ReposOwnerRepoCommitsRefCommentsOpts struct {
+ AccessToken optional.String
+ Page optional.Int32
+ PerPage optional.Int32
+}
+
+func (a *RepositoriesApiService) GetV5ReposOwnerRepoCommitsRefComments(ctx context.Context, owner string, repo string, ref string, localVarOptionals *GetV5ReposOwnerRepoCommitsRefCommentsOpts) (Note, *http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Get")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ localVarReturnValue Note
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/repos/{owner}/{repo}/commits/{ref}/comments"
+ localVarPath = strings.Replace(localVarPath, "{"+"owner"+"}", fmt.Sprintf("%v", owner), -1)
+ localVarPath = strings.Replace(localVarPath, "{"+"repo"+"}", fmt.Sprintf("%v", repo), -1)
+ localVarPath = strings.Replace(localVarPath, "{"+"ref"+"}", fmt.Sprintf("%v", ref), -1)
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarQueryParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Page.IsSet() {
+ localVarQueryParams.Add("page", parameterToString(localVarOptionals.Page.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.PerPage.IsSet() {
+ localVarQueryParams.Add("per_page", parameterToString(localVarOptionals.PerPage.Value(), ""))
+ }
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return localVarReturnValue, nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode < 300 {
+ // If we succeed, return the data, otherwise pass on to decode error.
+ err = a.client.decode(&localVarReturnValue, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ if localVarHttpResponse.StatusCode == 200 {
+ var v Note
+ err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err != nil {
+ newErr.error = err.Error()
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+ newErr.model = v
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, nil
+}
+
+/*
+RepositoriesApiService 仓库的某个提交
+仓库的某个提交
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param owner 仓库所属空间地址(企业、组织或个人的地址path)
+ * @param repo 仓库路径(path)
+ * @param sha 提交的SHA值或者分支名
+ * @param optional nil or *GetV5ReposOwnerRepoCommitsShaOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+
+@return RepoCommit
+*/
+
+type GetV5ReposOwnerRepoCommitsShaOpts struct {
+ AccessToken optional.String
+}
+
+func (a *RepositoriesApiService) GetV5ReposOwnerRepoCommitsSha(ctx context.Context, owner string, repo string, sha string, localVarOptionals *GetV5ReposOwnerRepoCommitsShaOpts) (RepoCommit, *http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Get")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ localVarReturnValue RepoCommit
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/repos/{owner}/{repo}/commits/{sha}"
+ localVarPath = strings.Replace(localVarPath, "{"+"owner"+"}", fmt.Sprintf("%v", owner), -1)
+ localVarPath = strings.Replace(localVarPath, "{"+"repo"+"}", fmt.Sprintf("%v", repo), -1)
+ localVarPath = strings.Replace(localVarPath, "{"+"sha"+"}", fmt.Sprintf("%v", sha), -1)
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarQueryParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return localVarReturnValue, nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode < 300 {
+ // If we succeed, return the data, otherwise pass on to decode error.
+ err = a.client.decode(&localVarReturnValue, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ if localVarHttpResponse.StatusCode == 200 {
+ var v RepoCommit
+ err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err != nil {
+ newErr.error = err.Error()
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+ newErr.model = v
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, nil
+}
+
+/*
+RepositoriesApiService 两个Commits之间对比的版本差异
+两个Commits之间对比的版本差异
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param owner 仓库所属空间地址(企业、组织或个人的地址path)
+ * @param repo 仓库路径(path)
+ * @param base Commit提交的SHA值或者分支名作为对比起点
+ * @param head Commit提交的SHA值或者分支名作为对比终点
+ * @param optional nil or *GetV5ReposOwnerRepoCompareBaseHeadOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+
+@return Compare
+*/
+
+type GetV5ReposOwnerRepoCompareBaseHeadOpts struct {
+ AccessToken optional.String
+}
+
+func (a *RepositoriesApiService) GetV5ReposOwnerRepoCompareBaseHead(ctx context.Context, owner string, repo string, base string, head string, localVarOptionals *GetV5ReposOwnerRepoCompareBaseHeadOpts) (Compare, *http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Get")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ localVarReturnValue Compare
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/repos/{owner}/{repo}/compare/{base}...{head}"
+ localVarPath = strings.Replace(localVarPath, "{"+"owner"+"}", fmt.Sprintf("%v", owner), -1)
+ localVarPath = strings.Replace(localVarPath, "{"+"repo"+"}", fmt.Sprintf("%v", repo), -1)
+ localVarPath = strings.Replace(localVarPath, "{"+"base"+"}", fmt.Sprintf("%v", base), -1)
+ localVarPath = strings.Replace(localVarPath, "{"+"head"+"}", fmt.Sprintf("%v", head), -1)
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarQueryParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return localVarReturnValue, nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode < 300 {
+ // If we succeed, return the data, otherwise pass on to decode error.
+ err = a.client.decode(&localVarReturnValue, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ if localVarHttpResponse.StatusCode == 200 {
+ var v Compare
+ err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err != nil {
+ newErr.error = err.Error()
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+ newErr.model = v
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, nil
+}
+
+/*
+RepositoriesApiService 获取仓库具体路径下的内容
+获取仓库具体路径下的内容
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param owner 仓库所属空间地址(企业、组织或个人的地址path)
+ * @param repo 仓库路径(path)
+ * @param path 文件的路径
+ * @param optional nil or *GetV5ReposOwnerRepoContentsPathOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+ * @param "Ref" (optional.String) - 分支、tag或commit。默认: 仓库的默认分支(通常是master)
+
+@return Content
+*/
+
+type GetV5ReposOwnerRepoContentsPathOpts struct {
+ AccessToken optional.String
+ Ref optional.String
+}
+
+func (a *RepositoriesApiService) GetV5ReposOwnerRepoContentsPath(ctx context.Context, owner string, repo string, path string, localVarOptionals *GetV5ReposOwnerRepoContentsPathOpts) (Content, *http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Get")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ localVarReturnValue Content
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/repos/{owner}/{repo}/contents/{path}"
+ localVarPath = strings.Replace(localVarPath, "{"+"owner"+"}", fmt.Sprintf("%v", owner), -1)
+ localVarPath = strings.Replace(localVarPath, "{"+"repo"+"}", fmt.Sprintf("%v", repo), -1)
+ localVarPath = strings.Replace(localVarPath, "{"+"path"+"}", fmt.Sprintf("%v", path), -1)
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarQueryParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Ref.IsSet() {
+ localVarQueryParams.Add("ref", parameterToString(localVarOptionals.Ref.Value(), ""))
+ }
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return localVarReturnValue, nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode < 300 {
+ // If we succeed, return the data, otherwise pass on to decode error.
+ err = a.client.decode(&localVarReturnValue, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ if localVarHttpResponse.StatusCode == 200 {
+ var v Content
+ err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err != nil {
+ newErr.error = err.Error()
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+ newErr.model = v
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, nil
+}
+
+/*
+RepositoriesApiService 获取仓库贡献者
+获取仓库贡献者
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param owner 仓库所属空间地址(企业、组织或个人的地址path)
+ * @param repo 仓库路径(path)
+ * @param optional nil or *GetV5ReposOwnerRepoContributorsOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+
+@return Contributor
+*/
+
+type GetV5ReposOwnerRepoContributorsOpts struct {
+ AccessToken optional.String
+}
+
+func (a *RepositoriesApiService) GetV5ReposOwnerRepoContributors(ctx context.Context, owner string, repo string, localVarOptionals *GetV5ReposOwnerRepoContributorsOpts) (Contributor, *http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Get")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ localVarReturnValue Contributor
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/repos/{owner}/{repo}/contributors"
+ localVarPath = strings.Replace(localVarPath, "{"+"owner"+"}", fmt.Sprintf("%v", owner), -1)
+ localVarPath = strings.Replace(localVarPath, "{"+"repo"+"}", fmt.Sprintf("%v", repo), -1)
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarQueryParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return localVarReturnValue, nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode < 300 {
+ // If we succeed, return the data, otherwise pass on to decode error.
+ err = a.client.decode(&localVarReturnValue, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ if localVarHttpResponse.StatusCode == 200 {
+ var v Contributor
+ err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err != nil {
+ newErr.error = err.Error()
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+ newErr.model = v
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, nil
+}
+
+/*
+RepositoriesApiService 查看仓库的Forks
+查看仓库的Forks
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param owner 仓库所属空间地址(企业、组织或个人的地址path)
+ * @param repo 仓库路径(path)
+ * @param optional nil or *GetV5ReposOwnerRepoForksOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+ * @param "Sort" (optional.String) - 排序方式: fork的时间(newest, oldest),star的人数(stargazers)
+ * @param "Page" (optional.Int32) - 当前的页码
+ * @param "PerPage" (optional.Int32) - 每页的数量,最大为 100
+
+@return Project
+*/
+
+type GetV5ReposOwnerRepoForksOpts struct {
+ AccessToken optional.String
+ Sort optional.String
+ Page optional.Int32
+ PerPage optional.Int32
+}
+
+func (a *RepositoriesApiService) GetV5ReposOwnerRepoForks(ctx context.Context, owner string, repo string, localVarOptionals *GetV5ReposOwnerRepoForksOpts) (Project, *http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Get")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ localVarReturnValue Project
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/repos/{owner}/{repo}/forks"
+ localVarPath = strings.Replace(localVarPath, "{"+"owner"+"}", fmt.Sprintf("%v", owner), -1)
+ localVarPath = strings.Replace(localVarPath, "{"+"repo"+"}", fmt.Sprintf("%v", repo), -1)
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarQueryParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Sort.IsSet() {
+ localVarQueryParams.Add("sort", parameterToString(localVarOptionals.Sort.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Page.IsSet() {
+ localVarQueryParams.Add("page", parameterToString(localVarOptionals.Page.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.PerPage.IsSet() {
+ localVarQueryParams.Add("per_page", parameterToString(localVarOptionals.PerPage.Value(), ""))
+ }
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return localVarReturnValue, nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode < 300 {
+ // If we succeed, return the data, otherwise pass on to decode error.
+ err = a.client.decode(&localVarReturnValue, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ if localVarHttpResponse.StatusCode == 200 {
+ var v Project
+ err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err != nil {
+ newErr.error = err.Error()
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+ newErr.model = v
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, nil
+}
+
+/*
+RepositoriesApiService 获取仓库已部署的公钥
+获取仓库已部署的公钥
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param owner 仓库所属空间地址(企业、组织或个人的地址path)
+ * @param repo 仓库路径(path)
+ * @param optional nil or *GetV5ReposOwnerRepoKeysOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+ * @param "Page" (optional.Int32) - 当前的页码
+ * @param "PerPage" (optional.Int32) - 每页的数量,最大为 100
+
+@return []SshKey
+*/
+
+type GetV5ReposOwnerRepoKeysOpts struct {
+ AccessToken optional.String
+ Page optional.Int32
+ PerPage optional.Int32
+}
+
+func (a *RepositoriesApiService) GetV5ReposOwnerRepoKeys(ctx context.Context, owner string, repo string, localVarOptionals *GetV5ReposOwnerRepoKeysOpts) ([]SshKey, *http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Get")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ localVarReturnValue []SshKey
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/repos/{owner}/{repo}/keys"
+ localVarPath = strings.Replace(localVarPath, "{"+"owner"+"}", fmt.Sprintf("%v", owner), -1)
+ localVarPath = strings.Replace(localVarPath, "{"+"repo"+"}", fmt.Sprintf("%v", repo), -1)
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarQueryParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Page.IsSet() {
+ localVarQueryParams.Add("page", parameterToString(localVarOptionals.Page.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.PerPage.IsSet() {
+ localVarQueryParams.Add("per_page", parameterToString(localVarOptionals.PerPage.Value(), ""))
+ }
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return localVarReturnValue, nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode < 300 {
+ // If we succeed, return the data, otherwise pass on to decode error.
+ err = a.client.decode(&localVarReturnValue, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ if localVarHttpResponse.StatusCode == 200 {
+ var v []SshKey
+ err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err != nil {
+ newErr.error = err.Error()
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+ newErr.model = v
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, nil
+}
+
+/*
+RepositoriesApiService 获取仓库可部署的公钥
+获取仓库可部署的公钥
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param owner 仓库所属空间地址(企业、组织或个人的地址path)
+ * @param repo 仓库路径(path)
+ * @param optional nil or *GetV5ReposOwnerRepoKeysAvailableOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+ * @param "Page" (optional.Int32) - 当前的页码
+ * @param "PerPage" (optional.Int32) - 每页的数量,最大为 100
+
+@return []SshKeyBasic
+*/
+
+type GetV5ReposOwnerRepoKeysAvailableOpts struct {
+ AccessToken optional.String
+ Page optional.Int32
+ PerPage optional.Int32
+}
+
+func (a *RepositoriesApiService) GetV5ReposOwnerRepoKeysAvailable(ctx context.Context, owner string, repo string, localVarOptionals *GetV5ReposOwnerRepoKeysAvailableOpts) ([]SshKeyBasic, *http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Get")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ localVarReturnValue []SshKeyBasic
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/repos/{owner}/{repo}/keys/available"
+ localVarPath = strings.Replace(localVarPath, "{"+"owner"+"}", fmt.Sprintf("%v", owner), -1)
+ localVarPath = strings.Replace(localVarPath, "{"+"repo"+"}", fmt.Sprintf("%v", repo), -1)
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarQueryParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Page.IsSet() {
+ localVarQueryParams.Add("page", parameterToString(localVarOptionals.Page.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.PerPage.IsSet() {
+ localVarQueryParams.Add("per_page", parameterToString(localVarOptionals.PerPage.Value(), ""))
+ }
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return localVarReturnValue, nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode < 300 {
+ // If we succeed, return the data, otherwise pass on to decode error.
+ err = a.client.decode(&localVarReturnValue, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ if localVarHttpResponse.StatusCode == 200 {
+ var v []SshKeyBasic
+ err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err != nil {
+ newErr.error = err.Error()
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+ newErr.model = v
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, nil
+}
+
+/*
+RepositoriesApiService 获取仓库的单个公钥
+获取仓库的单个公钥
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param owner 仓库所属空间地址(企业、组织或个人的地址path)
+ * @param repo 仓库路径(path)
+ * @param id 公钥 ID
+ * @param optional nil or *GetV5ReposOwnerRepoKeysIdOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+
+@return SshKey
+*/
+
+type GetV5ReposOwnerRepoKeysIdOpts struct {
+ AccessToken optional.String
+}
+
+func (a *RepositoriesApiService) GetV5ReposOwnerRepoKeysId(ctx context.Context, owner string, repo string, id int32, localVarOptionals *GetV5ReposOwnerRepoKeysIdOpts) (SshKey, *http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Get")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ localVarReturnValue SshKey
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/repos/{owner}/{repo}/keys/{id}"
+ localVarPath = strings.Replace(localVarPath, "{"+"owner"+"}", fmt.Sprintf("%v", owner), -1)
+ localVarPath = strings.Replace(localVarPath, "{"+"repo"+"}", fmt.Sprintf("%v", repo), -1)
+ localVarPath = strings.Replace(localVarPath, "{"+"id"+"}", fmt.Sprintf("%v", id), -1)
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarQueryParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return localVarReturnValue, nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode < 300 {
+ // If we succeed, return the data, otherwise pass on to decode error.
+ err = a.client.decode(&localVarReturnValue, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ if localVarHttpResponse.StatusCode == 200 {
+ var v SshKey
+ err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err != nil {
+ newErr.error = err.Error()
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+ newErr.model = v
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, nil
+}
+
+/*
+RepositoriesApiService 获取Pages信息
+获取Pages信息
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param owner 仓库所属空间地址(企业、组织或个人的地址path)
+ * @param repo 仓库路径(path)
+ * @param optional nil or *GetV5ReposOwnerRepoPagesOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+
+
+*/
+
+type GetV5ReposOwnerRepoPagesOpts struct {
+ AccessToken optional.String
+}
+
+func (a *RepositoriesApiService) GetV5ReposOwnerRepoPages(ctx context.Context, owner string, repo string, localVarOptionals *GetV5ReposOwnerRepoPagesOpts) (*http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Get")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/repos/{owner}/{repo}/pages"
+ localVarPath = strings.Replace(localVarPath, "{"+"owner"+"}", fmt.Sprintf("%v", owner), -1)
+ localVarPath = strings.Replace(localVarPath, "{"+"repo"+"}", fmt.Sprintf("%v", repo), -1)
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarQueryParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ return localVarHttpResponse, newErr
+ }
+
+ return localVarHttpResponse, nil
+}
+
+/*
+RepositoriesApiService 获取仓库README
+获取仓库README
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param owner 仓库所属空间地址(企业、组织或个人的地址path)
+ * @param repo 仓库路径(path)
+ * @param optional nil or *GetV5ReposOwnerRepoReadmeOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+ * @param "Ref" (optional.String) - 分支、tag或commit。默认: 仓库的默认分支(通常是master)
+
+@return Content
+*/
+
+type GetV5ReposOwnerRepoReadmeOpts struct {
+ AccessToken optional.String
+ Ref optional.String
+}
+
+func (a *RepositoriesApiService) GetV5ReposOwnerRepoReadme(ctx context.Context, owner string, repo string, localVarOptionals *GetV5ReposOwnerRepoReadmeOpts) (Content, *http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Get")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ localVarReturnValue Content
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/repos/{owner}/{repo}/readme"
+ localVarPath = strings.Replace(localVarPath, "{"+"owner"+"}", fmt.Sprintf("%v", owner), -1)
+ localVarPath = strings.Replace(localVarPath, "{"+"repo"+"}", fmt.Sprintf("%v", repo), -1)
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarQueryParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Ref.IsSet() {
+ localVarQueryParams.Add("ref", parameterToString(localVarOptionals.Ref.Value(), ""))
+ }
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return localVarReturnValue, nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode < 300 {
+ // If we succeed, return the data, otherwise pass on to decode error.
+ err = a.client.decode(&localVarReturnValue, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ if localVarHttpResponse.StatusCode == 200 {
+ var v Content
+ err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err != nil {
+ newErr.error = err.Error()
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+ newErr.model = v
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, nil
+}
+
+/*
+RepositoriesApiService 获取仓库的所有Releases
+获取仓库的所有Releases
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param owner 仓库所属空间地址(企业、组织或个人的地址path)
+ * @param repo 仓库路径(path)
+ * @param optional nil or *GetV5ReposOwnerRepoReleasesOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+ * @param "Page" (optional.Int32) - 当前的页码
+ * @param "PerPage" (optional.Int32) - 每页的数量,最大为 100
+
+@return []Release
+*/
+
+type GetV5ReposOwnerRepoReleasesOpts struct {
+ AccessToken optional.String
+ Page optional.Int32
+ PerPage optional.Int32
+}
+
+func (a *RepositoriesApiService) GetV5ReposOwnerRepoReleases(ctx context.Context, owner string, repo string, localVarOptionals *GetV5ReposOwnerRepoReleasesOpts) ([]Release, *http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Get")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ localVarReturnValue []Release
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/repos/{owner}/{repo}/releases"
+ localVarPath = strings.Replace(localVarPath, "{"+"owner"+"}", fmt.Sprintf("%v", owner), -1)
+ localVarPath = strings.Replace(localVarPath, "{"+"repo"+"}", fmt.Sprintf("%v", repo), -1)
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarQueryParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Page.IsSet() {
+ localVarQueryParams.Add("page", parameterToString(localVarOptionals.Page.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.PerPage.IsSet() {
+ localVarQueryParams.Add("per_page", parameterToString(localVarOptionals.PerPage.Value(), ""))
+ }
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return localVarReturnValue, nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode < 300 {
+ // If we succeed, return the data, otherwise pass on to decode error.
+ err = a.client.decode(&localVarReturnValue, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ if localVarHttpResponse.StatusCode == 200 {
+ var v []Release
+ err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err != nil {
+ newErr.error = err.Error()
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+ newErr.model = v
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, nil
+}
+
+/*
+RepositoriesApiService 获取仓库的单个Releases
+获取仓库的单个Releases
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param owner 仓库所属空间地址(企业、组织或个人的地址path)
+ * @param repo 仓库路径(path)
+ * @param id 发行版本的ID
+ * @param optional nil or *GetV5ReposOwnerRepoReleasesIdOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+
+@return Release
+*/
+
+type GetV5ReposOwnerRepoReleasesIdOpts struct {
+ AccessToken optional.String
+}
+
+func (a *RepositoriesApiService) GetV5ReposOwnerRepoReleasesId(ctx context.Context, owner string, repo string, id int32, localVarOptionals *GetV5ReposOwnerRepoReleasesIdOpts) (Release, *http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Get")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ localVarReturnValue Release
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/repos/{owner}/{repo}/releases/{id}"
+ localVarPath = strings.Replace(localVarPath, "{"+"owner"+"}", fmt.Sprintf("%v", owner), -1)
+ localVarPath = strings.Replace(localVarPath, "{"+"repo"+"}", fmt.Sprintf("%v", repo), -1)
+ localVarPath = strings.Replace(localVarPath, "{"+"id"+"}", fmt.Sprintf("%v", id), -1)
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarQueryParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return localVarReturnValue, nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode < 300 {
+ // If we succeed, return the data, otherwise pass on to decode error.
+ err = a.client.decode(&localVarReturnValue, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ if localVarHttpResponse.StatusCode == 200 {
+ var v Release
+ err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err != nil {
+ newErr.error = err.Error()
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+ newErr.model = v
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, nil
+}
+
+/*
+RepositoriesApiService 获取仓库的最后更新的Release
+获取仓库的最后更新的Release
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param owner 仓库所属空间地址(企业、组织或个人的地址path)
+ * @param repo 仓库路径(path)
+ * @param optional nil or *GetV5ReposOwnerRepoReleasesLatestOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+
+@return Release
+*/
+
+type GetV5ReposOwnerRepoReleasesLatestOpts struct {
+ AccessToken optional.String
+}
+
+func (a *RepositoriesApiService) GetV5ReposOwnerRepoReleasesLatest(ctx context.Context, owner string, repo string, localVarOptionals *GetV5ReposOwnerRepoReleasesLatestOpts) (Release, *http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Get")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ localVarReturnValue Release
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/repos/{owner}/{repo}/releases/latest"
+ localVarPath = strings.Replace(localVarPath, "{"+"owner"+"}", fmt.Sprintf("%v", owner), -1)
+ localVarPath = strings.Replace(localVarPath, "{"+"repo"+"}", fmt.Sprintf("%v", repo), -1)
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarQueryParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return localVarReturnValue, nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode < 300 {
+ // If we succeed, return the data, otherwise pass on to decode error.
+ err = a.client.decode(&localVarReturnValue, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ if localVarHttpResponse.StatusCode == 200 {
+ var v Release
+ err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err != nil {
+ newErr.error = err.Error()
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+ newErr.model = v
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, nil
+}
+
+/*
+RepositoriesApiService 根据Tag名称获取仓库的Release
+根据Tag名称获取仓库的Release
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param owner 仓库所属空间地址(企业、组织或个人的地址path)
+ * @param repo 仓库路径(path)
+ * @param tag Tag 名称
+ * @param optional nil or *GetV5ReposOwnerRepoReleasesTagsTagOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+
+@return Release
+*/
+
+type GetV5ReposOwnerRepoReleasesTagsTagOpts struct {
+ AccessToken optional.String
+}
+
+func (a *RepositoriesApiService) GetV5ReposOwnerRepoReleasesTagsTag(ctx context.Context, owner string, repo string, tag string, localVarOptionals *GetV5ReposOwnerRepoReleasesTagsTagOpts) (Release, *http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Get")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ localVarReturnValue Release
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/repos/{owner}/{repo}/releases/tags/{tag}"
+ localVarPath = strings.Replace(localVarPath, "{"+"owner"+"}", fmt.Sprintf("%v", owner), -1)
+ localVarPath = strings.Replace(localVarPath, "{"+"repo"+"}", fmt.Sprintf("%v", repo), -1)
+ localVarPath = strings.Replace(localVarPath, "{"+"tag"+"}", fmt.Sprintf("%v", tag), -1)
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarQueryParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return localVarReturnValue, nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode < 300 {
+ // If we succeed, return the data, otherwise pass on to decode error.
+ err = a.client.decode(&localVarReturnValue, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ if localVarHttpResponse.StatusCode == 200 {
+ var v Release
+ err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err != nil {
+ newErr.error = err.Error()
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+ newErr.model = v
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, nil
+}
+
+/*
+RepositoriesApiService 列出仓库所有的tags
+列出仓库所有的tags
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param owner 仓库所属空间地址(企业、组织或个人的地址path)
+ * @param repo 仓库路径(path)
+ * @param optional nil or *GetV5ReposOwnerRepoTagsOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+
+@return Tag
+*/
+
+type GetV5ReposOwnerRepoTagsOpts struct {
+ AccessToken optional.String
+}
+
+func (a *RepositoriesApiService) GetV5ReposOwnerRepoTags(ctx context.Context, owner string, repo string, localVarOptionals *GetV5ReposOwnerRepoTagsOpts) (Tag, *http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Get")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ localVarReturnValue Tag
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/repos/{owner}/{repo}/tags"
+ localVarPath = strings.Replace(localVarPath, "{"+"owner"+"}", fmt.Sprintf("%v", owner), -1)
+ localVarPath = strings.Replace(localVarPath, "{"+"repo"+"}", fmt.Sprintf("%v", repo), -1)
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarQueryParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return localVarReturnValue, nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode < 300 {
+ // If we succeed, return the data, otherwise pass on to decode error.
+ err = a.client.decode(&localVarReturnValue, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ if localVarHttpResponse.StatusCode == 200 {
+ var v Tag
+ err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err != nil {
+ newErr.error = err.Error()
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+ newErr.model = v
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, nil
+}
+
+/*
+RepositoriesApiService 列出授权用户的所有仓库
+列出授权用户的所有仓库
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param optional nil or *GetV5UserReposOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+ * @param "Visibility" (optional.String) - 公开(public)、私有(private)或者所有(all),默认: 所有(all)
+ * @param "Affiliation" (optional.String) - owner(授权用户拥有的仓库)、collaborator(授权用户为仓库成员)、organization_member(授权用户为仓库所在组织并有访问仓库权限)、enterprise_member(授权用户所在企业并有访问仓库权限)、admin(所有有权限的,包括所管理的组织中所有仓库、所管理的企业的所有仓库)。 可以用逗号分隔符组合。如: owner, organization_member 或 owner, collaborator, organization_member
+ * @param "Type_" (optional.String) - 筛选用户仓库: 其创建(owner)、个人(personal)、其为成员(member)、公开(public)、私有(private),不能与 visibility 或 affiliation 参数一并使用,否则会报 422 错误
+ * @param "Sort" (optional.String) - 排序方式: 创建时间(created),更新时间(updated),最后推送时间(pushed),仓库所属与名称(full_name)。默认: full_name
+ * @param "Direction" (optional.String) - 如果sort参数为full_name,用升序(asc)。否则降序(desc)
+ * @param "Page" (optional.Int32) - 当前的页码
+ * @param "PerPage" (optional.Int32) - 每页的数量,最大为 100
+
+@return Project
+*/
+
+type GetV5UserReposOpts struct {
+ AccessToken optional.String
+ Visibility optional.String
+ Affiliation optional.String
+ Type_ optional.String
+ Sort optional.String
+ Direction optional.String
+ Page optional.Int32
+ PerPage optional.Int32
+}
+
+func (a *RepositoriesApiService) GetV5UserRepos(ctx context.Context, localVarOptionals *GetV5UserReposOpts) (Project, *http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Get")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ localVarReturnValue Project
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/user/repos"
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarQueryParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Visibility.IsSet() {
+ localVarQueryParams.Add("visibility", parameterToString(localVarOptionals.Visibility.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Affiliation.IsSet() {
+ localVarQueryParams.Add("affiliation", parameterToString(localVarOptionals.Affiliation.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Type_.IsSet() {
+ localVarQueryParams.Add("type", parameterToString(localVarOptionals.Type_.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Sort.IsSet() {
+ localVarQueryParams.Add("sort", parameterToString(localVarOptionals.Sort.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Direction.IsSet() {
+ localVarQueryParams.Add("direction", parameterToString(localVarOptionals.Direction.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Page.IsSet() {
+ localVarQueryParams.Add("page", parameterToString(localVarOptionals.Page.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.PerPage.IsSet() {
+ localVarQueryParams.Add("per_page", parameterToString(localVarOptionals.PerPage.Value(), ""))
+ }
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return localVarReturnValue, nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode < 300 {
+ // If we succeed, return the data, otherwise pass on to decode error.
+ err = a.client.decode(&localVarReturnValue, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ if localVarHttpResponse.StatusCode == 200 {
+ var v Project
+ err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err != nil {
+ newErr.error = err.Error()
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+ newErr.model = v
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, nil
+}
+
+/*
+RepositoriesApiService 获取某个用户的公开仓库
+获取某个用户的公开仓库
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param username 用户名(username/login)
+ * @param optional nil or *GetV5UsersUsernameReposOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+ * @param "Type_" (optional.String) - 用户创建的仓库(owner),用户个人仓库(personal),用户为仓库成员(member),所有(all)。默认: 所有(all)
+ * @param "Sort" (optional.String) - 排序方式: 创建时间(created),更新时间(updated),最后推送时间(pushed),仓库所属与名称(full_name)。默认: full_name
+ * @param "Direction" (optional.String) - 如果sort参数为full_name,用升序(asc)。否则降序(desc)
+ * @param "Page" (optional.Int32) - 当前的页码
+ * @param "PerPage" (optional.Int32) - 每页的数量,最大为 100
+
+@return Project
+*/
+
+type GetV5UsersUsernameReposOpts struct {
+ AccessToken optional.String
+ Type_ optional.String
+ Sort optional.String
+ Direction optional.String
+ Page optional.Int32
+ PerPage optional.Int32
+}
+
+func (a *RepositoriesApiService) GetV5UsersUsernameRepos(ctx context.Context, username string, localVarOptionals *GetV5UsersUsernameReposOpts) (Project, *http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Get")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ localVarReturnValue Project
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/users/{username}/repos"
+ localVarPath = strings.Replace(localVarPath, "{"+"username"+"}", fmt.Sprintf("%v", username), -1)
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarQueryParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Type_.IsSet() {
+ localVarQueryParams.Add("type", parameterToString(localVarOptionals.Type_.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Sort.IsSet() {
+ localVarQueryParams.Add("sort", parameterToString(localVarOptionals.Sort.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Direction.IsSet() {
+ localVarQueryParams.Add("direction", parameterToString(localVarOptionals.Direction.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Page.IsSet() {
+ localVarQueryParams.Add("page", parameterToString(localVarOptionals.Page.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.PerPage.IsSet() {
+ localVarQueryParams.Add("per_page", parameterToString(localVarOptionals.PerPage.Value(), ""))
+ }
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return localVarReturnValue, nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode < 300 {
+ // If we succeed, return the data, otherwise pass on to decode error.
+ err = a.client.decode(&localVarReturnValue, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ if localVarHttpResponse.StatusCode == 200 {
+ var v Project
+ err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err != nil {
+ newErr.error = err.Error()
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+ newErr.model = v
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, nil
+}
+
+/*
+RepositoriesApiService 更新仓库设置
+更新仓库设置
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param owner 仓库所属空间地址(企业、组织或个人的地址path)
+ * @param repo 仓库路径(path)
+ * @param body repo patch param
+
+@return Project
+*/
+func (a *RepositoriesApiService) PatchV5ReposOwnerRepo(ctx context.Context, owner string, repo string, body RepoPatchParam) (Project, *http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Patch")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ localVarReturnValue Project
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/repos/{owner}/{repo}"
+ localVarPath = strings.Replace(localVarPath, "{"+"owner"+"}", fmt.Sprintf("%v", owner), -1)
+ localVarPath = strings.Replace(localVarPath, "{"+"repo"+"}", fmt.Sprintf("%v", repo), -1)
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ // body params
+ localVarPostBody = &body
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return localVarReturnValue, nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode < 300 {
+ // If we succeed, return the data, otherwise pass on to decode error.
+ err = a.client.decode(&localVarReturnValue, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ if localVarHttpResponse.StatusCode == 200 {
+ var v Project
+ err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err != nil {
+ newErr.error = err.Error()
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+ newErr.model = v
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, nil
+}
+
+/*
+RepositoriesApiService 更新Commit评论
+更新Commit评论
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param owner 仓库所属空间地址(企业、组织或个人的地址path)
+ * @param repo 仓库路径(path)
+ * @param id 评论的ID
+ * @param body 评论的内容
+ * @param optional nil or *PatchV5ReposOwnerRepoCommentsIdOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+
+@return Note
+*/
+
+type PatchV5ReposOwnerRepoCommentsIdOpts struct {
+ AccessToken optional.String
+}
+
+func (a *RepositoriesApiService) PatchV5ReposOwnerRepoCommentsId(ctx context.Context, owner string, repo string, id int32, body string, localVarOptionals *PatchV5ReposOwnerRepoCommentsIdOpts) (Note, *http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Patch")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ localVarReturnValue Note
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/repos/{owner}/{repo}/comments/{id}"
+ localVarPath = strings.Replace(localVarPath, "{"+"owner"+"}", fmt.Sprintf("%v", owner), -1)
+ localVarPath = strings.Replace(localVarPath, "{"+"repo"+"}", fmt.Sprintf("%v", repo), -1)
+ localVarPath = strings.Replace(localVarPath, "{"+"id"+"}", fmt.Sprintf("%v", id), -1)
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarFormParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ localVarFormParams.Add("body", parameterToString(body, ""))
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return localVarReturnValue, nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode < 300 {
+ // If we succeed, return the data, otherwise pass on to decode error.
+ err = a.client.decode(&localVarReturnValue, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ if localVarHttpResponse.StatusCode == 200 {
+ var v Note
+ err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err != nil {
+ newErr.error = err.Error()
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+ newErr.model = v
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, nil
+}
+
+/*
+RepositoriesApiService 更新仓库Release
+更新仓库Release
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param owner 仓库所属空间地址(企业、组织或个人的地址path)
+ * @param repo 仓库路径(path)
+ * @param tagName Tag 名称, 提倡以v字母为前缀做为Release名称,例如v1.0或者v2.3.4
+ * @param name Release 名称
+ * @param body Release 描述
+ * @param id
+ * @param optional nil or *PatchV5ReposOwnerRepoReleasesIdOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+ * @param "Prerelease" (optional.Bool) - 是否为预览版本。默认: false(非预览版本)
+
+@return Release
+*/
+
+type PatchV5ReposOwnerRepoReleasesIdOpts struct {
+ AccessToken optional.String
+ Prerelease optional.Bool
+}
+
+func (a *RepositoriesApiService) PatchV5ReposOwnerRepoReleasesId(ctx context.Context, owner string, repo string, tagName string, name string, body string, id int32, localVarOptionals *PatchV5ReposOwnerRepoReleasesIdOpts) (Release, *http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Patch")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ localVarReturnValue Release
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/repos/{owner}/{repo}/releases/{id}"
+ localVarPath = strings.Replace(localVarPath, "{"+"owner"+"}", fmt.Sprintf("%v", owner), -1)
+ localVarPath = strings.Replace(localVarPath, "{"+"repo"+"}", fmt.Sprintf("%v", repo), -1)
+ localVarPath = strings.Replace(localVarPath, "{"+"id"+"}", fmt.Sprintf("%v", id), -1)
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarFormParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ localVarFormParams.Add("tag_name", parameterToString(tagName, ""))
+ localVarFormParams.Add("name", parameterToString(name, ""))
+ localVarFormParams.Add("body", parameterToString(body, ""))
+ if localVarOptionals != nil && localVarOptionals.Prerelease.IsSet() {
+ localVarFormParams.Add("prerelease", parameterToString(localVarOptionals.Prerelease.Value(), ""))
+ }
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return localVarReturnValue, nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode < 300 {
+ // If we succeed, return the data, otherwise pass on to decode error.
+ err = a.client.decode(&localVarReturnValue, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ if localVarHttpResponse.StatusCode == 200 {
+ var v Release
+ err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err != nil {
+ newErr.error = err.Error()
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+ newErr.model = v
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, nil
+}
+
+/*
+RepositoriesApiService 创建企业仓库
+创建企业仓库
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param name 仓库名称
+ * @param enterprise 企业的路径(path/login)
+ * @param optional nil or *PostV5EnterprisesEnterpriseReposOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+ * @param "Description" (optional.String) - 仓库描述
+ * @param "Homepage" (optional.String) - 主页(eg: https://gitee.com)
+ * @param "HasIssues" (optional.Bool) - 允许提Issue与否。默认: 允许(true)
+ * @param "HasWiki" (optional.Bool) - 提供Wiki与否。默认: 提供(true)
+ * @param "CanComment" (optional.Bool) - 允许用户对仓库进行评论。默认: 允许(true)
+ * @param "AutoInit" (optional.Bool) - 值为true时则会用README初始化仓库。默认: 不初始化(false)
+ * @param "GitignoreTemplate" (optional.String) - Git Ingore模版
+ * @param "LicenseTemplate" (optional.String) - License模版
+ * @param "Private" (optional.Int32) - 仓库开源类型。0(私有), 1(外部开源), 2(内部开源)。默认: 0
+ * @param "Outsourced" (optional.Bool) - 值为true值为外包仓库, false值为内部仓库。默认: 内部仓库(false)
+ * @param "ProjectCreator" (optional.String) - 负责人的username
+ * @param "Members" (optional.String) - 用逗号分开的仓库成员。如: member1,member2
+
+@return Project
+*/
+
+type PostV5EnterprisesEnterpriseReposOpts struct {
+ AccessToken optional.String
+ Description optional.String
+ Homepage optional.String
+ HasIssues optional.Bool
+ HasWiki optional.Bool
+ CanComment optional.Bool
+ AutoInit optional.Bool
+ GitignoreTemplate optional.String
+ LicenseTemplate optional.String
+ Private optional.Int32
+ Outsourced optional.Bool
+ ProjectCreator optional.String
+ Members optional.String
+}
+
+func (a *RepositoriesApiService) PostV5EnterprisesEnterpriseRepos(ctx context.Context, name string, enterprise string, localVarOptionals *PostV5EnterprisesEnterpriseReposOpts) (Project, *http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Post")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ localVarReturnValue Project
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/enterprises/{enterprise}/repos"
+ localVarPath = strings.Replace(localVarPath, "{"+"enterprise"+"}", fmt.Sprintf("%v", enterprise), -1)
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarFormParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ localVarFormParams.Add("name", parameterToString(name, ""))
+ if localVarOptionals != nil && localVarOptionals.Description.IsSet() {
+ localVarFormParams.Add("description", parameterToString(localVarOptionals.Description.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Homepage.IsSet() {
+ localVarFormParams.Add("homepage", parameterToString(localVarOptionals.Homepage.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.HasIssues.IsSet() {
+ localVarFormParams.Add("has_issues", parameterToString(localVarOptionals.HasIssues.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.HasWiki.IsSet() {
+ localVarFormParams.Add("has_wiki", parameterToString(localVarOptionals.HasWiki.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.CanComment.IsSet() {
+ localVarFormParams.Add("can_comment", parameterToString(localVarOptionals.CanComment.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.AutoInit.IsSet() {
+ localVarFormParams.Add("auto_init", parameterToString(localVarOptionals.AutoInit.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.GitignoreTemplate.IsSet() {
+ localVarFormParams.Add("gitignore_template", parameterToString(localVarOptionals.GitignoreTemplate.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.LicenseTemplate.IsSet() {
+ localVarFormParams.Add("license_template", parameterToString(localVarOptionals.LicenseTemplate.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Private.IsSet() {
+ localVarFormParams.Add("private", parameterToString(localVarOptionals.Private.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Outsourced.IsSet() {
+ localVarFormParams.Add("outsourced", parameterToString(localVarOptionals.Outsourced.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.ProjectCreator.IsSet() {
+ localVarFormParams.Add("project_creator", parameterToString(localVarOptionals.ProjectCreator.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Members.IsSet() {
+ localVarFormParams.Add("members", parameterToString(localVarOptionals.Members.Value(), ""))
+ }
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return localVarReturnValue, nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode < 300 {
+ // If we succeed, return the data, otherwise pass on to decode error.
+ err = a.client.decode(&localVarReturnValue, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ if localVarHttpResponse.StatusCode == 201 {
+ var v Project
+ err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err != nil {
+ newErr.error = err.Error()
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+ newErr.model = v
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, nil
+}
+
+/*
+RepositoriesApiService 创建组织仓库
+创建组织仓库
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param org 组织的路径(path/login)
+ * @param body Repositorie 内容
+
+@return Project
+*/
+func (a *RepositoriesApiService) PostV5OrgsOrgRepos(ctx context.Context, org string, body RepositoryPostParam) (Project, *http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Post")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ localVarReturnValue Project
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/orgs/{org}/repos"
+ localVarPath = strings.Replace(localVarPath, "{"+"org"+"}", fmt.Sprintf("%v", org), -1)
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ // body params
+ localVarPostBody = &body
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return localVarReturnValue, nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode < 300 {
+ // If we succeed, return the data, otherwise pass on to decode error.
+ err = a.client.decode(&localVarReturnValue, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ if localVarHttpResponse.StatusCode == 201 {
+ var v Project
+ err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err != nil {
+ newErr.error = err.Error()
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+ newErr.model = v
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, nil
+}
+
+/*
+RepositoriesApiService 创建分支
+创建分支
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param owner 仓库所属空间地址(企业、组织或个人的地址path)
+ * @param repo 仓库路径(path)
+ * @param refs 起点名称, 默认:master
+ * @param branchName 新创建的分支名称
+ * @param optional nil or *PostV5ReposOwnerRepoBranchesOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+
+@return CompleteBranch
+*/
+
+type PostV5ReposOwnerRepoBranchesOpts struct {
+ AccessToken optional.String
+}
+
+func (a *RepositoriesApiService) PostV5ReposOwnerRepoBranches(ctx context.Context, owner string, repo string, refs string, branchName string, localVarOptionals *PostV5ReposOwnerRepoBranchesOpts) (CompleteBranch, *http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Post")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ localVarReturnValue CompleteBranch
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/repos/{owner}/{repo}/branches"
+ localVarPath = strings.Replace(localVarPath, "{"+"owner"+"}", fmt.Sprintf("%v", owner), -1)
+ localVarPath = strings.Replace(localVarPath, "{"+"repo"+"}", fmt.Sprintf("%v", repo), -1)
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarFormParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ localVarFormParams.Add("refs", parameterToString(refs, ""))
+ localVarFormParams.Add("branch_name", parameterToString(branchName, ""))
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return localVarReturnValue, nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode < 300 {
+ // If we succeed, return the data, otherwise pass on to decode error.
+ err = a.client.decode(&localVarReturnValue, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ if localVarHttpResponse.StatusCode == 201 {
+ var v CompleteBranch
+ err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err != nil {
+ newErr.error = err.Error()
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+ newErr.model = v
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, nil
+}
+
+/*
+RepositoriesApiService 创建Commit评论
+创建Commit评论
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param owner 仓库所属空间地址(企业、组织或个人的地址path)
+ * @param repo 仓库路径(path)
+ * @param sha 评论的sha值
+ * @param body 评论的内容
+ * @param optional nil or *PostV5ReposOwnerRepoCommitsShaCommentsOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+ * @param "Path" (optional.String) - 文件的相对路径
+ * @param "Position" (optional.Int32) - Diff的相对行数
+
+@return Note
+*/
+
+type PostV5ReposOwnerRepoCommitsShaCommentsOpts struct {
+ AccessToken optional.String
+ Path optional.String
+ Position optional.Int32
+}
+
+func (a *RepositoriesApiService) PostV5ReposOwnerRepoCommitsShaComments(ctx context.Context, owner string, repo string, sha string, body string, localVarOptionals *PostV5ReposOwnerRepoCommitsShaCommentsOpts) (Note, *http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Post")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ localVarReturnValue Note
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/repos/{owner}/{repo}/commits/{sha}/comments"
+ localVarPath = strings.Replace(localVarPath, "{"+"owner"+"}", fmt.Sprintf("%v", owner), -1)
+ localVarPath = strings.Replace(localVarPath, "{"+"repo"+"}", fmt.Sprintf("%v", repo), -1)
+ localVarPath = strings.Replace(localVarPath, "{"+"sha"+"}", fmt.Sprintf("%v", sha), -1)
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarFormParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ localVarFormParams.Add("body", parameterToString(body, ""))
+ if localVarOptionals != nil && localVarOptionals.Path.IsSet() {
+ localVarFormParams.Add("path", parameterToString(localVarOptionals.Path.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Position.IsSet() {
+ localVarFormParams.Add("position", parameterToString(localVarOptionals.Position.Value(), ""))
+ }
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return localVarReturnValue, nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode < 300 {
+ // If we succeed, return the data, otherwise pass on to decode error.
+ err = a.client.decode(&localVarReturnValue, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ if localVarHttpResponse.StatusCode == 201 {
+ var v Note
+ err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err != nil {
+ newErr.error = err.Error()
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+ newErr.model = v
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, nil
+}
+
+/*
+RepositoriesApiService 新建文件
+新建文件
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param owner 仓库所属空间地址(企业、组织或个人的地址path)
+ * @param repo 仓库路径(path)
+ * @param path 文件的路径
+ * @param content 文件内容, 要用 base64 编码
+ * @param message 提交信息
+ * @param optional nil or *PostV5ReposOwnerRepoContentsPathOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+ * @param "Branch" (optional.String) - 分支名称。默认为仓库对默认分支
+ * @param "CommitterName" (optional.String) - Committer的名字,默认为当前用户的名字
+ * @param "CommitterEmail" (optional.String) - Committer的邮箱,默认为当前用户的邮箱
+ * @param "AuthorName" (optional.String) - Author的名字,默认为当前用户的名字
+ * @param "AuthorEmail" (optional.String) - Author的邮箱,默认为当前用户的邮箱
+
+@return CommitContent
+*/
+
+type PostV5ReposOwnerRepoContentsPathOpts struct {
+ AccessToken optional.String
+ Branch optional.String
+ CommitterName optional.String
+ CommitterEmail optional.String
+ AuthorName optional.String
+ AuthorEmail optional.String
+}
+
+func (a *RepositoriesApiService) PostV5ReposOwnerRepoContentsPath(ctx context.Context, owner string, repo string, path string, content string, message string, localVarOptionals *PostV5ReposOwnerRepoContentsPathOpts) (CommitContent, *http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Post")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ localVarReturnValue CommitContent
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/repos/{owner}/{repo}/contents/{path}"
+ localVarPath = strings.Replace(localVarPath, "{"+"owner"+"}", fmt.Sprintf("%v", owner), -1)
+ localVarPath = strings.Replace(localVarPath, "{"+"repo"+"}", fmt.Sprintf("%v", repo), -1)
+ localVarPath = strings.Replace(localVarPath, "{"+"path"+"}", fmt.Sprintf("%v", path), -1)
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarFormParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ localVarFormParams.Add("content", parameterToString(content, ""))
+ localVarFormParams.Add("message", parameterToString(message, ""))
+ if localVarOptionals != nil && localVarOptionals.Branch.IsSet() {
+ localVarFormParams.Add("branch", parameterToString(localVarOptionals.Branch.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.CommitterName.IsSet() {
+ localVarFormParams.Add("committer[name]", parameterToString(localVarOptionals.CommitterName.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.CommitterEmail.IsSet() {
+ localVarFormParams.Add("committer[email]", parameterToString(localVarOptionals.CommitterEmail.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.AuthorName.IsSet() {
+ localVarFormParams.Add("author[name]", parameterToString(localVarOptionals.AuthorName.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.AuthorEmail.IsSet() {
+ localVarFormParams.Add("author[email]", parameterToString(localVarOptionals.AuthorEmail.Value(), ""))
+ }
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return localVarReturnValue, nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode < 300 {
+ // If we succeed, return the data, otherwise pass on to decode error.
+ err = a.client.decode(&localVarReturnValue, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ if localVarHttpResponse.StatusCode == 201 {
+ var v CommitContent
+ err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err != nil {
+ newErr.error = err.Error()
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+ newErr.model = v
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, nil
+}
+
+/*
+RepositoriesApiService Fork一个仓库
+Fork一个仓库
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param owner 仓库所属空间地址(企业、组织或个人的地址path)
+ * @param repo 仓库路径(path)
+ * @param optional nil or *PostV5ReposOwnerRepoForksOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+ * @param "Organization" (optional.String) - 组织空间地址,不填写默认Fork到用户个人空间地址
+
+@return Project
+*/
+
+type PostV5ReposOwnerRepoForksOpts struct {
+ AccessToken optional.String
+ Organization optional.String
+}
+
+func (a *RepositoriesApiService) PostV5ReposOwnerRepoForks(ctx context.Context, owner string, repo string, localVarOptionals *PostV5ReposOwnerRepoForksOpts) (Project, *http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Post")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ localVarReturnValue Project
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/repos/{owner}/{repo}/forks"
+ localVarPath = strings.Replace(localVarPath, "{"+"owner"+"}", fmt.Sprintf("%v", owner), -1)
+ localVarPath = strings.Replace(localVarPath, "{"+"repo"+"}", fmt.Sprintf("%v", repo), -1)
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarFormParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Organization.IsSet() {
+ localVarFormParams.Add("organization", parameterToString(localVarOptionals.Organization.Value(), ""))
+ }
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return localVarReturnValue, nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode < 300 {
+ // If we succeed, return the data, otherwise pass on to decode error.
+ err = a.client.decode(&localVarReturnValue, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ if localVarHttpResponse.StatusCode == 201 {
+ var v Project
+ err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err != nil {
+ newErr.error = err.Error()
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+ newErr.model = v
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, nil
+}
+
+/*
+RepositoriesApiService 为仓库添加公钥
+为仓库添加公钥
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param owner 仓库所属空间地址(企业、组织或个人的地址path)
+ * @param repo 仓库路径(path)
+ * @param key 公钥内容
+ * @param title 公钥名称
+ * @param optional nil or *PostV5ReposOwnerRepoKeysOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+
+@return SshKey
+*/
+
+type PostV5ReposOwnerRepoKeysOpts struct {
+ AccessToken optional.String
+}
+
+func (a *RepositoriesApiService) PostV5ReposOwnerRepoKeys(ctx context.Context, owner string, repo string, key string, title string, localVarOptionals *PostV5ReposOwnerRepoKeysOpts) (SshKey, *http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Post")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ localVarReturnValue SshKey
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/repos/{owner}/{repo}/keys"
+ localVarPath = strings.Replace(localVarPath, "{"+"owner"+"}", fmt.Sprintf("%v", owner), -1)
+ localVarPath = strings.Replace(localVarPath, "{"+"repo"+"}", fmt.Sprintf("%v", repo), -1)
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarFormParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ localVarFormParams.Add("key", parameterToString(key, ""))
+ localVarFormParams.Add("title", parameterToString(title, ""))
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return localVarReturnValue, nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode < 300 {
+ // If we succeed, return the data, otherwise pass on to decode error.
+ err = a.client.decode(&localVarReturnValue, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ if localVarHttpResponse.StatusCode == 201 {
+ var v SshKey
+ err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err != nil {
+ newErr.error = err.Error()
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+ newErr.model = v
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, nil
+}
+
+/*
+RepositoriesApiService 请求建立Pages
+请求建立Pages
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param owner 仓库所属空间地址(企业、组织或个人的地址path)
+ * @param repo 仓库路径(path)
+ * @param optional nil or *PostV5ReposOwnerRepoPagesBuildsOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+
+
+*/
+
+type PostV5ReposOwnerRepoPagesBuildsOpts struct {
+ AccessToken optional.String
+}
+
+func (a *RepositoriesApiService) PostV5ReposOwnerRepoPagesBuilds(ctx context.Context, owner string, repo string, localVarOptionals *PostV5ReposOwnerRepoPagesBuildsOpts) (*http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Post")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/repos/{owner}/{repo}/pages/builds"
+ localVarPath = strings.Replace(localVarPath, "{"+"owner"+"}", fmt.Sprintf("%v", owner), -1)
+ localVarPath = strings.Replace(localVarPath, "{"+"repo"+"}", fmt.Sprintf("%v", repo), -1)
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarFormParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ return localVarHttpResponse, newErr
+ }
+
+ return localVarHttpResponse, nil
+}
+
+/*
+RepositoriesApiService 创建仓库Release
+创建仓库Release
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param owner 仓库所属空间地址(企业、组织或个人的地址path)
+ * @param repo 仓库路径(path)
+ * @param tagName Tag 名称, 提倡以v字母为前缀做为Release名称,例如v1.0或者v2.3.4
+ * @param name Release 名称
+ * @param body Release 描述
+ * @param targetCommitish 分支名称或者commit SHA, 默认是当前默认分支
+ * @param optional nil or *PostV5ReposOwnerRepoReleasesOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+ * @param "Prerelease" (optional.Bool) - 是否为预览版本。默认: false(非预览版本)
+
+@return Release
+*/
+
+type PostV5ReposOwnerRepoReleasesOpts struct {
+ AccessToken optional.String
+ Prerelease optional.Bool
+}
+
+func (a *RepositoriesApiService) PostV5ReposOwnerRepoReleases(ctx context.Context, owner string, repo string, tagName string, name string, body string, targetCommitish string, localVarOptionals *PostV5ReposOwnerRepoReleasesOpts) (Release, *http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Post")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ localVarReturnValue Release
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/repos/{owner}/{repo}/releases"
+ localVarPath = strings.Replace(localVarPath, "{"+"owner"+"}", fmt.Sprintf("%v", owner), -1)
+ localVarPath = strings.Replace(localVarPath, "{"+"repo"+"}", fmt.Sprintf("%v", repo), -1)
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarFormParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ localVarFormParams.Add("tag_name", parameterToString(tagName, ""))
+ localVarFormParams.Add("name", parameterToString(name, ""))
+ localVarFormParams.Add("body", parameterToString(body, ""))
+ if localVarOptionals != nil && localVarOptionals.Prerelease.IsSet() {
+ localVarFormParams.Add("prerelease", parameterToString(localVarOptionals.Prerelease.Value(), ""))
+ }
+ localVarFormParams.Add("target_commitish", parameterToString(targetCommitish, ""))
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return localVarReturnValue, nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode < 300 {
+ // If we succeed, return the data, otherwise pass on to decode error.
+ err = a.client.decode(&localVarReturnValue, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ if localVarHttpResponse.StatusCode == 201 {
+ var v Release
+ err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err != nil {
+ newErr.error = err.Error()
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+ newErr.model = v
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, nil
+}
+
+/*
+RepositoriesApiService 创建一个仓库
+创建一个仓库
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param name 仓库名称
+ * @param optional nil or *PostV5UserReposOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+ * @param "Description" (optional.String) - 仓库描述
+ * @param "Homepage" (optional.String) - 主页(eg: https://gitee.com)
+ * @param "HasIssues" (optional.Bool) - 允许提Issue与否。默认: 允许(true)
+ * @param "HasWiki" (optional.Bool) - 提供Wiki与否。默认: 提供(true)
+ * @param "CanComment" (optional.Bool) - 允许用户对仓库进行评论。默认: 允许(true)
+ * @param "AutoInit" (optional.Bool) - 值为true时则会用README初始化仓库。默认: 不初始化(false)
+ * @param "GitignoreTemplate" (optional.String) - Git Ingore模版
+ * @param "LicenseTemplate" (optional.String) - License模版
+ * @param "Private" (optional.Bool) - 仓库公开或私有。默认: 公开(false)
+
+@return Project
+*/
+
+type PostV5UserReposOpts struct {
+ AccessToken optional.String
+ Description optional.String
+ Homepage optional.String
+ HasIssues optional.Bool
+ HasWiki optional.Bool
+ CanComment optional.Bool
+ AutoInit optional.Bool
+ GitignoreTemplate optional.String
+ LicenseTemplate optional.String
+ Private optional.Bool
+}
+
+func (a *RepositoriesApiService) PostV5UserRepos(ctx context.Context, name string, localVarOptionals *PostV5UserReposOpts) (Project, *http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Post")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ localVarReturnValue Project
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/user/repos"
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarFormParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ localVarFormParams.Add("name", parameterToString(name, ""))
+ if localVarOptionals != nil && localVarOptionals.Description.IsSet() {
+ localVarFormParams.Add("description", parameterToString(localVarOptionals.Description.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Homepage.IsSet() {
+ localVarFormParams.Add("homepage", parameterToString(localVarOptionals.Homepage.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.HasIssues.IsSet() {
+ localVarFormParams.Add("has_issues", parameterToString(localVarOptionals.HasIssues.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.HasWiki.IsSet() {
+ localVarFormParams.Add("has_wiki", parameterToString(localVarOptionals.HasWiki.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.CanComment.IsSet() {
+ localVarFormParams.Add("can_comment", parameterToString(localVarOptionals.CanComment.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.AutoInit.IsSet() {
+ localVarFormParams.Add("auto_init", parameterToString(localVarOptionals.AutoInit.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.GitignoreTemplate.IsSet() {
+ localVarFormParams.Add("gitignore_template", parameterToString(localVarOptionals.GitignoreTemplate.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.LicenseTemplate.IsSet() {
+ localVarFormParams.Add("license_template", parameterToString(localVarOptionals.LicenseTemplate.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Private.IsSet() {
+ localVarFormParams.Add("private", parameterToString(localVarOptionals.Private.Value(), ""))
+ }
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return localVarReturnValue, nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode < 300 {
+ // If we succeed, return the data, otherwise pass on to decode error.
+ err = a.client.decode(&localVarReturnValue, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ if localVarHttpResponse.StatusCode == 201 {
+ var v Project
+ err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err != nil {
+ newErr.error = err.Error()
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+ newErr.model = v
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, nil
+}
+
+/*
+RepositoriesApiService 设置分支保护
+设置分支保护
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param owner 仓库所属空间地址(企业、组织或个人的地址path)
+ * @param repo 仓库路径(path)
+ * @param branch 分支名称
+ * @param body 设置分支保护参数
+
+@return CompleteBranch
+*/
+func (a *RepositoriesApiService) PutV5ReposOwnerRepoBranchesBranchProtection(ctx context.Context, owner string, repo string, branch string, body BranchProtectionPutParam) (CompleteBranch, *http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Put")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ localVarReturnValue CompleteBranch
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/repos/{owner}/{repo}/branches/{branch}/protection"
+ localVarPath = strings.Replace(localVarPath, "{"+"owner"+"}", fmt.Sprintf("%v", owner), -1)
+ localVarPath = strings.Replace(localVarPath, "{"+"repo"+"}", fmt.Sprintf("%v", repo), -1)
+ localVarPath = strings.Replace(localVarPath, "{"+"branch"+"}", fmt.Sprintf("%v", branch), -1)
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ // body params
+ localVarPostBody = &body
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return localVarReturnValue, nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode < 300 {
+ // If we succeed, return the data, otherwise pass on to decode error.
+ err = a.client.decode(&localVarReturnValue, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ if localVarHttpResponse.StatusCode == 200 {
+ var v CompleteBranch
+ err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err != nil {
+ newErr.error = err.Error()
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+ newErr.model = v
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, nil
+}
+
+/*
+RepositoriesApiService 清空一个仓库
+清空一个仓库
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param owner 仓库所属空间地址(企业、组织或个人的地址path)
+ * @param repo 仓库路径(path)
+ * @param optional nil or *PutV5ReposOwnerRepoClearOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+
+
+*/
+
+type PutV5ReposOwnerRepoClearOpts struct {
+ AccessToken optional.String
+}
+
+func (a *RepositoriesApiService) PutV5ReposOwnerRepoClear(ctx context.Context, owner string, repo string, localVarOptionals *PutV5ReposOwnerRepoClearOpts) (*http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Put")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/repos/{owner}/{repo}/clear"
+ localVarPath = strings.Replace(localVarPath, "{"+"owner"+"}", fmt.Sprintf("%v", owner), -1)
+ localVarPath = strings.Replace(localVarPath, "{"+"repo"+"}", fmt.Sprintf("%v", repo), -1)
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarFormParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ return localVarHttpResponse, newErr
+ }
+
+ return localVarHttpResponse, nil
+}
+
+/*
+RepositoriesApiService 添加仓库成员
+添加仓库成员
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param owner 仓库所属空间地址(企业、组织或个人的地址path)
+ * @param repo 仓库路径(path)
+ * @param username 用户名(username/login)
+ * @param body 仓库成员内容
+
+@return ProjectMember
+*/
+func (a *RepositoriesApiService) PutV5ReposOwnerRepoCollaboratorsUsername(ctx context.Context, owner string, repo string, username string, body ProjectMemberPutParam) (ProjectMember, *http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Put")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ localVarReturnValue ProjectMember
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/repos/{owner}/{repo}/collaborators/{username}"
+ localVarPath = strings.Replace(localVarPath, "{"+"owner"+"}", fmt.Sprintf("%v", owner), -1)
+ localVarPath = strings.Replace(localVarPath, "{"+"repo"+"}", fmt.Sprintf("%v", repo), -1)
+ localVarPath = strings.Replace(localVarPath, "{"+"username"+"}", fmt.Sprintf("%v", username), -1)
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ // body params
+ localVarPostBody = &body
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return localVarReturnValue, nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode < 300 {
+ // If we succeed, return the data, otherwise pass on to decode error.
+ err = a.client.decode(&localVarReturnValue, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ if localVarHttpResponse.StatusCode == 200 {
+ var v ProjectMember
+ err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err != nil {
+ newErr.error = err.Error()
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+ newErr.model = v
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, nil
+}
+
+/*
+RepositoriesApiService 更新文件
+更新文件
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param owner 仓库所属空间地址(企业、组织或个人的地址path)
+ * @param repo 仓库路径(path)
+ * @param path 文件的路径
+ * @param content 文件内容, 要用 base64 编码
+ * @param sha 文件的 Blob SHA,可通过 [获取仓库具体路径下的内容] API 获取
+ * @param message 提交信息
+ * @param optional nil or *PutV5ReposOwnerRepoContentsPathOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+ * @param "Branch" (optional.String) - 分支名称。默认为仓库对默认分支
+ * @param "CommitterName" (optional.String) - Committer的名字,默认为当前用户的名字
+ * @param "CommitterEmail" (optional.String) - Committer的邮箱,默认为当前用户的邮箱
+ * @param "AuthorName" (optional.String) - Author的名字,默认为当前用户的名字
+ * @param "AuthorEmail" (optional.String) - Author的邮箱,默认为当前用户的邮箱
+
+@return CommitContent
+*/
+
+type PutV5ReposOwnerRepoContentsPathOpts struct {
+ AccessToken optional.String
+ Branch optional.String
+ CommitterName optional.String
+ CommitterEmail optional.String
+ AuthorName optional.String
+ AuthorEmail optional.String
+}
+
+func (a *RepositoriesApiService) PutV5ReposOwnerRepoContentsPath(ctx context.Context, owner string, repo string, path string, content string, sha string, message string, localVarOptionals *PutV5ReposOwnerRepoContentsPathOpts) (CommitContent, *http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Put")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ localVarReturnValue CommitContent
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/repos/{owner}/{repo}/contents/{path}"
+ localVarPath = strings.Replace(localVarPath, "{"+"owner"+"}", fmt.Sprintf("%v", owner), -1)
+ localVarPath = strings.Replace(localVarPath, "{"+"repo"+"}", fmt.Sprintf("%v", repo), -1)
+ localVarPath = strings.Replace(localVarPath, "{"+"path"+"}", fmt.Sprintf("%v", path), -1)
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarFormParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ localVarFormParams.Add("content", parameterToString(content, ""))
+ localVarFormParams.Add("sha", parameterToString(sha, ""))
+ localVarFormParams.Add("message", parameterToString(message, ""))
+ if localVarOptionals != nil && localVarOptionals.Branch.IsSet() {
+ localVarFormParams.Add("branch", parameterToString(localVarOptionals.Branch.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.CommitterName.IsSet() {
+ localVarFormParams.Add("committer[name]", parameterToString(localVarOptionals.CommitterName.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.CommitterEmail.IsSet() {
+ localVarFormParams.Add("committer[email]", parameterToString(localVarOptionals.CommitterEmail.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.AuthorName.IsSet() {
+ localVarFormParams.Add("author[name]", parameterToString(localVarOptionals.AuthorName.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.AuthorEmail.IsSet() {
+ localVarFormParams.Add("author[email]", parameterToString(localVarOptionals.AuthorEmail.Value(), ""))
+ }
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return localVarReturnValue, nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode < 300 {
+ // If we succeed, return the data, otherwise pass on to decode error.
+ err = a.client.decode(&localVarReturnValue, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ if localVarHttpResponse.StatusCode == 200 {
+ var v CommitContent
+ err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err != nil {
+ newErr.error = err.Error()
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+ newErr.model = v
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, nil
+}
+
+/*
+RepositoriesApiService 启用仓库公钥
+启用仓库公钥
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param owner 仓库所属空间地址(企业、组织或个人的地址path)
+ * @param repo 仓库路径(path)
+ * @param id 公钥 ID
+ * @param optional nil or *PutV5ReposOwnerRepoKeysEnableIdOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+
+
+*/
+
+type PutV5ReposOwnerRepoKeysEnableIdOpts struct {
+ AccessToken optional.String
+}
+
+func (a *RepositoriesApiService) PutV5ReposOwnerRepoKeysEnableId(ctx context.Context, owner string, repo string, id int32, localVarOptionals *PutV5ReposOwnerRepoKeysEnableIdOpts) (*http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Put")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/repos/{owner}/{repo}/keys/enable/{id}"
+ localVarPath = strings.Replace(localVarPath, "{"+"owner"+"}", fmt.Sprintf("%v", owner), -1)
+ localVarPath = strings.Replace(localVarPath, "{"+"repo"+"}", fmt.Sprintf("%v", repo), -1)
+ localVarPath = strings.Replace(localVarPath, "{"+"id"+"}", fmt.Sprintf("%v", id), -1)
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarFormParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ return localVarHttpResponse, newErr
+ }
+
+ return localVarHttpResponse, nil
+}
diff --git a/vendor/gitee.com/openeuler/go-gitee/gitee/api_search.go b/vendor/gitee.com/openeuler/go-gitee/gitee/api_search.go
new file mode 100644
index 0000000000000000000000000000000000000000..d185b78ea919f6484d4b1b8684f321a6a7422f7c
--- /dev/null
+++ b/vendor/gitee.com/openeuler/go-gitee/gitee/api_search.go
@@ -0,0 +1,558 @@
+/*
+ * 码云 Open API
+ *
+ * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen)
+ *
+ * API version: 5.3.2
+ * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
+ */
+
+package gitee
+
+import (
+ "context"
+ "io/ioutil"
+ "net/http"
+ "net/url"
+ "strings"
+
+ "github.com/antihax/optional"
+)
+
+// Linger please
+var (
+ _ context.Context
+)
+
+type SearchApiService service
+
+/*
+SearchApiService 搜索代码片段
+搜索代码片段
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param q 搜索关键字
+ * @param optional nil or *GetV5SearchGistsOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+ * @param "Page" (optional.Int32) - 当前的页码
+ * @param "PerPage" (optional.Int32) - 每页的数量,最大为 100
+ * @param "Language" (optional.String) - 筛选指定语言的代码片段
+ * @param "Owner" (optional.String) - 筛选所属用户 (username/login) 的代码片段
+ * @param "Sort" (optional.String) - 排序字段,created_at(创建时间)、updated_at(更新时间)、notes_count(评论数)、stars_count(收藏数)、forks_count(Fork 数),默认为最佳匹配
+ * @param "Order" (optional.String) - 排序顺序: desc(default)、asc
+
+@return []Code
+*/
+
+type GetV5SearchGistsOpts struct {
+ AccessToken optional.String
+ Page optional.Int32
+ PerPage optional.Int32
+ Language optional.String
+ Owner optional.String
+ Sort optional.String
+ Order optional.String
+}
+
+func (a *SearchApiService) GetV5SearchGists(ctx context.Context, q string, localVarOptionals *GetV5SearchGistsOpts) ([]Code, *http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Get")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ localVarReturnValue []Code
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/search/gists"
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarQueryParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ localVarQueryParams.Add("q", parameterToString(q, ""))
+ if localVarOptionals != nil && localVarOptionals.Page.IsSet() {
+ localVarQueryParams.Add("page", parameterToString(localVarOptionals.Page.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.PerPage.IsSet() {
+ localVarQueryParams.Add("per_page", parameterToString(localVarOptionals.PerPage.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Language.IsSet() {
+ localVarQueryParams.Add("language", parameterToString(localVarOptionals.Language.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Owner.IsSet() {
+ localVarQueryParams.Add("owner", parameterToString(localVarOptionals.Owner.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Sort.IsSet() {
+ localVarQueryParams.Add("sort", parameterToString(localVarOptionals.Sort.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Order.IsSet() {
+ localVarQueryParams.Add("order", parameterToString(localVarOptionals.Order.Value(), ""))
+ }
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return localVarReturnValue, nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode < 300 {
+ // If we succeed, return the data, otherwise pass on to decode error.
+ err = a.client.decode(&localVarReturnValue, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ if localVarHttpResponse.StatusCode == 200 {
+ var v []Code
+ err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err != nil {
+ newErr.error = err.Error()
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+ newErr.model = v
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, nil
+}
+
+/*
+SearchApiService 搜索 Issues
+搜索 Issues
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param q 搜索关键字
+ * @param optional nil or *GetV5SearchIssuesOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+ * @param "Page" (optional.Int32) - 当前的页码
+ * @param "PerPage" (optional.Int32) - 每页的数量,最大为 100
+ * @param "Repo" (optional.String) - 筛选指定仓库 (path, e.g. oschina/git-osc) 的 issues
+ * @param "Language" (optional.String) - 筛选指定语言的 issues
+ * @param "Label" (optional.String) - 筛选指定标签的 issues
+ * @param "State" (optional.String) - 筛选指定状态的 issues, open(开启)、closed(完成)、rejected(拒绝)
+ * @param "Author" (optional.String) - 筛选指定创建者 (username/login) 的 issues
+ * @param "Assignee" (optional.String) - 筛选指定负责人 (username/login) 的 issues
+ * @param "Sort" (optional.String) - 排序字段,created_at(创建时间)、last_push_at(更新时间)、notes_count(评论数),默认为最佳匹配
+ * @param "Order" (optional.String) - 排序顺序: desc(default)、asc
+
+@return []Issue
+*/
+
+type GetV5SearchIssuesOpts struct {
+ AccessToken optional.String
+ Page optional.Int32
+ PerPage optional.Int32
+ Repo optional.String
+ Language optional.String
+ Label optional.String
+ State optional.String
+ Author optional.String
+ Assignee optional.String
+ Sort optional.String
+ Order optional.String
+}
+
+func (a *SearchApiService) GetV5SearchIssues(ctx context.Context, q string, localVarOptionals *GetV5SearchIssuesOpts) ([]Issue, *http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Get")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ localVarReturnValue []Issue
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/search/issues"
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarQueryParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ localVarQueryParams.Add("q", parameterToString(q, ""))
+ if localVarOptionals != nil && localVarOptionals.Page.IsSet() {
+ localVarQueryParams.Add("page", parameterToString(localVarOptionals.Page.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.PerPage.IsSet() {
+ localVarQueryParams.Add("per_page", parameterToString(localVarOptionals.PerPage.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Repo.IsSet() {
+ localVarQueryParams.Add("repo", parameterToString(localVarOptionals.Repo.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Language.IsSet() {
+ localVarQueryParams.Add("language", parameterToString(localVarOptionals.Language.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Label.IsSet() {
+ localVarQueryParams.Add("label", parameterToString(localVarOptionals.Label.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.State.IsSet() {
+ localVarQueryParams.Add("state", parameterToString(localVarOptionals.State.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Author.IsSet() {
+ localVarQueryParams.Add("author", parameterToString(localVarOptionals.Author.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Assignee.IsSet() {
+ localVarQueryParams.Add("assignee", parameterToString(localVarOptionals.Assignee.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Sort.IsSet() {
+ localVarQueryParams.Add("sort", parameterToString(localVarOptionals.Sort.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Order.IsSet() {
+ localVarQueryParams.Add("order", parameterToString(localVarOptionals.Order.Value(), ""))
+ }
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return localVarReturnValue, nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode < 300 {
+ // If we succeed, return the data, otherwise pass on to decode error.
+ err = a.client.decode(&localVarReturnValue, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ if localVarHttpResponse.StatusCode == 200 {
+ var v []Issue
+ err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err != nil {
+ newErr.error = err.Error()
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+ newErr.model = v
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, nil
+}
+
+/*
+SearchApiService 搜索仓库
+搜索仓库
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param q 搜索关键字
+ * @param optional nil or *GetV5SearchRepositoriesOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+ * @param "Page" (optional.Int32) - 当前的页码
+ * @param "PerPage" (optional.Int32) - 每页的数量,最大为 100
+ * @param "Owner" (optional.String) - 筛选指定空间地址(企业、组织或个人的地址 path) 的仓库
+ * @param "Fork" (optional.Bool) - 是否搜索含 fork 的仓库,默认:否
+ * @param "Language" (optional.String) - 筛选指定语言的仓库
+ * @param "Sort" (optional.String) - 排序字段,created_at(创建时间)、last_push_at(更新时间)、stars_count(收藏数)、forks_count(Fork 数)、watches_count(关注数),默认为最佳匹配
+ * @param "Order" (optional.String) - 排序顺序: desc(default)、asc
+
+@return []Project
+*/
+
+type GetV5SearchRepositoriesOpts struct {
+ AccessToken optional.String
+ Page optional.Int32
+ PerPage optional.Int32
+ Owner optional.String
+ Fork optional.Bool
+ Language optional.String
+ Sort optional.String
+ Order optional.String
+}
+
+func (a *SearchApiService) GetV5SearchRepositories(ctx context.Context, q string, localVarOptionals *GetV5SearchRepositoriesOpts) ([]Project, *http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Get")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ localVarReturnValue []Project
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/search/repositories"
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarQueryParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ localVarQueryParams.Add("q", parameterToString(q, ""))
+ if localVarOptionals != nil && localVarOptionals.Page.IsSet() {
+ localVarQueryParams.Add("page", parameterToString(localVarOptionals.Page.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.PerPage.IsSet() {
+ localVarQueryParams.Add("per_page", parameterToString(localVarOptionals.PerPage.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Owner.IsSet() {
+ localVarQueryParams.Add("owner", parameterToString(localVarOptionals.Owner.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Fork.IsSet() {
+ localVarQueryParams.Add("fork", parameterToString(localVarOptionals.Fork.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Language.IsSet() {
+ localVarQueryParams.Add("language", parameterToString(localVarOptionals.Language.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Sort.IsSet() {
+ localVarQueryParams.Add("sort", parameterToString(localVarOptionals.Sort.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Order.IsSet() {
+ localVarQueryParams.Add("order", parameterToString(localVarOptionals.Order.Value(), ""))
+ }
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return localVarReturnValue, nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode < 300 {
+ // If we succeed, return the data, otherwise pass on to decode error.
+ err = a.client.decode(&localVarReturnValue, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ if localVarHttpResponse.StatusCode == 200 {
+ var v []Project
+ err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err != nil {
+ newErr.error = err.Error()
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+ newErr.model = v
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, nil
+}
+
+/*
+SearchApiService 搜索用户
+搜索用户
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param q 搜索关键字
+ * @param optional nil or *GetV5SearchUsersOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+ * @param "Page" (optional.Int32) - 当前的页码
+ * @param "PerPage" (optional.Int32) - 每页的数量,最大为 100
+ * @param "Sort" (optional.String) - 排序字段,joined_at(注册时间),默认为最佳匹配
+ * @param "Order" (optional.String) - 排序顺序: desc(default)、asc
+
+@return []User
+*/
+
+type GetV5SearchUsersOpts struct {
+ AccessToken optional.String
+ Page optional.Int32
+ PerPage optional.Int32
+ Sort optional.String
+ Order optional.String
+}
+
+func (a *SearchApiService) GetV5SearchUsers(ctx context.Context, q string, localVarOptionals *GetV5SearchUsersOpts) ([]User, *http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Get")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ localVarReturnValue []User
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/search/users"
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarQueryParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ localVarQueryParams.Add("q", parameterToString(q, ""))
+ if localVarOptionals != nil && localVarOptionals.Page.IsSet() {
+ localVarQueryParams.Add("page", parameterToString(localVarOptionals.Page.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.PerPage.IsSet() {
+ localVarQueryParams.Add("per_page", parameterToString(localVarOptionals.PerPage.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Sort.IsSet() {
+ localVarQueryParams.Add("sort", parameterToString(localVarOptionals.Sort.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Order.IsSet() {
+ localVarQueryParams.Add("order", parameterToString(localVarOptionals.Order.Value(), ""))
+ }
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return localVarReturnValue, nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode < 300 {
+ // If we succeed, return the data, otherwise pass on to decode error.
+ err = a.client.decode(&localVarReturnValue, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ if localVarHttpResponse.StatusCode == 200 {
+ var v []User
+ err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err != nil {
+ newErr.error = err.Error()
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+ newErr.model = v
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, nil
+}
diff --git a/vendor/gitee.com/openeuler/go-gitee/gitee/api_users.go b/vendor/gitee.com/openeuler/go-gitee/gitee/api_users.go
new file mode 100644
index 0000000000000000000000000000000000000000..9e438d51c70cebaeba5336989d0b9861fbcc48fd
--- /dev/null
+++ b/vendor/gitee.com/openeuler/go-gitee/gitee/api_users.go
@@ -0,0 +1,1787 @@
+/*
+ * 码云 Open API
+ *
+ * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen)
+ *
+ * API version: 5.3.2
+ * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
+ */
+
+package gitee
+
+import (
+ "context"
+ "fmt"
+ "io/ioutil"
+ "net/http"
+ "net/url"
+ "strings"
+
+ "github.com/antihax/optional"
+)
+
+// Linger please
+var (
+ _ context.Context
+)
+
+type UsersApiService service
+
+/*
+UsersApiService 取消关注一个用户
+取消关注一个用户
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param username 用户名(username/login)
+ * @param optional nil or *DeleteV5UserFollowingUsernameOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+
+
+*/
+
+type DeleteV5UserFollowingUsernameOpts struct {
+ AccessToken optional.String
+}
+
+func (a *UsersApiService) DeleteV5UserFollowingUsername(ctx context.Context, username string, localVarOptionals *DeleteV5UserFollowingUsernameOpts) (*http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Delete")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/user/following/{username}"
+ localVarPath = strings.Replace(localVarPath, "{"+"username"+"}", fmt.Sprintf("%v", username), -1)
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarQueryParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ return localVarHttpResponse, newErr
+ }
+
+ return localVarHttpResponse, nil
+}
+
+/*
+UsersApiService 删除一个公钥
+删除一个公钥
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param id 公钥 ID
+ * @param optional nil or *DeleteV5UserKeysIdOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+
+
+*/
+
+type DeleteV5UserKeysIdOpts struct {
+ AccessToken optional.String
+}
+
+func (a *UsersApiService) DeleteV5UserKeysId(ctx context.Context, id int32, localVarOptionals *DeleteV5UserKeysIdOpts) (*http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Delete")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/user/keys/{id}"
+ localVarPath = strings.Replace(localVarPath, "{"+"id"+"}", fmt.Sprintf("%v", id), -1)
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarQueryParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ return localVarHttpResponse, newErr
+ }
+
+ return localVarHttpResponse, nil
+}
+
+/*
+UsersApiService 获取授权用户的资料
+获取授权用户的资料
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param optional nil or *GetV5UserOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+
+@return User
+*/
+
+type GetV5UserOpts struct {
+ AccessToken optional.String
+}
+
+func (a *UsersApiService) GetV5User(ctx context.Context, localVarOptionals *GetV5UserOpts) (User, *http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Get")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ localVarReturnValue User
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/user"
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarQueryParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return localVarReturnValue, nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode < 300 {
+ // If we succeed, return the data, otherwise pass on to decode error.
+ err = a.client.decode(&localVarReturnValue, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ if localVarHttpResponse.StatusCode == 200 {
+ var v User
+ err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err != nil {
+ newErr.error = err.Error()
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+ newErr.model = v
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, nil
+}
+
+/*
+UsersApiService 列出授权用户的关注者
+列出授权用户的关注者
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param optional nil or *GetV5UserFollowersOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+ * @param "Page" (optional.Int32) - 当前的页码
+ * @param "PerPage" (optional.Int32) - 每页的数量,最大为 100
+
+@return []UserBasic
+*/
+
+type GetV5UserFollowersOpts struct {
+ AccessToken optional.String
+ Page optional.Int32
+ PerPage optional.Int32
+}
+
+func (a *UsersApiService) GetV5UserFollowers(ctx context.Context, localVarOptionals *GetV5UserFollowersOpts) ([]UserBasic, *http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Get")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ localVarReturnValue []UserBasic
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/user/followers"
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarQueryParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Page.IsSet() {
+ localVarQueryParams.Add("page", parameterToString(localVarOptionals.Page.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.PerPage.IsSet() {
+ localVarQueryParams.Add("per_page", parameterToString(localVarOptionals.PerPage.Value(), ""))
+ }
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return localVarReturnValue, nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode < 300 {
+ // If we succeed, return the data, otherwise pass on to decode error.
+ err = a.client.decode(&localVarReturnValue, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ if localVarHttpResponse.StatusCode == 200 {
+ var v []UserBasic
+ err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err != nil {
+ newErr.error = err.Error()
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+ newErr.model = v
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, nil
+}
+
+/*
+UsersApiService 列出授权用户正关注的用户
+列出授权用户正关注的用户
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param optional nil or *GetV5UserFollowingOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+ * @param "Page" (optional.Int32) - 当前的页码
+ * @param "PerPage" (optional.Int32) - 每页的数量,最大为 100
+
+@return []UserBasic
+*/
+
+type GetV5UserFollowingOpts struct {
+ AccessToken optional.String
+ Page optional.Int32
+ PerPage optional.Int32
+}
+
+func (a *UsersApiService) GetV5UserFollowing(ctx context.Context, localVarOptionals *GetV5UserFollowingOpts) ([]UserBasic, *http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Get")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ localVarReturnValue []UserBasic
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/user/following"
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarQueryParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Page.IsSet() {
+ localVarQueryParams.Add("page", parameterToString(localVarOptionals.Page.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.PerPage.IsSet() {
+ localVarQueryParams.Add("per_page", parameterToString(localVarOptionals.PerPage.Value(), ""))
+ }
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return localVarReturnValue, nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode < 300 {
+ // If we succeed, return the data, otherwise pass on to decode error.
+ err = a.client.decode(&localVarReturnValue, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ if localVarHttpResponse.StatusCode == 200 {
+ var v []UserBasic
+ err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err != nil {
+ newErr.error = err.Error()
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+ newErr.model = v
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, nil
+}
+
+/*
+UsersApiService 检查授权用户是否关注了一个用户
+检查授权用户是否关注了一个用户
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param username 用户名(username/login)
+ * @param optional nil or *GetV5UserFollowingUsernameOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+
+
+*/
+
+type GetV5UserFollowingUsernameOpts struct {
+ AccessToken optional.String
+}
+
+func (a *UsersApiService) GetV5UserFollowingUsername(ctx context.Context, username string, localVarOptionals *GetV5UserFollowingUsernameOpts) (*http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Get")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/user/following/{username}"
+ localVarPath = strings.Replace(localVarPath, "{"+"username"+"}", fmt.Sprintf("%v", username), -1)
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarQueryParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ return localVarHttpResponse, newErr
+ }
+
+ return localVarHttpResponse, nil
+}
+
+/*
+UsersApiService 列出授权用户的所有公钥
+列出授权用户的所有公钥
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param optional nil or *GetV5UserKeysOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+ * @param "Page" (optional.Int32) - 当前的页码
+ * @param "PerPage" (optional.Int32) - 每页的数量,最大为 100
+
+@return []SshKey
+*/
+
+type GetV5UserKeysOpts struct {
+ AccessToken optional.String
+ Page optional.Int32
+ PerPage optional.Int32
+}
+
+func (a *UsersApiService) GetV5UserKeys(ctx context.Context, localVarOptionals *GetV5UserKeysOpts) ([]SshKey, *http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Get")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ localVarReturnValue []SshKey
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/user/keys"
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarQueryParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Page.IsSet() {
+ localVarQueryParams.Add("page", parameterToString(localVarOptionals.Page.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.PerPage.IsSet() {
+ localVarQueryParams.Add("per_page", parameterToString(localVarOptionals.PerPage.Value(), ""))
+ }
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return localVarReturnValue, nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode < 300 {
+ // If we succeed, return the data, otherwise pass on to decode error.
+ err = a.client.decode(&localVarReturnValue, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ if localVarHttpResponse.StatusCode == 200 {
+ var v []SshKey
+ err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err != nil {
+ newErr.error = err.Error()
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+ newErr.model = v
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, nil
+}
+
+/*
+UsersApiService 获取一个公钥
+获取一个公钥
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param id 公钥 ID
+ * @param optional nil or *GetV5UserKeysIdOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+
+@return SshKey
+*/
+
+type GetV5UserKeysIdOpts struct {
+ AccessToken optional.String
+}
+
+func (a *UsersApiService) GetV5UserKeysId(ctx context.Context, id int32, localVarOptionals *GetV5UserKeysIdOpts) (SshKey, *http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Get")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ localVarReturnValue SshKey
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/user/keys/{id}"
+ localVarPath = strings.Replace(localVarPath, "{"+"id"+"}", fmt.Sprintf("%v", id), -1)
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarQueryParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return localVarReturnValue, nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode < 300 {
+ // If we succeed, return the data, otherwise pass on to decode error.
+ err = a.client.decode(&localVarReturnValue, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ if localVarHttpResponse.StatusCode == 200 {
+ var v SshKey
+ err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err != nil {
+ newErr.error = err.Error()
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+ newErr.model = v
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, nil
+}
+
+/*
+UsersApiService 获取授权用户的一个 Namespace
+获取授权用户的一个 Namespace
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param path Namespace path
+ * @param optional nil or *GetV5UserNamespaceOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+
+@return []Namespace
+*/
+
+type GetV5UserNamespaceOpts struct {
+ AccessToken optional.String
+}
+
+func (a *UsersApiService) GetV5UserNamespace(ctx context.Context, path string, localVarOptionals *GetV5UserNamespaceOpts) ([]Namespace, *http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Get")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ localVarReturnValue []Namespace
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/user/namespace"
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarQueryParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ localVarQueryParams.Add("path", parameterToString(path, ""))
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return localVarReturnValue, nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode < 300 {
+ // If we succeed, return the data, otherwise pass on to decode error.
+ err = a.client.decode(&localVarReturnValue, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ if localVarHttpResponse.StatusCode == 200 {
+ var v []Namespace
+ err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err != nil {
+ newErr.error = err.Error()
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+ newErr.model = v
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, nil
+}
+
+/*
+UsersApiService 列出授权用户所有的 Namespace
+列出授权用户所有的 Namespace
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param optional nil or *GetV5UserNamespacesOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+ * @param "Mode" (optional.String) - 参与方式: project(所有参与仓库的namepsce)、intrant(所加入的namespace)、all(包含前两者),默认(intrant)
+
+@return []Namespace
+*/
+
+type GetV5UserNamespacesOpts struct {
+ AccessToken optional.String
+ Mode optional.String
+}
+
+func (a *UsersApiService) GetV5UserNamespaces(ctx context.Context, localVarOptionals *GetV5UserNamespacesOpts) ([]Namespace, *http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Get")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ localVarReturnValue []Namespace
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/user/namespaces"
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarQueryParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Mode.IsSet() {
+ localVarQueryParams.Add("mode", parameterToString(localVarOptionals.Mode.Value(), ""))
+ }
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return localVarReturnValue, nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode < 300 {
+ // If we succeed, return the data, otherwise pass on to decode error.
+ err = a.client.decode(&localVarReturnValue, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ if localVarHttpResponse.StatusCode == 200 {
+ var v []Namespace
+ err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err != nil {
+ newErr.error = err.Error()
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+ newErr.model = v
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, nil
+}
+
+/*
+UsersApiService 获取一个用户
+获取一个用户
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param username 用户名(username/login)
+ * @param optional nil or *GetV5UsersUsernameOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+
+@return User
+*/
+
+type GetV5UsersUsernameOpts struct {
+ AccessToken optional.String
+}
+
+func (a *UsersApiService) GetV5UsersUsername(ctx context.Context, username string, localVarOptionals *GetV5UsersUsernameOpts) (User, *http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Get")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ localVarReturnValue User
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/users/{username}"
+ localVarPath = strings.Replace(localVarPath, "{"+"username"+"}", fmt.Sprintf("%v", username), -1)
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarQueryParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return localVarReturnValue, nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode < 300 {
+ // If we succeed, return the data, otherwise pass on to decode error.
+ err = a.client.decode(&localVarReturnValue, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ if localVarHttpResponse.StatusCode == 200 {
+ var v User
+ err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err != nil {
+ newErr.error = err.Error()
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+ newErr.model = v
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, nil
+}
+
+/*
+UsersApiService 列出指定用户的关注者
+列出指定用户的关注者
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param username 用户名(username/login)
+ * @param optional nil or *GetV5UsersUsernameFollowersOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+ * @param "Page" (optional.Int32) - 当前的页码
+ * @param "PerPage" (optional.Int32) - 每页的数量,最大为 100
+
+@return []UserBasic
+*/
+
+type GetV5UsersUsernameFollowersOpts struct {
+ AccessToken optional.String
+ Page optional.Int32
+ PerPage optional.Int32
+}
+
+func (a *UsersApiService) GetV5UsersUsernameFollowers(ctx context.Context, username string, localVarOptionals *GetV5UsersUsernameFollowersOpts) ([]UserBasic, *http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Get")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ localVarReturnValue []UserBasic
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/users/{username}/followers"
+ localVarPath = strings.Replace(localVarPath, "{"+"username"+"}", fmt.Sprintf("%v", username), -1)
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarQueryParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Page.IsSet() {
+ localVarQueryParams.Add("page", parameterToString(localVarOptionals.Page.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.PerPage.IsSet() {
+ localVarQueryParams.Add("per_page", parameterToString(localVarOptionals.PerPage.Value(), ""))
+ }
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return localVarReturnValue, nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode < 300 {
+ // If we succeed, return the data, otherwise pass on to decode error.
+ err = a.client.decode(&localVarReturnValue, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ if localVarHttpResponse.StatusCode == 200 {
+ var v []UserBasic
+ err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err != nil {
+ newErr.error = err.Error()
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+ newErr.model = v
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, nil
+}
+
+/*
+UsersApiService 列出指定用户正在关注的用户
+列出指定用户正在关注的用户
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param username 用户名(username/login)
+ * @param optional nil or *GetV5UsersUsernameFollowingOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+ * @param "Page" (optional.Int32) - 当前的页码
+ * @param "PerPage" (optional.Int32) - 每页的数量,最大为 100
+
+@return []UserBasic
+*/
+
+type GetV5UsersUsernameFollowingOpts struct {
+ AccessToken optional.String
+ Page optional.Int32
+ PerPage optional.Int32
+}
+
+func (a *UsersApiService) GetV5UsersUsernameFollowing(ctx context.Context, username string, localVarOptionals *GetV5UsersUsernameFollowingOpts) ([]UserBasic, *http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Get")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ localVarReturnValue []UserBasic
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/users/{username}/following"
+ localVarPath = strings.Replace(localVarPath, "{"+"username"+"}", fmt.Sprintf("%v", username), -1)
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarQueryParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Page.IsSet() {
+ localVarQueryParams.Add("page", parameterToString(localVarOptionals.Page.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.PerPage.IsSet() {
+ localVarQueryParams.Add("per_page", parameterToString(localVarOptionals.PerPage.Value(), ""))
+ }
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return localVarReturnValue, nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode < 300 {
+ // If we succeed, return the data, otherwise pass on to decode error.
+ err = a.client.decode(&localVarReturnValue, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ if localVarHttpResponse.StatusCode == 200 {
+ var v []UserBasic
+ err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err != nil {
+ newErr.error = err.Error()
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+ newErr.model = v
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, nil
+}
+
+/*
+UsersApiService 检查指定用户是否关注目标用户
+检查指定用户是否关注目标用户
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param username 用户名(username/login)
+ * @param targetUser 目标用户的用户名(username/login)
+ * @param optional nil or *GetV5UsersUsernameFollowingTargetUserOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+
+
+*/
+
+type GetV5UsersUsernameFollowingTargetUserOpts struct {
+ AccessToken optional.String
+}
+
+func (a *UsersApiService) GetV5UsersUsernameFollowingTargetUser(ctx context.Context, username string, targetUser string, localVarOptionals *GetV5UsersUsernameFollowingTargetUserOpts) (*http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Get")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/users/{username}/following/{target_user}"
+ localVarPath = strings.Replace(localVarPath, "{"+"username"+"}", fmt.Sprintf("%v", username), -1)
+ localVarPath = strings.Replace(localVarPath, "{"+"target_user"+"}", fmt.Sprintf("%v", targetUser), -1)
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarQueryParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ return localVarHttpResponse, newErr
+ }
+
+ return localVarHttpResponse, nil
+}
+
+/*
+UsersApiService 列出指定用户的所有公钥
+列出指定用户的所有公钥
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param username 用户名(username/login)
+ * @param optional nil or *GetV5UsersUsernameKeysOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+ * @param "Page" (optional.Int32) - 当前的页码
+ * @param "PerPage" (optional.Int32) - 每页的数量,最大为 100
+
+@return []SshKeyBasic
+*/
+
+type GetV5UsersUsernameKeysOpts struct {
+ AccessToken optional.String
+ Page optional.Int32
+ PerPage optional.Int32
+}
+
+func (a *UsersApiService) GetV5UsersUsernameKeys(ctx context.Context, username string, localVarOptionals *GetV5UsersUsernameKeysOpts) ([]SshKeyBasic, *http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Get")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ localVarReturnValue []SshKeyBasic
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/users/{username}/keys"
+ localVarPath = strings.Replace(localVarPath, "{"+"username"+"}", fmt.Sprintf("%v", username), -1)
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarQueryParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Page.IsSet() {
+ localVarQueryParams.Add("page", parameterToString(localVarOptionals.Page.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.PerPage.IsSet() {
+ localVarQueryParams.Add("per_page", parameterToString(localVarOptionals.PerPage.Value(), ""))
+ }
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return localVarReturnValue, nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode < 300 {
+ // If we succeed, return the data, otherwise pass on to decode error.
+ err = a.client.decode(&localVarReturnValue, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ if localVarHttpResponse.StatusCode == 200 {
+ var v []SshKeyBasic
+ err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err != nil {
+ newErr.error = err.Error()
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+ newErr.model = v
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, nil
+}
+
+/*
+UsersApiService 更新授权用户的资料
+更新授权用户的资料
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param optional nil or *PatchV5UserOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+ * @param "Name" (optional.String) - 昵称
+ * @param "Blog" (optional.String) - 微博链接
+ * @param "Weibo" (optional.String) - 博客站点
+ * @param "Bio" (optional.String) - 自我介绍
+
+@return User
+*/
+
+type PatchV5UserOpts struct {
+ AccessToken optional.String
+ Name optional.String
+ Blog optional.String
+ Weibo optional.String
+ Bio optional.String
+}
+
+func (a *UsersApiService) PatchV5User(ctx context.Context, localVarOptionals *PatchV5UserOpts) (User, *http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Patch")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ localVarReturnValue User
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/user"
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarFormParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Name.IsSet() {
+ localVarFormParams.Add("name", parameterToString(localVarOptionals.Name.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Blog.IsSet() {
+ localVarFormParams.Add("blog", parameterToString(localVarOptionals.Blog.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Weibo.IsSet() {
+ localVarFormParams.Add("weibo", parameterToString(localVarOptionals.Weibo.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Bio.IsSet() {
+ localVarFormParams.Add("bio", parameterToString(localVarOptionals.Bio.Value(), ""))
+ }
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return localVarReturnValue, nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode < 300 {
+ // If we succeed, return the data, otherwise pass on to decode error.
+ err = a.client.decode(&localVarReturnValue, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ if localVarHttpResponse.StatusCode == 200 {
+ var v User
+ err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err != nil {
+ newErr.error = err.Error()
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+ newErr.model = v
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, nil
+}
+
+/*
+UsersApiService 添加一个公钥
+添加一个公钥
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param key 公钥内容
+ * @param title 公钥名称
+ * @param optional nil or *PostV5UserKeysOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+
+@return SshKey
+*/
+
+type PostV5UserKeysOpts struct {
+ AccessToken optional.String
+}
+
+func (a *UsersApiService) PostV5UserKeys(ctx context.Context, key string, title string, localVarOptionals *PostV5UserKeysOpts) (SshKey, *http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Post")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ localVarReturnValue SshKey
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/user/keys"
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarFormParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ localVarFormParams.Add("key", parameterToString(key, ""))
+ localVarFormParams.Add("title", parameterToString(title, ""))
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return localVarReturnValue, nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode < 300 {
+ // If we succeed, return the data, otherwise pass on to decode error.
+ err = a.client.decode(&localVarReturnValue, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ if localVarHttpResponse.StatusCode == 201 {
+ var v SshKey
+ err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err != nil {
+ newErr.error = err.Error()
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+ newErr.model = v
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, nil
+}
+
+/*
+UsersApiService 关注一个用户
+关注一个用户
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param username 用户名(username/login)
+ * @param optional nil or *PutV5UserFollowingUsernameOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+
+
+*/
+
+type PutV5UserFollowingUsernameOpts struct {
+ AccessToken optional.String
+}
+
+func (a *UsersApiService) PutV5UserFollowingUsername(ctx context.Context, username string, localVarOptionals *PutV5UserFollowingUsernameOpts) (*http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Put")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/user/following/{username}"
+ localVarPath = strings.Replace(localVarPath, "{"+"username"+"}", fmt.Sprintf("%v", username), -1)
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarFormParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ return localVarHttpResponse, newErr
+ }
+
+ return localVarHttpResponse, nil
+}
diff --git a/vendor/gitee.com/openeuler/go-gitee/gitee/api_webhooks.go b/vendor/gitee.com/openeuler/go-gitee/gitee/api_webhooks.go
new file mode 100644
index 0000000000000000000000000000000000000000..abccd5d2cc97c90c270a29f9489a52cf387637f4
--- /dev/null
+++ b/vendor/gitee.com/openeuler/go-gitee/gitee/api_webhooks.go
@@ -0,0 +1,677 @@
+/*
+ * 码云 Open API
+ *
+ * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen)
+ *
+ * API version: 5.3.2
+ * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
+ */
+
+package gitee
+
+import (
+ "context"
+ "fmt"
+ "io/ioutil"
+ "net/http"
+ "net/url"
+ neturl "net/url"
+ "strings"
+
+ "github.com/antihax/optional"
+)
+
+// Linger please
+var (
+ _ context.Context
+)
+
+type WebhooksApiService service
+
+/*
+ WebhooksApiService 删除一个仓库WebHook
+ 删除一个仓库WebHook
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param owner 仓库所属空间地址(企业、组织或个人的地址path)
+ * @param repo 仓库路径(path)
+ * @param id Webhook的ID
+ * @param optional nil or *DeleteV5ReposOwnerRepoHooksIdOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+
+
+*/
+
+type DeleteV5ReposOwnerRepoHooksIdOpts struct {
+ AccessToken optional.String
+}
+
+func (a *WebhooksApiService) DeleteV5ReposOwnerRepoHooksId(ctx context.Context, owner string, repo string, id int32, localVarOptionals *DeleteV5ReposOwnerRepoHooksIdOpts) (*http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Delete")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/repos/{owner}/{repo}/hooks/{id}"
+ localVarPath = strings.Replace(localVarPath, "{"+"owner"+"}", fmt.Sprintf("%v", owner), -1)
+ localVarPath = strings.Replace(localVarPath, "{"+"repo"+"}", fmt.Sprintf("%v", repo), -1)
+ localVarPath = strings.Replace(localVarPath, "{"+"id"+"}", fmt.Sprintf("%v", id), -1)
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarQueryParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ return localVarHttpResponse, newErr
+ }
+
+ return localVarHttpResponse, nil
+}
+
+/*
+ WebhooksApiService 列出仓库的WebHooks
+ 列出仓库的WebHooks
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param owner 仓库所属空间地址(企业、组织或个人的地址path)
+ * @param repo 仓库路径(path)
+ * @param optional nil or *GetV5ReposOwnerRepoHooksOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+ * @param "Page" (optional.Int32) - 当前的页码
+ * @param "PerPage" (optional.Int32) - 每页的数量,最大为 100
+
+ @return []Hook
+*/
+
+type GetV5ReposOwnerRepoHooksOpts struct {
+ AccessToken optional.String
+ Page optional.Int32
+ PerPage optional.Int32
+}
+
+func (a *WebhooksApiService) GetV5ReposOwnerRepoHooks(ctx context.Context, owner string, repo string, localVarOptionals *GetV5ReposOwnerRepoHooksOpts) ([]Hook, *http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Get")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ localVarReturnValue []Hook
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/repos/{owner}/{repo}/hooks"
+ localVarPath = strings.Replace(localVarPath, "{"+"owner"+"}", fmt.Sprintf("%v", owner), -1)
+ localVarPath = strings.Replace(localVarPath, "{"+"repo"+"}", fmt.Sprintf("%v", repo), -1)
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarQueryParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.Page.IsSet() {
+ localVarQueryParams.Add("page", parameterToString(localVarOptionals.Page.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.PerPage.IsSet() {
+ localVarQueryParams.Add("per_page", parameterToString(localVarOptionals.PerPage.Value(), ""))
+ }
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return localVarReturnValue, nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode < 300 {
+ // If we succeed, return the data, otherwise pass on to decode error.
+ err = a.client.decode(&localVarReturnValue, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ if localVarHttpResponse.StatusCode == 200 {
+ var v []Hook
+ err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err != nil {
+ newErr.error = err.Error()
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+ newErr.model = v
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, nil
+}
+
+/*
+ WebhooksApiService 获取仓库单个WebHook
+ 获取仓库单个WebHook
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param owner 仓库所属空间地址(企业、组织或个人的地址path)
+ * @param repo 仓库路径(path)
+ * @param id Webhook的ID
+ * @param optional nil or *GetV5ReposOwnerRepoHooksIdOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+
+ @return Hook
+*/
+
+type GetV5ReposOwnerRepoHooksIdOpts struct {
+ AccessToken optional.String
+}
+
+func (a *WebhooksApiService) GetV5ReposOwnerRepoHooksId(ctx context.Context, owner string, repo string, id int32, localVarOptionals *GetV5ReposOwnerRepoHooksIdOpts) (Hook, *http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Get")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ localVarReturnValue Hook
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/repos/{owner}/{repo}/hooks/{id}"
+ localVarPath = strings.Replace(localVarPath, "{"+"owner"+"}", fmt.Sprintf("%v", owner), -1)
+ localVarPath = strings.Replace(localVarPath, "{"+"repo"+"}", fmt.Sprintf("%v", repo), -1)
+ localVarPath = strings.Replace(localVarPath, "{"+"id"+"}", fmt.Sprintf("%v", id), -1)
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarQueryParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return localVarReturnValue, nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode < 300 {
+ // If we succeed, return the data, otherwise pass on to decode error.
+ err = a.client.decode(&localVarReturnValue, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ if localVarHttpResponse.StatusCode == 200 {
+ var v Hook
+ err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err != nil {
+ newErr.error = err.Error()
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+ newErr.model = v
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, nil
+}
+
+/*
+ WebhooksApiService 更新一个仓库WebHook
+ 更新一个仓库WebHook
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param owner 仓库所属空间地址(企业、组织或个人的地址path)
+ * @param repo 仓库路径(path)
+ * @param id Webhook的ID
+ * @param url 远程HTTP URL
+ * @param optional nil or *PatchV5ReposOwnerRepoHooksIdOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+ * @param "Password" (optional.String) - 请求URL时会带上该密码,防止URL被恶意请求
+ * @param "PushEvents" (optional.Bool) - Push代码到仓库
+ * @param "TagPushEvents" (optional.Bool) - 提交Tag到仓库
+ * @param "IssuesEvents" (optional.Bool) - 创建/关闭Issue
+ * @param "NoteEvents" (optional.Bool) - 评论了Issue/代码等等
+ * @param "MergeRequestsEvents" (optional.Bool) - 合并请求和合并后
+
+ @return Hook
+*/
+
+type PatchV5ReposOwnerRepoHooksIdOpts struct {
+ AccessToken optional.String
+ Password optional.String
+ PushEvents optional.Bool
+ TagPushEvents optional.Bool
+ IssuesEvents optional.Bool
+ NoteEvents optional.Bool
+ MergeRequestsEvents optional.Bool
+}
+
+func (a *WebhooksApiService) PatchV5ReposOwnerRepoHooksId(ctx context.Context, owner string, repo string, id int32, url string, localVarOptionals *PatchV5ReposOwnerRepoHooksIdOpts) (Hook, *http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Patch")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ localVarReturnValue Hook
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/repos/{owner}/{repo}/hooks/{id}"
+ localVarPath = strings.Replace(localVarPath, "{"+"owner"+"}", fmt.Sprintf("%v", owner), -1)
+ localVarPath = strings.Replace(localVarPath, "{"+"repo"+"}", fmt.Sprintf("%v", repo), -1)
+ localVarPath = strings.Replace(localVarPath, "{"+"id"+"}", fmt.Sprintf("%v", id), -1)
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := neturl.Values{}
+ localVarFormParams := neturl.Values{}
+
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarFormParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ localVarFormParams.Add("url", parameterToString(url, ""))
+ if localVarOptionals != nil && localVarOptionals.Password.IsSet() {
+ localVarFormParams.Add("password", parameterToString(localVarOptionals.Password.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.PushEvents.IsSet() {
+ localVarFormParams.Add("push_events", parameterToString(localVarOptionals.PushEvents.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.TagPushEvents.IsSet() {
+ localVarFormParams.Add("tag_push_events", parameterToString(localVarOptionals.TagPushEvents.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.IssuesEvents.IsSet() {
+ localVarFormParams.Add("issues_events", parameterToString(localVarOptionals.IssuesEvents.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.NoteEvents.IsSet() {
+ localVarFormParams.Add("note_events", parameterToString(localVarOptionals.NoteEvents.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.MergeRequestsEvents.IsSet() {
+ localVarFormParams.Add("merge_requests_events", parameterToString(localVarOptionals.MergeRequestsEvents.Value(), ""))
+ }
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return localVarReturnValue, nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode < 300 {
+ // If we succeed, return the data, otherwise pass on to decode error.
+ err = a.client.decode(&localVarReturnValue, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ if localVarHttpResponse.StatusCode == 200 {
+ var v Hook
+ err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err != nil {
+ newErr.error = err.Error()
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+ newErr.model = v
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, nil
+}
+
+/*
+ WebhooksApiService 创建一个仓库WebHook
+ 创建一个仓库WebHook
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param owner 仓库所属空间地址(企业、组织或个人的地址path)
+ * @param repo 仓库路径(path)
+ * @param url 远程HTTP URL
+ * @param optional nil or *PostV5ReposOwnerRepoHooksOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+ * @param "Password" (optional.String) - 请求URL时会带上该密码,防止URL被恶意请求
+ * @param "PushEvents" (optional.Bool) - Push代码到仓库
+ * @param "TagPushEvents" (optional.Bool) - 提交Tag到仓库
+ * @param "IssuesEvents" (optional.Bool) - 创建/关闭Issue
+ * @param "NoteEvents" (optional.Bool) - 评论了Issue/代码等等
+ * @param "MergeRequestsEvents" (optional.Bool) - 合并请求和合并后
+
+ @return Hook
+*/
+
+type PostV5ReposOwnerRepoHooksOpts struct {
+ AccessToken optional.String
+ Password optional.String
+ PushEvents optional.Bool
+ TagPushEvents optional.Bool
+ IssuesEvents optional.Bool
+ NoteEvents optional.Bool
+ MergeRequestsEvents optional.Bool
+}
+
+func (a *WebhooksApiService) PostV5ReposOwnerRepoHooks(ctx context.Context, owner string, repo string, url string, localVarOptionals *PostV5ReposOwnerRepoHooksOpts) (Hook, *http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Post")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ localVarReturnValue Hook
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/repos/{owner}/{repo}/hooks"
+ localVarPath = strings.Replace(localVarPath, "{"+"owner"+"}", fmt.Sprintf("%v", owner), -1)
+ localVarPath = strings.Replace(localVarPath, "{"+"repo"+"}", fmt.Sprintf("%v", repo), -1)
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := neturl.Values{}
+ localVarFormParams := neturl.Values{}
+
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarFormParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ localVarFormParams.Add("url", parameterToString(url, ""))
+ if localVarOptionals != nil && localVarOptionals.Password.IsSet() {
+ localVarFormParams.Add("password", parameterToString(localVarOptionals.Password.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.PushEvents.IsSet() {
+ localVarFormParams.Add("push_events", parameterToString(localVarOptionals.PushEvents.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.TagPushEvents.IsSet() {
+ localVarFormParams.Add("tag_push_events", parameterToString(localVarOptionals.TagPushEvents.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.IssuesEvents.IsSet() {
+ localVarFormParams.Add("issues_events", parameterToString(localVarOptionals.IssuesEvents.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.NoteEvents.IsSet() {
+ localVarFormParams.Add("note_events", parameterToString(localVarOptionals.NoteEvents.Value(), ""))
+ }
+ if localVarOptionals != nil && localVarOptionals.MergeRequestsEvents.IsSet() {
+ localVarFormParams.Add("merge_requests_events", parameterToString(localVarOptionals.MergeRequestsEvents.Value(), ""))
+ }
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return localVarReturnValue, nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode < 300 {
+ // If we succeed, return the data, otherwise pass on to decode error.
+ err = a.client.decode(&localVarReturnValue, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err == nil {
+ return localVarReturnValue, localVarHttpResponse, err
+ }
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ if localVarHttpResponse.StatusCode == 201 {
+ var v Hook
+ err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type"))
+ if err != nil {
+ newErr.error = err.Error()
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+ newErr.model = v
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, newErr
+ }
+
+ return localVarReturnValue, localVarHttpResponse, nil
+}
+
+/*
+ WebhooksApiService 测试WebHook是否发送成功
+ 测试WebHook是否发送成功
+ * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
+ * @param owner 仓库所属空间地址(企业、组织或个人的地址path)
+ * @param repo 仓库路径(path)
+ * @param id Webhook的ID
+ * @param optional nil or *PostV5ReposOwnerRepoHooksIdTestsOpts - Optional Parameters:
+ * @param "AccessToken" (optional.String) - 用户授权码
+
+
+*/
+
+type PostV5ReposOwnerRepoHooksIdTestsOpts struct {
+ AccessToken optional.String
+}
+
+func (a *WebhooksApiService) PostV5ReposOwnerRepoHooksIdTests(ctx context.Context, owner string, repo string, id int32, localVarOptionals *PostV5ReposOwnerRepoHooksIdTestsOpts) (*http.Response, error) {
+ var (
+ localVarHttpMethod = strings.ToUpper("Post")
+ localVarPostBody interface{}
+ localVarFileName string
+ localVarFileBytes []byte
+ )
+
+ // create path and map variables
+ localVarPath := a.client.cfg.BasePath + "/v5/repos/{owner}/{repo}/hooks/{id}/tests"
+ localVarPath = strings.Replace(localVarPath, "{"+"owner"+"}", fmt.Sprintf("%v", owner), -1)
+ localVarPath = strings.Replace(localVarPath, "{"+"repo"+"}", fmt.Sprintf("%v", repo), -1)
+ localVarPath = strings.Replace(localVarPath, "{"+"id"+"}", fmt.Sprintf("%v", id), -1)
+
+ localVarHeaderParams := make(map[string]string)
+ localVarQueryParams := url.Values{}
+ localVarFormParams := url.Values{}
+
+ // to determine the Content-Type header
+ localVarHttpContentTypes := []string{"application/json", "multipart/form-data"}
+
+ // set Content-Type header
+ localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes)
+ if localVarHttpContentType != "" {
+ localVarHeaderParams["Content-Type"] = localVarHttpContentType
+ }
+
+ // to determine the Accept header
+ localVarHttpHeaderAccepts := []string{"application/json"}
+
+ // set Accept header
+ localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts)
+ if localVarHttpHeaderAccept != "" {
+ localVarHeaderParams["Accept"] = localVarHttpHeaderAccept
+ }
+ if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() {
+ localVarFormParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), ""))
+ }
+ r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes)
+ if err != nil {
+ return nil, err
+ }
+
+ localVarHttpResponse, err := a.client.callAPI(r)
+ if err != nil || localVarHttpResponse == nil {
+ return localVarHttpResponse, err
+ }
+
+ localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body)
+ localVarHttpResponse.Body.Close()
+ if err != nil {
+ return localVarHttpResponse, err
+ }
+
+ if localVarHttpResponse.StatusCode >= 300 {
+ newErr := GenericSwaggerError{
+ body: localVarBody,
+ error: localVarHttpResponse.Status,
+ }
+
+ return localVarHttpResponse, newErr
+ }
+
+ return localVarHttpResponse, nil
+}
diff --git a/vendor/gitee.com/openeuler/go-gitee/gitee/client.go b/vendor/gitee.com/openeuler/go-gitee/gitee/client.go
new file mode 100644
index 0000000000000000000000000000000000000000..bf6510ca824e2515aa6029999c6868ddb8a40a39
--- /dev/null
+++ b/vendor/gitee.com/openeuler/go-gitee/gitee/client.go
@@ -0,0 +1,506 @@
+/*
+ * 码云 Open API
+ *
+ * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen)
+ *
+ * API version: 5.3.2
+ * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
+ */
+
+package gitee
+
+import (
+ "bytes"
+ "context"
+ "encoding/json"
+ "encoding/xml"
+ "errors"
+ "fmt"
+ "io"
+ "mime/multipart"
+ "net/http"
+ "net/url"
+ "os"
+ "path/filepath"
+ "reflect"
+ "regexp"
+ "strconv"
+ "strings"
+ "time"
+ "unicode/utf8"
+
+ "golang.org/x/oauth2"
+)
+
+var (
+ jsonCheck = regexp.MustCompile("(?i:[application|text]/json)")
+ xmlCheck = regexp.MustCompile("(?i:[application|text]/xml)")
+)
+
+// APIClient manages communication with the 码云 Open API API v5.3.2
+// In most cases there should be only one, shared, APIClient.
+type APIClient struct {
+ cfg *Configuration
+ common service // Reuse a single struct instead of allocating one for each service on the heap.
+
+ // API Services
+
+ ActivityApi *ActivityApiService
+
+ EmailsApi *EmailsApiService
+
+ EnterprisesApi *EnterprisesApiService
+
+ GistsApi *GistsApiService
+
+ GitDataApi *GitDataApiService
+
+ IssuesApi *IssuesApiService
+
+ LabelsApi *LabelsApiService
+
+ MilestonesApi *MilestonesApiService
+
+ MiscellaneousApi *MiscellaneousApiService
+
+ OrganizationsApi *OrganizationsApiService
+
+ PullRequestsApi *PullRequestsApiService
+
+ RepositoriesApi *RepositoriesApiService
+
+ SearchApi *SearchApiService
+
+ UsersApi *UsersApiService
+
+ WebhooksApi *WebhooksApiService
+}
+
+type service struct {
+ client *APIClient
+}
+
+// NewAPIClient creates a new API client. Requires a userAgent string describing your application.
+// optionally a custom http.Client to allow for advanced features such as caching.
+func NewAPIClient(cfg *Configuration) *APIClient {
+ if cfg.HTTPClient == nil {
+ cfg.HTTPClient = http.DefaultClient
+ }
+
+ c := &APIClient{}
+ c.cfg = cfg
+ c.common.client = c
+
+ // API Services
+ c.ActivityApi = (*ActivityApiService)(&c.common)
+ c.EmailsApi = (*EmailsApiService)(&c.common)
+ c.EnterprisesApi = (*EnterprisesApiService)(&c.common)
+ c.GistsApi = (*GistsApiService)(&c.common)
+ c.GitDataApi = (*GitDataApiService)(&c.common)
+ c.IssuesApi = (*IssuesApiService)(&c.common)
+ c.LabelsApi = (*LabelsApiService)(&c.common)
+ c.MilestonesApi = (*MilestonesApiService)(&c.common)
+ c.MiscellaneousApi = (*MiscellaneousApiService)(&c.common)
+ c.OrganizationsApi = (*OrganizationsApiService)(&c.common)
+ c.PullRequestsApi = (*PullRequestsApiService)(&c.common)
+ c.RepositoriesApi = (*RepositoriesApiService)(&c.common)
+ c.SearchApi = (*SearchApiService)(&c.common)
+ c.UsersApi = (*UsersApiService)(&c.common)
+ c.WebhooksApi = (*WebhooksApiService)(&c.common)
+
+ return c
+}
+
+func atoi(in string) (int, error) {
+ return strconv.Atoi(in)
+}
+
+// selectHeaderContentType select a content type from the available list.
+func selectHeaderContentType(contentTypes []string) string {
+ if len(contentTypes) == 0 {
+ return ""
+ }
+ if contains(contentTypes, "application/json") {
+ return "application/json"
+ }
+ return contentTypes[0] // use the first content type specified in 'consumes'
+}
+
+// selectHeaderAccept join all accept types and return
+func selectHeaderAccept(accepts []string) string {
+ if len(accepts) == 0 {
+ return ""
+ }
+
+ if contains(accepts, "application/json") {
+ return "application/json"
+ }
+
+ return strings.Join(accepts, ",")
+}
+
+// contains is a case insenstive match, finding needle in a haystack
+func contains(haystack []string, needle string) bool {
+ for _, a := range haystack {
+ if strings.ToLower(a) == strings.ToLower(needle) {
+ return true
+ }
+ }
+ return false
+}
+
+// Verify optional parameters are of the correct type.
+func typeCheckParameter(obj interface{}, expected string, name string) error {
+ // Make sure there is an object.
+ if obj == nil {
+ return nil
+ }
+
+ // Check the type is as expected.
+ if reflect.TypeOf(obj).String() != expected {
+ return fmt.Errorf("Expected %s to be of type %s but received %s.", name, expected, reflect.TypeOf(obj).String())
+ }
+ return nil
+}
+
+// parameterToString convert interface{} parameters to string, using a delimiter if format is provided.
+func parameterToString(obj interface{}, collectionFormat string) string {
+ var delimiter string
+
+ switch collectionFormat {
+ case "pipes":
+ delimiter = "|"
+ case "ssv":
+ delimiter = " "
+ case "tsv":
+ delimiter = "\t"
+ case "csv":
+ delimiter = ","
+ }
+
+ if reflect.TypeOf(obj).Kind() == reflect.Slice {
+ return strings.Trim(strings.Replace(fmt.Sprint(obj), " ", delimiter, -1), "[]")
+ }
+
+ return fmt.Sprintf("%v", obj)
+}
+
+// callAPI do the request.
+func (c *APIClient) callAPI(request *http.Request) (*http.Response, error) {
+ return c.cfg.HTTPClient.Do(request)
+}
+
+// Change base path to allow switching to mocks
+func (c *APIClient) ChangeBasePath(path string) {
+ c.cfg.BasePath = path
+}
+
+// prepareRequest build the request
+func (c *APIClient) prepareRequest(
+ ctx context.Context,
+ path string, method string,
+ postBody interface{},
+ headerParams map[string]string,
+ queryParams url.Values,
+ formParams url.Values,
+ fileName string,
+ fileBytes []byte) (localVarRequest *http.Request, err error) {
+
+ var body *bytes.Buffer
+
+ // Detect postBody type and post.
+ if postBody != nil {
+ contentType := headerParams["Content-Type"]
+ if contentType == "" {
+ contentType = detectContentType(postBody)
+ headerParams["Content-Type"] = contentType
+ }
+
+ body, err = setBody(postBody, contentType)
+ if err != nil {
+ return nil, err
+ }
+ }
+
+ // add form parameters and file if available.
+ if len(formParams) > 0 || (len(fileBytes) > 0 && fileName != "") {
+ if body != nil {
+ return nil, errors.New("Cannot specify postBody and multipart form at the same time.")
+ }
+ body = &bytes.Buffer{}
+ w := multipart.NewWriter(body)
+
+ for k, v := range formParams {
+ for _, iv := range v {
+ if strings.HasPrefix(k, "@") { // file
+ err = addFile(w, k[1:], iv)
+ if err != nil {
+ return nil, err
+ }
+ } else { // form value
+ w.WriteField(k, iv)
+ }
+ }
+ }
+ if len(fileBytes) > 0 && fileName != "" {
+ w.Boundary()
+ //_, fileNm := filepath.Split(fileName)
+ part, err := w.CreateFormFile("file", filepath.Base(fileName))
+ if err != nil {
+ return nil, err
+ }
+ _, err = part.Write(fileBytes)
+ if err != nil {
+ return nil, err
+ }
+ // Set the Boundary in the Content-Type
+ headerParams["Content-Type"] = w.FormDataContentType()
+ }
+
+ // Set Content-Length
+ headerParams["Content-Length"] = fmt.Sprintf("%d", body.Len())
+ w.Close()
+ }
+
+ // Setup path and query parameters
+ url, err := url.Parse(path)
+ if err != nil {
+ return nil, err
+ }
+
+ // Adding Query Param
+ query := url.Query()
+ for k, v := range queryParams {
+ for _, iv := range v {
+ query.Add(k, iv)
+ }
+ }
+
+ // Encode the parameters.
+ url.RawQuery = query.Encode()
+
+ // Generate a new request
+ if body != nil {
+ localVarRequest, err = http.NewRequest(method, url.String(), body)
+ } else {
+ localVarRequest, err = http.NewRequest(method, url.String(), nil)
+ }
+ if err != nil {
+ return nil, err
+ }
+
+ // add header parameters, if any
+ if len(headerParams) > 0 {
+ headers := http.Header{}
+ for h, v := range headerParams {
+ headers.Set(h, v)
+ }
+ localVarRequest.Header = headers
+ }
+
+ // Override request host, if applicable
+ if c.cfg.Host != "" {
+ localVarRequest.Host = c.cfg.Host
+ }
+
+ // Add the user agent to the request.
+ localVarRequest.Header.Add("User-Agent", c.cfg.UserAgent)
+
+ if ctx != nil {
+ // add context to the request
+ localVarRequest = localVarRequest.WithContext(ctx)
+
+ // Walk through any authentication.
+
+ // OAuth2 authentication
+ if tok, ok := ctx.Value(ContextOAuth2).(oauth2.TokenSource); ok {
+ // We were able to grab an oauth2 token from the context
+ var latestToken *oauth2.Token
+ if latestToken, err = tok.Token(); err != nil {
+ return nil, err
+ }
+
+ latestToken.SetAuthHeader(localVarRequest)
+ }
+
+ // Basic HTTP Authentication
+ if auth, ok := ctx.Value(ContextBasicAuth).(BasicAuth); ok {
+ localVarRequest.SetBasicAuth(auth.UserName, auth.Password)
+ }
+
+ // AccessToken Authentication
+ if auth, ok := ctx.Value(ContextAccessToken).(string); ok {
+ localVarRequest.Header.Add("Authorization", "Bearer "+auth)
+ }
+ }
+
+ for header, value := range c.cfg.DefaultHeader {
+ localVarRequest.Header.Add(header, value)
+ }
+
+ return localVarRequest, nil
+}
+
+func (c *APIClient) decode(v interface{}, b []byte, contentType string) (err error) {
+ if strings.Contains(contentType, "application/xml") {
+ if err = xml.Unmarshal(b, v); err != nil {
+ return err
+ }
+ return nil
+ } else if strings.Contains(contentType, "application/json") {
+ if err = json.Unmarshal(b, v); err != nil {
+ return err
+ }
+ return nil
+ }
+ return errors.New("undefined response type")
+}
+
+// Add a file to the multipart request
+func addFile(w *multipart.Writer, fieldName, path string) error {
+ file, err := os.Open(path)
+ if err != nil {
+ return err
+ }
+ defer file.Close()
+
+ part, err := w.CreateFormFile(fieldName, filepath.Base(path))
+ if err != nil {
+ return err
+ }
+ _, err = io.Copy(part, file)
+
+ return err
+}
+
+// Prevent trying to import "fmt"
+func reportError(format string, a ...interface{}) error {
+ return fmt.Errorf(format, a...)
+}
+
+// Set request body from an interface{}
+func setBody(body interface{}, contentType string) (bodyBuf *bytes.Buffer, err error) {
+ if bodyBuf == nil {
+ bodyBuf = &bytes.Buffer{}
+ }
+
+ if reader, ok := body.(io.Reader); ok {
+ _, err = bodyBuf.ReadFrom(reader)
+ } else if b, ok := body.([]byte); ok {
+ _, err = bodyBuf.Write(b)
+ } else if s, ok := body.(string); ok {
+ _, err = bodyBuf.WriteString(s)
+ } else if s, ok := body.(*string); ok {
+ _, err = bodyBuf.WriteString(*s)
+ } else if jsonCheck.MatchString(contentType) {
+ err = json.NewEncoder(bodyBuf).Encode(body)
+ } else if xmlCheck.MatchString(contentType) {
+ xml.NewEncoder(bodyBuf).Encode(body)
+ }
+
+ if err != nil {
+ return nil, err
+ }
+
+ if bodyBuf.Len() == 0 {
+ err = fmt.Errorf("Invalid body type %s\n", contentType)
+ return nil, err
+ }
+ return bodyBuf, nil
+}
+
+// detectContentType method is used to figure out `Request.Body` content type for request header
+func detectContentType(body interface{}) string {
+ contentType := "text/plain; charset=utf-8"
+ kind := reflect.TypeOf(body).Kind()
+
+ switch kind {
+ case reflect.Struct, reflect.Map, reflect.Ptr:
+ contentType = "application/json; charset=utf-8"
+ case reflect.String:
+ contentType = "text/plain; charset=utf-8"
+ default:
+ if b, ok := body.([]byte); ok {
+ contentType = http.DetectContentType(b)
+ } else if kind == reflect.Slice {
+ contentType = "application/json; charset=utf-8"
+ }
+ }
+
+ return contentType
+}
+
+// Ripped from https://github.com/gregjones/httpcache/blob/master/httpcache.go
+type cacheControl map[string]string
+
+func parseCacheControl(headers http.Header) cacheControl {
+ cc := cacheControl{}
+ ccHeader := headers.Get("Cache-Control")
+ for _, part := range strings.Split(ccHeader, ",") {
+ part = strings.Trim(part, " ")
+ if part == "" {
+ continue
+ }
+ if strings.ContainsRune(part, '=') {
+ keyval := strings.Split(part, "=")
+ cc[strings.Trim(keyval[0], " ")] = strings.Trim(keyval[1], ",")
+ } else {
+ cc[part] = ""
+ }
+ }
+ return cc
+}
+
+// CacheExpires helper function to determine remaining time before repeating a request.
+func CacheExpires(r *http.Response) time.Time {
+ // Figure out when the cache expires.
+ var expires time.Time
+ now, err := time.Parse(time.RFC1123, r.Header.Get("date"))
+ if err != nil {
+ return time.Now()
+ }
+ respCacheControl := parseCacheControl(r.Header)
+
+ if maxAge, ok := respCacheControl["max-age"]; ok {
+ lifetime, err := time.ParseDuration(maxAge + "s")
+ if err != nil {
+ expires = now
+ }
+ expires = now.Add(lifetime)
+ } else {
+ expiresHeader := r.Header.Get("Expires")
+ if expiresHeader != "" {
+ expires, err = time.Parse(time.RFC1123, expiresHeader)
+ if err != nil {
+ expires = now
+ }
+ }
+ }
+ return expires
+}
+
+func strlen(s string) int {
+ return utf8.RuneCountInString(s)
+}
+
+// GenericSwaggerError Provides access to the body, error and model on returned errors.
+type GenericSwaggerError struct {
+ body []byte
+ error string
+ model interface{}
+}
+
+// Error returns non-empty string if there was an error.
+func (e GenericSwaggerError) Error() string {
+ return e.error
+}
+
+// Body returns the raw bytes of the response
+func (e GenericSwaggerError) Body() []byte {
+ return e.body
+}
+
+// Model returns the unpacked model of the error
+func (e GenericSwaggerError) Model() interface{} {
+ return e.model
+}
diff --git a/vendor/gitee.com/openeuler/go-gitee/gitee/configuration.go b/vendor/gitee.com/openeuler/go-gitee/gitee/configuration.go
new file mode 100644
index 0000000000000000000000000000000000000000..687eccc6c995f1325a037cdfb119a98fc5a839a0
--- /dev/null
+++ b/vendor/gitee.com/openeuler/go-gitee/gitee/configuration.go
@@ -0,0 +1,72 @@
+/*
+ * 码云 Open API
+ *
+ * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen)
+ *
+ * API version: 5.3.2
+ * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
+ */
+
+package gitee
+
+import (
+ "net/http"
+)
+
+// contextKeys are used to identify the type of value in the context.
+// Since these are string, it is possible to get a short description of the
+// context key for logging and debugging using key.String().
+
+type contextKey string
+
+func (c contextKey) String() string {
+ return "auth " + string(c)
+}
+
+var (
+ // ContextOAuth2 takes a oauth2.TokenSource as authentication for the request.
+ ContextOAuth2 = contextKey("token")
+
+ // ContextBasicAuth takes BasicAuth as authentication for the request.
+ ContextBasicAuth = contextKey("basic")
+
+ // ContextAccessToken takes a string oauth2 access token as authentication for the request.
+ ContextAccessToken = contextKey("accesstoken")
+
+ // ContextAPIKey takes an APIKey as authentication for the request
+ ContextAPIKey = contextKey("apikey")
+)
+
+// BasicAuth provides basic http authentication to a request passed via context using ContextBasicAuth
+type BasicAuth struct {
+ UserName string `json:"userName,omitempty"`
+ Password string `json:"password,omitempty"`
+}
+
+// APIKey provides API key based authentication to a request passed via context using ContextAPIKey
+type APIKey struct {
+ Key string
+ Prefix string
+}
+
+type Configuration struct {
+ BasePath string `json:"basePath,omitempty"`
+ Host string `json:"host,omitempty"`
+ Scheme string `json:"scheme,omitempty"`
+ DefaultHeader map[string]string `json:"defaultHeader,omitempty"`
+ UserAgent string `json:"userAgent,omitempty"`
+ HTTPClient *http.Client
+}
+
+func NewConfiguration() *Configuration {
+ cfg := &Configuration{
+ BasePath: "https://gitee.com/api",
+ DefaultHeader: make(map[string]string),
+ UserAgent: "Swagger-Codegen/1.0.0/go",
+ }
+ return cfg
+}
+
+func (c *Configuration) AddDefaultHeader(key string, value string) {
+ c.DefaultHeader[key] = value
+}
diff --git a/vendor/gitee.com/openeuler/go-gitee/gitee/hook_event_models.go b/vendor/gitee.com/openeuler/go-gitee/gitee/hook_event_models.go
new file mode 100644
index 0000000000000000000000000000000000000000..fbdba51e853c1f93cd8ee3ef88bac3c58d192282
--- /dev/null
+++ b/vendor/gitee.com/openeuler/go-gitee/gitee/hook_event_models.go
@@ -0,0 +1,186 @@
+package gitee
+
+import "time"
+
+// See https://gitee.com/help/articles/4271 for the details of all
+// the webhook modles.
+
+// LabelHook : 标签, issue 和 pull request 的对应标签
+type LabelHook struct {
+ Id int32 `json:"id,omitempty"`
+ Name string `json:"name,omitempty"`
+ Color string `json:"color,omitempty"`
+}
+
+// EnterpriseHook : 企业信息
+type EnterpriseHook struct {
+ Name string `json:"name,omitempty"`
+ Url string `json:"url,omitempty"`
+}
+
+// NoteHook : 评论信息
+type NoteHook struct {
+ Id int32 `json:"id,omitempty"`
+ Body string `json:"body,omitempty"`
+ User *UserHook `json:"user,omitempty"`
+ CreatedAt string `json:"created_at,omitempty"`
+ UpdatedAt string `json:"updated_at,omitempty"`
+ HtmlUrl string `json:"html_url,omitempty"`
+ Position string `json:"position,omitempty"`
+ CommitId string `json:"commit_id,omitempty"`
+}
+
+// UserHook : 用户信息
+type UserHook struct {
+ Id int32 `json:"id,omitempty"`
+ Name string `json:"name,omitempty"`
+ Email string `json:"email,omitempty"`
+ Username string `json:"username,omitempty"`
+ UserName string `json:"user_name,omitempty"`
+ Url string `json:"url,omitempty"`
+ Login string `json:"login,omitempty"`
+ AvatarUrl string `json:"avatar_url,omitempty"`
+ HtmlUrl string `json:"html_url,omitempty"`
+ Type_ string `json:"type,omitempty"`
+ SiteAdmin bool `json:"site_admin,omitempty"`
+ Time time.Time `json:"time,omitempty"`
+ Remark string `json:"remark,omitempty"`
+}
+
+// CommitHook : git commit 中的信息
+type CommitHook struct {
+ Id string `json:"id,omitempty"`
+ TreeId string `json:"tree_id,omitempty"`
+ ParentIds []string `json:"parent_ids,omitempty"`
+ Message string `json:"message,omitempty"`
+ Timestamp time.Time `json:"timestamp,omitempty"`
+ Url string `json:"url,omitempty"`
+ Author *UserHook `json:"author,omitempty"`
+ Committer *UserHook `json:"committer,omitempty"`
+ Distinct bool `json:"distinct,omitempty"`
+ Added []string `json:"added,omitempty"`
+ Removed []string `json:"removed,omitempty"`
+ Modified []string `json:"modified,omitempty"`
+}
+
+// MilestoneHook : 里程碑信息
+type MilestoneHook struct {
+ Id string `json:"id,omitempty"`
+ HtmlUrl string `json:"html_url,omitempty"`
+ Number int32 `json:"number,omitempty"`
+ Title string `json:"title,omitempty"`
+ Description string `json:"description,omitempty"`
+ OpenIssues int32 `json:"open_issues,omitempty"`
+ ClosedIssues int32 `json:"closed_issues,omitempty"`
+ State string `json:"state,omitempty"`
+ CreatedAt time.Time `json:"created_at,omitempty"`
+ UpdatedAt time.Time `json:"updated_at,omitempty"`
+ DueOn string `json:"due_on,omitempty"`
+}
+
+// IssueHook : issue 信息
+type IssueHook struct {
+ Id int32 `json:"id,omitempty"`
+ HtmlUrl string `json:"html_url,omitempty"`
+ Number string `json:"number,omitempty"`
+ Title string `json:"title,omitempty"`
+ User *UserHook `json:"user,omitempty"`
+ Labels []LabelHook `json:"labels,omitempty"`
+ State string `json:"state,omitempty"`
+ StateName string `json:"state_name,omitempty"`
+ TypeName string `json:"type_name,omitempty"`
+ Assignee *UserHook `json:"assignee,omitempty"`
+ Collaborators []UserHook `json:"collaborators,omitempty"`
+ Milestone *MilestoneHook `json:"milestone,omitempty"`
+ Comments int32 `json:"comments,omitempty"`
+ CreatedAt time.Time `json:"created_at,omitempty"`
+ UpdatedAt time.Time `json:"updated_at,omitempty"`
+ Body string `json:"body,omitempty"`
+}
+
+// ProjectHook : project 信息
+type ProjectHook struct {
+ Id int32 `json:"id,omitempty"`
+ Name string `json:"name,omitempty"`
+ Path string `json:"path,omitempty"`
+ FullName string `json:"full_name,omitempty"`
+ Owner *UserHook `json:"owner,omitempty"`
+ Private bool `json:"private,omitempty"`
+ HtmlUrl string `json:"html_url,omitempty"`
+ Url string `json:"url,omitempty"`
+ Description string `json:"description,omitempty"`
+ Fork bool `json:"fork,omitempty"`
+ PushedAt string `json:"pushed_at,omitempty"`
+ CreatedAt string `json:"created_at,omitempty"`
+ UpdatedAt string `json:"updated_at,omitempty"`
+ SshUrl string `json:"ssh_url,omitempty"`
+ GitUrl string `json:"git_url,omitempty"`
+ CloneUrl string `json:"clone_url,omitempty"`
+ SvnUrl string `json:"svn_url,omitempty"`
+ GitHttpUrl string `json:"git_http_url,omitempty"`
+ GitSshUrl string `json:"git_ssh_url,omitempty"`
+ GitSvnUrl string `json:"git_svn_url,omitempty"`
+ Homepage string `json:"homepage,omitempty"`
+ StargazersCount int32 `json:"stargazers_count,omitempty"`
+ WatchersCount int32 `json:"watchers_count,omitempty"`
+ ForksCount int32 `json:"forks_count,omitempty"`
+ Language string `json:"language,omitempty"`
+
+ HasIssues bool `json:"has_issues,omitempty"`
+ HasWiki bool `json:"has_wiki,omitempty"`
+ HasPage bool `json:"has_pages,omitempty"`
+ License string `json:"license,omitempty"`
+
+ OpenIssuesCount int32 `json:"open_issues_count,omitempty"`
+ DefaultBranch string `json:"default_branch,omitempty"`
+ Namespace string `json:"namespace,omitempty"`
+
+ NameWithNamespace string `json:"name_with_namespace,omitempty"`
+ PathWithNamespace string `json:"path_with_namespace,omitempty"`
+}
+
+// BranchHook : 分支信息
+type BranchHook struct {
+ Label string `json:"label,omitempty"`
+ Ref string `json:"ref,omitempty"`
+ Sha string `json:"sha,omitempty"`
+ User *UserHook `json:"user,omitempty"`
+ Repo *ProjectHook `json:"repo,omitempty"`
+}
+
+// PullRequestHook : PR 信息
+type PullRequestHook struct {
+ Id int32 `json:"id,omitempty"`
+ Number int32 `json:"number,omitempty"`
+ State string `json:"state,omitempty"`
+ HtmlUrl string `json:"html_url,omitempty"`
+ DiffUrl string `json:"diff_url,omitempty"`
+ PatchUrl string `json:"patch_url,omitempty"`
+ Title string `json:"title,omitempty"`
+ Body string `json:"body,omitempty"`
+ CreatedAt string `json:"created_at,omitempty"`
+ UpdatedAt string `json:"updated_at,omitempty"`
+ ClosedAt string `json:"closed_at,omitempty"`
+ MergedAt string `json:"merged_at,omitempty"`
+ MergeCommitSha string `json:"merge_commit_sha,omitempty"`
+ MergeReferenceName string `json:"merge_reference_name,omitempty"`
+ User *UserHook `json:"user,omitempty"`
+ Assignee *UserHook `json:"assignee,omitempty"`
+ Assignees []UserHook `json:"assignees,omitempty"`
+ Tester []UserHook `json:"tester,omitempty"`
+ Testers []UserHook `json:"testers,omitempty"`
+ NeedTest bool `json:"need_test,omitempty"`
+ need_review bool `json:"need_review,omitempty"`
+ Milestone *MilestoneHook `json:"milestone,omitempty"`
+ Head *BranchHook `json:"head,omitempty"`
+ Base *BranchHook `json:"base,omitempty"`
+ Merged bool `json:"merged,omitempty"`
+ Mergeable bool `json:"mergeable,omitempty"`
+ merge_status string `json:"merge_status,omitempty"`
+ UpdatedBy *UserHook `json:"updated_by,omitempty"`
+ Comments int32 `json:"comments,omitempty"`
+ Commits int32 `json:"commits,omitempty"`
+ Additions int32 `json:"additions,omitempty"`
+ Deletions int32 `json:"deletions,omitempty"`
+ ChangedFiles int32 `json:"changed_files,omitempty"`
+}
diff --git a/vendor/gitee.com/openeuler/go-gitee/gitee/hook_event_types.go b/vendor/gitee.com/openeuler/go-gitee/gitee/hook_event_types.go
new file mode 100644
index 0000000000000000000000000000000000000000..1081a7528a87690c71b42885b9296c3ad9e1df22
--- /dev/null
+++ b/vendor/gitee.com/openeuler/go-gitee/gitee/hook_event_types.go
@@ -0,0 +1,101 @@
+package gitee
+
+type NoteEvent struct {
+ Action *string `json:"action,omitempty"`
+ Comment *NoteHook `json:"comment,omitempty"`
+ Repository *ProjectHook `json:"repository,omitempty"`
+ Project *ProjectHook `json:"project,omitempty"`
+ Author *UserHook `json:"author,omitempty"`
+ Sender *UserHook `json:"sender,omitempty"`
+ URL *string `json:"url,omitempty"`
+ Note *string `json:"note,omitempty"`
+ NoteableType *string `json:"noteable_type,omitempty"`
+ NoteableID int64 `json:"noteable_id,omitempty"`
+ Title *string `json:"title,omitempty"`
+ PerIID *string `json:"per_iid,omitempty"`
+ ShortCommitID *string `json:"short_commit_id,omitempty"`
+ Enterprise *EnterpriseHook `json:"enterprise,omitempty"`
+ PullRequest *PullRequestHook `json:"pull_request,omitempty"`
+ Issue *IssueHook `json:"issue,omitempty"`
+ HookName *string `json:"hook_name,omitempty"`
+ Password *string `json:"password,omitempty"`
+}
+
+type PushEvent struct {
+ Ref *string `json:"ref,omitempty"`
+ Before *string `json:"before,omitempty"`
+ After *string `json:"after,omitempty"`
+ TotalCommitsCount int64 `json:"total_commits_count,omitempty"`
+ CommitsMoreThanTen *bool `json:"commits_more_than_ten,omitempty"`
+ Created *bool `json:"created,omitempty"`
+ Deleted *bool `json:"deleted,omitempty"`
+ Compare *string `json:"compare,omitempty"`
+ Commits []CommitHook `json:"commits,omitempty"`
+ HeadCommit *CommitHook `json:"head_commit,omitempty"`
+ Repository *ProjectHook `json:"repository,omitempty"`
+ Project *ProjectHook `json:"project,omitempty"`
+ UserID int64 `json:"user_id,omitempty"`
+ UserName *string `json:"user_name,omitempty"`
+ User *UserHook `json:"user,omitempty"`
+ Pusher *UserHook `json:"pusher,omitempty"`
+ Sender *UserHook `json:"sender,omitempty"`
+ Enterprise *EnterpriseHook `json:"enterprise,omitempty"`
+ HookName *string `json:"hook_name,omitempty"`
+ Password *string `json:"password,omitempty"`
+}
+
+type IssueEvent struct {
+ Action *string `json:"action,omitempty"`
+ Issue *IssueHook `json:"issue,omitempty"`
+ Repository *ProjectHook `json:"repository,omitempty"`
+ Project *ProjectHook `json:"project,omitempty"`
+ Sender *UserHook `json:"sender,omitempty"`
+ TargetUser *UserHook `json:"target_user,omitempty"`
+ User *UserHook `json:"user,omitempty"`
+ Assignee *UserHook `json:"assignee,omitempty"`
+ UpdatedBy *UserHook `json:"updated_by,omitempty"`
+ IID string `json:"iid,omitempty"`
+ Title *string `json:"title,omitempty"`
+ Description *string `json:"description,omitempty"`
+ State *string `json:"state,omitempty"`
+ Milestone *MilestoneHook `json:"milestone,omitempty"`
+ URL *string `json:"url,omitempty"`
+ Enterprise *EnterpriseHook `json:"enterprise,omitempty"`
+ HookName *string `json:"hook_name,omitempty"`
+ Password *string `json:"password,omitempty"`
+}
+
+type RepoInfo struct {
+ Project *ProjectHook `json:"project,omitempty"`
+ Repository *ProjectHook `json:"repository,omitempty"`
+}
+
+type PullRequestEvent struct {
+ Action *string `json:"action,omitempty"`
+ PullRequest *PullRequestHook `json:"pull_request,omitempty"`
+ Number int64 `json:"number,omitempty"`
+ IID int64 `json:"iid,omitempty"`
+ Title *string `json:"title,omitempty"`
+ Body *string `json:"body,omitempty"`
+ State *string `json:"state,omitempty"`
+ MergeStatus *string `json:"merge_status,omitempty"`
+ MergeCommitSha *string `json:"merge_commit_sha,omitempty"`
+ URL *string `json:"url,omitempty"`
+ SourceBranch *string `json:"source_branch,omitempty"`
+ SourceRepo *ProjectHook `json:"source_repo,omitempty"`
+ TargetBranch *string `json:"target_branch,omitempty"`
+ TargetRepo *ProjectHook `json:"target_repo,omitempty"`
+ Project *ProjectHook `json:"project,omitempty"`
+ Repository *ProjectHook `json:"repository,omitempty"`
+ Author *UserHook `json:"author,omitempty"`
+ UpdatedBy *UserHook `json:"updated_by,omitempty"`
+ Sender *UserHook `json:"sender,omitempty"`
+ TargetUser *UserHook `json:"target_user,omitempty"`
+ Enterprise *EnterpriseHook `json:"enterprise,omitempty"`
+ HookName *string `json:"hook_name,omitempty"`
+ Password *string `json:"password,omitempty"`
+}
+
+type TagPushEvent struct {
+ Action *string `json:"action,omitempty"`
+}
diff --git a/vendor/gitee.com/openeuler/go-gitee/gitee/hook_events.go b/vendor/gitee.com/openeuler/go-gitee/gitee/hook_events.go
new file mode 100644
index 0000000000000000000000000000000000000000..4f945cbc9a89307452382bb4a04bd408e730e0a6
--- /dev/null
+++ b/vendor/gitee.com/openeuler/go-gitee/gitee/hook_events.go
@@ -0,0 +1,35 @@
+package gitee
+
+import (
+ "encoding/json"
+ "time"
+)
+
+// HookEvent represents a Gitee hook event.
+type HookEvent struct {
+ Type *string `json:"type,omitempty"`
+ RawPayload *json.RawMessage `json:"payload,omitempty"`
+ Actor *User `json:"actor,omitempty"`
+ CreatedAt *time.Time `json:"created_at,omitempty"`
+ ID *string `json:"id,omitempty"`
+}
+
+// ParsePayload parses the event payload. For recognized event types,
+// a value of the corresponding struct type will be returned.
+func (e *HookEvent) ParsePayload() (payload interface{}, err error) {
+ switch *e.Type {
+ case "NoteEvent":
+ payload = &NoteEvent{}
+ case "PushEvent":
+ payload = &PushEvent{}
+ case "IssueEvent":
+ payload = &IssueEvent{}
+ case "PullRequestEvent":
+ payload = &PullRequestEvent{}
+ case "TagPushEvent":
+ payload = &TagPushEvent{}
+ }
+
+ err = json.Unmarshal(*e.RawPayload, &payload)
+ return payload, err
+}
diff --git a/vendor/gitee.com/openeuler/go-gitee/gitee/messages.go b/vendor/gitee.com/openeuler/go-gitee/gitee/messages.go
new file mode 100644
index 0000000000000000000000000000000000000000..6f04733fda9dca0714c15ed45a7b42058897b194
--- /dev/null
+++ b/vendor/gitee.com/openeuler/go-gitee/gitee/messages.go
@@ -0,0 +1,92 @@
+package gitee
+
+import (
+ "encoding/json"
+ "errors"
+ "fmt"
+ "io/ioutil"
+ "net/http"
+ "net/url"
+)
+
+/*
+Header Example:
+
+Request URL: http://gitee.com/webhook
+Request Method: POST
+Content-Type: application/json
+User-Agent: git-oschina-hook
+X-Gitee-Token: ******
+X-Gitee-Ping: false
+X-Gitee-Event: Merge Request Hook
+X-Git-Oschina-Event: Merge Request Hook
+
+*/
+const (
+ // eventTypeHeader is the Gitee header key used to pass the event type.
+ eventTypeHeader = "X-Gitee-Event"
+ // tokenTypeHeader is the Gitee header key used to pass the webhook secret.
+ tokenTypeHeader = "X-Gitee-Token"
+)
+
+var (
+ // eventTypeMapping maps webhooks types
+ eventTypeMapping = map[string]string{
+ "Note Hook": "NoteEvent",
+ "Push Hook": "PushEvent",
+ "Issue Hook": "IssueEvent",
+ "Merge Request Hook": "PullRequestEvent",
+ "Tag Push Hook": "TagPushEvent",
+ }
+)
+
+// ValidatePayload validates an incoming Gitee Webhook event request
+func ValidatePayload(r *http.Request, secretKey []byte) (payload []byte, err error) {
+ var body []byte
+
+ switch ct := r.Header.Get("Content-Type"); ct {
+ case "application/json":
+ var err error
+ if body, err = ioutil.ReadAll(r.Body); err != nil {
+ return nil, err
+ }
+ payload = body
+ case "application/x-www-form-urlencoded":
+ const payloadFormParam = "payload"
+ var err error
+ if body, err = ioutil.ReadAll(r.Body); err != nil {
+ return nil, err
+ }
+ form, err := url.ParseQuery(string(body))
+ if err != nil {
+ return nil, err
+ }
+ payload = []byte(form.Get(payloadFormParam))
+ default:
+ return nil, fmt.Errorf("webhook request has unsupported Content-Type %q", ct)
+ }
+
+ token := r.Header.Get(tokenTypeHeader)
+ if token != string(secretKey) {
+ return nil, errors.New("payload token check failed")
+ }
+ return payload, nil
+}
+
+// WebHookType returns the event type of webhook request r.
+func WebHookType(r *http.Request) string {
+ return r.Header.Get(eventTypeHeader)
+}
+
+// ParseWebHook parses the event payload.
+func ParseWebHook(messageType string, payload []byte) (interface{}, error) {
+ eventType, ok := eventTypeMapping[messageType]
+ if !ok {
+ return nil, fmt.Errorf("unknown X-Gitee-Event in message: %v", messageType)
+ }
+ hookEvent := HookEvent{
+ Type: &eventType,
+ RawPayload: (*json.RawMessage)(&payload),
+ }
+ return hookEvent.ParsePayload()
+}
diff --git a/vendor/gitee.com/openeuler/go-gitee/gitee/model_basic_info.go b/vendor/gitee.com/openeuler/go-gitee/gitee/model_basic_info.go
new file mode 100644
index 0000000000000000000000000000000000000000..6032671a65f0137109810ab80c15c98e9ee9800b
--- /dev/null
+++ b/vendor/gitee.com/openeuler/go-gitee/gitee/model_basic_info.go
@@ -0,0 +1,19 @@
+/*
+ * 码云 Open API
+ *
+ * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen)
+ *
+ * API version: 5.3.2
+ * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
+ */
+
+package gitee
+
+// basic information
+type BasicInfo struct {
+ Label string `json:"label,omitempty"`
+ Ref string `json:"ref,omitempty"`
+ Sha string `json:"sha,omitempty"`
+ User *UserBasic `json:"user,omitempty"`
+ Repo *Project `json:"repo,omitempty"`
+}
diff --git a/vendor/gitee.com/openeuler/go-gitee/gitee/model_blob.go b/vendor/gitee.com/openeuler/go-gitee/gitee/model_blob.go
new file mode 100644
index 0000000000000000000000000000000000000000..a839cf68d65b41260a0e34d658f67d42c960002c
--- /dev/null
+++ b/vendor/gitee.com/openeuler/go-gitee/gitee/model_blob.go
@@ -0,0 +1,19 @@
+/*
+ * 码云 Open API
+ *
+ * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen)
+ *
+ * API version: 5.3.2
+ * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
+ */
+
+package gitee
+
+// 获取文件Blob
+type Blob struct {
+ Sha string `json:"sha,omitempty"`
+ Size string `json:"size,omitempty"`
+ Url string `json:"url,omitempty"`
+ Content string `json:"content,omitempty"`
+ Encoding string `json:"encoding,omitempty"`
+}
diff --git a/vendor/gitee.com/openeuler/go-gitee/gitee/model_branch.go b/vendor/gitee.com/openeuler/go-gitee/gitee/model_branch.go
new file mode 100644
index 0000000000000000000000000000000000000000..98b8e66aa1db0db826632d540d57b885545ebaea
--- /dev/null
+++ b/vendor/gitee.com/openeuler/go-gitee/gitee/model_branch.go
@@ -0,0 +1,18 @@
+/*
+ * 码云 Open API
+ *
+ * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen)
+ *
+ * API version: 5.3.2
+ * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
+ */
+
+package gitee
+
+// 获取所有分支
+type Branch struct {
+ Name string `json:"name,omitempty"`
+ Commit string `json:"commit,omitempty"`
+ Protected string `json:"protected,omitempty"`
+ ProtectionUrl string `json:"protection_url,omitempty"`
+}
diff --git a/vendor/gitee.com/openeuler/go-gitee/gitee/model_branch_protection_put_param.go b/vendor/gitee.com/openeuler/go-gitee/gitee/model_branch_protection_put_param.go
new file mode 100644
index 0000000000000000000000000000000000000000..909c885e84739d579d3f98021be00c7e7228fcc7
--- /dev/null
+++ b/vendor/gitee.com/openeuler/go-gitee/gitee/model_branch_protection_put_param.go
@@ -0,0 +1,16 @@
+/*
+ * 码云 Open API
+ *
+ * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen)
+ *
+ * API version: 5.3.2
+ * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
+ */
+
+package gitee
+
+// branch protection parameter
+type BranchProtectionPutParam struct {
+ // 用户授权码
+ AccessToken string `json:"access_token,omitempty"`
+}
diff --git a/vendor/gitee.com/openeuler/go-gitee/gitee/model_code.go b/vendor/gitee.com/openeuler/go-gitee/gitee/model_code.go
new file mode 100644
index 0000000000000000000000000000000000000000..e120b4b943f71ba752a8733896d185652edec813
--- /dev/null
+++ b/vendor/gitee.com/openeuler/go-gitee/gitee/model_code.go
@@ -0,0 +1,31 @@
+/*
+ * 码云 Open API
+ *
+ * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen)
+ *
+ * API version: 5.3.2
+ * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
+ */
+
+package gitee
+
+// 搜索代码片段
+type Code struct {
+ Url string `json:"url,omitempty"`
+ ForksUrl string `json:"forks_url,omitempty"`
+ CommitsUrl string `json:"commits_url,omitempty"`
+ Id string `json:"id,omitempty"`
+ Description string `json:"description,omitempty"`
+ Public string `json:"public,omitempty"`
+ Owner string `json:"owner,omitempty"`
+ User string `json:"user,omitempty"`
+ Files string `json:"files,omitempty"`
+ Truncated string `json:"truncated,omitempty"`
+ HtmlUrl string `json:"html_url,omitempty"`
+ Comments string `json:"comments,omitempty"`
+ CommentsUrl string `json:"comments_url,omitempty"`
+ GitPullUrl string `json:"git_pull_url,omitempty"`
+ GitPushUrl string `json:"git_push_url,omitempty"`
+ CreatedAt string `json:"created_at,omitempty"`
+ UpdatedAt string `json:"updated_at,omitempty"`
+}
diff --git a/vendor/gitee.com/openeuler/go-gitee/gitee/model_code_comment.go b/vendor/gitee.com/openeuler/go-gitee/gitee/model_code_comment.go
new file mode 100644
index 0000000000000000000000000000000000000000..5b92d49bb951f807ab1047a2a3946b054f440e7e
--- /dev/null
+++ b/vendor/gitee.com/openeuler/go-gitee/gitee/model_code_comment.go
@@ -0,0 +1,18 @@
+/*
+ * 码云 Open API
+ *
+ * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen)
+ *
+ * API version: 5.3.2
+ * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
+ */
+
+package gitee
+
+// 修改代码片段的评论
+type CodeComment struct {
+ Id string `json:"id,omitempty"`
+ Body string `json:"body,omitempty"`
+ CreatedAt string `json:"created_at,omitempty"`
+ UpdatedAt string `json:"updated_at,omitempty"`
+}
diff --git a/vendor/gitee.com/openeuler/go-gitee/gitee/model_code_forks.go b/vendor/gitee.com/openeuler/go-gitee/gitee/model_code_forks.go
new file mode 100644
index 0000000000000000000000000000000000000000..55615f2c5c90b633ac03cf84f15af88b502ed921
--- /dev/null
+++ b/vendor/gitee.com/openeuler/go-gitee/gitee/model_code_forks.go
@@ -0,0 +1,19 @@
+/*
+ * 码云 Open API
+ *
+ * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen)
+ *
+ * API version: 5.3.2
+ * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
+ */
+
+package gitee
+
+// 获取 Fork 了指定代码片段的列表
+type CodeForks struct {
+ User string `json:"user,omitempty"`
+ Url string `json:"url,omitempty"`
+ Id string `json:"id,omitempty"`
+ CreatedAt string `json:"created_at,omitempty"`
+ UpdatedAt string `json:"updated_at,omitempty"`
+}
diff --git a/vendor/gitee.com/openeuler/go-gitee/gitee/model_code_forks_history.go b/vendor/gitee.com/openeuler/go-gitee/gitee/model_code_forks_history.go
new file mode 100644
index 0000000000000000000000000000000000000000..7ca9f25403aea3a6536ad0d504a1c79f45bce39d
--- /dev/null
+++ b/vendor/gitee.com/openeuler/go-gitee/gitee/model_code_forks_history.go
@@ -0,0 +1,33 @@
+/*
+ * 码云 Open API
+ *
+ * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen)
+ *
+ * API version: 5.3.2
+ * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
+ */
+
+package gitee
+
+// 获取代码片段的commit
+type CodeForksHistory struct {
+ Url string `json:"url,omitempty"`
+ ForksUrl string `json:"forks_url,omitempty"`
+ CommitsUrl string `json:"commits_url,omitempty"`
+ Id string `json:"id,omitempty"`
+ Description string `json:"description,omitempty"`
+ Public string `json:"public,omitempty"`
+ Owner string `json:"owner,omitempty"`
+ User string `json:"user,omitempty"`
+ Files string `json:"files,omitempty"`
+ Truncated string `json:"truncated,omitempty"`
+ HtmlUrl string `json:"html_url,omitempty"`
+ Comments string `json:"comments,omitempty"`
+ CommentsUrl string `json:"comments_url,omitempty"`
+ GitPullUrl string `json:"git_pull_url,omitempty"`
+ GitPushUrl string `json:"git_push_url,omitempty"`
+ CreatedAt string `json:"created_at,omitempty"`
+ UpdatedAt string `json:"updated_at,omitempty"`
+ Forks string `json:"forks,omitempty"`
+ History string `json:"history,omitempty"`
+}
diff --git a/vendor/gitee.com/openeuler/go-gitee/gitee/model_commit.go b/vendor/gitee.com/openeuler/go-gitee/gitee/model_commit.go
new file mode 100644
index 0000000000000000000000000000000000000000..a03ec910de746e189259b4799714a9ff035a2425
--- /dev/null
+++ b/vendor/gitee.com/openeuler/go-gitee/gitee/model_commit.go
@@ -0,0 +1,29 @@
+/*
+ * 码云 Open API
+ *
+ * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen)
+ *
+ * API version: 5.3.2
+ * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
+ */
+
+package gitee
+
+import (
+ "time"
+)
+
+type Commit struct {
+ Id string `json:"id,omitempty"`
+ TreeId string `json:"tree_id,omitempty"`
+ ParentIds []string `json:"parent_ids,omitempty"`
+ Message string `json:"message,omitempty"`
+ Timestamp time.Time `json:"timestamp,omitempty"`
+ Url string `json:"url,omitempty"`
+ Author *UserBasic `json:"author,omitempty"`
+ Committer *UserBasic `json:"committer,omitempty"`
+ Distinct bool `json:"distinct,omitempty"`
+ Added []string `json:"added,omitempty"`
+ Removed []string `json:"removed,omitempty"`
+ Modified []string `json:"modified,omitempty"`
+}
diff --git a/vendor/gitee.com/openeuler/go-gitee/gitee/model_commit_content.go b/vendor/gitee.com/openeuler/go-gitee/gitee/model_commit_content.go
new file mode 100644
index 0000000000000000000000000000000000000000..e02f3e07092025ad59a46c8681e1a5490a6d7529
--- /dev/null
+++ b/vendor/gitee.com/openeuler/go-gitee/gitee/model_commit_content.go
@@ -0,0 +1,16 @@
+/*
+ * 码云 Open API
+ *
+ * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen)
+ *
+ * API version: 5.3.2
+ * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
+ */
+
+package gitee
+
+// 删除文件
+type CommitContent struct {
+ Content *ContentBasic `json:"content,omitempty"`
+ Commit *Commit `json:"commit,omitempty"`
+}
diff --git a/vendor/gitee.com/openeuler/go-gitee/gitee/model_compare.go b/vendor/gitee.com/openeuler/go-gitee/gitee/model_compare.go
new file mode 100644
index 0000000000000000000000000000000000000000..cd3d63e4f2084bcc2d9c46b41f215889210212c2
--- /dev/null
+++ b/vendor/gitee.com/openeuler/go-gitee/gitee/model_compare.go
@@ -0,0 +1,18 @@
+/*
+ * 码云 Open API
+ *
+ * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen)
+ *
+ * API version: 5.3.2
+ * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
+ */
+
+package gitee
+
+// 两个Commits之间对比的版本差异
+type Compare struct {
+ BaseCommit string `json:"base_commit,omitempty"`
+ MergeBaseCommit string `json:"merge_base_commit,omitempty"`
+ Commits string `json:"commits,omitempty"`
+ Files string `json:"files,omitempty"`
+}
diff --git a/vendor/gitee.com/openeuler/go-gitee/gitee/model_complete_branch.go b/vendor/gitee.com/openeuler/go-gitee/gitee/model_complete_branch.go
new file mode 100644
index 0000000000000000000000000000000000000000..df48bc0e39dca007e5d6516d689ab647e55f49b3
--- /dev/null
+++ b/vendor/gitee.com/openeuler/go-gitee/gitee/model_complete_branch.go
@@ -0,0 +1,19 @@
+/*
+ * 码云 Open API
+ *
+ * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen)
+ *
+ * API version: 5.3.2
+ * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
+ */
+
+package gitee
+
+// 创建分支
+type CompleteBranch struct {
+ Name string `json:"name,omitempty"`
+ Commit string `json:"commit,omitempty"`
+ Links string `json:"_links,omitempty"`
+ Protected string `json:"protected,omitempty"`
+ ProtectionUrl string `json:"protection_url,omitempty"`
+}
diff --git a/vendor/gitee.com/openeuler/go-gitee/gitee/model_content.go b/vendor/gitee.com/openeuler/go-gitee/gitee/model_content.go
new file mode 100644
index 0000000000000000000000000000000000000000..94e4ebab518f5df98270718ba0282f8f290c5479
--- /dev/null
+++ b/vendor/gitee.com/openeuler/go-gitee/gitee/model_content.go
@@ -0,0 +1,25 @@
+/*
+ * 码云 Open API
+ *
+ * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen)
+ *
+ * API version: 5.3.2
+ * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
+ */
+
+package gitee
+
+// 获取仓库具体路径下的内容
+type Content struct {
+ Type_ string `json:"type,omitempty"`
+ Encoding string `json:"encoding,omitempty"`
+ Size string `json:"size,omitempty"`
+ Name string `json:"name,omitempty"`
+ Path string `json:"path,omitempty"`
+ Content string `json:"content,omitempty"`
+ Sha string `json:"sha,omitempty"`
+ Url string `json:"url,omitempty"`
+ HtmlUrl string `json:"html_url,omitempty"`
+ DownloadUrl string `json:"download_url,omitempty"`
+ Links string `json:"_links,omitempty"`
+}
diff --git a/vendor/gitee.com/openeuler/go-gitee/gitee/model_content_basic.go b/vendor/gitee.com/openeuler/go-gitee/gitee/model_content_basic.go
new file mode 100644
index 0000000000000000000000000000000000000000..0c2715979fd63d64b19dcd559926edaaf925ab7a
--- /dev/null
+++ b/vendor/gitee.com/openeuler/go-gitee/gitee/model_content_basic.go
@@ -0,0 +1,22 @@
+/*
+ * 码云 Open API
+ *
+ * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen)
+ *
+ * API version: 5.3.2
+ * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
+ */
+
+package gitee
+
+type ContentBasic struct {
+ Name string `json:"name,omitempty"`
+ Path string `json:"path,omitempty"`
+ Size string `json:"size,omitempty"`
+ Sha string `json:"sha,omitempty"`
+ Type_ string `json:"type,omitempty"`
+ Url string `json:"url,omitempty"`
+ HtmlUrl string `json:"html_url,omitempty"`
+ DownloadUrl string `json:"download_url,omitempty"`
+ Links string `json:"_links,omitempty"`
+}
diff --git a/vendor/gitee.com/openeuler/go-gitee/gitee/model_contributor.go b/vendor/gitee.com/openeuler/go-gitee/gitee/model_contributor.go
new file mode 100644
index 0000000000000000000000000000000000000000..1e282e25d9fe19343015b26080133d6f16a1bd3b
--- /dev/null
+++ b/vendor/gitee.com/openeuler/go-gitee/gitee/model_contributor.go
@@ -0,0 +1,17 @@
+/*
+ * 码云 Open API
+ *
+ * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen)
+ *
+ * API version: 5.3.2
+ * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
+ */
+
+package gitee
+
+// 获取仓库贡献者
+type Contributor struct {
+ Email string `json:"email,omitempty"`
+ Name string `json:"name,omitempty"`
+ Contributions string `json:"contributions,omitempty"`
+}
diff --git a/vendor/gitee.com/openeuler/go-gitee/gitee/model_email.go b/vendor/gitee.com/openeuler/go-gitee/gitee/model_email.go
new file mode 100644
index 0000000000000000000000000000000000000000..40de10db1c61a91258faa5d0c3d09a07d8ea4cae
--- /dev/null
+++ b/vendor/gitee.com/openeuler/go-gitee/gitee/model_email.go
@@ -0,0 +1,17 @@
+/*
+ * 码云 Open API
+ *
+ * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen)
+ *
+ * API version: 5.3.2
+ * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
+ */
+
+package gitee
+
+// 获取授权用户的邮件地址
+type Email struct {
+ Email string `json:"email,omitempty"`
+ State string `json:"state,omitempty"`
+ Scope []string `json:"scope,omitempty"`
+}
diff --git a/vendor/gitee.com/openeuler/go-gitee/gitee/model_enterprise_basic.go b/vendor/gitee.com/openeuler/go-gitee/gitee/model_enterprise_basic.go
new file mode 100644
index 0000000000000000000000000000000000000000..9649af3bf3e8605f962a18e64ca1e789e2002d86
--- /dev/null
+++ b/vendor/gitee.com/openeuler/go-gitee/gitee/model_enterprise_basic.go
@@ -0,0 +1,19 @@
+/*
+ * 码云 Open API
+ *
+ * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen)
+ *
+ * API version: 5.3.2
+ * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
+ */
+
+package gitee
+
+// 获取一个企业
+type EnterpriseBasic struct {
+ Id int32 `json:"id,omitempty"`
+ Path string `json:"path,omitempty"`
+ Name string `json:"name,omitempty"`
+ Url string `json:"url,omitempty"`
+ AvatarUrl string `json:"avatar_url,omitempty"`
+}
diff --git a/vendor/gitee.com/openeuler/go-gitee/gitee/model_enterprise_member.go b/vendor/gitee.com/openeuler/go-gitee/gitee/model_enterprise_member.go
new file mode 100644
index 0000000000000000000000000000000000000000..5918623bc7d86089bbb1757bd7795dbf96738cff
--- /dev/null
+++ b/vendor/gitee.com/openeuler/go-gitee/gitee/model_enterprise_member.go
@@ -0,0 +1,21 @@
+/*
+ * 码云 Open API
+ *
+ * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen)
+ *
+ * API version: 5.3.2
+ * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
+ */
+
+package gitee
+
+// 修改企业成员权限或备注
+type EnterpriseMember struct {
+ Url string `json:"url,omitempty"`
+ Active string `json:"active,omitempty"`
+ Remark string `json:"remark,omitempty"`
+ Role string `json:"role,omitempty"`
+ Outsourced string `json:"outsourced,omitempty"`
+ Enterprise *EnterpriseBasic `json:"enterprise,omitempty"`
+ User string `json:"user,omitempty"`
+}
diff --git a/vendor/gitee.com/openeuler/go-gitee/gitee/model_event.go b/vendor/gitee.com/openeuler/go-gitee/gitee/model_event.go
new file mode 100644
index 0000000000000000000000000000000000000000..23c89d44c48eefd79189fc9d5ddb38902e2b01d8
--- /dev/null
+++ b/vendor/gitee.com/openeuler/go-gitee/gitee/model_event.go
@@ -0,0 +1,23 @@
+/*
+ * 码云 Open API
+ *
+ * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen)
+ *
+ * API version: 5.3.2
+ * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
+ */
+
+package gitee
+
+// 列出仓库的所有公开动态
+type Event struct {
+ Id int32 `json:"id,omitempty"`
+ Type_ string `json:"type,omitempty"`
+ Actor string `json:"actor,omitempty"`
+ Repo string `json:"repo,omitempty"`
+ Org string `json:"org,omitempty"`
+ Public string `json:"public,omitempty"`
+ CreatedAt string `json:"created_at,omitempty"`
+ // 不同类型动态的内容
+ Payload *interface{} `json:"payload,omitempty"`
+}
diff --git a/vendor/gitee.com/openeuler/go-gitee/gitee/model_group.go b/vendor/gitee.com/openeuler/go-gitee/gitee/model_group.go
new file mode 100644
index 0000000000000000000000000000000000000000..4805b33993ab01da44ee2de9fc61859fc22337c4
--- /dev/null
+++ b/vendor/gitee.com/openeuler/go-gitee/gitee/model_group.go
@@ -0,0 +1,22 @@
+/*
+ * 码云 Open API
+ *
+ * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen)
+ *
+ * API version: 5.3.2
+ * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
+ */
+
+package gitee
+
+// 获取一个组织
+type Group struct {
+ Id int32 `json:"id,omitempty"`
+ Login string `json:"login,omitempty"`
+ Url string `json:"url,omitempty"`
+ AvatarUrl string `json:"avatar_url,omitempty"`
+ ReposUrl string `json:"repos_url,omitempty"`
+ EventsUrl string `json:"events_url,omitempty"`
+ MembersUrl string `json:"members_url,omitempty"`
+ Description string `json:"description,omitempty"`
+}
diff --git a/vendor/gitee.com/openeuler/go-gitee/gitee/model_group_detail.go b/vendor/gitee.com/openeuler/go-gitee/gitee/model_group_detail.go
new file mode 100644
index 0000000000000000000000000000000000000000..4db8653d6b4cf363fb750ae41bf324b6e8125ac7
--- /dev/null
+++ b/vendor/gitee.com/openeuler/go-gitee/gitee/model_group_detail.go
@@ -0,0 +1,34 @@
+/*
+ * 码云 Open API
+ *
+ * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen)
+ *
+ * API version: 5.3.2
+ * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
+ */
+
+package gitee
+
+// 更新授权用户所管理的组织资料
+type GroupDetail struct {
+ Id int32 `json:"id,omitempty"`
+ Login string `json:"login,omitempty"`
+ Url string `json:"url,omitempty"`
+ AvatarUrl string `json:"avatar_url,omitempty"`
+ ReposUrl string `json:"repos_url,omitempty"`
+ EventsUrl string `json:"events_url,omitempty"`
+ MembersUrl string `json:"members_url,omitempty"`
+ Description string `json:"description,omitempty"`
+ Name string `json:"name,omitempty"`
+ CreatedAt string `json:"created_at,omitempty"`
+ Type_ string `json:"type,omitempty"`
+ Location string `json:"location,omitempty"`
+ Email string `json:"email,omitempty"`
+ HtmlUrl string `json:"html_url,omitempty"`
+ Public string `json:"public,omitempty"`
+ Enterprise string `json:"enterprise,omitempty"`
+ Members string `json:"members,omitempty"`
+ PublicRepos string `json:"public_repos,omitempty"`
+ PrivateRepos string `json:"private_repos,omitempty"`
+ Owner string `json:"owner,omitempty"`
+}
diff --git a/vendor/gitee.com/openeuler/go-gitee/gitee/model_group_member.go b/vendor/gitee.com/openeuler/go-gitee/gitee/model_group_member.go
new file mode 100644
index 0000000000000000000000000000000000000000..8dc0a5f53f038589a0988c4f7cb02d884c229311
--- /dev/null
+++ b/vendor/gitee.com/openeuler/go-gitee/gitee/model_group_member.go
@@ -0,0 +1,21 @@
+/*
+ * 码云 Open API
+ *
+ * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen)
+ *
+ * API version: 5.3.2
+ * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
+ */
+
+package gitee
+
+// 增加或更新授权用户所管理组织的成员
+type GroupMember struct {
+ Url string `json:"url,omitempty"`
+ Active string `json:"active,omitempty"`
+ Remark string `json:"remark,omitempty"`
+ Role string `json:"role,omitempty"`
+ OrganizationUrl string `json:"organization_url,omitempty"`
+ Organization *Group `json:"organization,omitempty"`
+ User string `json:"user,omitempty"`
+}
diff --git a/vendor/gitee.com/openeuler/go-gitee/gitee/model_hook.go b/vendor/gitee.com/openeuler/go-gitee/gitee/model_hook.go
new file mode 100644
index 0000000000000000000000000000000000000000..dcb68b7227bf2b9b233afed68d9c8c5d3eac5382
--- /dev/null
+++ b/vendor/gitee.com/openeuler/go-gitee/gitee/model_hook.go
@@ -0,0 +1,26 @@
+/*
+ * 码云 Open API
+ *
+ * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen)
+ *
+ * API version: 5.3.2
+ * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
+ */
+
+package gitee
+
+// 更新一个仓库WebHook
+type Hook struct {
+ Id string `json:"id,omitempty"`
+ Url string `json:"url,omitempty"`
+ CreatedAt string `json:"created_at,omitempty"`
+ Password string `json:"password,omitempty"`
+ ProjectId string `json:"project_id,omitempty"`
+ Result string `json:"result,omitempty"`
+ ResultCode string `json:"result_code,omitempty"`
+ PushEvents string `json:"push_events,omitempty"`
+ TagPushEvents string `json:"tag_push_events,omitempty"`
+ IssuesEvents string `json:"issues_events,omitempty"`
+ NoteEvents string `json:"note_events,omitempty"`
+ MergeRequestsEvents string `json:"merge_requests_events,omitempty"`
+}
diff --git a/vendor/gitee.com/openeuler/go-gitee/gitee/model_issue.go b/vendor/gitee.com/openeuler/go-gitee/gitee/model_issue.go
new file mode 100644
index 0000000000000000000000000000000000000000..d1cebfdd7768fc4e288d0fc4b559c1ea4bde715b
--- /dev/null
+++ b/vendor/gitee.com/openeuler/go-gitee/gitee/model_issue.go
@@ -0,0 +1,45 @@
+/*
+ * 码云 Open API
+ *
+ * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen)
+ *
+ * API version: 5.3.2
+ * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
+ */
+
+package gitee
+
+import (
+ "time"
+)
+
+// 搜索 Issues
+type Issue struct {
+ Id int32 `json:"id,omitempty"`
+ Url string `json:"url,omitempty"`
+ RepositoryUrl string `json:"repository_url,omitempty"`
+ LabelsUrl string `json:"labels_url,omitempty"`
+ CommentsUrl string `json:"comments_url,omitempty"`
+ HtmlUrl string `json:"html_url,omitempty"`
+ ParentUrl string `json:"parent_url,omitempty"`
+ Number string `json:"number,omitempty"`
+ State string `json:"state,omitempty"`
+ Title string `json:"title,omitempty"`
+ Body string `json:"body,omitempty"`
+ BodyHtml string `json:"body_html,omitempty"`
+ User *UserBasic `json:"user,omitempty"`
+ Labels []Label `json:"labels,omitempty"`
+ Assignee *UserBasic `json:"assignee,omitempty"`
+ Collaborators []UserBasic `json:"collaborators,omitempty"`
+ Repository string `json:"repository,omitempty"`
+ Milestone *Milestone `json:"milestone,omitempty"`
+ CreatedAt time.Time `json:"created_at,omitempty"`
+ UpdatedAt time.Time `json:"updated_at,omitempty"`
+ PlanStartedAt time.Time `json:"plan_started_at,omitempty"`
+ Deadline time.Time `json:"deadline,omitempty"`
+ FinishedAt time.Time `json:"finished_at,omitempty"`
+ ScheduledTime string `json:"scheduled_time,omitempty"`
+ Comments int32 `json:"comments,omitempty"`
+ IssueType string `json:"issue_type,omitempty"`
+ Program *ProgramBasic `json:"program,omitempty"`
+}
diff --git a/vendor/gitee.com/openeuler/go-gitee/gitee/model_issue_comment_post_param.go b/vendor/gitee.com/openeuler/go-gitee/gitee/model_issue_comment_post_param.go
new file mode 100644
index 0000000000000000000000000000000000000000..2ee393a70d6555901ddd21f94fe24b1112c1b29b
--- /dev/null
+++ b/vendor/gitee.com/openeuler/go-gitee/gitee/model_issue_comment_post_param.go
@@ -0,0 +1,17 @@
+/*
+ * 码云 Open API
+ *
+ * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen)
+ *
+ * API version: 5.3.2
+ * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
+ */
+
+package gitee
+
+type IssueCommentPostParam struct {
+ // 用户授权码
+ AccessToken string `json:"access_token,omitempty"`
+ // The contents of the comment
+ Body string `json:"body,omitempty"`
+}
diff --git a/vendor/gitee.com/openeuler/go-gitee/gitee/model_issue_update_param.go b/vendor/gitee.com/openeuler/go-gitee/gitee/model_issue_update_param.go
new file mode 100644
index 0000000000000000000000000000000000000000..3f682fa98bfd23a76cc6dd73797aa6f285199ade
--- /dev/null
+++ b/vendor/gitee.com/openeuler/go-gitee/gitee/model_issue_update_param.go
@@ -0,0 +1,32 @@
+/*
+ * 码云 Open API
+ *
+ * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen)
+ *
+ * API version: 5.3.2
+ * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
+ */
+
+package gitee
+
+// update issue information
+type IssueUpdateParam struct {
+ // 用户授权码
+ AccessToken string `json:"access_token,omitempty"`
+ // 仓库路径(path)
+ Repo string `json:"repo,omitempty"`
+ // Issue标题
+ Title string `json:"title,omitempty"`
+ // Issue 状态,open(开启的)、progressing(进行中)、closed(关闭的)
+ State string `json:"state,omitempty"`
+ // Issue描述
+ Body string `json:"body,omitempty"`
+ // Issue负责人的username
+ Assignee string `json:"assignee,omitempty"`
+ // 里程碑序号
+ Milestone int32 `json:"milestone,omitempty"`
+ // 用逗号分开的标签,名称要求长度在 2-20 之间且非特殊字符。如: bug,performance
+ Labels string `json:"labels,omitempty"`
+ // 项目ID
+ Program string `json:"program,omitempty"`
+}
diff --git a/vendor/gitee.com/openeuler/go-gitee/gitee/model_label.go b/vendor/gitee.com/openeuler/go-gitee/gitee/model_label.go
new file mode 100644
index 0000000000000000000000000000000000000000..f2826d1e326959015ac85664697013141681eb04
--- /dev/null
+++ b/vendor/gitee.com/openeuler/go-gitee/gitee/model_label.go
@@ -0,0 +1,19 @@
+/*
+ * 码云 Open API
+ *
+ * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen)
+ *
+ * API version: 5.3.2
+ * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
+ */
+
+package gitee
+
+// 获取企业某个标签
+type Label struct {
+ Id int32 `json:"id,omitempty"`
+ Name string `json:"name,omitempty"`
+ Color string `json:"color,omitempty"`
+ RepositoryId int32 `json:"repository_id,omitempty"`
+ Url string `json:"url,omitempty"`
+}
diff --git a/vendor/gitee.com/openeuler/go-gitee/gitee/model_label_post_param.go b/vendor/gitee.com/openeuler/go-gitee/gitee/model_label_post_param.go
new file mode 100644
index 0000000000000000000000000000000000000000..06f8a9b5ea5aca1815e8368e49cc6e17bb87664b
--- /dev/null
+++ b/vendor/gitee.com/openeuler/go-gitee/gitee/model_label_post_param.go
@@ -0,0 +1,19 @@
+/*
+ * 码云 Open API
+ *
+ * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen)
+ *
+ * API version: 5.3.2
+ * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
+ */
+
+package gitee
+
+type LabelPostParam struct {
+ // 用户授权码
+ AccessToken string `json:"access_token,omitempty"`
+ // 标签的名称,必选。
+ Name string `json:"name,omitempty"`
+ // 标签的颜色,为6位的数字,如: 000000,必选。
+ Color string `json:"color,omitempty"`
+}
diff --git a/vendor/gitee.com/openeuler/go-gitee/gitee/model_milestone.go b/vendor/gitee.com/openeuler/go-gitee/gitee/model_milestone.go
new file mode 100644
index 0000000000000000000000000000000000000000..50cd0088003d4aa8135a90e8b0681d38760d1726
--- /dev/null
+++ b/vendor/gitee.com/openeuler/go-gitee/gitee/model_milestone.go
@@ -0,0 +1,30 @@
+/*
+ * 码云 Open API
+ *
+ * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen)
+ *
+ * API version: 5.3.2
+ * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
+ */
+
+package gitee
+
+import (
+ "time"
+)
+
+// 更新仓库里程碑
+type Milestone struct {
+ Url string `json:"url,omitempty"`
+ HtmlUrl string `json:"html_url,omitempty"`
+ Number int32 `json:"number,omitempty"`
+ RepositoryId int32 `json:"repository_id,omitempty"`
+ State string `json:"state,omitempty"`
+ Title string `json:"title,omitempty"`
+ Description string `json:"description,omitempty"`
+ UpdatedAt time.Time `json:"updated_at,omitempty"`
+ CreatedAt time.Time `json:"created_at,omitempty"`
+ OpenIssues int32 `json:"open_issues,omitempty"`
+ ClosedIssues int32 `json:"closed_issues,omitempty"`
+ DueOn string `json:"due_on,omitempty"`
+}
diff --git a/vendor/gitee.com/openeuler/go-gitee/gitee/model_namespace.go b/vendor/gitee.com/openeuler/go-gitee/gitee/model_namespace.go
new file mode 100644
index 0000000000000000000000000000000000000000..592ef7c05a8be6477f9904532ca1975e38a3d478
--- /dev/null
+++ b/vendor/gitee.com/openeuler/go-gitee/gitee/model_namespace.go
@@ -0,0 +1,20 @@
+/*
+ * 码云 Open API
+ *
+ * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen)
+ *
+ * API version: 5.3.2
+ * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
+ */
+
+package gitee
+
+// 获取授权用户的一个 Namespace
+type Namespace struct {
+ Id int32 `json:"id,omitempty"`
+ Type_ string `json:"type,omitempty"`
+ Name string `json:"name,omitempty"`
+ Path string `json:"path,omitempty"`
+ HtmlUrl string `json:"html_url,omitempty"`
+ Parent *NamespaceMini `json:"parent,omitempty"`
+}
diff --git a/vendor/gitee.com/openeuler/go-gitee/gitee/model_namespace_mini.go b/vendor/gitee.com/openeuler/go-gitee/gitee/model_namespace_mini.go
new file mode 100644
index 0000000000000000000000000000000000000000..d024352f433d01e9e03137c487c8895574a7f310
--- /dev/null
+++ b/vendor/gitee.com/openeuler/go-gitee/gitee/model_namespace_mini.go
@@ -0,0 +1,18 @@
+/*
+ * 码云 Open API
+ *
+ * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen)
+ *
+ * API version: 5.3.2
+ * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
+ */
+
+package gitee
+
+type NamespaceMini struct {
+ Id int32 `json:"id,omitempty"`
+ Type_ string `json:"type,omitempty"`
+ Name string `json:"name,omitempty"`
+ Path string `json:"path,omitempty"`
+ HtmlUrl string `json:"html_url,omitempty"`
+}
diff --git a/vendor/gitee.com/openeuler/go-gitee/gitee/model_note.go b/vendor/gitee.com/openeuler/go-gitee/gitee/model_note.go
new file mode 100644
index 0000000000000000000000000000000000000000..f8260f63b9edcff2607c08e6e1711912e3f48f88
--- /dev/null
+++ b/vendor/gitee.com/openeuler/go-gitee/gitee/model_note.go
@@ -0,0 +1,21 @@
+/*
+ * 码云 Open API
+ *
+ * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen)
+ *
+ * API version: 5.3.2
+ * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
+ */
+
+package gitee
+
+// 获取企业某个Issue所有评论
+type Note struct {
+ Id int32 `json:"id,omitempty"`
+ Body string `json:"body,omitempty"`
+ BodyHtml string `json:"body_html,omitempty"`
+ User *User `json:"user,omitempty"`
+ Source string `json:"source,omitempty"`
+ CreatedAt string `json:"created_at,omitempty"`
+ Target string `json:"target,omitempty"`
+}
diff --git a/vendor/gitee.com/openeuler/go-gitee/gitee/model_operate_log.go b/vendor/gitee.com/openeuler/go-gitee/gitee/model_operate_log.go
new file mode 100644
index 0000000000000000000000000000000000000000..968c23ebba55fb7bb2391651ee892489d11eb01a
--- /dev/null
+++ b/vendor/gitee.com/openeuler/go-gitee/gitee/model_operate_log.go
@@ -0,0 +1,19 @@
+/*
+ * 码云 Open API
+ *
+ * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen)
+ *
+ * API version: 5.3.2
+ * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
+ */
+
+package gitee
+
+// 获取某个Pull Request的操作日志
+type OperateLog struct {
+ Id string `json:"id,omitempty"`
+ Icon string `json:"icon,omitempty"`
+ User string `json:"user,omitempty"`
+ Content string `json:"content,omitempty"`
+ CreatedAt string `json:"created_at,omitempty"`
+}
diff --git a/vendor/gitee.com/openeuler/go-gitee/gitee/model_program_basic.go b/vendor/gitee.com/openeuler/go-gitee/gitee/model_program_basic.go
new file mode 100644
index 0000000000000000000000000000000000000000..6e55b47b50ae30e8423d0cdc9da21eeddd09895c
--- /dev/null
+++ b/vendor/gitee.com/openeuler/go-gitee/gitee/model_program_basic.go
@@ -0,0 +1,18 @@
+/*
+ * 码云 Open API
+ *
+ * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen)
+ *
+ * API version: 5.3.2
+ * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
+ */
+
+package gitee
+
+type ProgramBasic struct {
+ Id string `json:"id,omitempty"`
+ Name string `json:"name,omitempty"`
+ Description string `json:"description,omitempty"`
+ Assignee string `json:"assignee,omitempty"`
+ Author string `json:"author,omitempty"`
+}
diff --git a/vendor/gitee.com/openeuler/go-gitee/gitee/model_project.go b/vendor/gitee.com/openeuler/go-gitee/gitee/model_project.go
new file mode 100644
index 0000000000000000000000000000000000000000..9a93b380e16957565debc4329e8cd5b5a57a26d8
--- /dev/null
+++ b/vendor/gitee.com/openeuler/go-gitee/gitee/model_project.go
@@ -0,0 +1,73 @@
+/*
+ * 码云 Open API
+ *
+ * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen)
+ *
+ * API version: 5.3.2
+ * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
+ */
+
+package gitee
+
+// 搜索仓库
+type Project struct {
+ Id int32 `json:"id,omitempty"`
+ FullName string `json:"full_name,omitempty"`
+ HumanName string `json:"human_name,omitempty"`
+ Url string `json:"url,omitempty"`
+ Namespace *Namespace `json:"namespace,omitempty"`
+ Path string `json:"path,omitempty"`
+ Name string `json:"name,omitempty"`
+ Owner *UserBasic `json:"owner,omitempty"`
+ Description string `json:"description,omitempty"`
+ Private bool `json:"private,omitempty"`
+ Public bool `json:"public,omitempty"`
+ Internal bool `json:"internal,omitempty"`
+ Fork bool `json:"fork,omitempty"`
+ HtmlUrl string `json:"html_url,omitempty"`
+ SshUrl string `json:"ssh_url,omitempty"`
+ ForksUrl string `json:"forks_url,omitempty"`
+ KeysUrl string `json:"keys_url,omitempty"`
+ CollaboratorsUrl string `json:"collaborators_url,omitempty"`
+ HooksUrl string `json:"hooks_url,omitempty"`
+ BranchesUrl string `json:"branches_url,omitempty"`
+ TagsUrl string `json:"tags_url,omitempty"`
+ BlobsUrl string `json:"blobs_url,omitempty"`
+ StargazersUrl string `json:"stargazers_url,omitempty"`
+ ContributorsUrl string `json:"contributors_url,omitempty"`
+ CommitsUrl string `json:"commits_url,omitempty"`
+ CommentsUrl string `json:"comments_url,omitempty"`
+ IssueCommentUrl string `json:"issue_comment_url,omitempty"`
+ IssuesUrl string `json:"issues_url,omitempty"`
+ PullsUrl string `json:"pulls_url,omitempty"`
+ MilestonesUrl string `json:"milestones_url,omitempty"`
+ NotificationsUrl string `json:"notifications_url,omitempty"`
+ LabelsUrl string `json:"labels_url,omitempty"`
+ ReleasesUrl string `json:"releases_url,omitempty"`
+ Recommend bool `json:"recommend,omitempty"`
+ Homepage string `json:"homepage,omitempty"`
+ Language string `json:"language,omitempty"`
+ ForksCount int32 `json:"forks_count,omitempty"`
+ StargazersCount int32 `json:"stargazers_count,omitempty"`
+ WatchersCount int32 `json:"watchers_count,omitempty"`
+ DefaultBranch string `json:"default_branch,omitempty"`
+ OpenIssuesCount int32 `json:"open_issues_count,omitempty"`
+ HasIssues bool `json:"has_issues,omitempty"`
+ HasWiki bool `json:"has_wiki,omitempty"`
+ CanComment bool `json:"can_comment,omitempty"`
+ PullRequestsEnabled bool `json:"pull_requests_enabled,omitempty"`
+ HasPage bool `json:"has_page,omitempty"`
+ License string `json:"license,omitempty"`
+ Outsourced bool `json:"outsourced,omitempty"`
+ ProjectCreator string `json:"project_creator,omitempty"`
+ Members []string `json:"members,omitempty"`
+ PushedAt string `json:"pushed_at,omitempty"`
+ CreatedAt string `json:"created_at,omitempty"`
+ UpdatedAt string `json:"updated_at,omitempty"`
+ Parent *Project `json:"parent,omitempty"`
+ Paas string `json:"paas,omitempty"`
+ Stared string `json:"stared,omitempty"`
+ Watched string `json:"watched,omitempty"`
+ Permission string `json:"permission,omitempty"`
+ Relation string `json:"relation,omitempty"`
+}
diff --git a/vendor/gitee.com/openeuler/go-gitee/gitee/model_project_basic.go b/vendor/gitee.com/openeuler/go-gitee/gitee/model_project_basic.go
new file mode 100644
index 0000000000000000000000000000000000000000..0304c8cb0222811882768f3b3841d16ec993ba08
--- /dev/null
+++ b/vendor/gitee.com/openeuler/go-gitee/gitee/model_project_basic.go
@@ -0,0 +1,28 @@
+/*
+ * 码云 Open API
+ *
+ * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen)
+ *
+ * API version: 5.3.2
+ * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
+ */
+
+package gitee
+
+type ProjectBasic struct {
+ Id int32 `json:"id,omitempty"`
+ FullName string `json:"full_name,omitempty"`
+ HumanName string `json:"human_name,omitempty"`
+ Url string `json:"url,omitempty"`
+ Namespace *interface{} `json:"namespace,omitempty"`
+ Path string `json:"path,omitempty"`
+ Name string `json:"name,omitempty"`
+ Owner *UserBasic `json:"owner,omitempty"`
+ Description string `json:"description,omitempty"`
+ Private bool `json:"private,omitempty"`
+ Public bool `json:"public,omitempty"`
+ Internal bool `json:"internal,omitempty"`
+ Fork bool `json:"fork,omitempty"`
+ HtmlUrl string `json:"html_url,omitempty"`
+ SshUrl string `json:"ssh_url,omitempty"`
+}
diff --git a/vendor/gitee.com/openeuler/go-gitee/gitee/model_project_member.go b/vendor/gitee.com/openeuler/go-gitee/gitee/model_project_member.go
new file mode 100644
index 0000000000000000000000000000000000000000..a71df9381a8a3a690ad72ba86606ec9539f29397
--- /dev/null
+++ b/vendor/gitee.com/openeuler/go-gitee/gitee/model_project_member.go
@@ -0,0 +1,32 @@
+/*
+ * 码云 Open API
+ *
+ * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen)
+ *
+ * API version: 5.3.2
+ * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
+ */
+
+package gitee
+
+// 添加仓库成员
+type ProjectMember struct {
+ Id int32 `json:"id,omitempty"`
+ Login string `json:"login,omitempty"`
+ Name string `json:"name,omitempty"`
+ AvatarUrl string `json:"avatar_url,omitempty"`
+ Url string `json:"url,omitempty"`
+ HtmlUrl string `json:"html_url,omitempty"`
+ FollowersUrl string `json:"followers_url,omitempty"`
+ FollowingUrl string `json:"following_url,omitempty"`
+ GistsUrl string `json:"gists_url,omitempty"`
+ StarredUrl string `json:"starred_url,omitempty"`
+ SubscriptionsUrl string `json:"subscriptions_url,omitempty"`
+ OrganizationsUrl string `json:"organizations_url,omitempty"`
+ ReposUrl string `json:"repos_url,omitempty"`
+ EventsUrl string `json:"events_url,omitempty"`
+ ReceivedEventsUrl string `json:"received_events_url,omitempty"`
+ Type_ string `json:"type,omitempty"`
+ SiteAdmin string `json:"site_admin,omitempty"`
+ Permissions string `json:"permissions,omitempty"`
+}
diff --git a/vendor/gitee.com/openeuler/go-gitee/gitee/model_project_member_permission.go b/vendor/gitee.com/openeuler/go-gitee/gitee/model_project_member_permission.go
new file mode 100644
index 0000000000000000000000000000000000000000..929eb0415a84ca04da4e19bb9620388c72502179
--- /dev/null
+++ b/vendor/gitee.com/openeuler/go-gitee/gitee/model_project_member_permission.go
@@ -0,0 +1,32 @@
+/*
+ * 码云 Open API
+ *
+ * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen)
+ *
+ * API version: 5.3.2
+ * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
+ */
+
+package gitee
+
+// 查看仓库成员的权限
+type ProjectMemberPermission struct {
+ Id int32 `json:"id,omitempty"`
+ Login string `json:"login,omitempty"`
+ Name string `json:"name,omitempty"`
+ AvatarUrl string `json:"avatar_url,omitempty"`
+ Url string `json:"url,omitempty"`
+ HtmlUrl string `json:"html_url,omitempty"`
+ FollowersUrl string `json:"followers_url,omitempty"`
+ FollowingUrl string `json:"following_url,omitempty"`
+ GistsUrl string `json:"gists_url,omitempty"`
+ StarredUrl string `json:"starred_url,omitempty"`
+ SubscriptionsUrl string `json:"subscriptions_url,omitempty"`
+ OrganizationsUrl string `json:"organizations_url,omitempty"`
+ ReposUrl string `json:"repos_url,omitempty"`
+ EventsUrl string `json:"events_url,omitempty"`
+ ReceivedEventsUrl string `json:"received_events_url,omitempty"`
+ Type_ string `json:"type,omitempty"`
+ SiteAdmin string `json:"site_admin,omitempty"`
+ Permission string `json:"permission,omitempty"`
+}
diff --git a/vendor/gitee.com/openeuler/go-gitee/gitee/model_project_member_put_param.go b/vendor/gitee.com/openeuler/go-gitee/gitee/model_project_member_put_param.go
new file mode 100644
index 0000000000000000000000000000000000000000..e31780e38bb20f41e8ed2be6fa964c0bcae4e0c1
--- /dev/null
+++ b/vendor/gitee.com/openeuler/go-gitee/gitee/model_project_member_put_param.go
@@ -0,0 +1,18 @@
+/*
+ * 码云 Open API
+ *
+ * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen)
+ *
+ * API version: 5.3.2
+ * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
+ */
+
+package gitee
+
+// create project member
+type ProjectMemberPutParam struct {
+ // 用户授权码
+ AccessToken string `json:"access_token,omitempty"`
+ // 成员权限: 拉代码(pull),推代码(push),管理员(admin)。默认: push
+ Permission string `json:"permission,omitempty"`
+}
diff --git a/vendor/gitee.com/openeuler/go-gitee/gitee/model_pull_request.go b/vendor/gitee.com/openeuler/go-gitee/gitee/model_pull_request.go
new file mode 100644
index 0000000000000000000000000000000000000000..efb97e2b94d6b228346324477385bbb63b616b1a
--- /dev/null
+++ b/vendor/gitee.com/openeuler/go-gitee/gitee/model_pull_request.go
@@ -0,0 +1,49 @@
+/*
+ * 码云 Open API
+ *
+ * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen)
+ *
+ * API version: 5.3.2
+ * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
+ */
+
+package gitee
+
+// 取消用户测试 Pull Request
+type PullRequest struct {
+ Id int32 `json:"id,omitempty"`
+ Url string `json:"url,omitempty"`
+ HtmlUrl string `json:"html_url,omitempty"`
+ DiffUrl string `json:"diff_url,omitempty"`
+ PatchUrl string `json:"patch_url,omitempty"`
+ IssueUrl string `json:"issue_url,omitempty"`
+ CommitsUrl string `json:"commits_url,omitempty"`
+ ReviewCommentsUrl string `json:"review_comments_url,omitempty"`
+ ReviewCommentUrl string `json:"review_comment_url,omitempty"`
+ CommentsUrl string `json:"comments_url,omitempty"`
+ StatusesUrl string `json:"statuses_url,omitempty"`
+ Number int32 `json:"number,omitempty"`
+ State string `json:"state,omitempty"`
+ Title string `json:"title,omitempty"`
+ Body string `json:"body,omitempty"`
+ BodyHtml string `json:"body_html,omitempty"`
+ Assignees []UserBasic `json:"assignees,omitempty"`
+ Testers []UserBasic `json:"testers,omitempty"`
+ Milestone *Milestone `json:"milestone,omitempty"`
+ Labels []Label `json:"labels,omitempty"`
+ Locked string `json:"locked,omitempty"`
+ CreatedAt string `json:"created_at,omitempty"`
+ UpdatedAt string `json:"updated_at,omitempty"`
+ ClosedAt string `json:"closed_at,omitempty"`
+ MergedAt string `json:"merged_at,omitempty"`
+ Mergeable bool `json:"mergeable,omitempty"`
+ Head *BasicInfo `json:"head,omitempty"`
+ Base *BasicInfo `json:"base,omitempty"`
+ Links string `json:"_links,omitempty"`
+ User *UserBasic `json:"user,omitempty"`
+ Comments int32 `json:"comments,omitempty"`
+ Commits int32 `json:"commits,omitempty"`
+ Additions int32 `json:"additions,omitempty"`
+ Deletions int32 `json:"deletions,omitempty"`
+ ChangedFiles int32 `json:"changed_files,omitempty"`
+}
diff --git a/vendor/gitee.com/openeuler/go-gitee/gitee/model_pull_request_comment_post_param.go b/vendor/gitee.com/openeuler/go-gitee/gitee/model_pull_request_comment_post_param.go
new file mode 100644
index 0000000000000000000000000000000000000000..94334e915d02c9924f52e5f16004b1bfd1619308
--- /dev/null
+++ b/vendor/gitee.com/openeuler/go-gitee/gitee/model_pull_request_comment_post_param.go
@@ -0,0 +1,24 @@
+/*
+ * 码云 Open API
+ *
+ * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen)
+ *
+ * API version: 5.3.2
+ * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
+ */
+
+package gitee
+
+// create pull request comment
+type PullRequestCommentPostParam struct {
+ // 用户授权码
+ AccessToken string `json:"access_token,omitempty"`
+ // 必填。评论内容
+ Body string `json:"body,omitempty"`
+ // 可选。PR代码评论的commit id
+ CommitId string `json:"commit_id,omitempty"`
+ // 可选。PR代码评论的文件名
+ Path string `json:"path,omitempty"`
+ // 可选。PR代码评论diff中的行数
+ Position int32 `json:"position,omitempty"`
+}
diff --git a/vendor/gitee.com/openeuler/go-gitee/gitee/model_pull_request_comments.go b/vendor/gitee.com/openeuler/go-gitee/gitee/model_pull_request_comments.go
new file mode 100644
index 0000000000000000000000000000000000000000..546e0e92de630ef1a7e9bf6173f795d1732aba33
--- /dev/null
+++ b/vendor/gitee.com/openeuler/go-gitee/gitee/model_pull_request_comments.go
@@ -0,0 +1,28 @@
+/*
+ * 码云 Open API
+ *
+ * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen)
+ *
+ * API version: 5.3.2
+ * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
+ */
+
+package gitee
+
+// 编辑评论
+type PullRequestComments struct {
+ Url string `json:"url,omitempty"`
+ Id string `json:"id,omitempty"`
+ Path string `json:"path,omitempty"`
+ Position string `json:"position,omitempty"`
+ OriginalPosition string `json:"original_position,omitempty"`
+ CommitId string `json:"commit_id,omitempty"`
+ OriginalCommitId string `json:"original_commit_id,omitempty"`
+ User *UserBasic `json:"user,omitempty"`
+ Body string `json:"body,omitempty"`
+ CreatedAt string `json:"created_at,omitempty"`
+ UpdatedAt string `json:"updated_at,omitempty"`
+ HtmlUrl string `json:"html_url,omitempty"`
+ PullRequestUrl string `json:"pull_request_url,omitempty"`
+ Links string `json:"_links,omitempty"`
+}
diff --git a/vendor/gitee.com/openeuler/go-gitee/gitee/model_pull_request_commits.go b/vendor/gitee.com/openeuler/go-gitee/gitee/model_pull_request_commits.go
new file mode 100644
index 0000000000000000000000000000000000000000..ef82c6490ba647e954408d2591db1e38bfb6d483
--- /dev/null
+++ b/vendor/gitee.com/openeuler/go-gitee/gitee/model_pull_request_commits.go
@@ -0,0 +1,22 @@
+/*
+ * 码云 Open API
+ *
+ * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen)
+ *
+ * API version: 5.3.2
+ * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
+ */
+
+package gitee
+
+// 获取某Pull Request的所有Commit信息。最多显示250条Commit
+type PullRequestCommits struct {
+ Url string `json:"url,omitempty"`
+ Sha string `json:"sha,omitempty"`
+ HtmlUrl string `json:"html_url,omitempty"`
+ CommentsUrl string `json:"comments_url,omitempty"`
+ Commit string `json:"commit,omitempty"`
+ Author string `json:"author,omitempty"`
+ Committer string `json:"committer,omitempty"`
+ Parents string `json:"parents,omitempty"`
+}
diff --git a/vendor/gitee.com/openeuler/go-gitee/gitee/model_pull_request_files.go b/vendor/gitee.com/openeuler/go-gitee/gitee/model_pull_request_files.go
new file mode 100644
index 0000000000000000000000000000000000000000..538698f9b0e0644ac70ee706985c8ea43df7d69d
--- /dev/null
+++ b/vendor/gitee.com/openeuler/go-gitee/gitee/model_pull_request_files.go
@@ -0,0 +1,22 @@
+/*
+ * 码云 Open API
+ *
+ * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen)
+ *
+ * API version: 5.3.2
+ * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
+ */
+
+package gitee
+
+// Pull Request Commit文件列表。最多显示300条diff
+type PullRequestFiles struct {
+ Sha string `json:"sha,omitempty"`
+ Filename string `json:"filename,omitempty"`
+ Status string `json:"status,omitempty"`
+ Additions string `json:"additions,omitempty"`
+ Deletions string `json:"deletions,omitempty"`
+ BlobUrl string `json:"blob_url,omitempty"`
+ RawUrl string `json:"raw_url,omitempty"`
+ Patch string `json:"patch,omitempty"`
+}
diff --git a/vendor/gitee.com/openeuler/go-gitee/gitee/model_pull_request_merge_put_param.go b/vendor/gitee.com/openeuler/go-gitee/gitee/model_pull_request_merge_put_param.go
new file mode 100644
index 0000000000000000000000000000000000000000..49f141609a3cc61cacbbe6acc9b9a5c2466cc38a
--- /dev/null
+++ b/vendor/gitee.com/openeuler/go-gitee/gitee/model_pull_request_merge_put_param.go
@@ -0,0 +1,24 @@
+/*
+ * 码云 Open API
+ *
+ * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen)
+ *
+ * API version: 5.3.2
+ * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
+ */
+
+package gitee
+
+// merge pull request parameter
+type PullRequestMergePutParam struct {
+ // 用户授权码
+ AccessToken string `json:"access_token,omitempty"`
+ // 可选。合并PR的方法,merge(合并所有提交)和 squash(扁平化分支合并)。默认为merge。
+ MergeMethod string `json:"merge_method,omitempty"`
+ // 可选。合并PR后是否删除源分支,默认false(不删除)
+ PruneSourceBranch bool `json:"prune_source_branch,omitempty"`
+ // 可选。合并标题,默认为PR的标题
+ Title string `json:"title,omitempty"`
+ // 可选。合并描述,默认为 \"Merge pull request !{pr_id} from {author}/{source_branch}\",与页面显示的默认一致。
+ Description string `json:"description,omitempty"`
+}
diff --git a/vendor/gitee.com/openeuler/go-gitee/gitee/model_pull_request_update_param.go b/vendor/gitee.com/openeuler/go-gitee/gitee/model_pull_request_update_param.go
new file mode 100644
index 0000000000000000000000000000000000000000..c6e06e3f81700039c6c2cf6b4e51d1dac7c02d38
--- /dev/null
+++ b/vendor/gitee.com/openeuler/go-gitee/gitee/model_pull_request_update_param.go
@@ -0,0 +1,26 @@
+/*
+ * 码云 Open API
+ *
+ * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen)
+ *
+ * API version: 5.3.2
+ * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
+ */
+
+package gitee
+
+// update pull request information
+type PullRequestUpdateParam struct {
+ // 用户授权码
+ AccessToken string `json:"access_token,omitempty"`
+ // 可选。Pull Request 标题
+ Title string `json:"title,omitempty"`
+ // 可选。Pull Request 内容
+ Body string `json:"body,omitempty"`
+ // 可选。Pull Request 状态
+ State string `json:"state,omitempty"`
+ // 可选。里程碑序号(id)
+ MilestoneNumber int32 `json:"milestone_number,omitempty"`
+ // 用逗号分开的标签,名称要求长度在 2-20 之间且非特殊字符。如: bug,performance
+ Labels string `json:"labels,omitempty"`
+}
diff --git a/vendor/gitee.com/openeuler/go-gitee/gitee/model_release.go b/vendor/gitee.com/openeuler/go-gitee/gitee/model_release.go
new file mode 100644
index 0000000000000000000000000000000000000000..11b167473eb279739fb6dfba25f9d755fb8099ff
--- /dev/null
+++ b/vendor/gitee.com/openeuler/go-gitee/gitee/model_release.go
@@ -0,0 +1,27 @@
+/*
+ * 码云 Open API
+ *
+ * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen)
+ *
+ * API version: 5.3.2
+ * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
+ */
+
+package gitee
+
+import (
+ "time"
+)
+
+// 更新仓库Release
+type Release struct {
+ Id int32 `json:"id,omitempty"`
+ TagName string `json:"tag_name,omitempty"`
+ TargetCommitish string `json:"target_commitish,omitempty"`
+ Prerelease string `json:"prerelease,omitempty"`
+ Name string `json:"name,omitempty"`
+ Body string `json:"body,omitempty"`
+ Author string `json:"author,omitempty"`
+ CreatedAt time.Time `json:"created_at,omitempty"`
+ Assets string `json:"assets,omitempty"`
+}
diff --git a/vendor/gitee.com/openeuler/go-gitee/gitee/model_repo_commit.go b/vendor/gitee.com/openeuler/go-gitee/gitee/model_repo_commit.go
new file mode 100644
index 0000000000000000000000000000000000000000..c0969ea3ba6b62b49d9ee41dc87cec890fee51ae
--- /dev/null
+++ b/vendor/gitee.com/openeuler/go-gitee/gitee/model_repo_commit.go
@@ -0,0 +1,23 @@
+/*
+ * 码云 Open API
+ *
+ * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen)
+ *
+ * API version: 5.3.2
+ * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
+ */
+
+package gitee
+
+// 仓库的某个提交
+type RepoCommit struct {
+ Url string `json:"url,omitempty"`
+ Sha string `json:"sha,omitempty"`
+ HtmlUrl string `json:"html_url,omitempty"`
+ CommentsUrl string `json:"comments_url,omitempty"`
+ Commit string `json:"commit,omitempty"`
+ Author string `json:"author,omitempty"`
+ Committer string `json:"committer,omitempty"`
+ Parents string `json:"parents,omitempty"`
+ Stats string `json:"stats,omitempty"`
+}
diff --git a/vendor/gitee.com/openeuler/go-gitee/gitee/model_repo_patch_param.go b/vendor/gitee.com/openeuler/go-gitee/gitee/model_repo_patch_param.go
new file mode 100644
index 0000000000000000000000000000000000000000..ff57762f62103eae0615c9fd31f9a626f9a2fab1
--- /dev/null
+++ b/vendor/gitee.com/openeuler/go-gitee/gitee/model_repo_patch_param.go
@@ -0,0 +1,34 @@
+/*
+ * 码云 Open API
+ *
+ * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen)
+ *
+ * API version: 5.3.2
+ * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
+ */
+
+package gitee
+
+// repo patch parameter
+type RepoPatchParam struct {
+ // 用户授权码
+ AccessToken string `json:"access_token,omitempty"`
+ // 仓库名称
+ Name string `json:"name,omitempty"`
+ // 仓库描述
+ Description string `json:"description,omitempty"`
+ // 主页(eg: https://gitee.com)
+ Homepage string `json:"homepage,omitempty"`
+ // 允许提Issue与否。默认: 允许(true)
+ HasIssues string `json:"has_issues,omitempty"`
+ // 提供Wiki与否。默认: 提供(true)
+ HasWiki string `json:"has_wiki,omitempty"`
+ // 允许用户对仓库进行评论
+ CanComment string `json:"can_comment,omitempty"`
+ // 仓库公开或私有。
+ Private string `json:"private,omitempty"`
+ // 更新仓库路径
+ Path string `json:"path,omitempty"`
+ // 更新默认分支
+ DefaultBranch string `json:"default_branch,omitempty"`
+}
diff --git a/vendor/gitee.com/openeuler/go-gitee/gitee/model_repository_post_param.go b/vendor/gitee.com/openeuler/go-gitee/gitee/model_repository_post_param.go
new file mode 100644
index 0000000000000000000000000000000000000000..33821e457eb27f0152e43657fb7959f81c77b701
--- /dev/null
+++ b/vendor/gitee.com/openeuler/go-gitee/gitee/model_repository_post_param.go
@@ -0,0 +1,38 @@
+/*
+ * 码云 Open API
+ *
+ * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen)
+ *
+ * API version: 5.3.2
+ * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
+ */
+
+package gitee
+
+// create repository
+type RepositoryPostParam struct {
+ // 用户授权码
+ AccessToken string `json:"access_token,omitempty"`
+ // 仓库名称
+ Name string `json:"name,omitempty"`
+ // 仓库描述
+ Description string `json:"description,omitempty"`
+ // 主页(eg: https://gitee.com)
+ Homepage string `json:"homepage,omitempty"`
+ // 允许提Issue与否。默认: 允许(true)
+ HasIssues bool `json:"has_issues,omitempty"`
+ // 提供Wiki与否。默认: 提供(true)
+ HasWiki bool `json:"has_wiki,omitempty"`
+ // 允许用户对仓库进行评论。默认: 允许(true)
+ CanComment bool `json:"can_comment,omitempty"`
+ // 仓库开源类型。0(私有), 1(外部开源), 2(内部开源),注:与private互斥,以public为主。
+ Public int32 `json:"public,omitempty"`
+ // 仓库公开或私有。默认: 公开(false),注:与public互斥,以public为主。
+ Private bool `json:"private,omitempty"`
+ // 值为true时则会用README初始化仓库。默认: 不初始化(false)
+ AutoInit bool `json:"auto_init,omitempty"`
+ // Git Ingore模版
+ GitignoreTemplate string `json:"gitignore_template,omitempty"`
+ // License模版
+ LicenseTemplate string `json:"license_template,omitempty"`
+}
diff --git a/vendor/gitee.com/openeuler/go-gitee/gitee/model_ssh_key.go b/vendor/gitee.com/openeuler/go-gitee/gitee/model_ssh_key.go
new file mode 100644
index 0000000000000000000000000000000000000000..4387dbc72b2960e64f2bf92364792fbfdf1fa865
--- /dev/null
+++ b/vendor/gitee.com/openeuler/go-gitee/gitee/model_ssh_key.go
@@ -0,0 +1,19 @@
+/*
+ * 码云 Open API
+ *
+ * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen)
+ *
+ * API version: 5.3.2
+ * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
+ */
+
+package gitee
+
+// 获取一个公钥
+type SshKey struct {
+ Id string `json:"id,omitempty"`
+ Key string `json:"key,omitempty"`
+ Url string `json:"url,omitempty"`
+ Title string `json:"title,omitempty"`
+ CreatedAt string `json:"created_at,omitempty"`
+}
diff --git a/vendor/gitee.com/openeuler/go-gitee/gitee/model_ssh_key_basic.go b/vendor/gitee.com/openeuler/go-gitee/gitee/model_ssh_key_basic.go
new file mode 100644
index 0000000000000000000000000000000000000000..d7b800988547c04ba83873d0be15efec3ed7165f
--- /dev/null
+++ b/vendor/gitee.com/openeuler/go-gitee/gitee/model_ssh_key_basic.go
@@ -0,0 +1,16 @@
+/*
+ * 码云 Open API
+ *
+ * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen)
+ *
+ * API version: 5.3.2
+ * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
+ */
+
+package gitee
+
+// 列出指定用户的所有公钥
+type SshKeyBasic struct {
+ Id string `json:"id,omitempty"`
+ Key string `json:"key,omitempty"`
+}
diff --git a/vendor/gitee.com/openeuler/go-gitee/gitee/model_tag.go b/vendor/gitee.com/openeuler/go-gitee/gitee/model_tag.go
new file mode 100644
index 0000000000000000000000000000000000000000..1372a012bdc30acaf3f379fe225803044ca1c326
--- /dev/null
+++ b/vendor/gitee.com/openeuler/go-gitee/gitee/model_tag.go
@@ -0,0 +1,16 @@
+/*
+ * 码云 Open API
+ *
+ * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen)
+ *
+ * API version: 5.3.2
+ * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
+ */
+
+package gitee
+
+// 列出仓库所有的tags
+type Tag struct {
+ Name string `json:"name,omitempty"`
+ Commit string `json:"commit,omitempty"`
+}
diff --git a/vendor/gitee.com/openeuler/go-gitee/gitee/model_tree.go b/vendor/gitee.com/openeuler/go-gitee/gitee/model_tree.go
new file mode 100644
index 0000000000000000000000000000000000000000..236661d508bd4c6e99e6d1b645a4c6dee33043e9
--- /dev/null
+++ b/vendor/gitee.com/openeuler/go-gitee/gitee/model_tree.go
@@ -0,0 +1,18 @@
+/*
+ * 码云 Open API
+ *
+ * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen)
+ *
+ * API version: 5.3.2
+ * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
+ */
+
+package gitee
+
+// 获取目录Tree
+type Tree struct {
+ Sha string `json:"sha,omitempty"`
+ Url string `json:"url,omitempty"`
+ Tree []TreeBasic `json:"tree,omitempty"`
+ Truncated string `json:"truncated,omitempty"`
+}
diff --git a/vendor/gitee.com/openeuler/go-gitee/gitee/model_tree_basic.go b/vendor/gitee.com/openeuler/go-gitee/gitee/model_tree_basic.go
new file mode 100644
index 0000000000000000000000000000000000000000..aaa02d4ffd4f6e73442f047a18821beb21285cd6
--- /dev/null
+++ b/vendor/gitee.com/openeuler/go-gitee/gitee/model_tree_basic.go
@@ -0,0 +1,19 @@
+/*
+ * 码云 Open API
+ *
+ * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen)
+ *
+ * API version: 5.3.2
+ * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
+ */
+
+package gitee
+
+type TreeBasic struct {
+ Path string `json:"path,omitempty"`
+ Mode string `json:"mode,omitempty"`
+ Type_ string `json:"type,omitempty"`
+ Sha string `json:"sha,omitempty"`
+ Size int32 `json:"size,omitempty"`
+ Url string `json:"url,omitempty"`
+}
diff --git a/vendor/gitee.com/openeuler/go-gitee/gitee/model_user.go b/vendor/gitee.com/openeuler/go-gitee/gitee/model_user.go
new file mode 100644
index 0000000000000000000000000000000000000000..ed1b507095206d8f35b7f3fcdd907f8f578ee003
--- /dev/null
+++ b/vendor/gitee.com/openeuler/go-gitee/gitee/model_user.go
@@ -0,0 +1,43 @@
+/*
+ * 码云 Open API
+ *
+ * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen)
+ *
+ * API version: 5.3.2
+ * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
+ */
+
+package gitee
+
+// 搜索用户
+type User struct {
+ Id int32 `json:"id,omitempty"`
+ Login string `json:"login,omitempty"`
+ Name string `json:"name,omitempty"`
+ AvatarUrl string `json:"avatar_url,omitempty"`
+ Url string `json:"url,omitempty"`
+ HtmlUrl string `json:"html_url,omitempty"`
+ FollowersUrl string `json:"followers_url,omitempty"`
+ FollowingUrl string `json:"following_url,omitempty"`
+ GistsUrl string `json:"gists_url,omitempty"`
+ StarredUrl string `json:"starred_url,omitempty"`
+ SubscriptionsUrl string `json:"subscriptions_url,omitempty"`
+ OrganizationsUrl string `json:"organizations_url,omitempty"`
+ ReposUrl string `json:"repos_url,omitempty"`
+ EventsUrl string `json:"events_url,omitempty"`
+ ReceivedEventsUrl string `json:"received_events_url,omitempty"`
+ Type_ string `json:"type,omitempty"`
+ SiteAdmin bool `json:"site_admin,omitempty"`
+ Blog string `json:"blog,omitempty"`
+ Weibo string `json:"weibo,omitempty"`
+ Bio string `json:"bio,omitempty"`
+ PublicRepos string `json:"public_repos,omitempty"`
+ PublicGists string `json:"public_gists,omitempty"`
+ Followers string `json:"followers,omitempty"`
+ Following string `json:"following,omitempty"`
+ Stared string `json:"stared,omitempty"`
+ Watched string `json:"watched,omitempty"`
+ CreatedAt string `json:"created_at,omitempty"`
+ UpdatedAt string `json:"updated_at,omitempty"`
+ Email string `json:"email,omitempty"`
+}
diff --git a/vendor/gitee.com/openeuler/go-gitee/gitee/model_user_basic.go b/vendor/gitee.com/openeuler/go-gitee/gitee/model_user_basic.go
new file mode 100644
index 0000000000000000000000000000000000000000..9f1f55aba6c20c7ff711ba6c33e13fd600dc78e3
--- /dev/null
+++ b/vendor/gitee.com/openeuler/go-gitee/gitee/model_user_basic.go
@@ -0,0 +1,32 @@
+/*
+ * 码云 Open API
+ *
+ * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen)
+ *
+ * API version: 5.3.2
+ * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
+ */
+
+package gitee
+
+// 列出一个组织的所有成员
+type UserBasic struct {
+ Id int32 `json:"id,omitempty"`
+ Login string `json:"login,omitempty"`
+ Name string `json:"name,omitempty"`
+ AvatarUrl string `json:"avatar_url,omitempty"`
+ Url string `json:"url,omitempty"`
+ HtmlUrl string `json:"html_url,omitempty"`
+ FollowersUrl string `json:"followers_url,omitempty"`
+ FollowingUrl string `json:"following_url,omitempty"`
+ GistsUrl string `json:"gists_url,omitempty"`
+ StarredUrl string `json:"starred_url,omitempty"`
+ SubscriptionsUrl string `json:"subscriptions_url,omitempty"`
+ OrganizationsUrl string `json:"organizations_url,omitempty"`
+ ReposUrl string `json:"repos_url,omitempty"`
+ EventsUrl string `json:"events_url,omitempty"`
+ ReceivedEventsUrl string `json:"received_events_url,omitempty"`
+ Type_ string `json:"type,omitempty"`
+ SiteAdmin bool `json:"site_admin,omitempty"`
+ Email string `json:"email,omitempty"`
+}
diff --git a/vendor/gitee.com/openeuler/go-gitee/gitee/model_user_message.go b/vendor/gitee.com/openeuler/go-gitee/gitee/model_user_message.go
new file mode 100644
index 0000000000000000000000000000000000000000..f8773258dd53d89983a3d6be826f1c7924183d5b
--- /dev/null
+++ b/vendor/gitee.com/openeuler/go-gitee/gitee/model_user_message.go
@@ -0,0 +1,22 @@
+/*
+ * 码云 Open API
+ *
+ * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen)
+ *
+ * API version: 5.3.2
+ * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
+ */
+
+package gitee
+
+// 获取一条私信
+type UserMessage struct {
+ Id int32 `json:"id,omitempty"`
+ // 发送者
+ Sender *UserBasic `json:"sender,omitempty"`
+ Unread string `json:"unread,omitempty"`
+ Content string `json:"content,omitempty"`
+ UpdatedAt string `json:"updated_at,omitempty"`
+ Url string `json:"url,omitempty"`
+ HtmlUrl string `json:"html_url,omitempty"`
+}
diff --git a/vendor/gitee.com/openeuler/go-gitee/gitee/model_user_message_list.go b/vendor/gitee.com/openeuler/go-gitee/gitee/model_user_message_list.go
new file mode 100644
index 0000000000000000000000000000000000000000..88b33683a3edd80c891ce339bb2259733136cf0d
--- /dev/null
+++ b/vendor/gitee.com/openeuler/go-gitee/gitee/model_user_message_list.go
@@ -0,0 +1,17 @@
+/*
+ * 码云 Open API
+ *
+ * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen)
+ *
+ * API version: 5.3.2
+ * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
+ */
+
+package gitee
+
+// 列出授权用户的所有私信
+type UserMessageList struct {
+ TotalCount int32 `json:"total_count,omitempty"`
+ // 私信列表
+ List []UserMessage `json:"list,omitempty"`
+}
diff --git a/vendor/gitee.com/openeuler/go-gitee/gitee/model_user_mini.go b/vendor/gitee.com/openeuler/go-gitee/gitee/model_user_mini.go
new file mode 100644
index 0000000000000000000000000000000000000000..98837427737e906d0e8b5f006d7adf65a1723933
--- /dev/null
+++ b/vendor/gitee.com/openeuler/go-gitee/gitee/model_user_mini.go
@@ -0,0 +1,19 @@
+/*
+ * 码云 Open API
+ *
+ * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen)
+ *
+ * API version: 5.3.2
+ * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
+ */
+
+package gitee
+
+type UserMini struct {
+ Id int32 `json:"id,omitempty"`
+ Login string `json:"login,omitempty"`
+ Name string `json:"name,omitempty"`
+ AvatarUrl string `json:"avatar_url,omitempty"`
+ Url string `json:"url,omitempty"`
+ HtmlUrl string `json:"html_url,omitempty"`
+}
diff --git a/vendor/gitee.com/openeuler/go-gitee/gitee/model_user_notification.go b/vendor/gitee.com/openeuler/go-gitee/gitee/model_user_notification.go
new file mode 100644
index 0000000000000000000000000000000000000000..7acab34e14d0b3340cafac1c9b8362b2462b76b3
--- /dev/null
+++ b/vendor/gitee.com/openeuler/go-gitee/gitee/model_user_notification.go
@@ -0,0 +1,29 @@
+/*
+ * 码云 Open API
+ *
+ * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen)
+ *
+ * API version: 5.3.2
+ * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
+ */
+
+package gitee
+
+// 获取一条通知
+type UserNotification struct {
+ Id int32 `json:"id,omitempty"`
+ Content string `json:"content,omitempty"`
+ Type_ string `json:"type,omitempty"`
+ Unread string `json:"unread,omitempty"`
+ Mute string `json:"mute,omitempty"`
+ UpdatedAt string `json:"updated_at,omitempty"`
+ Url string `json:"url,omitempty"`
+ HtmlUrl string `json:"html_url,omitempty"`
+ // 通知发送者
+ Actor *UserBasic `json:"actor,omitempty"`
+ Repository *ProjectBasic `json:"repository,omitempty"`
+ // 通知直接关联对象
+ Subject *UserNotificationSubject `json:"subject,omitempty"`
+ // 通知次级关联对象
+ Namespaces []UserNotificationNamespace `json:"namespaces,omitempty"`
+}
diff --git a/vendor/gitee.com/openeuler/go-gitee/gitee/model_user_notification_count.go b/vendor/gitee.com/openeuler/go-gitee/gitee/model_user_notification_count.go
new file mode 100644
index 0000000000000000000000000000000000000000..8b98fbf09d0030ecf5997835b8a05f8cd6e08880
--- /dev/null
+++ b/vendor/gitee.com/openeuler/go-gitee/gitee/model_user_notification_count.go
@@ -0,0 +1,20 @@
+/*
+ * 码云 Open API
+ *
+ * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen)
+ *
+ * API version: 5.3.2
+ * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
+ */
+
+package gitee
+
+// 获取授权用户的通知数
+type UserNotificationCount struct {
+ // 通知总数
+ TotalCount int32 `json:"total_count,omitempty"`
+ // 通知数量
+ NotificationCount int32 `json:"notification_count,omitempty"`
+ // 私信数量
+ MessageCount int32 `json:"message_count,omitempty"`
+}
diff --git a/vendor/gitee.com/openeuler/go-gitee/gitee/model_user_notification_list.go b/vendor/gitee.com/openeuler/go-gitee/gitee/model_user_notification_list.go
new file mode 100644
index 0000000000000000000000000000000000000000..f913dd4b8b3cc3b162b6d4016a8fbd2588e24943
--- /dev/null
+++ b/vendor/gitee.com/openeuler/go-gitee/gitee/model_user_notification_list.go
@@ -0,0 +1,17 @@
+/*
+ * 码云 Open API
+ *
+ * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen)
+ *
+ * API version: 5.3.2
+ * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
+ */
+
+package gitee
+
+// 列出授权用户的所有通知
+type UserNotificationList struct {
+ TotalCount int32 `json:"total_count,omitempty"`
+ // 通知列表
+ List []UserNotification `json:"list,omitempty"`
+}
diff --git a/vendor/gitee.com/openeuler/go-gitee/gitee/model_user_notification_namespace.go b/vendor/gitee.com/openeuler/go-gitee/gitee/model_user_notification_namespace.go
new file mode 100644
index 0000000000000000000000000000000000000000..51f93a263277dc49809a1ea3a2ba4b4012fb7fcf
--- /dev/null
+++ b/vendor/gitee.com/openeuler/go-gitee/gitee/model_user_notification_namespace.go
@@ -0,0 +1,16 @@
+/*
+ * 码云 Open API
+ *
+ * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen)
+ *
+ * API version: 5.3.2
+ * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
+ */
+
+package gitee
+
+type UserNotificationNamespace struct {
+ Name string `json:"name,omitempty"`
+ HtmlUrl string `json:"html_url,omitempty"`
+ Type_ string `json:"type,omitempty"`
+}
diff --git a/vendor/gitee.com/openeuler/go-gitee/gitee/model_user_notification_subject.go b/vendor/gitee.com/openeuler/go-gitee/gitee/model_user_notification_subject.go
new file mode 100644
index 0000000000000000000000000000000000000000..1b4b4f6b223a3a2d9ea64b6ba02c622e0a56ac13
--- /dev/null
+++ b/vendor/gitee.com/openeuler/go-gitee/gitee/model_user_notification_subject.go
@@ -0,0 +1,17 @@
+/*
+ * 码云 Open API
+ *
+ * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen)
+ *
+ * API version: 5.3.2
+ * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
+ */
+
+package gitee
+
+type UserNotificationSubject struct {
+ Title string `json:"title,omitempty"`
+ Url string `json:"url,omitempty"`
+ LatestCommentUrl string `json:"latest_comment_url,omitempty"`
+ Type_ string `json:"type,omitempty"`
+}
diff --git a/vendor/gitee.com/openeuler/go-gitee/gitee/model_week_report.go b/vendor/gitee.com/openeuler/go-gitee/gitee/model_week_report.go
new file mode 100644
index 0000000000000000000000000000000000000000..eb3769900d3632a29f97829d4db4d32e65db272b
--- /dev/null
+++ b/vendor/gitee.com/openeuler/go-gitee/gitee/model_week_report.go
@@ -0,0 +1,25 @@
+/*
+ * 码云 Open API
+ *
+ * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen)
+ *
+ * API version: 5.3.2
+ * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
+ */
+
+package gitee
+
+// 新建周报
+type WeekReport struct {
+ Id int32 `json:"id,omitempty"`
+ Content string `json:"content,omitempty"`
+ ContentHtml string `json:"content_html,omitempty"`
+ Year string `json:"year,omitempty"`
+ Month string `json:"month,omitempty"`
+ WeekIndex string `json:"week_index,omitempty"`
+ WeekBegin string `json:"week_begin,omitempty"`
+ WeekEnd string `json:"week_end,omitempty"`
+ CreatedAt string `json:"created_at,omitempty"`
+ UpdatedAt string `json:"updated_at,omitempty"`
+ User *UserMini `json:"user,omitempty"`
+}
diff --git a/vendor/gitee.com/openeuler/go-gitee/gitee/response.go b/vendor/gitee.com/openeuler/go-gitee/gitee/response.go
new file mode 100644
index 0000000000000000000000000000000000000000..c501f2ac9b389c3d45d86f939544d1cd56a29c7f
--- /dev/null
+++ b/vendor/gitee.com/openeuler/go-gitee/gitee/response.go
@@ -0,0 +1,43 @@
+/*
+ * 码云 Open API
+ *
+ * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen)
+ *
+ * API version: 5.3.2
+ * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
+ */
+
+package gitee
+
+import (
+ "net/http"
+)
+
+type APIResponse struct {
+ *http.Response `json:"-"`
+ Message string `json:"message,omitempty"`
+ // Operation is the name of the swagger operation.
+ Operation string `json:"operation,omitempty"`
+ // RequestURL is the request URL. This value is always available, even if the
+ // embedded *http.Response is nil.
+ RequestURL string `json:"url,omitempty"`
+ // Method is the HTTP method used for the request. This value is always
+ // available, even if the embedded *http.Response is nil.
+ Method string `json:"method,omitempty"`
+ // Payload holds the contents of the response body (which may be nil or empty).
+ // This is provided here as the raw response.Body() reader will have already
+ // been drained.
+ Payload []byte `json:"-"`
+}
+
+func NewAPIResponse(r *http.Response) *APIResponse {
+
+ response := &APIResponse{Response: r}
+ return response
+}
+
+func NewAPIResponseWithError(errorMessage string) *APIResponse {
+
+ response := &APIResponse{Message: errorMessage}
+ return response
+}
diff --git a/vendor/github.com/antihax/optional/LICENSE b/vendor/github.com/antihax/optional/LICENSE
new file mode 100644
index 0000000000000000000000000000000000000000..19587fe47991554e389a1009765eb94a22a6cac7
--- /dev/null
+++ b/vendor/github.com/antihax/optional/LICENSE
@@ -0,0 +1,8 @@
+The MIT License (MIT)
+Copyright (c) 2016 Adam Hintz
+
+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.
diff --git a/vendor/github.com/antihax/optional/bool.go b/vendor/github.com/antihax/optional/bool.go
new file mode 100644
index 0000000000000000000000000000000000000000..4f35ff561321a95aea77d9cd82fd024240b10361
--- /dev/null
+++ b/vendor/github.com/antihax/optional/bool.go
@@ -0,0 +1,36 @@
+package optional
+
+type Bool struct {
+ isSet bool
+ value bool
+}
+
+func NewBool(value bool) Bool {
+ return Bool{
+ true,
+ value,
+ }
+}
+
+// EmptyBool returns a new Bool that does not have a value set.
+func EmptyBool() Bool {
+ return Bool{
+ false,
+ false,
+ }
+}
+
+func (b Bool) IsSet() bool {
+ return b.isSet
+}
+
+func (b Bool) Value() bool {
+ return b.value
+}
+
+func (b Bool) Default(defaultValue bool) bool {
+ if b.isSet {
+ return b.value
+ }
+ return defaultValue
+}
diff --git a/vendor/github.com/antihax/optional/byte.go b/vendor/github.com/antihax/optional/byte.go
new file mode 100644
index 0000000000000000000000000000000000000000..d22bbe8ff9062d24987683395ccf96e1bb6be214
--- /dev/null
+++ b/vendor/github.com/antihax/optional/byte.go
@@ -0,0 +1,36 @@
+package optional
+
+type Byte struct {
+ isSet bool
+ value byte
+}
+
+func NewByte(value byte) Byte {
+ return Byte{
+ true,
+ value,
+ }
+}
+
+// EmptyByte returns a new Byte that does not have a value set.
+func EmptyByte() Byte {
+ return Byte{
+ false,
+ 0,
+ }
+}
+
+func (b Byte) IsSet() bool {
+ return b.isSet
+}
+
+func (b Byte) Value() byte {
+ return b.value
+}
+
+func (b Byte) Default(defaultValue byte) byte {
+ if b.isSet {
+ return b.value
+ }
+ return defaultValue
+}
diff --git a/vendor/github.com/antihax/optional/complex128.go b/vendor/github.com/antihax/optional/complex128.go
new file mode 100644
index 0000000000000000000000000000000000000000..290b3f37b53bfb44f479fe8a2ff981d9b70179b2
--- /dev/null
+++ b/vendor/github.com/antihax/optional/complex128.go
@@ -0,0 +1,36 @@
+package optional
+
+type Complex128 struct {
+ isSet bool
+ value complex128
+}
+
+func NewComplex128(value complex128) Complex128 {
+ return Complex128{
+ true,
+ value,
+ }
+}
+
+// EmptyComplex128 returns a new Complex128 that does not have a value set.
+func EmptyComplex128() Complex128 {
+ return Complex128{
+ false,
+ 0,
+ }
+}
+
+func (i Complex128) IsSet() bool {
+ return i.isSet
+}
+
+func (i Complex128) Value() complex128 {
+ return i.value
+}
+
+func (i Complex128) Default(defaultValue complex128) complex128 {
+ if i.isSet {
+ return i.value
+ }
+ return defaultValue
+}
diff --git a/vendor/github.com/antihax/optional/complex64.go b/vendor/github.com/antihax/optional/complex64.go
new file mode 100644
index 0000000000000000000000000000000000000000..7d372d8c18a2ee4d11f4242ea5f8c0d73b4cd7a6
--- /dev/null
+++ b/vendor/github.com/antihax/optional/complex64.go
@@ -0,0 +1,36 @@
+package optional
+
+type Complex64 struct {
+ isSet bool
+ value complex64
+}
+
+func NewComplex64(value complex64) Complex64 {
+ return Complex64{
+ true,
+ value,
+ }
+}
+
+// EmptyComplex64 returns a new Complex64 that does not have a value set.
+func EmptyComplex64() Complex64 {
+ return Complex64{
+ false,
+ 0,
+ }
+}
+
+func (i Complex64) IsSet() bool {
+ return i.isSet
+}
+
+func (i Complex64) Value() complex64 {
+ return i.value
+}
+
+func (i Complex64) Default(defaultValue complex64) complex64 {
+ if i.isSet {
+ return i.value
+ }
+ return defaultValue
+}
diff --git a/vendor/github.com/antihax/optional/float32.go b/vendor/github.com/antihax/optional/float32.go
new file mode 100644
index 0000000000000000000000000000000000000000..519cc5d692f7fd3bce5a493cf72bbd0d69f64ac2
--- /dev/null
+++ b/vendor/github.com/antihax/optional/float32.go
@@ -0,0 +1,36 @@
+package optional
+
+type Float32 struct {
+ isSet bool
+ value float32
+}
+
+func NewFloat32(value float32) Float32 {
+ return Float32{
+ true,
+ value,
+ }
+}
+
+// EmptyFloat32 returns a new Float32 that does not have a value set.
+func EmptyFloat32() Float32 {
+ return Float32{
+ false,
+ 0,
+ }
+}
+
+func (i Float32) IsSet() bool {
+ return i.isSet
+}
+
+func (i Float32) Value() float32 {
+ return i.value
+}
+
+func (i Float32) Default(defaultValue float32) float32 {
+ if i.isSet {
+ return i.value
+ }
+ return defaultValue
+}
diff --git a/vendor/github.com/antihax/optional/float64.go b/vendor/github.com/antihax/optional/float64.go
new file mode 100644
index 0000000000000000000000000000000000000000..835f7058e24b1428c7a6cfeddd37cd27ea127258
--- /dev/null
+++ b/vendor/github.com/antihax/optional/float64.go
@@ -0,0 +1,36 @@
+package optional
+
+type Float64 struct {
+ isSet bool
+ value float64
+}
+
+func NewFloat64(value float64) Float64 {
+ return Float64{
+ true,
+ value,
+ }
+}
+
+// EmptyFloat64 returns a new Float64 that does not have a value set.
+func EmptyFloat64() Float64 {
+ return Float64{
+ false,
+ 0,
+ }
+}
+
+func (i Float64) IsSet() bool {
+ return i.isSet
+}
+
+func (i Float64) Value() float64 {
+ return i.value
+}
+
+func (i Float64) Default(defaultValue float64) float64 {
+ if i.isSet {
+ return i.value
+ }
+ return defaultValue
+}
diff --git a/vendor/github.com/antihax/optional/go.mod b/vendor/github.com/antihax/optional/go.mod
new file mode 100644
index 0000000000000000000000000000000000000000..27b7e9021f09681a0c5865c065d0e7e2114938a6
--- /dev/null
+++ b/vendor/github.com/antihax/optional/go.mod
@@ -0,0 +1,3 @@
+module github.com/antihax/optional
+
+go 1.13
diff --git a/vendor/github.com/antihax/optional/int.go b/vendor/github.com/antihax/optional/int.go
new file mode 100644
index 0000000000000000000000000000000000000000..6c3e65b9230fcaac23826d5a15b6faa3ce684fd1
--- /dev/null
+++ b/vendor/github.com/antihax/optional/int.go
@@ -0,0 +1,36 @@
+package optional
+
+type Int struct {
+ isSet bool
+ value int
+}
+
+func NewInt(value int) Int {
+ return Int{
+ true,
+ value,
+ }
+}
+
+// EmptyInt returns a new Int that does not have a value set.
+func EmptyInt() Int {
+ return Int{
+ false,
+ 0,
+ }
+}
+
+func (i Int) IsSet() bool {
+ return i.isSet
+}
+
+func (i Int) Value() int {
+ return i.value
+}
+
+func (i Int) Default(defaultValue int) int {
+ if i.isSet {
+ return i.value
+ }
+ return defaultValue
+}
diff --git a/vendor/github.com/antihax/optional/int16.go b/vendor/github.com/antihax/optional/int16.go
new file mode 100644
index 0000000000000000000000000000000000000000..49465b8c7f7f7e5f888721b9682bdcfbf55b25f0
--- /dev/null
+++ b/vendor/github.com/antihax/optional/int16.go
@@ -0,0 +1,36 @@
+package optional
+
+type Int16 struct {
+ isSet bool
+ value int16
+}
+
+func NewInt16(value int16) Int16 {
+ return Int16{
+ true,
+ value,
+ }
+}
+
+// EmptyInt16 returns a new Int16 that does not have a value set.
+func EmptyInt16() Int16 {
+ return Int16{
+ false,
+ 0,
+ }
+}
+
+func (i Int16) IsSet() bool {
+ return i.isSet
+}
+
+func (i Int16) Value() int16 {
+ return i.value
+}
+
+func (i Int16) Default(defaultValue int16) int16 {
+ if i.isSet {
+ return i.value
+ }
+ return defaultValue
+}
diff --git a/vendor/github.com/antihax/optional/int32.go b/vendor/github.com/antihax/optional/int32.go
new file mode 100644
index 0000000000000000000000000000000000000000..f3a33c78d471392a82b3fae44369949f32af594f
--- /dev/null
+++ b/vendor/github.com/antihax/optional/int32.go
@@ -0,0 +1,36 @@
+package optional
+
+type Int32 struct {
+ isSet bool
+ value int32
+}
+
+func NewInt32(value int32) Int32 {
+ return Int32{
+ true,
+ value,
+ }
+}
+
+// EmptyInt32 returns a new Int32 that does not have a value set.
+func EmptyInt32() Int32 {
+ return Int32{
+ false,
+ 0,
+ }
+}
+
+func (i Int32) IsSet() bool {
+ return i.isSet
+}
+
+func (i Int32) Value() int32 {
+ return i.value
+}
+
+func (i Int32) Default(defaultValue int32) int32 {
+ if i.isSet {
+ return i.value
+ }
+ return defaultValue
+}
diff --git a/vendor/github.com/antihax/optional/int64.go b/vendor/github.com/antihax/optional/int64.go
new file mode 100644
index 0000000000000000000000000000000000000000..d047470b79c92549fcd8f4f226a529d8e20eaa57
--- /dev/null
+++ b/vendor/github.com/antihax/optional/int64.go
@@ -0,0 +1,36 @@
+package optional
+
+type Int64 struct {
+ isSet bool
+ value int64
+}
+
+func NewInt64(value int64) Int64 {
+ return Int64{
+ true,
+ value,
+ }
+}
+
+// EmptyInt64 returns a new Int64 that does not have a value set.
+func EmptyInt64() Int64 {
+ return Int64{
+ false,
+ 0,
+ }
+}
+
+func (i Int64) IsSet() bool {
+ return i.isSet
+}
+
+func (i Int64) Value() int64 {
+ return i.value
+}
+
+func (i Int64) Default(defaultValue int64) int64 {
+ if i.isSet {
+ return i.value
+ }
+ return defaultValue
+}
diff --git a/vendor/github.com/antihax/optional/int8.go b/vendor/github.com/antihax/optional/int8.go
new file mode 100644
index 0000000000000000000000000000000000000000..2bd11bda7adb99831154287b775f1d75d836608f
--- /dev/null
+++ b/vendor/github.com/antihax/optional/int8.go
@@ -0,0 +1,36 @@
+package optional
+
+type Int8 struct {
+ isSet bool
+ value int8
+}
+
+func NewInt8(value int8) Int8 {
+ return Int8{
+ true,
+ value,
+ }
+}
+
+// EmptyInt8 returns a new Int8 that does not have a value set.
+func EmptyInt8() Int8 {
+ return Int8{
+ false,
+ 0,
+ }
+}
+
+func (i Int8) IsSet() bool {
+ return i.isSet
+}
+
+func (i Int8) Value() int8 {
+ return i.value
+}
+
+func (i Int8) Default(defaultValue int8) int8 {
+ if i.isSet {
+ return i.value
+ }
+ return defaultValue
+}
diff --git a/vendor/github.com/antihax/optional/interface.go b/vendor/github.com/antihax/optional/interface.go
new file mode 100644
index 0000000000000000000000000000000000000000..a6f2416ddb28b91d041be3be449f56b6a709b44e
--- /dev/null
+++ b/vendor/github.com/antihax/optional/interface.go
@@ -0,0 +1,37 @@
+package optional
+
+// Optional represents a generic optional type, stored as an interface{}.
+type Interface struct {
+ isSet bool
+ value interface{}
+}
+
+func NewInterface(value interface{}) Interface {
+ return Interface{
+ true,
+ value,
+ }
+}
+
+// EmptyInterface returns a new Interface that does not have a value set.
+func EmptyInterface() Interface {
+ return Interface{
+ false,
+ nil,
+ }
+}
+
+func (b Interface) IsSet() bool {
+ return b.isSet
+}
+
+func (b Interface) Value() interface{} {
+ return b.value
+}
+
+func (b Interface) Default(defaultValue interface{}) interface{} {
+ if b.isSet {
+ return b.value
+ }
+ return defaultValue
+}
diff --git a/vendor/github.com/antihax/optional/rune.go b/vendor/github.com/antihax/optional/rune.go
new file mode 100644
index 0000000000000000000000000000000000000000..cbac8192949a9aaf017728503b8fa749ae647b1c
--- /dev/null
+++ b/vendor/github.com/antihax/optional/rune.go
@@ -0,0 +1,36 @@
+package optional
+
+type Rune struct {
+ isSet bool
+ value rune
+}
+
+func NewRune(value rune) Rune {
+ return Rune{
+ true,
+ value,
+ }
+}
+
+// EmptyRune returns a new Rune that does not have a value set.
+func EmptyRune() Rune {
+ return Rune{
+ false,
+ 0,
+ }
+}
+
+func (b Rune) IsSet() bool {
+ return b.isSet
+}
+
+func (b Rune) Value() rune {
+ return b.value
+}
+
+func (b Rune) Default(defaultValue rune) rune {
+ if b.isSet {
+ return b.value
+ }
+ return defaultValue
+}
diff --git a/vendor/github.com/antihax/optional/string.go b/vendor/github.com/antihax/optional/string.go
new file mode 100644
index 0000000000000000000000000000000000000000..a2e5a2b4497f774091a4151814b111337fccfb41
--- /dev/null
+++ b/vendor/github.com/antihax/optional/string.go
@@ -0,0 +1,36 @@
+package optional
+
+type String struct {
+ isSet bool
+ value string
+}
+
+func NewString(value string) String {
+ return String{
+ true,
+ value,
+ }
+}
+
+// EmptyString returns a new String that does not have a value set.
+func EmptyString() String {
+ return String{
+ false,
+ "",
+ }
+}
+
+func (b String) IsSet() bool {
+ return b.isSet
+}
+
+func (b String) Value() string {
+ return b.value
+}
+
+func (b String) Default(defaultValue string) string {
+ if b.isSet {
+ return b.value
+ }
+ return defaultValue
+}
diff --git a/vendor/github.com/antihax/optional/time.go b/vendor/github.com/antihax/optional/time.go
new file mode 100644
index 0000000000000000000000000000000000000000..a92a55aa436c3b811b5ab25a58b40dde42aa9f31
--- /dev/null
+++ b/vendor/github.com/antihax/optional/time.go
@@ -0,0 +1,38 @@
+package optional
+
+import "time"
+
+type Time struct {
+ isSet bool
+ value time.Time
+}
+
+func NewTime(value time.Time) Time {
+ return Time{
+ true,
+ value,
+ }
+}
+
+// EmptyTime returns a new Time that does not have a value set.
+func EmptyTime() Time {
+ return Time{
+ false,
+ time.Time{},
+ }
+}
+
+func (b Time) IsSet() bool {
+ return b.isSet
+}
+
+func (b Time) Value() time.Time {
+ return b.value
+}
+
+func (b Time) Default(defaultValue time.Time) time.Time {
+ if b.isSet {
+ return b.value
+ }
+ return defaultValue
+}
diff --git a/vendor/github.com/antihax/optional/uint.go b/vendor/github.com/antihax/optional/uint.go
new file mode 100644
index 0000000000000000000000000000000000000000..f9e53a41bc7ded5f70c8b16d9e92ed84887810fa
--- /dev/null
+++ b/vendor/github.com/antihax/optional/uint.go
@@ -0,0 +1,36 @@
+package optional
+
+type Uint struct {
+ isSet bool
+ value uint
+}
+
+func NewUint(value uint) Uint {
+ return Uint{
+ true,
+ value,
+ }
+}
+
+// EmptyUint returns a new Uint that does not have a value set.
+func EmptyUint() Uint {
+ return Uint{
+ false,
+ 0,
+ }
+}
+
+func (i Uint) IsSet() bool {
+ return i.isSet
+}
+
+func (i Uint) Value() uint {
+ return i.value
+}
+
+func (i Uint) Default(defaultValue uint) uint {
+ if i.isSet {
+ return i.value
+ }
+ return defaultValue
+}
diff --git a/vendor/github.com/antihax/optional/uint16.go b/vendor/github.com/antihax/optional/uint16.go
new file mode 100644
index 0000000000000000000000000000000000000000..487eb673b31bef1aa9e6862293c562684e4eb371
--- /dev/null
+++ b/vendor/github.com/antihax/optional/uint16.go
@@ -0,0 +1,36 @@
+package optional
+
+type Uint16 struct {
+ isSet bool
+ value uint16
+}
+
+func NewUint16(value uint16) Uint16 {
+ return Uint16{
+ true,
+ value,
+ }
+}
+
+// EmptyUint16 returns a new Uint16 that does not have a value set.
+func EmptyUint16() Uint16 {
+ return Uint16{
+ false,
+ 0,
+ }
+}
+
+func (i Uint16) IsSet() bool {
+ return i.isSet
+}
+
+func (i Uint16) Value() uint16 {
+ return i.value
+}
+
+func (i Uint16) Default(defaultValue uint16) uint16 {
+ if i.isSet {
+ return i.value
+ }
+ return defaultValue
+}
diff --git a/vendor/github.com/antihax/optional/uint32.go b/vendor/github.com/antihax/optional/uint32.go
new file mode 100644
index 0000000000000000000000000000000000000000..0e46c837837c7a93b0407c754d575c06d7c1594a
--- /dev/null
+++ b/vendor/github.com/antihax/optional/uint32.go
@@ -0,0 +1,36 @@
+package optional
+
+type Uint32 struct {
+ isSet bool
+ value uint32
+}
+
+func NewUint32(value uint32) Uint32 {
+ return Uint32{
+ true,
+ value,
+ }
+}
+
+// EmptyUint32 returns a new Uint32 that does not have a value set.
+func EmptyUint32() Uint32 {
+ return Uint32{
+ false,
+ 0,
+ }
+}
+
+func (i Uint32) IsSet() bool {
+ return i.isSet
+}
+
+func (i Uint32) Value() uint32 {
+ return i.value
+}
+
+func (i Uint32) Default(defaultValue uint32) uint32 {
+ if i.isSet {
+ return i.value
+ }
+ return defaultValue
+}
diff --git a/vendor/github.com/antihax/optional/uint64.go b/vendor/github.com/antihax/optional/uint64.go
new file mode 100644
index 0000000000000000000000000000000000000000..16004df34bb10f3296c4b0fe993a9a43d3a53dfb
--- /dev/null
+++ b/vendor/github.com/antihax/optional/uint64.go
@@ -0,0 +1,36 @@
+package optional
+
+type Uint64 struct {
+ isSet bool
+ value uint64
+}
+
+func NewUint64(value uint64) Uint64 {
+ return Uint64{
+ true,
+ value,
+ }
+}
+
+// EmptyUint64 returns a new Uint64 that does not have a value set.
+func EmptyUint64() Uint64 {
+ return Uint64{
+ false,
+ 0,
+ }
+}
+
+func (i Uint64) IsSet() bool {
+ return i.isSet
+}
+
+func (i Uint64) Value() uint64 {
+ return i.value
+}
+
+func (i Uint64) Default(defaultValue uint64) uint64 {
+ if i.isSet {
+ return i.value
+ }
+ return defaultValue
+}
diff --git a/vendor/github.com/antihax/optional/uint8.go b/vendor/github.com/antihax/optional/uint8.go
new file mode 100644
index 0000000000000000000000000000000000000000..469ceb53a8fc96b46c8b17c81c2d611573bc681a
--- /dev/null
+++ b/vendor/github.com/antihax/optional/uint8.go
@@ -0,0 +1,36 @@
+package optional
+
+type Uint8 struct {
+ isSet bool
+ value uint8
+}
+
+func NewUint8(value uint8) Uint8 {
+ return Uint8{
+ true,
+ value,
+ }
+}
+
+// EmptyUint8 returns a new Uint8 that does not have a value set.
+func EmptyUint8() Uint8 {
+ return Uint8{
+ false,
+ 0,
+ }
+}
+
+func (i Uint8) IsSet() bool {
+ return i.isSet
+}
+
+func (i Uint8) Value() uint8 {
+ return i.value
+}
+
+func (i Uint8) Default(defaultValue uint8) uint8 {
+ if i.isSet {
+ return i.value
+ }
+ return defaultValue
+}
diff --git a/vendor/github.com/antihax/optional/uintptr.go b/vendor/github.com/antihax/optional/uintptr.go
new file mode 100644
index 0000000000000000000000000000000000000000..e7e2cabe0cf45c332bcf740772d40998729c5746
--- /dev/null
+++ b/vendor/github.com/antihax/optional/uintptr.go
@@ -0,0 +1,36 @@
+package optional
+
+type Uintptr struct {
+ isSet bool
+ value uintptr
+}
+
+func NewUintptr(value uintptr) Uintptr {
+ return Uintptr{
+ true,
+ value,
+ }
+}
+
+// EmptyUintptr returns a new Uintptr that does not have a value set.
+func EmptyUintptr() Uintptr {
+ return Uintptr{
+ false,
+ 0,
+ }
+}
+
+func (i Uintptr) IsSet() bool {
+ return i.isSet
+}
+
+func (i Uintptr) Value() uintptr {
+ return i.value
+}
+
+func (i Uintptr) Default(defaultValue uintptr) uintptr {
+ if i.isSet {
+ return i.value
+ }
+ return defaultValue
+}
diff --git a/vendor/github.com/go-sql-driver/mysql/.gitignore b/vendor/github.com/go-sql-driver/mysql/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..2de28da16638ab523cbe1bc461ed2d67746939f4
--- /dev/null
+++ b/vendor/github.com/go-sql-driver/mysql/.gitignore
@@ -0,0 +1,9 @@
+.DS_Store
+.DS_Store?
+._*
+.Spotlight-V100
+.Trashes
+Icon?
+ehthumbs.db
+Thumbs.db
+.idea
diff --git a/vendor/github.com/go-sql-driver/mysql/.travis.yml b/vendor/github.com/go-sql-driver/mysql/.travis.yml
new file mode 100644
index 0000000000000000000000000000000000000000..cc1268c3613bfb27da6c906bd029d3867d30a6d5
--- /dev/null
+++ b/vendor/github.com/go-sql-driver/mysql/.travis.yml
@@ -0,0 +1,107 @@
+sudo: false
+language: go
+go:
+ - 1.7.x
+ - 1.8.x
+ - 1.9.x
+ - 1.10.x
+ - master
+
+before_install:
+ - go get golang.org/x/tools/cmd/cover
+ - go get github.com/mattn/goveralls
+
+before_script:
+ - echo -e "[server]\ninnodb_log_file_size=256MB\ninnodb_buffer_pool_size=512MB\nmax_allowed_packet=16MB" | sudo tee -a /etc/mysql/my.cnf
+ - sudo service mysql restart
+ - .travis/wait_mysql.sh
+ - mysql -e 'create database gotest;'
+
+matrix:
+ include:
+ - env: DB=MYSQL8
+ sudo: required
+ dist: trusty
+ go: 1.10.x
+ services:
+ - docker
+ before_install:
+ - go get golang.org/x/tools/cmd/cover
+ - go get github.com/mattn/goveralls
+ - docker pull mysql:8.0
+ - docker run -d -p 127.0.0.1:3307:3306 --name mysqld -e MYSQL_DATABASE=gotest -e MYSQL_USER=gotest -e MYSQL_PASSWORD=secret -e MYSQL_ROOT_PASSWORD=verysecret
+ mysql:8.0 --innodb_log_file_size=256MB --innodb_buffer_pool_size=512MB --max_allowed_packet=16MB --local-infile=1
+ - cp .travis/docker.cnf ~/.my.cnf
+ - .travis/wait_mysql.sh
+ before_script:
+ - export MYSQL_TEST_USER=gotest
+ - export MYSQL_TEST_PASS=secret
+ - export MYSQL_TEST_ADDR=127.0.0.1:3307
+ - export MYSQL_TEST_CONCURRENT=1
+
+ - env: DB=MYSQL57
+ sudo: required
+ dist: trusty
+ go: 1.10.x
+ services:
+ - docker
+ before_install:
+ - go get golang.org/x/tools/cmd/cover
+ - go get github.com/mattn/goveralls
+ - docker pull mysql:5.7
+ - docker run -d -p 127.0.0.1:3307:3306 --name mysqld -e MYSQL_DATABASE=gotest -e MYSQL_USER=gotest -e MYSQL_PASSWORD=secret -e MYSQL_ROOT_PASSWORD=verysecret
+ mysql:5.7 --innodb_log_file_size=256MB --innodb_buffer_pool_size=512MB --max_allowed_packet=16MB --local-infile=1
+ - cp .travis/docker.cnf ~/.my.cnf
+ - .travis/wait_mysql.sh
+ before_script:
+ - export MYSQL_TEST_USER=gotest
+ - export MYSQL_TEST_PASS=secret
+ - export MYSQL_TEST_ADDR=127.0.0.1:3307
+ - export MYSQL_TEST_CONCURRENT=1
+
+ - env: DB=MARIA55
+ sudo: required
+ dist: trusty
+ go: 1.10.x
+ services:
+ - docker
+ before_install:
+ - go get golang.org/x/tools/cmd/cover
+ - go get github.com/mattn/goveralls
+ - docker pull mariadb:5.5
+ - docker run -d -p 127.0.0.1:3307:3306 --name mysqld -e MYSQL_DATABASE=gotest -e MYSQL_USER=gotest -e MYSQL_PASSWORD=secret -e MYSQL_ROOT_PASSWORD=verysecret
+ mariadb:5.5 --innodb_log_file_size=256MB --innodb_buffer_pool_size=512MB --max_allowed_packet=16MB --local-infile=1
+ - cp .travis/docker.cnf ~/.my.cnf
+ - .travis/wait_mysql.sh
+ before_script:
+ - export MYSQL_TEST_USER=gotest
+ - export MYSQL_TEST_PASS=secret
+ - export MYSQL_TEST_ADDR=127.0.0.1:3307
+ - export MYSQL_TEST_CONCURRENT=1
+
+ - env: DB=MARIA10_1
+ sudo: required
+ dist: trusty
+ go: 1.10.x
+ services:
+ - docker
+ before_install:
+ - go get golang.org/x/tools/cmd/cover
+ - go get github.com/mattn/goveralls
+ - docker pull mariadb:10.1
+ - docker run -d -p 127.0.0.1:3307:3306 --name mysqld -e MYSQL_DATABASE=gotest -e MYSQL_USER=gotest -e MYSQL_PASSWORD=secret -e MYSQL_ROOT_PASSWORD=verysecret
+ mariadb:10.1 --innodb_log_file_size=256MB --innodb_buffer_pool_size=512MB --max_allowed_packet=16MB --local-infile=1
+ - cp .travis/docker.cnf ~/.my.cnf
+ - .travis/wait_mysql.sh
+ before_script:
+ - export MYSQL_TEST_USER=gotest
+ - export MYSQL_TEST_PASS=secret
+ - export MYSQL_TEST_ADDR=127.0.0.1:3307
+ - export MYSQL_TEST_CONCURRENT=1
+
+script:
+ - go test -v -covermode=count -coverprofile=coverage.out
+ - go vet ./...
+ - .travis/gofmt.sh
+after_script:
+ - $HOME/gopath/bin/goveralls -coverprofile=coverage.out -service=travis-ci
diff --git a/vendor/github.com/go-sql-driver/mysql/AUTHORS b/vendor/github.com/go-sql-driver/mysql/AUTHORS
new file mode 100644
index 0000000000000000000000000000000000000000..73ff68fbcf2233d7142e76981fc3d1621c33f7f7
--- /dev/null
+++ b/vendor/github.com/go-sql-driver/mysql/AUTHORS
@@ -0,0 +1,89 @@
+# This is the official list of Go-MySQL-Driver authors for copyright purposes.
+
+# If you are submitting a patch, please add your name or the name of the
+# organization which holds the copyright to this list in alphabetical order.
+
+# Names should be added to this file as
+# Name
+# The email address is not required for organizations.
+# Please keep the list sorted.
+
+
+# Individual Persons
+
+Aaron Hopkins
+Achille Roussel
+Alexey Palazhchenko
+Andrew Reid
+Arne Hormann
+Asta Xie
+Bulat Gaifullin
+Carlos Nieto
+Chris Moos
+Craig Wilson
+Daniel Montoya
+Daniel Nichter
+Daniël van Eeden
+Dave Protasowski
+DisposaBoy
+Egor Smolyakov
+Evan Shaw
+Frederick Mayle
+Gustavo Kristic
+Hajime Nakagami
+Hanno Braun
+Henri Yandell
+Hirotaka Yamamoto
+ICHINOSE Shogo
+INADA Naoki
+Jacek Szwec
+James Harr
+Jeff Hodges
+Jeffrey Charles
+Jian Zhen
+Joshua Prunier
+Julien Lefevre
+Julien Schmidt
+Justin Li
+Justin Nuß
+Kamil Dziedzic
+Kevin Malachowski
+Kieron Woodhouse
+Lennart Rudolph
+Leonardo YongUk Kim
+Linh Tran Tuan
+Lion Yang
+Luca Looz
+Lucas Liu
+Luke Scott
+Maciej Zimnoch
+Michael Woolnough
+Nicola Peduzzi
+Olivier Mengué
+oscarzhao
+Paul Bonser
+Peter Schultz
+Rebecca Chin
+Reed Allman
+Richard Wilkes
+Robert Russell
+Runrioter Wung
+Shuode Li
+Soroush Pour
+Stan Putrya
+Stanley Gunawan
+Xiangyu Hu
+Xiaobing Jiang
+Xiuming Chen
+Zhenye Xie
+
+# Organizations
+
+Barracuda Networks, Inc.
+Counting Ltd.
+Google Inc.
+InfoSum Ltd.
+Keybase Inc.
+Percona LLC
+Pivotal Inc.
+Stripe Inc.
diff --git a/vendor/github.com/go-sql-driver/mysql/CHANGELOG.md b/vendor/github.com/go-sql-driver/mysql/CHANGELOG.md
new file mode 100644
index 0000000000000000000000000000000000000000..ce1b5330a91a6d43a8306fa278d30203bdaf8948
--- /dev/null
+++ b/vendor/github.com/go-sql-driver/mysql/CHANGELOG.md
@@ -0,0 +1,178 @@
+## Version 1.4.1 (2018-11-14)
+
+Bugfixes:
+
+ - Fix TIME format for binary columns (#818)
+ - Fix handling of empty auth plugin names (#835)
+ - Fix caching_sha2_password with empty password (#826)
+ - Fix canceled context broke mysqlConn (#862)
+ - Fix OldAuthSwitchRequest support (#870)
+ - Fix Auth Response packet for cleartext password (#887)
+
+## Version 1.4 (2018-06-03)
+
+Changes:
+
+ - Documentation fixes (#530, #535, #567)
+ - Refactoring (#575, #579, #580, #581, #603, #615, #704)
+ - Cache column names (#444)
+ - Sort the DSN parameters in DSNs generated from a config (#637)
+ - Allow native password authentication by default (#644)
+ - Use the default port if it is missing in the DSN (#668)
+ - Removed the `strict` mode (#676)
+ - Do not query `max_allowed_packet` by default (#680)
+ - Dropped support Go 1.6 and lower (#696)
+ - Updated `ConvertValue()` to match the database/sql/driver implementation (#760)
+ - Document the usage of `0000-00-00T00:00:00` as the time.Time zero value (#783)
+ - Improved the compatibility of the authentication system (#807)
+
+New Features:
+
+ - Multi-Results support (#537)
+ - `rejectReadOnly` DSN option (#604)
+ - `context.Context` support (#608, #612, #627, #761)
+ - Transaction isolation level support (#619, #744)
+ - Read-Only transactions support (#618, #634)
+ - `NewConfig` function which initializes a config with default values (#679)
+ - Implemented the `ColumnType` interfaces (#667, #724)
+ - Support for custom string types in `ConvertValue` (#623)
+ - Implemented `NamedValueChecker`, improving support for uint64 with high bit set (#690, #709, #710)
+ - `caching_sha2_password` authentication plugin support (#794, #800, #801, #802)
+ - Implemented `driver.SessionResetter` (#779)
+ - `sha256_password` authentication plugin support (#808)
+
+Bugfixes:
+
+ - Use the DSN hostname as TLS default ServerName if `tls=true` (#564, #718)
+ - Fixed LOAD LOCAL DATA INFILE for empty files (#590)
+ - Removed columns definition cache since it sometimes cached invalid data (#592)
+ - Don't mutate registered TLS configs (#600)
+ - Make RegisterTLSConfig concurrency-safe (#613)
+ - Handle missing auth data in the handshake packet correctly (#646)
+ - Do not retry queries when data was written to avoid data corruption (#302, #736)
+ - Cache the connection pointer for error handling before invalidating it (#678)
+ - Fixed imports for appengine/cloudsql (#700)
+ - Fix sending STMT_LONG_DATA for 0 byte data (#734)
+ - Set correct capacity for []bytes read from length-encoded strings (#766)
+ - Make RegisterDial concurrency-safe (#773)
+
+
+## Version 1.3 (2016-12-01)
+
+Changes:
+
+ - Go 1.1 is no longer supported
+ - Use decimals fields in MySQL to format time types (#249)
+ - Buffer optimizations (#269)
+ - TLS ServerName defaults to the host (#283)
+ - Refactoring (#400, #410, #437)
+ - Adjusted documentation for second generation CloudSQL (#485)
+ - Documented DSN system var quoting rules (#502)
+ - Made statement.Close() calls idempotent to avoid errors in Go 1.6+ (#512)
+
+New Features:
+
+ - Enable microsecond resolution on TIME, DATETIME and TIMESTAMP (#249)
+ - Support for returning table alias on Columns() (#289, #359, #382)
+ - Placeholder interpolation, can be actived with the DSN parameter `interpolateParams=true` (#309, #318, #490)
+ - Support for uint64 parameters with high bit set (#332, #345)
+ - Cleartext authentication plugin support (#327)
+ - Exported ParseDSN function and the Config struct (#403, #419, #429)
+ - Read / Write timeouts (#401)
+ - Support for JSON field type (#414)
+ - Support for multi-statements and multi-results (#411, #431)
+ - DSN parameter to set the driver-side max_allowed_packet value manually (#489)
+ - Native password authentication plugin support (#494, #524)
+
+Bugfixes:
+
+ - Fixed handling of queries without columns and rows (#255)
+ - Fixed a panic when SetKeepAlive() failed (#298)
+ - Handle ERR packets while reading rows (#321)
+ - Fixed reading NULL length-encoded integers in MySQL 5.6+ (#349)
+ - Fixed absolute paths support in LOAD LOCAL DATA INFILE (#356)
+ - Actually zero out bytes in handshake response (#378)
+ - Fixed race condition in registering LOAD DATA INFILE handler (#383)
+ - Fixed tests with MySQL 5.7.9+ (#380)
+ - QueryUnescape TLS config names (#397)
+ - Fixed "broken pipe" error by writing to closed socket (#390)
+ - Fixed LOAD LOCAL DATA INFILE buffering (#424)
+ - Fixed parsing of floats into float64 when placeholders are used (#434)
+ - Fixed DSN tests with Go 1.7+ (#459)
+ - Handle ERR packets while waiting for EOF (#473)
+ - Invalidate connection on error while discarding additional results (#513)
+ - Allow terminating packets of length 0 (#516)
+
+
+## Version 1.2 (2014-06-03)
+
+Changes:
+
+ - We switched back to a "rolling release". `go get` installs the current master branch again
+ - Version v1 of the driver will not be maintained anymore. Go 1.0 is no longer supported by this driver
+ - Exported errors to allow easy checking from application code
+ - Enabled TCP Keepalives on TCP connections
+ - Optimized INFILE handling (better buffer size calculation, lazy init, ...)
+ - The DSN parser also checks for a missing separating slash
+ - Faster binary date / datetime to string formatting
+ - Also exported the MySQLWarning type
+ - mysqlConn.Close returns the first error encountered instead of ignoring all errors
+ - writePacket() automatically writes the packet size to the header
+ - readPacket() uses an iterative approach instead of the recursive approach to merge splitted packets
+
+New Features:
+
+ - `RegisterDial` allows the usage of a custom dial function to establish the network connection
+ - Setting the connection collation is possible with the `collation` DSN parameter. This parameter should be preferred over the `charset` parameter
+ - Logging of critical errors is configurable with `SetLogger`
+ - Google CloudSQL support
+
+Bugfixes:
+
+ - Allow more than 32 parameters in prepared statements
+ - Various old_password fixes
+ - Fixed TestConcurrent test to pass Go's race detection
+ - Fixed appendLengthEncodedInteger for large numbers
+ - Renamed readLengthEnodedString to readLengthEncodedString and skipLengthEnodedString to skipLengthEncodedString (fixed typo)
+
+
+## Version 1.1 (2013-11-02)
+
+Changes:
+
+ - Go-MySQL-Driver now requires Go 1.1
+ - Connections now use the collation `utf8_general_ci` by default. Adding `&charset=UTF8` to the DSN should not be necessary anymore
+ - Made closing rows and connections error tolerant. This allows for example deferring rows.Close() without checking for errors
+ - `[]byte(nil)` is now treated as a NULL value. Before, it was treated like an empty string / `[]byte("")`
+ - DSN parameter values must now be url.QueryEscape'ed. This allows text values to contain special characters, such as '&'.
+ - Use the IO buffer also for writing. This results in zero allocations (by the driver) for most queries
+ - Optimized the buffer for reading
+ - stmt.Query now caches column metadata
+ - New Logo
+ - Changed the copyright header to include all contributors
+ - Improved the LOAD INFILE documentation
+ - The driver struct is now exported to make the driver directly accessible
+ - Refactored the driver tests
+ - Added more benchmarks and moved all to a separate file
+ - Other small refactoring
+
+New Features:
+
+ - Added *old_passwords* support: Required in some cases, but must be enabled by adding `allowOldPasswords=true` to the DSN since it is insecure
+ - Added a `clientFoundRows` parameter: Return the number of matching rows instead of the number of rows changed on UPDATEs
+ - Added TLS/SSL support: Use a TLS/SSL encrypted connection to the server. Custom TLS configs can be registered and used
+
+Bugfixes:
+
+ - Fixed MySQL 4.1 support: MySQL 4.1 sends packets with lengths which differ from the specification
+ - Convert to DB timezone when inserting `time.Time`
+ - Splitted packets (more than 16MB) are now merged correctly
+ - Fixed false positive `io.EOF` errors when the data was fully read
+ - Avoid panics on reuse of closed connections
+ - Fixed empty string producing false nil values
+ - Fixed sign byte for positive TIME fields
+
+
+## Version 1.0 (2013-05-14)
+
+Initial Release
diff --git a/vendor/github.com/go-sql-driver/mysql/CONTRIBUTING.md b/vendor/github.com/go-sql-driver/mysql/CONTRIBUTING.md
new file mode 100644
index 0000000000000000000000000000000000000000..8fe16bcb497b7ce4bfa7deac567276ead4c17f81
--- /dev/null
+++ b/vendor/github.com/go-sql-driver/mysql/CONTRIBUTING.md
@@ -0,0 +1,23 @@
+# Contributing Guidelines
+
+## Reporting Issues
+
+Before creating a new Issue, please check first if a similar Issue [already exists](https://github.com/go-sql-driver/mysql/issues?state=open) or was [recently closed](https://github.com/go-sql-driver/mysql/issues?direction=desc&page=1&sort=updated&state=closed).
+
+## Contributing Code
+
+By contributing to this project, you share your code under the Mozilla Public License 2, as specified in the LICENSE file.
+Don't forget to add yourself to the AUTHORS file.
+
+### Code Review
+
+Everyone is invited to review and comment on pull requests.
+If it looks fine to you, comment with "LGTM" (Looks good to me).
+
+If changes are required, notice the reviewers with "PTAL" (Please take another look) after committing the fixes.
+
+Before merging the Pull Request, at least one [team member](https://github.com/go-sql-driver?tab=members) must have commented with "LGTM".
+
+## Development Ideas
+
+If you are looking for ideas for code contributions, please check our [Development Ideas](https://github.com/go-sql-driver/mysql/wiki/Development-Ideas) Wiki page.
diff --git a/vendor/github.com/go-sql-driver/mysql/LICENSE b/vendor/github.com/go-sql-driver/mysql/LICENSE
new file mode 100644
index 0000000000000000000000000000000000000000..14e2f777f6c395e7e04ab4aa306bbcc4b0c1120e
--- /dev/null
+++ b/vendor/github.com/go-sql-driver/mysql/LICENSE
@@ -0,0 +1,373 @@
+Mozilla Public License Version 2.0
+==================================
+
+1. Definitions
+--------------
+
+1.1. "Contributor"
+ means each individual or legal entity that creates, contributes to
+ the creation of, or owns Covered Software.
+
+1.2. "Contributor Version"
+ means the combination of the Contributions of others (if any) used
+ by a Contributor and that particular Contributor's Contribution.
+
+1.3. "Contribution"
+ means Covered Software of a particular Contributor.
+
+1.4. "Covered Software"
+ means Source Code Form to which the initial Contributor has attached
+ the notice in Exhibit A, the Executable Form of such Source Code
+ Form, and Modifications of such Source Code Form, in each case
+ including portions thereof.
+
+1.5. "Incompatible With Secondary Licenses"
+ means
+
+ (a) that the initial Contributor has attached the notice described
+ in Exhibit B to the Covered Software; or
+
+ (b) that the Covered Software was made available under the terms of
+ version 1.1 or earlier of the License, but not also under the
+ terms of a Secondary License.
+
+1.6. "Executable Form"
+ means any form of the work other than Source Code Form.
+
+1.7. "Larger Work"
+ means a work that combines Covered Software with other material, in
+ a separate file or files, that is not Covered Software.
+
+1.8. "License"
+ means this document.
+
+1.9. "Licensable"
+ means having the right to grant, to the maximum extent possible,
+ whether at the time of the initial grant or subsequently, any and
+ all of the rights conveyed by this License.
+
+1.10. "Modifications"
+ means any of the following:
+
+ (a) any file in Source Code Form that results from an addition to,
+ deletion from, or modification of the contents of Covered
+ Software; or
+
+ (b) any new file in Source Code Form that contains any Covered
+ Software.
+
+1.11. "Patent Claims" of a Contributor
+ means any patent claim(s), including without limitation, method,
+ process, and apparatus claims, in any patent Licensable by such
+ Contributor that would be infringed, but for the grant of the
+ License, by the making, using, selling, offering for sale, having
+ made, import, or transfer of either its Contributions or its
+ Contributor Version.
+
+1.12. "Secondary License"
+ means either the GNU General Public License, Version 2.0, the GNU
+ Lesser General Public License, Version 2.1, the GNU Affero General
+ Public License, Version 3.0, or any later versions of those
+ licenses.
+
+1.13. "Source Code Form"
+ means the form of the work preferred for making modifications.
+
+1.14. "You" (or "Your")
+ means an individual or a legal entity exercising rights under this
+ License. For legal entities, "You" includes any entity that
+ controls, is controlled by, or is under common control with You. For
+ purposes of this definition, "control" means (a) the power, direct
+ or indirect, to cause the direction or management of such entity,
+ whether by contract or otherwise, or (b) ownership of more than
+ fifty percent (50%) of the outstanding shares or beneficial
+ ownership of such entity.
+
+2. License Grants and Conditions
+--------------------------------
+
+2.1. Grants
+
+Each Contributor hereby grants You a world-wide, royalty-free,
+non-exclusive license:
+
+(a) under intellectual property rights (other than patent or trademark)
+ Licensable by such Contributor to use, reproduce, make available,
+ modify, display, perform, distribute, and otherwise exploit its
+ Contributions, either on an unmodified basis, with Modifications, or
+ as part of a Larger Work; and
+
+(b) under Patent Claims of such Contributor to make, use, sell, offer
+ for sale, have made, import, and otherwise transfer either its
+ Contributions or its Contributor Version.
+
+2.2. Effective Date
+
+The licenses granted in Section 2.1 with respect to any Contribution
+become effective for each Contribution on the date the Contributor first
+distributes such Contribution.
+
+2.3. Limitations on Grant Scope
+
+The licenses granted in this Section 2 are the only rights granted under
+this License. No additional rights or licenses will be implied from the
+distribution or licensing of Covered Software under this License.
+Notwithstanding Section 2.1(b) above, no patent license is granted by a
+Contributor:
+
+(a) for any code that a Contributor has removed from Covered Software;
+ or
+
+(b) for infringements caused by: (i) Your and any other third party's
+ modifications of Covered Software, or (ii) the combination of its
+ Contributions with other software (except as part of its Contributor
+ Version); or
+
+(c) under Patent Claims infringed by Covered Software in the absence of
+ its Contributions.
+
+This License does not grant any rights in the trademarks, service marks,
+or logos of any Contributor (except as may be necessary to comply with
+the notice requirements in Section 3.4).
+
+2.4. Subsequent Licenses
+
+No Contributor makes additional grants as a result of Your choice to
+distribute the Covered Software under a subsequent version of this
+License (see Section 10.2) or under the terms of a Secondary License (if
+permitted under the terms of Section 3.3).
+
+2.5. Representation
+
+Each Contributor represents that the Contributor believes its
+Contributions are its original creation(s) or it has sufficient rights
+to grant the rights to its Contributions conveyed by this License.
+
+2.6. Fair Use
+
+This License is not intended to limit any rights You have under
+applicable copyright doctrines of fair use, fair dealing, or other
+equivalents.
+
+2.7. Conditions
+
+Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted
+in Section 2.1.
+
+3. Responsibilities
+-------------------
+
+3.1. Distribution of Source Form
+
+All distribution of Covered Software in Source Code Form, including any
+Modifications that You create or to which You contribute, must be under
+the terms of this License. You must inform recipients that the Source
+Code Form of the Covered Software is governed by the terms of this
+License, and how they can obtain a copy of this License. You may not
+attempt to alter or restrict the recipients' rights in the Source Code
+Form.
+
+3.2. Distribution of Executable Form
+
+If You distribute Covered Software in Executable Form then:
+
+(a) such Covered Software must also be made available in Source Code
+ Form, as described in Section 3.1, and You must inform recipients of
+ the Executable Form how they can obtain a copy of such Source Code
+ Form by reasonable means in a timely manner, at a charge no more
+ than the cost of distribution to the recipient; and
+
+(b) You may distribute such Executable Form under the terms of this
+ License, or sublicense it under different terms, provided that the
+ license for the Executable Form does not attempt to limit or alter
+ the recipients' rights in the Source Code Form under this License.
+
+3.3. Distribution of a Larger Work
+
+You may create and distribute a Larger Work under terms of Your choice,
+provided that You also comply with the requirements of this License for
+the Covered Software. If the Larger Work is a combination of Covered
+Software with a work governed by one or more Secondary Licenses, and the
+Covered Software is not Incompatible With Secondary Licenses, this
+License permits You to additionally distribute such Covered Software
+under the terms of such Secondary License(s), so that the recipient of
+the Larger Work may, at their option, further distribute the Covered
+Software under the terms of either this License or such Secondary
+License(s).
+
+3.4. Notices
+
+You may not remove or alter the substance of any license notices
+(including copyright notices, patent notices, disclaimers of warranty,
+or limitations of liability) contained within the Source Code Form of
+the Covered Software, except that You may alter any license notices to
+the extent required to remedy known factual inaccuracies.
+
+3.5. Application of Additional Terms
+
+You may choose to offer, and to charge a fee for, warranty, support,
+indemnity or liability obligations to one or more recipients of Covered
+Software. However, You may do so only on Your own behalf, and not on
+behalf of any Contributor. You must make it absolutely clear that any
+such warranty, support, indemnity, or liability obligation is offered by
+You alone, and You hereby agree to indemnify every Contributor for any
+liability incurred by such Contributor as a result of warranty, support,
+indemnity or liability terms You offer. You may include additional
+disclaimers of warranty and limitations of liability specific to any
+jurisdiction.
+
+4. Inability to Comply Due to Statute or Regulation
+---------------------------------------------------
+
+If it is impossible for You to comply with any of the terms of this
+License with respect to some or all of the Covered Software due to
+statute, judicial order, or regulation then You must: (a) comply with
+the terms of this License to the maximum extent possible; and (b)
+describe the limitations and the code they affect. Such description must
+be placed in a text file included with all distributions of the Covered
+Software under this License. Except to the extent prohibited by statute
+or regulation, such description must be sufficiently detailed for a
+recipient of ordinary skill to be able to understand it.
+
+5. Termination
+--------------
+
+5.1. The rights granted under this License will terminate automatically
+if You fail to comply with any of its terms. However, if You become
+compliant, then the rights granted under this License from a particular
+Contributor are reinstated (a) provisionally, unless and until such
+Contributor explicitly and finally terminates Your grants, and (b) on an
+ongoing basis, if such Contributor fails to notify You of the
+non-compliance by some reasonable means prior to 60 days after You have
+come back into compliance. Moreover, Your grants from a particular
+Contributor are reinstated on an ongoing basis if such Contributor
+notifies You of the non-compliance by some reasonable means, this is the
+first time You have received notice of non-compliance with this License
+from such Contributor, and You become compliant prior to 30 days after
+Your receipt of the notice.
+
+5.2. If You initiate litigation against any entity by asserting a patent
+infringement claim (excluding declaratory judgment actions,
+counter-claims, and cross-claims) alleging that a Contributor Version
+directly or indirectly infringes any patent, then the rights granted to
+You by any and all Contributors for the Covered Software under Section
+2.1 of this License shall terminate.
+
+5.3. In the event of termination under Sections 5.1 or 5.2 above, all
+end user license agreements (excluding distributors and resellers) which
+have been validly granted by You or Your distributors under this License
+prior to termination shall survive termination.
+
+************************************************************************
+* *
+* 6. Disclaimer of Warranty *
+* ------------------------- *
+* *
+* Covered Software is provided under this License on an "as is" *
+* basis, without warranty of any kind, either expressed, implied, or *
+* statutory, including, without limitation, warranties that the *
+* Covered Software is free of defects, merchantable, fit for a *
+* particular purpose or non-infringing. The entire risk as to the *
+* quality and performance of the Covered Software is with You. *
+* Should any Covered Software prove defective in any respect, You *
+* (not any Contributor) assume the cost of any necessary servicing, *
+* repair, or correction. This disclaimer of warranty constitutes an *
+* essential part of this License. No use of any Covered Software is *
+* authorized under this License except under this disclaimer. *
+* *
+************************************************************************
+
+************************************************************************
+* *
+* 7. Limitation of Liability *
+* -------------------------- *
+* *
+* Under no circumstances and under no legal theory, whether tort *
+* (including negligence), contract, or otherwise, shall any *
+* Contributor, or anyone who distributes Covered Software as *
+* permitted above, be liable to You for any direct, indirect, *
+* special, incidental, or consequential damages of any character *
+* including, without limitation, damages for lost profits, loss of *
+* goodwill, work stoppage, computer failure or malfunction, or any *
+* and all other commercial damages or losses, even if such party *
+* shall have been informed of the possibility of such damages. This *
+* limitation of liability shall not apply to liability for death or *
+* personal injury resulting from such party's negligence to the *
+* extent applicable law prohibits such limitation. Some *
+* jurisdictions do not allow the exclusion or limitation of *
+* incidental or consequential damages, so this exclusion and *
+* limitation may not apply to You. *
+* *
+************************************************************************
+
+8. Litigation
+-------------
+
+Any litigation relating to this License may be brought only in the
+courts of a jurisdiction where the defendant maintains its principal
+place of business and such litigation shall be governed by laws of that
+jurisdiction, without reference to its conflict-of-law provisions.
+Nothing in this Section shall prevent a party's ability to bring
+cross-claims or counter-claims.
+
+9. Miscellaneous
+----------------
+
+This License represents the complete agreement concerning the subject
+matter hereof. If any provision of this License is held to be
+unenforceable, such provision shall be reformed only to the extent
+necessary to make it enforceable. Any law or regulation which provides
+that the language of a contract shall be construed against the drafter
+shall not be used to construe this License against a Contributor.
+
+10. Versions of the License
+---------------------------
+
+10.1. New Versions
+
+Mozilla Foundation is the license steward. Except as provided in Section
+10.3, no one other than the license steward has the right to modify or
+publish new versions of this License. Each version will be given a
+distinguishing version number.
+
+10.2. Effect of New Versions
+
+You may distribute the Covered Software under the terms of the version
+of the License under which You originally received the Covered Software,
+or under the terms of any subsequent version published by the license
+steward.
+
+10.3. Modified Versions
+
+If you create software not governed by this License, and you want to
+create a new license for such software, you may create and use a
+modified version of this License if you rename the license and remove
+any references to the name of the license steward (except to note that
+such modified license differs from this License).
+
+10.4. Distributing Source Code Form that is Incompatible With Secondary
+Licenses
+
+If You choose to distribute Source Code Form that is Incompatible With
+Secondary Licenses under the terms of this version of the License, the
+notice described in Exhibit B of this License must be attached.
+
+Exhibit A - Source Code Form License Notice
+-------------------------------------------
+
+ This Source Code Form is subject to the terms of the Mozilla Public
+ License, v. 2.0. If a copy of the MPL was not distributed with this
+ file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+If it is not possible or desirable to put the notice in a particular
+file, then You may include the notice in a location (such as a LICENSE
+file in a relevant directory) where a recipient would be likely to look
+for such a notice.
+
+You may add additional accurate notices of copyright ownership.
+
+Exhibit B - "Incompatible With Secondary Licenses" Notice
+---------------------------------------------------------
+
+ This Source Code Form is "Incompatible With Secondary Licenses", as
+ defined by the Mozilla Public License, v. 2.0.
diff --git a/vendor/github.com/go-sql-driver/mysql/README.md b/vendor/github.com/go-sql-driver/mysql/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..2e9b07eeb281f780351f5af6ffe1e8a98f870f61
--- /dev/null
+++ b/vendor/github.com/go-sql-driver/mysql/README.md
@@ -0,0 +1,490 @@
+# Go-MySQL-Driver
+
+A MySQL-Driver for Go's [database/sql](https://golang.org/pkg/database/sql/) package
+
+
+
+---------------------------------------
+ * [Features](#features)
+ * [Requirements](#requirements)
+ * [Installation](#installation)
+ * [Usage](#usage)
+ * [DSN (Data Source Name)](#dsn-data-source-name)
+ * [Password](#password)
+ * [Protocol](#protocol)
+ * [Address](#address)
+ * [Parameters](#parameters)
+ * [Examples](#examples)
+ * [Connection pool and timeouts](#connection-pool-and-timeouts)
+ * [context.Context Support](#contextcontext-support)
+ * [ColumnType Support](#columntype-support)
+ * [LOAD DATA LOCAL INFILE support](#load-data-local-infile-support)
+ * [time.Time support](#timetime-support)
+ * [Unicode support](#unicode-support)
+ * [Testing / Development](#testing--development)
+ * [License](#license)
+
+---------------------------------------
+
+## Features
+ * Lightweight and [fast](https://github.com/go-sql-driver/sql-benchmark "golang MySQL-Driver performance")
+ * Native Go implementation. No C-bindings, just pure Go
+ * Connections over TCP/IPv4, TCP/IPv6, Unix domain sockets or [custom protocols](https://godoc.org/github.com/go-sql-driver/mysql#DialFunc)
+ * Automatic handling of broken connections
+ * Automatic Connection Pooling *(by database/sql package)*
+ * Supports queries larger than 16MB
+ * Full [`sql.RawBytes`](https://golang.org/pkg/database/sql/#RawBytes) support.
+ * Intelligent `LONG DATA` handling in prepared statements
+ * Secure `LOAD DATA LOCAL INFILE` support with file Whitelisting and `io.Reader` support
+ * Optional `time.Time` parsing
+ * Optional placeholder interpolation
+
+## Requirements
+ * Go 1.7 or higher. We aim to support the 3 latest versions of Go.
+ * MySQL (4.1+), MariaDB, Percona Server, Google CloudSQL or Sphinx (2.2.3+)
+
+---------------------------------------
+
+## Installation
+Simple install the package to your [$GOPATH](https://github.com/golang/go/wiki/GOPATH "GOPATH") with the [go tool](https://golang.org/cmd/go/ "go command") from shell:
+```bash
+$ go get -u github.com/go-sql-driver/mysql
+```
+Make sure [Git is installed](https://git-scm.com/downloads) on your machine and in your system's `PATH`.
+
+## Usage
+_Go MySQL Driver_ is an implementation of Go's `database/sql/driver` interface. You only need to import the driver and can use the full [`database/sql`](https://golang.org/pkg/database/sql/) API then.
+
+Use `mysql` as `driverName` and a valid [DSN](#dsn-data-source-name) as `dataSourceName`:
+```go
+import "database/sql"
+import _ "github.com/go-sql-driver/mysql"
+
+db, err := sql.Open("mysql", "user:password@/dbname")
+```
+
+[Examples are available in our Wiki](https://github.com/go-sql-driver/mysql/wiki/Examples "Go-MySQL-Driver Examples").
+
+
+### DSN (Data Source Name)
+
+The Data Source Name has a common format, like e.g. [PEAR DB](http://pear.php.net/manual/en/package.database.db.intro-dsn.php) uses it, but without type-prefix (optional parts marked by squared brackets):
+```
+[username[:password]@][protocol[(address)]]/dbname[?param1=value1&...¶mN=valueN]
+```
+
+A DSN in its fullest form:
+```
+username:password@protocol(address)/dbname?param=value
+```
+
+Except for the databasename, all values are optional. So the minimal DSN is:
+```
+/dbname
+```
+
+If you do not want to preselect a database, leave `dbname` empty:
+```
+/
+```
+This has the same effect as an empty DSN string:
+```
+
+```
+
+Alternatively, [Config.FormatDSN](https://godoc.org/github.com/go-sql-driver/mysql#Config.FormatDSN) can be used to create a DSN string by filling a struct.
+
+#### Password
+Passwords can consist of any character. Escaping is **not** necessary.
+
+#### Protocol
+See [net.Dial](https://golang.org/pkg/net/#Dial) for more information which networks are available.
+In general you should use an Unix domain socket if available and TCP otherwise for best performance.
+
+#### Address
+For TCP and UDP networks, addresses have the form `host[:port]`.
+If `port` is omitted, the default port will be used.
+If `host` is a literal IPv6 address, it must be enclosed in square brackets.
+The functions [net.JoinHostPort](https://golang.org/pkg/net/#JoinHostPort) and [net.SplitHostPort](https://golang.org/pkg/net/#SplitHostPort) manipulate addresses in this form.
+
+For Unix domain sockets the address is the absolute path to the MySQL-Server-socket, e.g. `/var/run/mysqld/mysqld.sock` or `/tmp/mysql.sock`.
+
+#### Parameters
+*Parameters are case-sensitive!*
+
+Notice that any of `true`, `TRUE`, `True` or `1` is accepted to stand for a true boolean value. Not surprisingly, false can be specified as any of: `false`, `FALSE`, `False` or `0`.
+
+##### `allowAllFiles`
+
+```
+Type: bool
+Valid Values: true, false
+Default: false
+```
+
+`allowAllFiles=true` disables the file Whitelist for `LOAD DATA LOCAL INFILE` and allows *all* files.
+[*Might be insecure!*](http://dev.mysql.com/doc/refman/5.7/en/load-data-local.html)
+
+##### `allowCleartextPasswords`
+
+```
+Type: bool
+Valid Values: true, false
+Default: false
+```
+
+`allowCleartextPasswords=true` allows using the [cleartext client side plugin](http://dev.mysql.com/doc/en/cleartext-authentication-plugin.html) if required by an account, such as one defined with the [PAM authentication plugin](http://dev.mysql.com/doc/en/pam-authentication-plugin.html). Sending passwords in clear text may be a security problem in some configurations. To avoid problems if there is any possibility that the password would be intercepted, clients should connect to MySQL Server using a method that protects the password. Possibilities include [TLS / SSL](#tls), IPsec, or a private network.
+
+##### `allowNativePasswords`
+
+```
+Type: bool
+Valid Values: true, false
+Default: true
+```
+`allowNativePasswords=false` disallows the usage of MySQL native password method.
+
+##### `allowOldPasswords`
+
+```
+Type: bool
+Valid Values: true, false
+Default: false
+```
+`allowOldPasswords=true` allows the usage of the insecure old password method. This should be avoided, but is necessary in some cases. See also [the old_passwords wiki page](https://github.com/go-sql-driver/mysql/wiki/old_passwords).
+
+##### `charset`
+
+```
+Type: string
+Valid Values:
+Default: none
+```
+
+Sets the charset used for client-server interaction (`"SET NAMES "`). If multiple charsets are set (separated by a comma), the following charset is used if setting the charset failes. This enables for example support for `utf8mb4` ([introduced in MySQL 5.5.3](http://dev.mysql.com/doc/refman/5.5/en/charset-unicode-utf8mb4.html)) with fallback to `utf8` for older servers (`charset=utf8mb4,utf8`).
+
+Usage of the `charset` parameter is discouraged because it issues additional queries to the server.
+Unless you need the fallback behavior, please use `collation` instead.
+
+##### `collation`
+
+```
+Type: string
+Valid Values:
+Default: utf8_general_ci
+```
+
+Sets the collation used for client-server interaction on connection. In contrast to `charset`, `collation` does not issue additional queries. If the specified collation is unavailable on the target server, the connection will fail.
+
+A list of valid charsets for a server is retrievable with `SHOW COLLATION`.
+
+##### `clientFoundRows`
+
+```
+Type: bool
+Valid Values: true, false
+Default: false
+```
+
+`clientFoundRows=true` causes an UPDATE to return the number of matching rows instead of the number of rows changed.
+
+##### `columnsWithAlias`
+
+```
+Type: bool
+Valid Values: true, false
+Default: false
+```
+
+When `columnsWithAlias` is true, calls to `sql.Rows.Columns()` will return the table alias and the column name separated by a dot. For example:
+
+```
+SELECT u.id FROM users as u
+```
+
+will return `u.id` instead of just `id` if `columnsWithAlias=true`.
+
+##### `interpolateParams`
+
+```
+Type: bool
+Valid Values: true, false
+Default: false
+```
+
+If `interpolateParams` is true, placeholders (`?`) in calls to `db.Query()` and `db.Exec()` are interpolated into a single query string with given parameters. This reduces the number of roundtrips, since the driver has to prepare a statement, execute it with given parameters and close the statement again with `interpolateParams=false`.
+
+*This can not be used together with the multibyte encodings BIG5, CP932, GB2312, GBK or SJIS. These are blacklisted as they may [introduce a SQL injection vulnerability](http://stackoverflow.com/a/12118602/3430118)!*
+
+##### `loc`
+
+```
+Type: string
+Valid Values:
+Default: UTC
+```
+
+Sets the location for time.Time values (when using `parseTime=true`). *"Local"* sets the system's location. See [time.LoadLocation](https://golang.org/pkg/time/#LoadLocation) for details.
+
+Note that this sets the location for time.Time values but does not change MySQL's [time_zone setting](https://dev.mysql.com/doc/refman/5.5/en/time-zone-support.html). For that see the [time_zone system variable](#system-variables), which can also be set as a DSN parameter.
+
+Please keep in mind, that param values must be [url.QueryEscape](https://golang.org/pkg/net/url/#QueryEscape)'ed. Alternatively you can manually replace the `/` with `%2F`. For example `US/Pacific` would be `loc=US%2FPacific`.
+
+##### `maxAllowedPacket`
+```
+Type: decimal number
+Default: 4194304
+```
+
+Max packet size allowed in bytes. The default value is 4 MiB and should be adjusted to match the server settings. `maxAllowedPacket=0` can be used to automatically fetch the `max_allowed_packet` variable from server *on every connection*.
+
+##### `multiStatements`
+
+```
+Type: bool
+Valid Values: true, false
+Default: false
+```
+
+Allow multiple statements in one query. While this allows batch queries, it also greatly increases the risk of SQL injections. Only the result of the first query is returned, all other results are silently discarded.
+
+When `multiStatements` is used, `?` parameters must only be used in the first statement.
+
+##### `parseTime`
+
+```
+Type: bool
+Valid Values: true, false
+Default: false
+```
+
+`parseTime=true` changes the output type of `DATE` and `DATETIME` values to `time.Time` instead of `[]byte` / `string`
+The date or datetime like `0000-00-00 00:00:00` is converted into zero value of `time.Time`.
+
+
+##### `readTimeout`
+
+```
+Type: duration
+Default: 0
+```
+
+I/O read timeout. The value must be a decimal number with a unit suffix (*"ms"*, *"s"*, *"m"*, *"h"*), such as *"30s"*, *"0.5m"* or *"1m30s"*.
+
+##### `rejectReadOnly`
+
+```
+Type: bool
+Valid Values: true, false
+Default: false
+```
+
+
+`rejectReadOnly=true` causes the driver to reject read-only connections. This
+is for a possible race condition during an automatic failover, where the mysql
+client gets connected to a read-only replica after the failover.
+
+Note that this should be a fairly rare case, as an automatic failover normally
+happens when the primary is down, and the race condition shouldn't happen
+unless it comes back up online as soon as the failover is kicked off. On the
+other hand, when this happens, a MySQL application can get stuck on a
+read-only connection until restarted. It is however fairly easy to reproduce,
+for example, using a manual failover on AWS Aurora's MySQL-compatible cluster.
+
+If you are not relying on read-only transactions to reject writes that aren't
+supposed to happen, setting this on some MySQL providers (such as AWS Aurora)
+is safer for failovers.
+
+Note that ERROR 1290 can be returned for a `read-only` server and this option will
+cause a retry for that error. However the same error number is used for some
+other cases. You should ensure your application will never cause an ERROR 1290
+except for `read-only` mode when enabling this option.
+
+
+##### `serverPubKey`
+
+```
+Type: string
+Valid Values:
+Default: none
+```
+
+Server public keys can be registered with [`mysql.RegisterServerPubKey`](https://godoc.org/github.com/go-sql-driver/mysql#RegisterServerPubKey), which can then be used by the assigned name in the DSN.
+Public keys are used to transmit encrypted data, e.g. for authentication.
+If the server's public key is known, it should be set manually to avoid expensive and potentially insecure transmissions of the public key from the server to the client each time it is required.
+
+
+##### `timeout`
+
+```
+Type: duration
+Default: OS default
+```
+
+Timeout for establishing connections, aka dial timeout. The value must be a decimal number with a unit suffix (*"ms"*, *"s"*, *"m"*, *"h"*), such as *"30s"*, *"0.5m"* or *"1m30s"*.
+
+
+##### `tls`
+
+```
+Type: bool / string
+Valid Values: true, false, skip-verify,
+Default: false
+```
+
+`tls=true` enables TLS / SSL encrypted connection to the server. Use `skip-verify` if you want to use a self-signed or invalid certificate (server side). Use a custom value registered with [`mysql.RegisterTLSConfig`](https://godoc.org/github.com/go-sql-driver/mysql#RegisterTLSConfig).
+
+
+##### `writeTimeout`
+
+```
+Type: duration
+Default: 0
+```
+
+I/O write timeout. The value must be a decimal number with a unit suffix (*"ms"*, *"s"*, *"m"*, *"h"*), such as *"30s"*, *"0.5m"* or *"1m30s"*.
+
+
+##### System Variables
+
+Any other parameters are interpreted as system variables:
+ * `=`: `SET =`
+ * `=`: `SET =`
+ * `=%27%27`: `SET =''`
+
+Rules:
+* The values for string variables must be quoted with `'`.
+* The values must also be [url.QueryEscape](http://golang.org/pkg/net/url/#QueryEscape)'ed!
+ (which implies values of string variables must be wrapped with `%27`).
+
+Examples:
+ * `autocommit=1`: `SET autocommit=1`
+ * [`time_zone=%27Europe%2FParis%27`](https://dev.mysql.com/doc/refman/5.5/en/time-zone-support.html): `SET time_zone='Europe/Paris'`
+ * [`tx_isolation=%27REPEATABLE-READ%27`](https://dev.mysql.com/doc/refman/5.5/en/server-system-variables.html#sysvar_tx_isolation): `SET tx_isolation='REPEATABLE-READ'`
+
+
+#### Examples
+```
+user@unix(/path/to/socket)/dbname
+```
+
+```
+root:pw@unix(/tmp/mysql.sock)/myDatabase?loc=Local
+```
+
+```
+user:password@tcp(localhost:5555)/dbname?tls=skip-verify&autocommit=true
+```
+
+Treat warnings as errors by setting the system variable [`sql_mode`](https://dev.mysql.com/doc/refman/5.7/en/sql-mode.html):
+```
+user:password@/dbname?sql_mode=TRADITIONAL
+```
+
+TCP via IPv6:
+```
+user:password@tcp([de:ad:be:ef::ca:fe]:80)/dbname?timeout=90s&collation=utf8mb4_unicode_ci
+```
+
+TCP on a remote host, e.g. Amazon RDS:
+```
+id:password@tcp(your-amazonaws-uri.com:3306)/dbname
+```
+
+Google Cloud SQL on App Engine (First Generation MySQL Server):
+```
+user@cloudsql(project-id:instance-name)/dbname
+```
+
+Google Cloud SQL on App Engine (Second Generation MySQL Server):
+```
+user@cloudsql(project-id:regionname:instance-name)/dbname
+```
+
+TCP using default port (3306) on localhost:
+```
+user:password@tcp/dbname?charset=utf8mb4,utf8&sys_var=esc%40ped
+```
+
+Use the default protocol (tcp) and host (localhost:3306):
+```
+user:password@/dbname
+```
+
+No Database preselected:
+```
+user:password@/
+```
+
+
+### Connection pool and timeouts
+The connection pool is managed by Go's database/sql package. For details on how to configure the size of the pool and how long connections stay in the pool see `*DB.SetMaxOpenConns`, `*DB.SetMaxIdleConns`, and `*DB.SetConnMaxLifetime` in the [database/sql documentation](https://golang.org/pkg/database/sql/). The read, write, and dial timeouts for each individual connection are configured with the DSN parameters [`readTimeout`](#readtimeout), [`writeTimeout`](#writetimeout), and [`timeout`](#timeout), respectively.
+
+## `ColumnType` Support
+This driver supports the [`ColumnType` interface](https://golang.org/pkg/database/sql/#ColumnType) introduced in Go 1.8, with the exception of [`ColumnType.Length()`](https://golang.org/pkg/database/sql/#ColumnType.Length), which is currently not supported.
+
+## `context.Context` Support
+Go 1.8 added `database/sql` support for `context.Context`. This driver supports query timeouts and cancellation via contexts.
+See [context support in the database/sql package](https://golang.org/doc/go1.8#database_sql) for more details.
+
+
+### `LOAD DATA LOCAL INFILE` support
+For this feature you need direct access to the package. Therefore you must change the import path (no `_`):
+```go
+import "github.com/go-sql-driver/mysql"
+```
+
+Files must be whitelisted by registering them with `mysql.RegisterLocalFile(filepath)` (recommended) or the Whitelist check must be deactivated by using the DSN parameter `allowAllFiles=true` ([*Might be insecure!*](http://dev.mysql.com/doc/refman/5.7/en/load-data-local.html)).
+
+To use a `io.Reader` a handler function must be registered with `mysql.RegisterReaderHandler(name, handler)` which returns a `io.Reader` or `io.ReadCloser`. The Reader is available with the filepath `Reader::` then. Choose different names for different handlers and `DeregisterReaderHandler` when you don't need it anymore.
+
+See the [godoc of Go-MySQL-Driver](https://godoc.org/github.com/go-sql-driver/mysql "golang mysql driver documentation") for details.
+
+
+### `time.Time` support
+The default internal output type of MySQL `DATE` and `DATETIME` values is `[]byte` which allows you to scan the value into a `[]byte`, `string` or `sql.RawBytes` variable in your program.
+
+However, many want to scan MySQL `DATE` and `DATETIME` values into `time.Time` variables, which is the logical opposite in Go to `DATE` and `DATETIME` in MySQL. You can do that by changing the internal output type from `[]byte` to `time.Time` with the DSN parameter `parseTime=true`. You can set the default [`time.Time` location](https://golang.org/pkg/time/#Location) with the `loc` DSN parameter.
+
+**Caution:** As of Go 1.1, this makes `time.Time` the only variable type you can scan `DATE` and `DATETIME` values into. This breaks for example [`sql.RawBytes` support](https://github.com/go-sql-driver/mysql/wiki/Examples#rawbytes).
+
+Alternatively you can use the [`NullTime`](https://godoc.org/github.com/go-sql-driver/mysql#NullTime) type as the scan destination, which works with both `time.Time` and `string` / `[]byte`.
+
+
+### Unicode support
+Since version 1.1 Go-MySQL-Driver automatically uses the collation `utf8_general_ci` by default.
+
+Other collations / charsets can be set using the [`collation`](#collation) DSN parameter.
+
+Version 1.0 of the driver recommended adding `&charset=utf8` (alias for `SET NAMES utf8`) to the DSN to enable proper UTF-8 support. This is not necessary anymore. The [`collation`](#collation) parameter should be preferred to set another collation / charset than the default.
+
+See http://dev.mysql.com/doc/refman/5.7/en/charset-unicode.html for more details on MySQL's Unicode support.
+
+## Testing / Development
+To run the driver tests you may need to adjust the configuration. See the [Testing Wiki-Page](https://github.com/go-sql-driver/mysql/wiki/Testing "Testing") for details.
+
+Go-MySQL-Driver is not feature-complete yet. Your help is very appreciated.
+If you want to contribute, you can work on an [open issue](https://github.com/go-sql-driver/mysql/issues?state=open) or review a [pull request](https://github.com/go-sql-driver/mysql/pulls).
+
+See the [Contribution Guidelines](https://github.com/go-sql-driver/mysql/blob/master/CONTRIBUTING.md) for details.
+
+---------------------------------------
+
+## License
+Go-MySQL-Driver is licensed under the [Mozilla Public License Version 2.0](https://raw.github.com/go-sql-driver/mysql/master/LICENSE)
+
+Mozilla summarizes the license scope as follows:
+> MPL: The copyleft applies to any files containing MPLed code.
+
+
+That means:
+ * You can **use** the **unchanged** source code both in private and commercially.
+ * When distributing, you **must publish** the source code of any **changed files** licensed under the MPL 2.0 under a) the MPL 2.0 itself or b) a compatible license (e.g. GPL 3.0 or Apache License 2.0).
+ * You **needn't publish** the source code of your library as long as the files licensed under the MPL 2.0 are **unchanged**.
+
+Please read the [MPL 2.0 FAQ](https://www.mozilla.org/en-US/MPL/2.0/FAQ/) if you have further questions regarding the license.
+
+You can read the full terms here: [LICENSE](https://raw.github.com/go-sql-driver/mysql/master/LICENSE).
+
+
+
diff --git a/vendor/github.com/go-sql-driver/mysql/appengine.go b/vendor/github.com/go-sql-driver/mysql/appengine.go
new file mode 100644
index 0000000000000000000000000000000000000000..be41f2ee6d7f87ee9153066a5afb2653e481071d
--- /dev/null
+++ b/vendor/github.com/go-sql-driver/mysql/appengine.go
@@ -0,0 +1,19 @@
+// Go MySQL Driver - A MySQL-Driver for Go's database/sql package
+//
+// Copyright 2013 The Go-MySQL-Driver Authors. All rights reserved.
+//
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this file,
+// You can obtain one at http://mozilla.org/MPL/2.0/.
+
+// +build appengine
+
+package mysql
+
+import (
+ "google.golang.org/appengine/cloudsql"
+)
+
+func init() {
+ RegisterDial("cloudsql", cloudsql.Dial)
+}
diff --git a/vendor/github.com/go-sql-driver/mysql/auth.go b/vendor/github.com/go-sql-driver/mysql/auth.go
new file mode 100644
index 0000000000000000000000000000000000000000..14f678a87b6652fbcdd4e1a8212a34bce4c4eb2f
--- /dev/null
+++ b/vendor/github.com/go-sql-driver/mysql/auth.go
@@ -0,0 +1,420 @@
+// Go MySQL Driver - A MySQL-Driver for Go's database/sql package
+//
+// Copyright 2018 The Go-MySQL-Driver Authors. All rights reserved.
+//
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this file,
+// You can obtain one at http://mozilla.org/MPL/2.0/.
+
+package mysql
+
+import (
+ "crypto/rand"
+ "crypto/rsa"
+ "crypto/sha1"
+ "crypto/sha256"
+ "crypto/x509"
+ "encoding/pem"
+ "sync"
+)
+
+// server pub keys registry
+var (
+ serverPubKeyLock sync.RWMutex
+ serverPubKeyRegistry map[string]*rsa.PublicKey
+)
+
+// RegisterServerPubKey registers a server RSA public key which can be used to
+// send data in a secure manner to the server without receiving the public key
+// in a potentially insecure way from the server first.
+// Registered keys can afterwards be used adding serverPubKey= to the DSN.
+//
+// Note: The provided rsa.PublicKey instance is exclusively owned by the driver
+// after registering it and may not be modified.
+//
+// data, err := ioutil.ReadFile("mykey.pem")
+// if err != nil {
+// log.Fatal(err)
+// }
+//
+// block, _ := pem.Decode(data)
+// if block == nil || block.Type != "PUBLIC KEY" {
+// log.Fatal("failed to decode PEM block containing public key")
+// }
+//
+// pub, err := x509.ParsePKIXPublicKey(block.Bytes)
+// if err != nil {
+// log.Fatal(err)
+// }
+//
+// if rsaPubKey, ok := pub.(*rsa.PublicKey); ok {
+// mysql.RegisterServerPubKey("mykey", rsaPubKey)
+// } else {
+// log.Fatal("not a RSA public key")
+// }
+//
+func RegisterServerPubKey(name string, pubKey *rsa.PublicKey) {
+ serverPubKeyLock.Lock()
+ if serverPubKeyRegistry == nil {
+ serverPubKeyRegistry = make(map[string]*rsa.PublicKey)
+ }
+
+ serverPubKeyRegistry[name] = pubKey
+ serverPubKeyLock.Unlock()
+}
+
+// DeregisterServerPubKey removes the public key registered with the given name.
+func DeregisterServerPubKey(name string) {
+ serverPubKeyLock.Lock()
+ if serverPubKeyRegistry != nil {
+ delete(serverPubKeyRegistry, name)
+ }
+ serverPubKeyLock.Unlock()
+}
+
+func getServerPubKey(name string) (pubKey *rsa.PublicKey) {
+ serverPubKeyLock.RLock()
+ if v, ok := serverPubKeyRegistry[name]; ok {
+ pubKey = v
+ }
+ serverPubKeyLock.RUnlock()
+ return
+}
+
+// Hash password using pre 4.1 (old password) method
+// https://github.com/atcurtis/mariadb/blob/master/mysys/my_rnd.c
+type myRnd struct {
+ seed1, seed2 uint32
+}
+
+const myRndMaxVal = 0x3FFFFFFF
+
+// Pseudo random number generator
+func newMyRnd(seed1, seed2 uint32) *myRnd {
+ return &myRnd{
+ seed1: seed1 % myRndMaxVal,
+ seed2: seed2 % myRndMaxVal,
+ }
+}
+
+// Tested to be equivalent to MariaDB's floating point variant
+// http://play.golang.org/p/QHvhd4qved
+// http://play.golang.org/p/RG0q4ElWDx
+func (r *myRnd) NextByte() byte {
+ r.seed1 = (r.seed1*3 + r.seed2) % myRndMaxVal
+ r.seed2 = (r.seed1 + r.seed2 + 33) % myRndMaxVal
+
+ return byte(uint64(r.seed1) * 31 / myRndMaxVal)
+}
+
+// Generate binary hash from byte string using insecure pre 4.1 method
+func pwHash(password []byte) (result [2]uint32) {
+ var add uint32 = 7
+ var tmp uint32
+
+ result[0] = 1345345333
+ result[1] = 0x12345671
+
+ for _, c := range password {
+ // skip spaces and tabs in password
+ if c == ' ' || c == '\t' {
+ continue
+ }
+
+ tmp = uint32(c)
+ result[0] ^= (((result[0] & 63) + add) * tmp) + (result[0] << 8)
+ result[1] += (result[1] << 8) ^ result[0]
+ add += tmp
+ }
+
+ // Remove sign bit (1<<31)-1)
+ result[0] &= 0x7FFFFFFF
+ result[1] &= 0x7FFFFFFF
+
+ return
+}
+
+// Hash password using insecure pre 4.1 method
+func scrambleOldPassword(scramble []byte, password string) []byte {
+ if len(password) == 0 {
+ return nil
+ }
+
+ scramble = scramble[:8]
+
+ hashPw := pwHash([]byte(password))
+ hashSc := pwHash(scramble)
+
+ r := newMyRnd(hashPw[0]^hashSc[0], hashPw[1]^hashSc[1])
+
+ var out [8]byte
+ for i := range out {
+ out[i] = r.NextByte() + 64
+ }
+
+ mask := r.NextByte()
+ for i := range out {
+ out[i] ^= mask
+ }
+
+ return out[:]
+}
+
+// Hash password using 4.1+ method (SHA1)
+func scramblePassword(scramble []byte, password string) []byte {
+ if len(password) == 0 {
+ return nil
+ }
+
+ // stage1Hash = SHA1(password)
+ crypt := sha1.New()
+ crypt.Write([]byte(password))
+ stage1 := crypt.Sum(nil)
+
+ // scrambleHash = SHA1(scramble + SHA1(stage1Hash))
+ // inner Hash
+ crypt.Reset()
+ crypt.Write(stage1)
+ hash := crypt.Sum(nil)
+
+ // outer Hash
+ crypt.Reset()
+ crypt.Write(scramble)
+ crypt.Write(hash)
+ scramble = crypt.Sum(nil)
+
+ // token = scrambleHash XOR stage1Hash
+ for i := range scramble {
+ scramble[i] ^= stage1[i]
+ }
+ return scramble
+}
+
+// Hash password using MySQL 8+ method (SHA256)
+func scrambleSHA256Password(scramble []byte, password string) []byte {
+ if len(password) == 0 {
+ return nil
+ }
+
+ // XOR(SHA256(password), SHA256(SHA256(SHA256(password)), scramble))
+
+ crypt := sha256.New()
+ crypt.Write([]byte(password))
+ message1 := crypt.Sum(nil)
+
+ crypt.Reset()
+ crypt.Write(message1)
+ message1Hash := crypt.Sum(nil)
+
+ crypt.Reset()
+ crypt.Write(message1Hash)
+ crypt.Write(scramble)
+ message2 := crypt.Sum(nil)
+
+ for i := range message1 {
+ message1[i] ^= message2[i]
+ }
+
+ return message1
+}
+
+func encryptPassword(password string, seed []byte, pub *rsa.PublicKey) ([]byte, error) {
+ plain := make([]byte, len(password)+1)
+ copy(plain, password)
+ for i := range plain {
+ j := i % len(seed)
+ plain[i] ^= seed[j]
+ }
+ sha1 := sha1.New()
+ return rsa.EncryptOAEP(sha1, rand.Reader, pub, plain, nil)
+}
+
+func (mc *mysqlConn) sendEncryptedPassword(seed []byte, pub *rsa.PublicKey) error {
+ enc, err := encryptPassword(mc.cfg.Passwd, seed, pub)
+ if err != nil {
+ return err
+ }
+ return mc.writeAuthSwitchPacket(enc)
+}
+
+func (mc *mysqlConn) auth(authData []byte, plugin string) ([]byte, error) {
+ switch plugin {
+ case "caching_sha2_password":
+ authResp := scrambleSHA256Password(authData, mc.cfg.Passwd)
+ return authResp, nil
+
+ case "mysql_old_password":
+ if !mc.cfg.AllowOldPasswords {
+ return nil, ErrOldPassword
+ }
+ // Note: there are edge cases where this should work but doesn't;
+ // this is currently "wontfix":
+ // https://github.com/go-sql-driver/mysql/issues/184
+ authResp := append(scrambleOldPassword(authData[:8], mc.cfg.Passwd), 0)
+ return authResp, nil
+
+ case "mysql_clear_password":
+ if !mc.cfg.AllowCleartextPasswords {
+ return nil, ErrCleartextPassword
+ }
+ // http://dev.mysql.com/doc/refman/5.7/en/cleartext-authentication-plugin.html
+ // http://dev.mysql.com/doc/refman/5.7/en/pam-authentication-plugin.html
+ return append([]byte(mc.cfg.Passwd), 0), nil
+
+ case "mysql_native_password":
+ if !mc.cfg.AllowNativePasswords {
+ return nil, ErrNativePassword
+ }
+ // https://dev.mysql.com/doc/internals/en/secure-password-authentication.html
+ // Native password authentication only need and will need 20-byte challenge.
+ authResp := scramblePassword(authData[:20], mc.cfg.Passwd)
+ return authResp, nil
+
+ case "sha256_password":
+ if len(mc.cfg.Passwd) == 0 {
+ return []byte{0}, nil
+ }
+ if mc.cfg.tls != nil || mc.cfg.Net == "unix" {
+ // write cleartext auth packet
+ return append([]byte(mc.cfg.Passwd), 0), nil
+ }
+
+ pubKey := mc.cfg.pubKey
+ if pubKey == nil {
+ // request public key from server
+ return []byte{1}, nil
+ }
+
+ // encrypted password
+ enc, err := encryptPassword(mc.cfg.Passwd, authData, pubKey)
+ return enc, err
+
+ default:
+ errLog.Print("unknown auth plugin:", plugin)
+ return nil, ErrUnknownPlugin
+ }
+}
+
+func (mc *mysqlConn) handleAuthResult(oldAuthData []byte, plugin string) error {
+ // Read Result Packet
+ authData, newPlugin, err := mc.readAuthResult()
+ if err != nil {
+ return err
+ }
+
+ // handle auth plugin switch, if requested
+ if newPlugin != "" {
+ // If CLIENT_PLUGIN_AUTH capability is not supported, no new cipher is
+ // sent and we have to keep using the cipher sent in the init packet.
+ if authData == nil {
+ authData = oldAuthData
+ } else {
+ // copy data from read buffer to owned slice
+ copy(oldAuthData, authData)
+ }
+
+ plugin = newPlugin
+
+ authResp, err := mc.auth(authData, plugin)
+ if err != nil {
+ return err
+ }
+ if err = mc.writeAuthSwitchPacket(authResp); err != nil {
+ return err
+ }
+
+ // Read Result Packet
+ authData, newPlugin, err = mc.readAuthResult()
+ if err != nil {
+ return err
+ }
+
+ // Do not allow to change the auth plugin more than once
+ if newPlugin != "" {
+ return ErrMalformPkt
+ }
+ }
+
+ switch plugin {
+
+ // https://insidemysql.com/preparing-your-community-connector-for-mysql-8-part-2-sha256/
+ case "caching_sha2_password":
+ switch len(authData) {
+ case 0:
+ return nil // auth successful
+ case 1:
+ switch authData[0] {
+ case cachingSha2PasswordFastAuthSuccess:
+ if err = mc.readResultOK(); err == nil {
+ return nil // auth successful
+ }
+
+ case cachingSha2PasswordPerformFullAuthentication:
+ if mc.cfg.tls != nil || mc.cfg.Net == "unix" {
+ // write cleartext auth packet
+ err = mc.writeAuthSwitchPacket(append([]byte(mc.cfg.Passwd), 0))
+ if err != nil {
+ return err
+ }
+ } else {
+ pubKey := mc.cfg.pubKey
+ if pubKey == nil {
+ // request public key from server
+ data := mc.buf.takeSmallBuffer(4 + 1)
+ data[4] = cachingSha2PasswordRequestPublicKey
+ mc.writePacket(data)
+
+ // parse public key
+ data, err := mc.readPacket()
+ if err != nil {
+ return err
+ }
+
+ block, _ := pem.Decode(data[1:])
+ pkix, err := x509.ParsePKIXPublicKey(block.Bytes)
+ if err != nil {
+ return err
+ }
+ pubKey = pkix.(*rsa.PublicKey)
+ }
+
+ // send encrypted password
+ err = mc.sendEncryptedPassword(oldAuthData, pubKey)
+ if err != nil {
+ return err
+ }
+ }
+ return mc.readResultOK()
+
+ default:
+ return ErrMalformPkt
+ }
+ default:
+ return ErrMalformPkt
+ }
+
+ case "sha256_password":
+ switch len(authData) {
+ case 0:
+ return nil // auth successful
+ default:
+ block, _ := pem.Decode(authData)
+ pub, err := x509.ParsePKIXPublicKey(block.Bytes)
+ if err != nil {
+ return err
+ }
+
+ // send encrypted password
+ err = mc.sendEncryptedPassword(oldAuthData, pub.(*rsa.PublicKey))
+ if err != nil {
+ return err
+ }
+ return mc.readResultOK()
+ }
+
+ default:
+ return nil // auth successful
+ }
+
+ return err
+}
diff --git a/vendor/github.com/go-sql-driver/mysql/buffer.go b/vendor/github.com/go-sql-driver/mysql/buffer.go
new file mode 100644
index 0000000000000000000000000000000000000000..eb4748bf448d65ee672198b651a4cc149ba8701d
--- /dev/null
+++ b/vendor/github.com/go-sql-driver/mysql/buffer.go
@@ -0,0 +1,147 @@
+// Go MySQL Driver - A MySQL-Driver for Go's database/sql package
+//
+// Copyright 2013 The Go-MySQL-Driver Authors. All rights reserved.
+//
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this file,
+// You can obtain one at http://mozilla.org/MPL/2.0/.
+
+package mysql
+
+import (
+ "io"
+ "net"
+ "time"
+)
+
+const defaultBufSize = 4096
+
+// A buffer which is used for both reading and writing.
+// This is possible since communication on each connection is synchronous.
+// In other words, we can't write and read simultaneously on the same connection.
+// The buffer is similar to bufio.Reader / Writer but zero-copy-ish
+// Also highly optimized for this particular use case.
+type buffer struct {
+ buf []byte
+ nc net.Conn
+ idx int
+ length int
+ timeout time.Duration
+}
+
+func newBuffer(nc net.Conn) buffer {
+ var b [defaultBufSize]byte
+ return buffer{
+ buf: b[:],
+ nc: nc,
+ }
+}
+
+// fill reads into the buffer until at least _need_ bytes are in it
+func (b *buffer) fill(need int) error {
+ n := b.length
+
+ // move existing data to the beginning
+ if n > 0 && b.idx > 0 {
+ copy(b.buf[0:n], b.buf[b.idx:])
+ }
+
+ // grow buffer if necessary
+ // TODO: let the buffer shrink again at some point
+ // Maybe keep the org buf slice and swap back?
+ if need > len(b.buf) {
+ // Round up to the next multiple of the default size
+ newBuf := make([]byte, ((need/defaultBufSize)+1)*defaultBufSize)
+ copy(newBuf, b.buf)
+ b.buf = newBuf
+ }
+
+ b.idx = 0
+
+ for {
+ if b.timeout > 0 {
+ if err := b.nc.SetReadDeadline(time.Now().Add(b.timeout)); err != nil {
+ return err
+ }
+ }
+
+ nn, err := b.nc.Read(b.buf[n:])
+ n += nn
+
+ switch err {
+ case nil:
+ if n < need {
+ continue
+ }
+ b.length = n
+ return nil
+
+ case io.EOF:
+ if n >= need {
+ b.length = n
+ return nil
+ }
+ return io.ErrUnexpectedEOF
+
+ default:
+ return err
+ }
+ }
+}
+
+// returns next N bytes from buffer.
+// The returned slice is only guaranteed to be valid until the next read
+func (b *buffer) readNext(need int) ([]byte, error) {
+ if b.length < need {
+ // refill
+ if err := b.fill(need); err != nil {
+ return nil, err
+ }
+ }
+
+ offset := b.idx
+ b.idx += need
+ b.length -= need
+ return b.buf[offset:b.idx], nil
+}
+
+// returns a buffer with the requested size.
+// If possible, a slice from the existing buffer is returned.
+// Otherwise a bigger buffer is made.
+// Only one buffer (total) can be used at a time.
+func (b *buffer) takeBuffer(length int) []byte {
+ if b.length > 0 {
+ return nil
+ }
+
+ // test (cheap) general case first
+ if length <= defaultBufSize || length <= cap(b.buf) {
+ return b.buf[:length]
+ }
+
+ if length < maxPacketSize {
+ b.buf = make([]byte, length)
+ return b.buf
+ }
+ return make([]byte, length)
+}
+
+// shortcut which can be used if the requested buffer is guaranteed to be
+// smaller than defaultBufSize
+// Only one buffer (total) can be used at a time.
+func (b *buffer) takeSmallBuffer(length int) []byte {
+ if b.length > 0 {
+ return nil
+ }
+ return b.buf[:length]
+}
+
+// takeCompleteBuffer returns the complete existing buffer.
+// This can be used if the necessary buffer size is unknown.
+// Only one buffer (total) can be used at a time.
+func (b *buffer) takeCompleteBuffer() []byte {
+ if b.length > 0 {
+ return nil
+ }
+ return b.buf
+}
diff --git a/vendor/github.com/go-sql-driver/mysql/collations.go b/vendor/github.com/go-sql-driver/mysql/collations.go
new file mode 100644
index 0000000000000000000000000000000000000000..136c9e4d1e91cd855486aef047dc3f623a5f1d7a
--- /dev/null
+++ b/vendor/github.com/go-sql-driver/mysql/collations.go
@@ -0,0 +1,251 @@
+// Go MySQL Driver - A MySQL-Driver for Go's database/sql package
+//
+// Copyright 2014 The Go-MySQL-Driver Authors. All rights reserved.
+//
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this file,
+// You can obtain one at http://mozilla.org/MPL/2.0/.
+
+package mysql
+
+const defaultCollation = "utf8_general_ci"
+const binaryCollation = "binary"
+
+// A list of available collations mapped to the internal ID.
+// To update this map use the following MySQL query:
+// SELECT COLLATION_NAME, ID FROM information_schema.COLLATIONS
+var collations = map[string]byte{
+ "big5_chinese_ci": 1,
+ "latin2_czech_cs": 2,
+ "dec8_swedish_ci": 3,
+ "cp850_general_ci": 4,
+ "latin1_german1_ci": 5,
+ "hp8_english_ci": 6,
+ "koi8r_general_ci": 7,
+ "latin1_swedish_ci": 8,
+ "latin2_general_ci": 9,
+ "swe7_swedish_ci": 10,
+ "ascii_general_ci": 11,
+ "ujis_japanese_ci": 12,
+ "sjis_japanese_ci": 13,
+ "cp1251_bulgarian_ci": 14,
+ "latin1_danish_ci": 15,
+ "hebrew_general_ci": 16,
+ "tis620_thai_ci": 18,
+ "euckr_korean_ci": 19,
+ "latin7_estonian_cs": 20,
+ "latin2_hungarian_ci": 21,
+ "koi8u_general_ci": 22,
+ "cp1251_ukrainian_ci": 23,
+ "gb2312_chinese_ci": 24,
+ "greek_general_ci": 25,
+ "cp1250_general_ci": 26,
+ "latin2_croatian_ci": 27,
+ "gbk_chinese_ci": 28,
+ "cp1257_lithuanian_ci": 29,
+ "latin5_turkish_ci": 30,
+ "latin1_german2_ci": 31,
+ "armscii8_general_ci": 32,
+ "utf8_general_ci": 33,
+ "cp1250_czech_cs": 34,
+ "ucs2_general_ci": 35,
+ "cp866_general_ci": 36,
+ "keybcs2_general_ci": 37,
+ "macce_general_ci": 38,
+ "macroman_general_ci": 39,
+ "cp852_general_ci": 40,
+ "latin7_general_ci": 41,
+ "latin7_general_cs": 42,
+ "macce_bin": 43,
+ "cp1250_croatian_ci": 44,
+ "utf8mb4_general_ci": 45,
+ "utf8mb4_bin": 46,
+ "latin1_bin": 47,
+ "latin1_general_ci": 48,
+ "latin1_general_cs": 49,
+ "cp1251_bin": 50,
+ "cp1251_general_ci": 51,
+ "cp1251_general_cs": 52,
+ "macroman_bin": 53,
+ "utf16_general_ci": 54,
+ "utf16_bin": 55,
+ "utf16le_general_ci": 56,
+ "cp1256_general_ci": 57,
+ "cp1257_bin": 58,
+ "cp1257_general_ci": 59,
+ "utf32_general_ci": 60,
+ "utf32_bin": 61,
+ "utf16le_bin": 62,
+ "binary": 63,
+ "armscii8_bin": 64,
+ "ascii_bin": 65,
+ "cp1250_bin": 66,
+ "cp1256_bin": 67,
+ "cp866_bin": 68,
+ "dec8_bin": 69,
+ "greek_bin": 70,
+ "hebrew_bin": 71,
+ "hp8_bin": 72,
+ "keybcs2_bin": 73,
+ "koi8r_bin": 74,
+ "koi8u_bin": 75,
+ "latin2_bin": 77,
+ "latin5_bin": 78,
+ "latin7_bin": 79,
+ "cp850_bin": 80,
+ "cp852_bin": 81,
+ "swe7_bin": 82,
+ "utf8_bin": 83,
+ "big5_bin": 84,
+ "euckr_bin": 85,
+ "gb2312_bin": 86,
+ "gbk_bin": 87,
+ "sjis_bin": 88,
+ "tis620_bin": 89,
+ "ucs2_bin": 90,
+ "ujis_bin": 91,
+ "geostd8_general_ci": 92,
+ "geostd8_bin": 93,
+ "latin1_spanish_ci": 94,
+ "cp932_japanese_ci": 95,
+ "cp932_bin": 96,
+ "eucjpms_japanese_ci": 97,
+ "eucjpms_bin": 98,
+ "cp1250_polish_ci": 99,
+ "utf16_unicode_ci": 101,
+ "utf16_icelandic_ci": 102,
+ "utf16_latvian_ci": 103,
+ "utf16_romanian_ci": 104,
+ "utf16_slovenian_ci": 105,
+ "utf16_polish_ci": 106,
+ "utf16_estonian_ci": 107,
+ "utf16_spanish_ci": 108,
+ "utf16_swedish_ci": 109,
+ "utf16_turkish_ci": 110,
+ "utf16_czech_ci": 111,
+ "utf16_danish_ci": 112,
+ "utf16_lithuanian_ci": 113,
+ "utf16_slovak_ci": 114,
+ "utf16_spanish2_ci": 115,
+ "utf16_roman_ci": 116,
+ "utf16_persian_ci": 117,
+ "utf16_esperanto_ci": 118,
+ "utf16_hungarian_ci": 119,
+ "utf16_sinhala_ci": 120,
+ "utf16_german2_ci": 121,
+ "utf16_croatian_ci": 122,
+ "utf16_unicode_520_ci": 123,
+ "utf16_vietnamese_ci": 124,
+ "ucs2_unicode_ci": 128,
+ "ucs2_icelandic_ci": 129,
+ "ucs2_latvian_ci": 130,
+ "ucs2_romanian_ci": 131,
+ "ucs2_slovenian_ci": 132,
+ "ucs2_polish_ci": 133,
+ "ucs2_estonian_ci": 134,
+ "ucs2_spanish_ci": 135,
+ "ucs2_swedish_ci": 136,
+ "ucs2_turkish_ci": 137,
+ "ucs2_czech_ci": 138,
+ "ucs2_danish_ci": 139,
+ "ucs2_lithuanian_ci": 140,
+ "ucs2_slovak_ci": 141,
+ "ucs2_spanish2_ci": 142,
+ "ucs2_roman_ci": 143,
+ "ucs2_persian_ci": 144,
+ "ucs2_esperanto_ci": 145,
+ "ucs2_hungarian_ci": 146,
+ "ucs2_sinhala_ci": 147,
+ "ucs2_german2_ci": 148,
+ "ucs2_croatian_ci": 149,
+ "ucs2_unicode_520_ci": 150,
+ "ucs2_vietnamese_ci": 151,
+ "ucs2_general_mysql500_ci": 159,
+ "utf32_unicode_ci": 160,
+ "utf32_icelandic_ci": 161,
+ "utf32_latvian_ci": 162,
+ "utf32_romanian_ci": 163,
+ "utf32_slovenian_ci": 164,
+ "utf32_polish_ci": 165,
+ "utf32_estonian_ci": 166,
+ "utf32_spanish_ci": 167,
+ "utf32_swedish_ci": 168,
+ "utf32_turkish_ci": 169,
+ "utf32_czech_ci": 170,
+ "utf32_danish_ci": 171,
+ "utf32_lithuanian_ci": 172,
+ "utf32_slovak_ci": 173,
+ "utf32_spanish2_ci": 174,
+ "utf32_roman_ci": 175,
+ "utf32_persian_ci": 176,
+ "utf32_esperanto_ci": 177,
+ "utf32_hungarian_ci": 178,
+ "utf32_sinhala_ci": 179,
+ "utf32_german2_ci": 180,
+ "utf32_croatian_ci": 181,
+ "utf32_unicode_520_ci": 182,
+ "utf32_vietnamese_ci": 183,
+ "utf8_unicode_ci": 192,
+ "utf8_icelandic_ci": 193,
+ "utf8_latvian_ci": 194,
+ "utf8_romanian_ci": 195,
+ "utf8_slovenian_ci": 196,
+ "utf8_polish_ci": 197,
+ "utf8_estonian_ci": 198,
+ "utf8_spanish_ci": 199,
+ "utf8_swedish_ci": 200,
+ "utf8_turkish_ci": 201,
+ "utf8_czech_ci": 202,
+ "utf8_danish_ci": 203,
+ "utf8_lithuanian_ci": 204,
+ "utf8_slovak_ci": 205,
+ "utf8_spanish2_ci": 206,
+ "utf8_roman_ci": 207,
+ "utf8_persian_ci": 208,
+ "utf8_esperanto_ci": 209,
+ "utf8_hungarian_ci": 210,
+ "utf8_sinhala_ci": 211,
+ "utf8_german2_ci": 212,
+ "utf8_croatian_ci": 213,
+ "utf8_unicode_520_ci": 214,
+ "utf8_vietnamese_ci": 215,
+ "utf8_general_mysql500_ci": 223,
+ "utf8mb4_unicode_ci": 224,
+ "utf8mb4_icelandic_ci": 225,
+ "utf8mb4_latvian_ci": 226,
+ "utf8mb4_romanian_ci": 227,
+ "utf8mb4_slovenian_ci": 228,
+ "utf8mb4_polish_ci": 229,
+ "utf8mb4_estonian_ci": 230,
+ "utf8mb4_spanish_ci": 231,
+ "utf8mb4_swedish_ci": 232,
+ "utf8mb4_turkish_ci": 233,
+ "utf8mb4_czech_ci": 234,
+ "utf8mb4_danish_ci": 235,
+ "utf8mb4_lithuanian_ci": 236,
+ "utf8mb4_slovak_ci": 237,
+ "utf8mb4_spanish2_ci": 238,
+ "utf8mb4_roman_ci": 239,
+ "utf8mb4_persian_ci": 240,
+ "utf8mb4_esperanto_ci": 241,
+ "utf8mb4_hungarian_ci": 242,
+ "utf8mb4_sinhala_ci": 243,
+ "utf8mb4_german2_ci": 244,
+ "utf8mb4_croatian_ci": 245,
+ "utf8mb4_unicode_520_ci": 246,
+ "utf8mb4_vietnamese_ci": 247,
+}
+
+// A blacklist of collations which is unsafe to interpolate parameters.
+// These multibyte encodings may contains 0x5c (`\`) in their trailing bytes.
+var unsafeCollations = map[string]bool{
+ "big5_chinese_ci": true,
+ "sjis_japanese_ci": true,
+ "gbk_chinese_ci": true,
+ "big5_bin": true,
+ "gb2312_bin": true,
+ "gbk_bin": true,
+ "sjis_bin": true,
+ "cp932_japanese_ci": true,
+ "cp932_bin": true,
+}
diff --git a/vendor/github.com/go-sql-driver/mysql/connection.go b/vendor/github.com/go-sql-driver/mysql/connection.go
new file mode 100644
index 0000000000000000000000000000000000000000..e57061412bc2d12afb4fc073e89fab41158cdb52
--- /dev/null
+++ b/vendor/github.com/go-sql-driver/mysql/connection.go
@@ -0,0 +1,461 @@
+// Go MySQL Driver - A MySQL-Driver for Go's database/sql package
+//
+// Copyright 2012 The Go-MySQL-Driver Authors. All rights reserved.
+//
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this file,
+// You can obtain one at http://mozilla.org/MPL/2.0/.
+
+package mysql
+
+import (
+ "database/sql/driver"
+ "io"
+ "net"
+ "strconv"
+ "strings"
+ "time"
+)
+
+// a copy of context.Context for Go 1.7 and earlier
+type mysqlContext interface {
+ Done() <-chan struct{}
+ Err() error
+
+ // defined in context.Context, but not used in this driver:
+ // Deadline() (deadline time.Time, ok bool)
+ // Value(key interface{}) interface{}
+}
+
+type mysqlConn struct {
+ buf buffer
+ netConn net.Conn
+ affectedRows uint64
+ insertId uint64
+ cfg *Config
+ maxAllowedPacket int
+ maxWriteSize int
+ writeTimeout time.Duration
+ flags clientFlag
+ status statusFlag
+ sequence uint8
+ parseTime bool
+
+ // for context support (Go 1.8+)
+ watching bool
+ watcher chan<- mysqlContext
+ closech chan struct{}
+ finished chan<- struct{}
+ canceled atomicError // set non-nil if conn is canceled
+ closed atomicBool // set when conn is closed, before closech is closed
+}
+
+// Handles parameters set in DSN after the connection is established
+func (mc *mysqlConn) handleParams() (err error) {
+ for param, val := range mc.cfg.Params {
+ switch param {
+ // Charset
+ case "charset":
+ charsets := strings.Split(val, ",")
+ for i := range charsets {
+ // ignore errors here - a charset may not exist
+ err = mc.exec("SET NAMES " + charsets[i])
+ if err == nil {
+ break
+ }
+ }
+ if err != nil {
+ return
+ }
+
+ // System Vars
+ default:
+ err = mc.exec("SET " + param + "=" + val + "")
+ if err != nil {
+ return
+ }
+ }
+ }
+
+ return
+}
+
+func (mc *mysqlConn) markBadConn(err error) error {
+ if mc == nil {
+ return err
+ }
+ if err != errBadConnNoWrite {
+ return err
+ }
+ return driver.ErrBadConn
+}
+
+func (mc *mysqlConn) Begin() (driver.Tx, error) {
+ return mc.begin(false)
+}
+
+func (mc *mysqlConn) begin(readOnly bool) (driver.Tx, error) {
+ if mc.closed.IsSet() {
+ errLog.Print(ErrInvalidConn)
+ return nil, driver.ErrBadConn
+ }
+ var q string
+ if readOnly {
+ q = "START TRANSACTION READ ONLY"
+ } else {
+ q = "START TRANSACTION"
+ }
+ err := mc.exec(q)
+ if err == nil {
+ return &mysqlTx{mc}, err
+ }
+ return nil, mc.markBadConn(err)
+}
+
+func (mc *mysqlConn) Close() (err error) {
+ // Makes Close idempotent
+ if !mc.closed.IsSet() {
+ err = mc.writeCommandPacket(comQuit)
+ }
+
+ mc.cleanup()
+
+ return
+}
+
+// Closes the network connection and unsets internal variables. Do not call this
+// function after successfully authentication, call Close instead. This function
+// is called before auth or on auth failure because MySQL will have already
+// closed the network connection.
+func (mc *mysqlConn) cleanup() {
+ if !mc.closed.TrySet(true) {
+ return
+ }
+
+ // Makes cleanup idempotent
+ close(mc.closech)
+ if mc.netConn == nil {
+ return
+ }
+ if err := mc.netConn.Close(); err != nil {
+ errLog.Print(err)
+ }
+}
+
+func (mc *mysqlConn) error() error {
+ if mc.closed.IsSet() {
+ if err := mc.canceled.Value(); err != nil {
+ return err
+ }
+ return ErrInvalidConn
+ }
+ return nil
+}
+
+func (mc *mysqlConn) Prepare(query string) (driver.Stmt, error) {
+ if mc.closed.IsSet() {
+ errLog.Print(ErrInvalidConn)
+ return nil, driver.ErrBadConn
+ }
+ // Send command
+ err := mc.writeCommandPacketStr(comStmtPrepare, query)
+ if err != nil {
+ return nil, mc.markBadConn(err)
+ }
+
+ stmt := &mysqlStmt{
+ mc: mc,
+ }
+
+ // Read Result
+ columnCount, err := stmt.readPrepareResultPacket()
+ if err == nil {
+ if stmt.paramCount > 0 {
+ if err = mc.readUntilEOF(); err != nil {
+ return nil, err
+ }
+ }
+
+ if columnCount > 0 {
+ err = mc.readUntilEOF()
+ }
+ }
+
+ return stmt, err
+}
+
+func (mc *mysqlConn) interpolateParams(query string, args []driver.Value) (string, error) {
+ // Number of ? should be same to len(args)
+ if strings.Count(query, "?") != len(args) {
+ return "", driver.ErrSkip
+ }
+
+ buf := mc.buf.takeCompleteBuffer()
+ if buf == nil {
+ // can not take the buffer. Something must be wrong with the connection
+ errLog.Print(ErrBusyBuffer)
+ return "", ErrInvalidConn
+ }
+ buf = buf[:0]
+ argPos := 0
+
+ for i := 0; i < len(query); i++ {
+ q := strings.IndexByte(query[i:], '?')
+ if q == -1 {
+ buf = append(buf, query[i:]...)
+ break
+ }
+ buf = append(buf, query[i:i+q]...)
+ i += q
+
+ arg := args[argPos]
+ argPos++
+
+ if arg == nil {
+ buf = append(buf, "NULL"...)
+ continue
+ }
+
+ switch v := arg.(type) {
+ case int64:
+ buf = strconv.AppendInt(buf, v, 10)
+ case float64:
+ buf = strconv.AppendFloat(buf, v, 'g', -1, 64)
+ case bool:
+ if v {
+ buf = append(buf, '1')
+ } else {
+ buf = append(buf, '0')
+ }
+ case time.Time:
+ if v.IsZero() {
+ buf = append(buf, "'0000-00-00'"...)
+ } else {
+ v := v.In(mc.cfg.Loc)
+ v = v.Add(time.Nanosecond * 500) // To round under microsecond
+ year := v.Year()
+ year100 := year / 100
+ year1 := year % 100
+ month := v.Month()
+ day := v.Day()
+ hour := v.Hour()
+ minute := v.Minute()
+ second := v.Second()
+ micro := v.Nanosecond() / 1000
+
+ buf = append(buf, []byte{
+ '\'',
+ digits10[year100], digits01[year100],
+ digits10[year1], digits01[year1],
+ '-',
+ digits10[month], digits01[month],
+ '-',
+ digits10[day], digits01[day],
+ ' ',
+ digits10[hour], digits01[hour],
+ ':',
+ digits10[minute], digits01[minute],
+ ':',
+ digits10[second], digits01[second],
+ }...)
+
+ if micro != 0 {
+ micro10000 := micro / 10000
+ micro100 := micro / 100 % 100
+ micro1 := micro % 100
+ buf = append(buf, []byte{
+ '.',
+ digits10[micro10000], digits01[micro10000],
+ digits10[micro100], digits01[micro100],
+ digits10[micro1], digits01[micro1],
+ }...)
+ }
+ buf = append(buf, '\'')
+ }
+ case []byte:
+ if v == nil {
+ buf = append(buf, "NULL"...)
+ } else {
+ buf = append(buf, "_binary'"...)
+ if mc.status&statusNoBackslashEscapes == 0 {
+ buf = escapeBytesBackslash(buf, v)
+ } else {
+ buf = escapeBytesQuotes(buf, v)
+ }
+ buf = append(buf, '\'')
+ }
+ case string:
+ buf = append(buf, '\'')
+ if mc.status&statusNoBackslashEscapes == 0 {
+ buf = escapeStringBackslash(buf, v)
+ } else {
+ buf = escapeStringQuotes(buf, v)
+ }
+ buf = append(buf, '\'')
+ default:
+ return "", driver.ErrSkip
+ }
+
+ if len(buf)+4 > mc.maxAllowedPacket {
+ return "", driver.ErrSkip
+ }
+ }
+ if argPos != len(args) {
+ return "", driver.ErrSkip
+ }
+ return string(buf), nil
+}
+
+func (mc *mysqlConn) Exec(query string, args []driver.Value) (driver.Result, error) {
+ if mc.closed.IsSet() {
+ errLog.Print(ErrInvalidConn)
+ return nil, driver.ErrBadConn
+ }
+ if len(args) != 0 {
+ if !mc.cfg.InterpolateParams {
+ return nil, driver.ErrSkip
+ }
+ // try to interpolate the parameters to save extra roundtrips for preparing and closing a statement
+ prepared, err := mc.interpolateParams(query, args)
+ if err != nil {
+ return nil, err
+ }
+ query = prepared
+ }
+ mc.affectedRows = 0
+ mc.insertId = 0
+
+ err := mc.exec(query)
+ if err == nil {
+ return &mysqlResult{
+ affectedRows: int64(mc.affectedRows),
+ insertId: int64(mc.insertId),
+ }, err
+ }
+ return nil, mc.markBadConn(err)
+}
+
+// Internal function to execute commands
+func (mc *mysqlConn) exec(query string) error {
+ // Send command
+ if err := mc.writeCommandPacketStr(comQuery, query); err != nil {
+ return mc.markBadConn(err)
+ }
+
+ // Read Result
+ resLen, err := mc.readResultSetHeaderPacket()
+ if err != nil {
+ return err
+ }
+
+ if resLen > 0 {
+ // columns
+ if err := mc.readUntilEOF(); err != nil {
+ return err
+ }
+
+ // rows
+ if err := mc.readUntilEOF(); err != nil {
+ return err
+ }
+ }
+
+ return mc.discardResults()
+}
+
+func (mc *mysqlConn) Query(query string, args []driver.Value) (driver.Rows, error) {
+ return mc.query(query, args)
+}
+
+func (mc *mysqlConn) query(query string, args []driver.Value) (*textRows, error) {
+ if mc.closed.IsSet() {
+ errLog.Print(ErrInvalidConn)
+ return nil, driver.ErrBadConn
+ }
+ if len(args) != 0 {
+ if !mc.cfg.InterpolateParams {
+ return nil, driver.ErrSkip
+ }
+ // try client-side prepare to reduce roundtrip
+ prepared, err := mc.interpolateParams(query, args)
+ if err != nil {
+ return nil, err
+ }
+ query = prepared
+ }
+ // Send command
+ err := mc.writeCommandPacketStr(comQuery, query)
+ if err == nil {
+ // Read Result
+ var resLen int
+ resLen, err = mc.readResultSetHeaderPacket()
+ if err == nil {
+ rows := new(textRows)
+ rows.mc = mc
+
+ if resLen == 0 {
+ rows.rs.done = true
+
+ switch err := rows.NextResultSet(); err {
+ case nil, io.EOF:
+ return rows, nil
+ default:
+ return nil, err
+ }
+ }
+
+ // Columns
+ rows.rs.columns, err = mc.readColumns(resLen)
+ return rows, err
+ }
+ }
+ return nil, mc.markBadConn(err)
+}
+
+// Gets the value of the given MySQL System Variable
+// The returned byte slice is only valid until the next read
+func (mc *mysqlConn) getSystemVar(name string) ([]byte, error) {
+ // Send command
+ if err := mc.writeCommandPacketStr(comQuery, "SELECT @@"+name); err != nil {
+ return nil, err
+ }
+
+ // Read Result
+ resLen, err := mc.readResultSetHeaderPacket()
+ if err == nil {
+ rows := new(textRows)
+ rows.mc = mc
+ rows.rs.columns = []mysqlField{{fieldType: fieldTypeVarChar}}
+
+ if resLen > 0 {
+ // Columns
+ if err := mc.readUntilEOF(); err != nil {
+ return nil, err
+ }
+ }
+
+ dest := make([]driver.Value, resLen)
+ if err = rows.readRow(dest); err == nil {
+ return dest[0].([]byte), mc.readUntilEOF()
+ }
+ }
+ return nil, err
+}
+
+// finish is called when the query has canceled.
+func (mc *mysqlConn) cancel(err error) {
+ mc.canceled.Set(err)
+ mc.cleanup()
+}
+
+// finish is called when the query has succeeded.
+func (mc *mysqlConn) finish() {
+ if !mc.watching || mc.finished == nil {
+ return
+ }
+ select {
+ case mc.finished <- struct{}{}:
+ mc.watching = false
+ case <-mc.closech:
+ }
+}
diff --git a/vendor/github.com/go-sql-driver/mysql/connection_go18.go b/vendor/github.com/go-sql-driver/mysql/connection_go18.go
new file mode 100644
index 0000000000000000000000000000000000000000..ce52c7d1671aa2b46409911555d0533063607e3f
--- /dev/null
+++ b/vendor/github.com/go-sql-driver/mysql/connection_go18.go
@@ -0,0 +1,207 @@
+// Go MySQL Driver - A MySQL-Driver for Go's database/sql package
+//
+// Copyright 2012 The Go-MySQL-Driver Authors. All rights reserved.
+//
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this file,
+// You can obtain one at http://mozilla.org/MPL/2.0/.
+
+// +build go1.8
+
+package mysql
+
+import (
+ "context"
+ "database/sql"
+ "database/sql/driver"
+)
+
+// Ping implements driver.Pinger interface
+func (mc *mysqlConn) Ping(ctx context.Context) (err error) {
+ if mc.closed.IsSet() {
+ errLog.Print(ErrInvalidConn)
+ return driver.ErrBadConn
+ }
+
+ if err = mc.watchCancel(ctx); err != nil {
+ return
+ }
+ defer mc.finish()
+
+ if err = mc.writeCommandPacket(comPing); err != nil {
+ return
+ }
+
+ return mc.readResultOK()
+}
+
+// BeginTx implements driver.ConnBeginTx interface
+func (mc *mysqlConn) BeginTx(ctx context.Context, opts driver.TxOptions) (driver.Tx, error) {
+ if err := mc.watchCancel(ctx); err != nil {
+ return nil, err
+ }
+ defer mc.finish()
+
+ if sql.IsolationLevel(opts.Isolation) != sql.LevelDefault {
+ level, err := mapIsolationLevel(opts.Isolation)
+ if err != nil {
+ return nil, err
+ }
+ err = mc.exec("SET TRANSACTION ISOLATION LEVEL " + level)
+ if err != nil {
+ return nil, err
+ }
+ }
+
+ return mc.begin(opts.ReadOnly)
+}
+
+func (mc *mysqlConn) QueryContext(ctx context.Context, query string, args []driver.NamedValue) (driver.Rows, error) {
+ dargs, err := namedValueToValue(args)
+ if err != nil {
+ return nil, err
+ }
+
+ if err := mc.watchCancel(ctx); err != nil {
+ return nil, err
+ }
+
+ rows, err := mc.query(query, dargs)
+ if err != nil {
+ mc.finish()
+ return nil, err
+ }
+ rows.finish = mc.finish
+ return rows, err
+}
+
+func (mc *mysqlConn) ExecContext(ctx context.Context, query string, args []driver.NamedValue) (driver.Result, error) {
+ dargs, err := namedValueToValue(args)
+ if err != nil {
+ return nil, err
+ }
+
+ if err := mc.watchCancel(ctx); err != nil {
+ return nil, err
+ }
+ defer mc.finish()
+
+ return mc.Exec(query, dargs)
+}
+
+func (mc *mysqlConn) PrepareContext(ctx context.Context, query string) (driver.Stmt, error) {
+ if err := mc.watchCancel(ctx); err != nil {
+ return nil, err
+ }
+
+ stmt, err := mc.Prepare(query)
+ mc.finish()
+ if err != nil {
+ return nil, err
+ }
+
+ select {
+ default:
+ case <-ctx.Done():
+ stmt.Close()
+ return nil, ctx.Err()
+ }
+ return stmt, nil
+}
+
+func (stmt *mysqlStmt) QueryContext(ctx context.Context, args []driver.NamedValue) (driver.Rows, error) {
+ dargs, err := namedValueToValue(args)
+ if err != nil {
+ return nil, err
+ }
+
+ if err := stmt.mc.watchCancel(ctx); err != nil {
+ return nil, err
+ }
+
+ rows, err := stmt.query(dargs)
+ if err != nil {
+ stmt.mc.finish()
+ return nil, err
+ }
+ rows.finish = stmt.mc.finish
+ return rows, err
+}
+
+func (stmt *mysqlStmt) ExecContext(ctx context.Context, args []driver.NamedValue) (driver.Result, error) {
+ dargs, err := namedValueToValue(args)
+ if err != nil {
+ return nil, err
+ }
+
+ if err := stmt.mc.watchCancel(ctx); err != nil {
+ return nil, err
+ }
+ defer stmt.mc.finish()
+
+ return stmt.Exec(dargs)
+}
+
+func (mc *mysqlConn) watchCancel(ctx context.Context) error {
+ if mc.watching {
+ // Reach here if canceled,
+ // so the connection is already invalid
+ mc.cleanup()
+ return nil
+ }
+ // When ctx is already cancelled, don't watch it.
+ if err := ctx.Err(); err != nil {
+ return err
+ }
+ // When ctx is not cancellable, don't watch it.
+ if ctx.Done() == nil {
+ return nil
+ }
+ // When watcher is not alive, can't watch it.
+ if mc.watcher == nil {
+ return nil
+ }
+
+ mc.watching = true
+ mc.watcher <- ctx
+ return nil
+}
+
+func (mc *mysqlConn) startWatcher() {
+ watcher := make(chan mysqlContext, 1)
+ mc.watcher = watcher
+ finished := make(chan struct{})
+ mc.finished = finished
+ go func() {
+ for {
+ var ctx mysqlContext
+ select {
+ case ctx = <-watcher:
+ case <-mc.closech:
+ return
+ }
+
+ select {
+ case <-ctx.Done():
+ mc.cancel(ctx.Err())
+ case <-finished:
+ case <-mc.closech:
+ return
+ }
+ }
+ }()
+}
+
+func (mc *mysqlConn) CheckNamedValue(nv *driver.NamedValue) (err error) {
+ nv.Value, err = converter{}.ConvertValue(nv.Value)
+ return
+}
+
+// ResetSession implements driver.SessionResetter.
+// (From Go 1.10)
+func (mc *mysqlConn) ResetSession(ctx context.Context) error {
+ if mc.closed.IsSet() {
+ return driver.ErrBadConn
+ }
+ return nil
+}
diff --git a/vendor/github.com/go-sql-driver/mysql/const.go b/vendor/github.com/go-sql-driver/mysql/const.go
new file mode 100644
index 0000000000000000000000000000000000000000..b1e6b85efcae4244d1028ef8054782838dca4144
--- /dev/null
+++ b/vendor/github.com/go-sql-driver/mysql/const.go
@@ -0,0 +1,174 @@
+// Go MySQL Driver - A MySQL-Driver for Go's database/sql package
+//
+// Copyright 2012 The Go-MySQL-Driver Authors. All rights reserved.
+//
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this file,
+// You can obtain one at http://mozilla.org/MPL/2.0/.
+
+package mysql
+
+const (
+ defaultAuthPlugin = "mysql_native_password"
+ defaultMaxAllowedPacket = 4 << 20 // 4 MiB
+ minProtocolVersion = 10
+ maxPacketSize = 1<<24 - 1
+ timeFormat = "2006-01-02 15:04:05.999999"
+)
+
+// MySQL constants documentation:
+// http://dev.mysql.com/doc/internals/en/client-server-protocol.html
+
+const (
+ iOK byte = 0x00
+ iAuthMoreData byte = 0x01
+ iLocalInFile byte = 0xfb
+ iEOF byte = 0xfe
+ iERR byte = 0xff
+)
+
+// https://dev.mysql.com/doc/internals/en/capability-flags.html#packet-Protocol::CapabilityFlags
+type clientFlag uint32
+
+const (
+ clientLongPassword clientFlag = 1 << iota
+ clientFoundRows
+ clientLongFlag
+ clientConnectWithDB
+ clientNoSchema
+ clientCompress
+ clientODBC
+ clientLocalFiles
+ clientIgnoreSpace
+ clientProtocol41
+ clientInteractive
+ clientSSL
+ clientIgnoreSIGPIPE
+ clientTransactions
+ clientReserved
+ clientSecureConn
+ clientMultiStatements
+ clientMultiResults
+ clientPSMultiResults
+ clientPluginAuth
+ clientConnectAttrs
+ clientPluginAuthLenEncClientData
+ clientCanHandleExpiredPasswords
+ clientSessionTrack
+ clientDeprecateEOF
+)
+
+const (
+ comQuit byte = iota + 1
+ comInitDB
+ comQuery
+ comFieldList
+ comCreateDB
+ comDropDB
+ comRefresh
+ comShutdown
+ comStatistics
+ comProcessInfo
+ comConnect
+ comProcessKill
+ comDebug
+ comPing
+ comTime
+ comDelayedInsert
+ comChangeUser
+ comBinlogDump
+ comTableDump
+ comConnectOut
+ comRegisterSlave
+ comStmtPrepare
+ comStmtExecute
+ comStmtSendLongData
+ comStmtClose
+ comStmtReset
+ comSetOption
+ comStmtFetch
+)
+
+// https://dev.mysql.com/doc/internals/en/com-query-response.html#packet-Protocol::ColumnType
+type fieldType byte
+
+const (
+ fieldTypeDecimal fieldType = iota
+ fieldTypeTiny
+ fieldTypeShort
+ fieldTypeLong
+ fieldTypeFloat
+ fieldTypeDouble
+ fieldTypeNULL
+ fieldTypeTimestamp
+ fieldTypeLongLong
+ fieldTypeInt24
+ fieldTypeDate
+ fieldTypeTime
+ fieldTypeDateTime
+ fieldTypeYear
+ fieldTypeNewDate
+ fieldTypeVarChar
+ fieldTypeBit
+)
+const (
+ fieldTypeJSON fieldType = iota + 0xf5
+ fieldTypeNewDecimal
+ fieldTypeEnum
+ fieldTypeSet
+ fieldTypeTinyBLOB
+ fieldTypeMediumBLOB
+ fieldTypeLongBLOB
+ fieldTypeBLOB
+ fieldTypeVarString
+ fieldTypeString
+ fieldTypeGeometry
+)
+
+type fieldFlag uint16
+
+const (
+ flagNotNULL fieldFlag = 1 << iota
+ flagPriKey
+ flagUniqueKey
+ flagMultipleKey
+ flagBLOB
+ flagUnsigned
+ flagZeroFill
+ flagBinary
+ flagEnum
+ flagAutoIncrement
+ flagTimestamp
+ flagSet
+ flagUnknown1
+ flagUnknown2
+ flagUnknown3
+ flagUnknown4
+)
+
+// http://dev.mysql.com/doc/internals/en/status-flags.html
+type statusFlag uint16
+
+const (
+ statusInTrans statusFlag = 1 << iota
+ statusInAutocommit
+ statusReserved // Not in documentation
+ statusMoreResultsExists
+ statusNoGoodIndexUsed
+ statusNoIndexUsed
+ statusCursorExists
+ statusLastRowSent
+ statusDbDropped
+ statusNoBackslashEscapes
+ statusMetadataChanged
+ statusQueryWasSlow
+ statusPsOutParams
+ statusInTransReadonly
+ statusSessionStateChanged
+)
+
+const (
+ cachingSha2PasswordRequestPublicKey = 2
+ cachingSha2PasswordFastAuthSuccess = 3
+ cachingSha2PasswordPerformFullAuthentication = 4
+)
diff --git a/vendor/github.com/go-sql-driver/mysql/driver.go b/vendor/github.com/go-sql-driver/mysql/driver.go
new file mode 100644
index 0000000000000000000000000000000000000000..e9ede2c8dad6a5bf6c491493dc607f694cf1461e
--- /dev/null
+++ b/vendor/github.com/go-sql-driver/mysql/driver.go
@@ -0,0 +1,172 @@
+// Copyright 2012 The Go-MySQL-Driver Authors. All rights reserved.
+//
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this file,
+// You can obtain one at http://mozilla.org/MPL/2.0/.
+
+// Package mysql provides a MySQL driver for Go's database/sql package.
+//
+// The driver should be used via the database/sql package:
+//
+// import "database/sql"
+// import _ "github.com/go-sql-driver/mysql"
+//
+// db, err := sql.Open("mysql", "user:password@/dbname")
+//
+// See https://github.com/go-sql-driver/mysql#usage for details
+package mysql
+
+import (
+ "database/sql"
+ "database/sql/driver"
+ "net"
+ "sync"
+)
+
+// watcher interface is used for context support (From Go 1.8)
+type watcher interface {
+ startWatcher()
+}
+
+// MySQLDriver is exported to make the driver directly accessible.
+// In general the driver is used via the database/sql package.
+type MySQLDriver struct{}
+
+// DialFunc is a function which can be used to establish the network connection.
+// Custom dial functions must be registered with RegisterDial
+type DialFunc func(addr string) (net.Conn, error)
+
+var (
+ dialsLock sync.RWMutex
+ dials map[string]DialFunc
+)
+
+// RegisterDial registers a custom dial function. It can then be used by the
+// network address mynet(addr), where mynet is the registered new network.
+// addr is passed as a parameter to the dial function.
+func RegisterDial(net string, dial DialFunc) {
+ dialsLock.Lock()
+ defer dialsLock.Unlock()
+ if dials == nil {
+ dials = make(map[string]DialFunc)
+ }
+ dials[net] = dial
+}
+
+// Open new Connection.
+// See https://github.com/go-sql-driver/mysql#dsn-data-source-name for how
+// the DSN string is formated
+func (d MySQLDriver) Open(dsn string) (driver.Conn, error) {
+ var err error
+
+ // New mysqlConn
+ mc := &mysqlConn{
+ maxAllowedPacket: maxPacketSize,
+ maxWriteSize: maxPacketSize - 1,
+ closech: make(chan struct{}),
+ }
+ mc.cfg, err = ParseDSN(dsn)
+ if err != nil {
+ return nil, err
+ }
+ mc.parseTime = mc.cfg.ParseTime
+
+ // Connect to Server
+ dialsLock.RLock()
+ dial, ok := dials[mc.cfg.Net]
+ dialsLock.RUnlock()
+ if ok {
+ mc.netConn, err = dial(mc.cfg.Addr)
+ } else {
+ nd := net.Dialer{Timeout: mc.cfg.Timeout}
+ mc.netConn, err = nd.Dial(mc.cfg.Net, mc.cfg.Addr)
+ }
+ if err != nil {
+ return nil, err
+ }
+
+ // Enable TCP Keepalives on TCP connections
+ if tc, ok := mc.netConn.(*net.TCPConn); ok {
+ if err := tc.SetKeepAlive(true); err != nil {
+ // Don't send COM_QUIT before handshake.
+ mc.netConn.Close()
+ mc.netConn = nil
+ return nil, err
+ }
+ }
+
+ // Call startWatcher for context support (From Go 1.8)
+ if s, ok := interface{}(mc).(watcher); ok {
+ s.startWatcher()
+ }
+
+ mc.buf = newBuffer(mc.netConn)
+
+ // Set I/O timeouts
+ mc.buf.timeout = mc.cfg.ReadTimeout
+ mc.writeTimeout = mc.cfg.WriteTimeout
+
+ // Reading Handshake Initialization Packet
+ authData, plugin, err := mc.readHandshakePacket()
+ if err != nil {
+ mc.cleanup()
+ return nil, err
+ }
+ if plugin == "" {
+ plugin = defaultAuthPlugin
+ }
+
+ // Send Client Authentication Packet
+ authResp, err := mc.auth(authData, plugin)
+ if err != nil {
+ // try the default auth plugin, if using the requested plugin failed
+ errLog.Print("could not use requested auth plugin '"+plugin+"': ", err.Error())
+ plugin = defaultAuthPlugin
+ authResp, err = mc.auth(authData, plugin)
+ if err != nil {
+ mc.cleanup()
+ return nil, err
+ }
+ }
+ if err = mc.writeHandshakeResponsePacket(authResp, plugin); err != nil {
+ mc.cleanup()
+ return nil, err
+ }
+
+ // Handle response to auth packet, switch methods if possible
+ if err = mc.handleAuthResult(authData, plugin); err != nil {
+ // Authentication failed and MySQL has already closed the connection
+ // (https://dev.mysql.com/doc/internals/en/authentication-fails.html).
+ // Do not send COM_QUIT, just cleanup and return the error.
+ mc.cleanup()
+ return nil, err
+ }
+
+ if mc.cfg.MaxAllowedPacket > 0 {
+ mc.maxAllowedPacket = mc.cfg.MaxAllowedPacket
+ } else {
+ // Get max allowed packet size
+ maxap, err := mc.getSystemVar("max_allowed_packet")
+ if err != nil {
+ mc.Close()
+ return nil, err
+ }
+ mc.maxAllowedPacket = stringToInt(maxap) - 1
+ }
+ if mc.maxAllowedPacket < maxPacketSize {
+ mc.maxWriteSize = mc.maxAllowedPacket
+ }
+
+ // Handle DSN Params
+ err = mc.handleParams()
+ if err != nil {
+ mc.Close()
+ return nil, err
+ }
+
+ return mc, nil
+}
+
+func init() {
+ sql.Register("mysql", &MySQLDriver{})
+}
diff --git a/vendor/github.com/go-sql-driver/mysql/dsn.go b/vendor/github.com/go-sql-driver/mysql/dsn.go
new file mode 100644
index 0000000000000000000000000000000000000000..be014babe3335703c74b93c4f0d3e74f6534bb5e
--- /dev/null
+++ b/vendor/github.com/go-sql-driver/mysql/dsn.go
@@ -0,0 +1,611 @@
+// Go MySQL Driver - A MySQL-Driver for Go's database/sql package
+//
+// Copyright 2016 The Go-MySQL-Driver Authors. All rights reserved.
+//
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this file,
+// You can obtain one at http://mozilla.org/MPL/2.0/.
+
+package mysql
+
+import (
+ "bytes"
+ "crypto/rsa"
+ "crypto/tls"
+ "errors"
+ "fmt"
+ "net"
+ "net/url"
+ "sort"
+ "strconv"
+ "strings"
+ "time"
+)
+
+var (
+ errInvalidDSNUnescaped = errors.New("invalid DSN: did you forget to escape a param value?")
+ errInvalidDSNAddr = errors.New("invalid DSN: network address not terminated (missing closing brace)")
+ errInvalidDSNNoSlash = errors.New("invalid DSN: missing the slash separating the database name")
+ errInvalidDSNUnsafeCollation = errors.New("invalid DSN: interpolateParams can not be used with unsafe collations")
+)
+
+// Config is a configuration parsed from a DSN string.
+// If a new Config is created instead of being parsed from a DSN string,
+// the NewConfig function should be used, which sets default values.
+type Config struct {
+ User string // Username
+ Passwd string // Password (requires User)
+ Net string // Network type
+ Addr string // Network address (requires Net)
+ DBName string // Database name
+ Params map[string]string // Connection parameters
+ Collation string // Connection collation
+ Loc *time.Location // Location for time.Time values
+ MaxAllowedPacket int // Max packet size allowed
+ ServerPubKey string // Server public key name
+ pubKey *rsa.PublicKey // Server public key
+ TLSConfig string // TLS configuration name
+ tls *tls.Config // TLS configuration
+ Timeout time.Duration // Dial timeout
+ ReadTimeout time.Duration // I/O read timeout
+ WriteTimeout time.Duration // I/O write timeout
+
+ AllowAllFiles bool // Allow all files to be used with LOAD DATA LOCAL INFILE
+ AllowCleartextPasswords bool // Allows the cleartext client side plugin
+ AllowNativePasswords bool // Allows the native password authentication method
+ AllowOldPasswords bool // Allows the old insecure password method
+ ClientFoundRows bool // Return number of matching rows instead of rows changed
+ ColumnsWithAlias bool // Prepend table alias to column names
+ InterpolateParams bool // Interpolate placeholders into query string
+ MultiStatements bool // Allow multiple statements in one query
+ ParseTime bool // Parse time values to time.Time
+ RejectReadOnly bool // Reject read-only connections
+}
+
+// NewConfig creates a new Config and sets default values.
+func NewConfig() *Config {
+ return &Config{
+ Collation: defaultCollation,
+ Loc: time.UTC,
+ MaxAllowedPacket: defaultMaxAllowedPacket,
+ AllowNativePasswords: true,
+ }
+}
+
+func (cfg *Config) normalize() error {
+ if cfg.InterpolateParams && unsafeCollations[cfg.Collation] {
+ return errInvalidDSNUnsafeCollation
+ }
+
+ // Set default network if empty
+ if cfg.Net == "" {
+ cfg.Net = "tcp"
+ }
+
+ // Set default address if empty
+ if cfg.Addr == "" {
+ switch cfg.Net {
+ case "tcp":
+ cfg.Addr = "127.0.0.1:3306"
+ case "unix":
+ cfg.Addr = "/tmp/mysql.sock"
+ default:
+ return errors.New("default addr for network '" + cfg.Net + "' unknown")
+ }
+
+ } else if cfg.Net == "tcp" {
+ cfg.Addr = ensureHavePort(cfg.Addr)
+ }
+
+ if cfg.tls != nil {
+ if cfg.tls.ServerName == "" && !cfg.tls.InsecureSkipVerify {
+ host, _, err := net.SplitHostPort(cfg.Addr)
+ if err == nil {
+ cfg.tls.ServerName = host
+ }
+ }
+ }
+
+ return nil
+}
+
+// FormatDSN formats the given Config into a DSN string which can be passed to
+// the driver.
+func (cfg *Config) FormatDSN() string {
+ var buf bytes.Buffer
+
+ // [username[:password]@]
+ if len(cfg.User) > 0 {
+ buf.WriteString(cfg.User)
+ if len(cfg.Passwd) > 0 {
+ buf.WriteByte(':')
+ buf.WriteString(cfg.Passwd)
+ }
+ buf.WriteByte('@')
+ }
+
+ // [protocol[(address)]]
+ if len(cfg.Net) > 0 {
+ buf.WriteString(cfg.Net)
+ if len(cfg.Addr) > 0 {
+ buf.WriteByte('(')
+ buf.WriteString(cfg.Addr)
+ buf.WriteByte(')')
+ }
+ }
+
+ // /dbname
+ buf.WriteByte('/')
+ buf.WriteString(cfg.DBName)
+
+ // [?param1=value1&...¶mN=valueN]
+ hasParam := false
+
+ if cfg.AllowAllFiles {
+ hasParam = true
+ buf.WriteString("?allowAllFiles=true")
+ }
+
+ if cfg.AllowCleartextPasswords {
+ if hasParam {
+ buf.WriteString("&allowCleartextPasswords=true")
+ } else {
+ hasParam = true
+ buf.WriteString("?allowCleartextPasswords=true")
+ }
+ }
+
+ if !cfg.AllowNativePasswords {
+ if hasParam {
+ buf.WriteString("&allowNativePasswords=false")
+ } else {
+ hasParam = true
+ buf.WriteString("?allowNativePasswords=false")
+ }
+ }
+
+ if cfg.AllowOldPasswords {
+ if hasParam {
+ buf.WriteString("&allowOldPasswords=true")
+ } else {
+ hasParam = true
+ buf.WriteString("?allowOldPasswords=true")
+ }
+ }
+
+ if cfg.ClientFoundRows {
+ if hasParam {
+ buf.WriteString("&clientFoundRows=true")
+ } else {
+ hasParam = true
+ buf.WriteString("?clientFoundRows=true")
+ }
+ }
+
+ if col := cfg.Collation; col != defaultCollation && len(col) > 0 {
+ if hasParam {
+ buf.WriteString("&collation=")
+ } else {
+ hasParam = true
+ buf.WriteString("?collation=")
+ }
+ buf.WriteString(col)
+ }
+
+ if cfg.ColumnsWithAlias {
+ if hasParam {
+ buf.WriteString("&columnsWithAlias=true")
+ } else {
+ hasParam = true
+ buf.WriteString("?columnsWithAlias=true")
+ }
+ }
+
+ if cfg.InterpolateParams {
+ if hasParam {
+ buf.WriteString("&interpolateParams=true")
+ } else {
+ hasParam = true
+ buf.WriteString("?interpolateParams=true")
+ }
+ }
+
+ if cfg.Loc != time.UTC && cfg.Loc != nil {
+ if hasParam {
+ buf.WriteString("&loc=")
+ } else {
+ hasParam = true
+ buf.WriteString("?loc=")
+ }
+ buf.WriteString(url.QueryEscape(cfg.Loc.String()))
+ }
+
+ if cfg.MultiStatements {
+ if hasParam {
+ buf.WriteString("&multiStatements=true")
+ } else {
+ hasParam = true
+ buf.WriteString("?multiStatements=true")
+ }
+ }
+
+ if cfg.ParseTime {
+ if hasParam {
+ buf.WriteString("&parseTime=true")
+ } else {
+ hasParam = true
+ buf.WriteString("?parseTime=true")
+ }
+ }
+
+ if cfg.ReadTimeout > 0 {
+ if hasParam {
+ buf.WriteString("&readTimeout=")
+ } else {
+ hasParam = true
+ buf.WriteString("?readTimeout=")
+ }
+ buf.WriteString(cfg.ReadTimeout.String())
+ }
+
+ if cfg.RejectReadOnly {
+ if hasParam {
+ buf.WriteString("&rejectReadOnly=true")
+ } else {
+ hasParam = true
+ buf.WriteString("?rejectReadOnly=true")
+ }
+ }
+
+ if len(cfg.ServerPubKey) > 0 {
+ if hasParam {
+ buf.WriteString("&serverPubKey=")
+ } else {
+ hasParam = true
+ buf.WriteString("?serverPubKey=")
+ }
+ buf.WriteString(url.QueryEscape(cfg.ServerPubKey))
+ }
+
+ if cfg.Timeout > 0 {
+ if hasParam {
+ buf.WriteString("&timeout=")
+ } else {
+ hasParam = true
+ buf.WriteString("?timeout=")
+ }
+ buf.WriteString(cfg.Timeout.String())
+ }
+
+ if len(cfg.TLSConfig) > 0 {
+ if hasParam {
+ buf.WriteString("&tls=")
+ } else {
+ hasParam = true
+ buf.WriteString("?tls=")
+ }
+ buf.WriteString(url.QueryEscape(cfg.TLSConfig))
+ }
+
+ if cfg.WriteTimeout > 0 {
+ if hasParam {
+ buf.WriteString("&writeTimeout=")
+ } else {
+ hasParam = true
+ buf.WriteString("?writeTimeout=")
+ }
+ buf.WriteString(cfg.WriteTimeout.String())
+ }
+
+ if cfg.MaxAllowedPacket != defaultMaxAllowedPacket {
+ if hasParam {
+ buf.WriteString("&maxAllowedPacket=")
+ } else {
+ hasParam = true
+ buf.WriteString("?maxAllowedPacket=")
+ }
+ buf.WriteString(strconv.Itoa(cfg.MaxAllowedPacket))
+
+ }
+
+ // other params
+ if cfg.Params != nil {
+ var params []string
+ for param := range cfg.Params {
+ params = append(params, param)
+ }
+ sort.Strings(params)
+ for _, param := range params {
+ if hasParam {
+ buf.WriteByte('&')
+ } else {
+ hasParam = true
+ buf.WriteByte('?')
+ }
+
+ buf.WriteString(param)
+ buf.WriteByte('=')
+ buf.WriteString(url.QueryEscape(cfg.Params[param]))
+ }
+ }
+
+ return buf.String()
+}
+
+// ParseDSN parses the DSN string to a Config
+func ParseDSN(dsn string) (cfg *Config, err error) {
+ // New config with some default values
+ cfg = NewConfig()
+
+ // [user[:password]@][net[(addr)]]/dbname[?param1=value1¶mN=valueN]
+ // Find the last '/' (since the password or the net addr might contain a '/')
+ foundSlash := false
+ for i := len(dsn) - 1; i >= 0; i-- {
+ if dsn[i] == '/' {
+ foundSlash = true
+ var j, k int
+
+ // left part is empty if i <= 0
+ if i > 0 {
+ // [username[:password]@][protocol[(address)]]
+ // Find the last '@' in dsn[:i]
+ for j = i; j >= 0; j-- {
+ if dsn[j] == '@' {
+ // username[:password]
+ // Find the first ':' in dsn[:j]
+ for k = 0; k < j; k++ {
+ if dsn[k] == ':' {
+ cfg.Passwd = dsn[k+1 : j]
+ break
+ }
+ }
+ cfg.User = dsn[:k]
+
+ break
+ }
+ }
+
+ // [protocol[(address)]]
+ // Find the first '(' in dsn[j+1:i]
+ for k = j + 1; k < i; k++ {
+ if dsn[k] == '(' {
+ // dsn[i-1] must be == ')' if an address is specified
+ if dsn[i-1] != ')' {
+ if strings.ContainsRune(dsn[k+1:i], ')') {
+ return nil, errInvalidDSNUnescaped
+ }
+ return nil, errInvalidDSNAddr
+ }
+ cfg.Addr = dsn[k+1 : i-1]
+ break
+ }
+ }
+ cfg.Net = dsn[j+1 : k]
+ }
+
+ // dbname[?param1=value1&...¶mN=valueN]
+ // Find the first '?' in dsn[i+1:]
+ for j = i + 1; j < len(dsn); j++ {
+ if dsn[j] == '?' {
+ if err = parseDSNParams(cfg, dsn[j+1:]); err != nil {
+ return
+ }
+ break
+ }
+ }
+ cfg.DBName = dsn[i+1 : j]
+
+ break
+ }
+ }
+
+ if !foundSlash && len(dsn) > 0 {
+ return nil, errInvalidDSNNoSlash
+ }
+
+ if err = cfg.normalize(); err != nil {
+ return nil, err
+ }
+ return
+}
+
+// parseDSNParams parses the DSN "query string"
+// Values must be url.QueryEscape'ed
+func parseDSNParams(cfg *Config, params string) (err error) {
+ for _, v := range strings.Split(params, "&") {
+ param := strings.SplitN(v, "=", 2)
+ if len(param) != 2 {
+ continue
+ }
+
+ // cfg params
+ switch value := param[1]; param[0] {
+ // Disable INFILE whitelist / enable all files
+ case "allowAllFiles":
+ var isBool bool
+ cfg.AllowAllFiles, isBool = readBool(value)
+ if !isBool {
+ return errors.New("invalid bool value: " + value)
+ }
+
+ // Use cleartext authentication mode (MySQL 5.5.10+)
+ case "allowCleartextPasswords":
+ var isBool bool
+ cfg.AllowCleartextPasswords, isBool = readBool(value)
+ if !isBool {
+ return errors.New("invalid bool value: " + value)
+ }
+
+ // Use native password authentication
+ case "allowNativePasswords":
+ var isBool bool
+ cfg.AllowNativePasswords, isBool = readBool(value)
+ if !isBool {
+ return errors.New("invalid bool value: " + value)
+ }
+
+ // Use old authentication mode (pre MySQL 4.1)
+ case "allowOldPasswords":
+ var isBool bool
+ cfg.AllowOldPasswords, isBool = readBool(value)
+ if !isBool {
+ return errors.New("invalid bool value: " + value)
+ }
+
+ // Switch "rowsAffected" mode
+ case "clientFoundRows":
+ var isBool bool
+ cfg.ClientFoundRows, isBool = readBool(value)
+ if !isBool {
+ return errors.New("invalid bool value: " + value)
+ }
+
+ // Collation
+ case "collation":
+ cfg.Collation = value
+ break
+
+ case "columnsWithAlias":
+ var isBool bool
+ cfg.ColumnsWithAlias, isBool = readBool(value)
+ if !isBool {
+ return errors.New("invalid bool value: " + value)
+ }
+
+ // Compression
+ case "compress":
+ return errors.New("compression not implemented yet")
+
+ // Enable client side placeholder substitution
+ case "interpolateParams":
+ var isBool bool
+ cfg.InterpolateParams, isBool = readBool(value)
+ if !isBool {
+ return errors.New("invalid bool value: " + value)
+ }
+
+ // Time Location
+ case "loc":
+ if value, err = url.QueryUnescape(value); err != nil {
+ return
+ }
+ cfg.Loc, err = time.LoadLocation(value)
+ if err != nil {
+ return
+ }
+
+ // multiple statements in one query
+ case "multiStatements":
+ var isBool bool
+ cfg.MultiStatements, isBool = readBool(value)
+ if !isBool {
+ return errors.New("invalid bool value: " + value)
+ }
+
+ // time.Time parsing
+ case "parseTime":
+ var isBool bool
+ cfg.ParseTime, isBool = readBool(value)
+ if !isBool {
+ return errors.New("invalid bool value: " + value)
+ }
+
+ // I/O read Timeout
+ case "readTimeout":
+ cfg.ReadTimeout, err = time.ParseDuration(value)
+ if err != nil {
+ return
+ }
+
+ // Reject read-only connections
+ case "rejectReadOnly":
+ var isBool bool
+ cfg.RejectReadOnly, isBool = readBool(value)
+ if !isBool {
+ return errors.New("invalid bool value: " + value)
+ }
+
+ // Server public key
+ case "serverPubKey":
+ name, err := url.QueryUnescape(value)
+ if err != nil {
+ return fmt.Errorf("invalid value for server pub key name: %v", err)
+ }
+
+ if pubKey := getServerPubKey(name); pubKey != nil {
+ cfg.ServerPubKey = name
+ cfg.pubKey = pubKey
+ } else {
+ return errors.New("invalid value / unknown server pub key name: " + name)
+ }
+
+ // Strict mode
+ case "strict":
+ panic("strict mode has been removed. See https://github.com/go-sql-driver/mysql/wiki/strict-mode")
+
+ // Dial Timeout
+ case "timeout":
+ cfg.Timeout, err = time.ParseDuration(value)
+ if err != nil {
+ return
+ }
+
+ // TLS-Encryption
+ case "tls":
+ boolValue, isBool := readBool(value)
+ if isBool {
+ if boolValue {
+ cfg.TLSConfig = "true"
+ cfg.tls = &tls.Config{}
+ } else {
+ cfg.TLSConfig = "false"
+ }
+ } else if vl := strings.ToLower(value); vl == "skip-verify" {
+ cfg.TLSConfig = vl
+ cfg.tls = &tls.Config{InsecureSkipVerify: true}
+ } else {
+ name, err := url.QueryUnescape(value)
+ if err != nil {
+ return fmt.Errorf("invalid value for TLS config name: %v", err)
+ }
+
+ if tlsConfig := getTLSConfigClone(name); tlsConfig != nil {
+ cfg.TLSConfig = name
+ cfg.tls = tlsConfig
+ } else {
+ return errors.New("invalid value / unknown config name: " + name)
+ }
+ }
+
+ // I/O write Timeout
+ case "writeTimeout":
+ cfg.WriteTimeout, err = time.ParseDuration(value)
+ if err != nil {
+ return
+ }
+ case "maxAllowedPacket":
+ cfg.MaxAllowedPacket, err = strconv.Atoi(value)
+ if err != nil {
+ return
+ }
+ default:
+ // lazy init
+ if cfg.Params == nil {
+ cfg.Params = make(map[string]string)
+ }
+
+ if cfg.Params[param[0]], err = url.QueryUnescape(value); err != nil {
+ return
+ }
+ }
+ }
+
+ return
+}
+
+func ensureHavePort(addr string) string {
+ if _, _, err := net.SplitHostPort(addr); err != nil {
+ return net.JoinHostPort(addr, "3306")
+ }
+ return addr
+}
diff --git a/vendor/github.com/go-sql-driver/mysql/errors.go b/vendor/github.com/go-sql-driver/mysql/errors.go
new file mode 100644
index 0000000000000000000000000000000000000000..760782ff2fb507b092db8fccfa3f598f2b1d0638
--- /dev/null
+++ b/vendor/github.com/go-sql-driver/mysql/errors.go
@@ -0,0 +1,65 @@
+// Go MySQL Driver - A MySQL-Driver for Go's database/sql package
+//
+// Copyright 2013 The Go-MySQL-Driver Authors. All rights reserved.
+//
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this file,
+// You can obtain one at http://mozilla.org/MPL/2.0/.
+
+package mysql
+
+import (
+ "errors"
+ "fmt"
+ "log"
+ "os"
+)
+
+// Various errors the driver might return. Can change between driver versions.
+var (
+ ErrInvalidConn = errors.New("invalid connection")
+ ErrMalformPkt = errors.New("malformed packet")
+ ErrNoTLS = errors.New("TLS requested but server does not support TLS")
+ ErrCleartextPassword = errors.New("this user requires clear text authentication. If you still want to use it, please add 'allowCleartextPasswords=1' to your DSN")
+ ErrNativePassword = errors.New("this user requires mysql native password authentication.")
+ ErrOldPassword = errors.New("this user requires old password authentication. If you still want to use it, please add 'allowOldPasswords=1' to your DSN. See also https://github.com/go-sql-driver/mysql/wiki/old_passwords")
+ ErrUnknownPlugin = errors.New("this authentication plugin is not supported")
+ ErrOldProtocol = errors.New("MySQL server does not support required protocol 41+")
+ ErrPktSync = errors.New("commands out of sync. You can't run this command now")
+ ErrPktSyncMul = errors.New("commands out of sync. Did you run multiple statements at once?")
+ ErrPktTooLarge = errors.New("packet for query is too large. Try adjusting the 'max_allowed_packet' variable on the server")
+ ErrBusyBuffer = errors.New("busy buffer")
+
+ // errBadConnNoWrite is used for connection errors where nothing was sent to the database yet.
+ // If this happens first in a function starting a database interaction, it should be replaced by driver.ErrBadConn
+ // to trigger a resend.
+ // See https://github.com/go-sql-driver/mysql/pull/302
+ errBadConnNoWrite = errors.New("bad connection")
+)
+
+var errLog = Logger(log.New(os.Stderr, "[mysql] ", log.Ldate|log.Ltime|log.Lshortfile))
+
+// Logger is used to log critical error messages.
+type Logger interface {
+ Print(v ...interface{})
+}
+
+// SetLogger is used to set the logger for critical errors.
+// The initial logger is os.Stderr.
+func SetLogger(logger Logger) error {
+ if logger == nil {
+ return errors.New("logger is nil")
+ }
+ errLog = logger
+ return nil
+}
+
+// MySQLError is an error type which represents a single MySQL error
+type MySQLError struct {
+ Number uint16
+ Message string
+}
+
+func (me *MySQLError) Error() string {
+ return fmt.Sprintf("Error %d: %s", me.Number, me.Message)
+}
diff --git a/vendor/github.com/go-sql-driver/mysql/fields.go b/vendor/github.com/go-sql-driver/mysql/fields.go
new file mode 100644
index 0000000000000000000000000000000000000000..e1e2ece4b163a8b5ae3ee9c0fc6337f8e97847b4
--- /dev/null
+++ b/vendor/github.com/go-sql-driver/mysql/fields.go
@@ -0,0 +1,194 @@
+// Go MySQL Driver - A MySQL-Driver for Go's database/sql package
+//
+// Copyright 2017 The Go-MySQL-Driver Authors. All rights reserved.
+//
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this file,
+// You can obtain one at http://mozilla.org/MPL/2.0/.
+
+package mysql
+
+import (
+ "database/sql"
+ "reflect"
+)
+
+func (mf *mysqlField) typeDatabaseName() string {
+ switch mf.fieldType {
+ case fieldTypeBit:
+ return "BIT"
+ case fieldTypeBLOB:
+ if mf.charSet != collations[binaryCollation] {
+ return "TEXT"
+ }
+ return "BLOB"
+ case fieldTypeDate:
+ return "DATE"
+ case fieldTypeDateTime:
+ return "DATETIME"
+ case fieldTypeDecimal:
+ return "DECIMAL"
+ case fieldTypeDouble:
+ return "DOUBLE"
+ case fieldTypeEnum:
+ return "ENUM"
+ case fieldTypeFloat:
+ return "FLOAT"
+ case fieldTypeGeometry:
+ return "GEOMETRY"
+ case fieldTypeInt24:
+ return "MEDIUMINT"
+ case fieldTypeJSON:
+ return "JSON"
+ case fieldTypeLong:
+ return "INT"
+ case fieldTypeLongBLOB:
+ if mf.charSet != collations[binaryCollation] {
+ return "LONGTEXT"
+ }
+ return "LONGBLOB"
+ case fieldTypeLongLong:
+ return "BIGINT"
+ case fieldTypeMediumBLOB:
+ if mf.charSet != collations[binaryCollation] {
+ return "MEDIUMTEXT"
+ }
+ return "MEDIUMBLOB"
+ case fieldTypeNewDate:
+ return "DATE"
+ case fieldTypeNewDecimal:
+ return "DECIMAL"
+ case fieldTypeNULL:
+ return "NULL"
+ case fieldTypeSet:
+ return "SET"
+ case fieldTypeShort:
+ return "SMALLINT"
+ case fieldTypeString:
+ if mf.charSet == collations[binaryCollation] {
+ return "BINARY"
+ }
+ return "CHAR"
+ case fieldTypeTime:
+ return "TIME"
+ case fieldTypeTimestamp:
+ return "TIMESTAMP"
+ case fieldTypeTiny:
+ return "TINYINT"
+ case fieldTypeTinyBLOB:
+ if mf.charSet != collations[binaryCollation] {
+ return "TINYTEXT"
+ }
+ return "TINYBLOB"
+ case fieldTypeVarChar:
+ if mf.charSet == collations[binaryCollation] {
+ return "VARBINARY"
+ }
+ return "VARCHAR"
+ case fieldTypeVarString:
+ if mf.charSet == collations[binaryCollation] {
+ return "VARBINARY"
+ }
+ return "VARCHAR"
+ case fieldTypeYear:
+ return "YEAR"
+ default:
+ return ""
+ }
+}
+
+var (
+ scanTypeFloat32 = reflect.TypeOf(float32(0))
+ scanTypeFloat64 = reflect.TypeOf(float64(0))
+ scanTypeInt8 = reflect.TypeOf(int8(0))
+ scanTypeInt16 = reflect.TypeOf(int16(0))
+ scanTypeInt32 = reflect.TypeOf(int32(0))
+ scanTypeInt64 = reflect.TypeOf(int64(0))
+ scanTypeNullFloat = reflect.TypeOf(sql.NullFloat64{})
+ scanTypeNullInt = reflect.TypeOf(sql.NullInt64{})
+ scanTypeNullTime = reflect.TypeOf(NullTime{})
+ scanTypeUint8 = reflect.TypeOf(uint8(0))
+ scanTypeUint16 = reflect.TypeOf(uint16(0))
+ scanTypeUint32 = reflect.TypeOf(uint32(0))
+ scanTypeUint64 = reflect.TypeOf(uint64(0))
+ scanTypeRawBytes = reflect.TypeOf(sql.RawBytes{})
+ scanTypeUnknown = reflect.TypeOf(new(interface{}))
+)
+
+type mysqlField struct {
+ tableName string
+ name string
+ length uint32
+ flags fieldFlag
+ fieldType fieldType
+ decimals byte
+ charSet uint8
+}
+
+func (mf *mysqlField) scanType() reflect.Type {
+ switch mf.fieldType {
+ case fieldTypeTiny:
+ if mf.flags&flagNotNULL != 0 {
+ if mf.flags&flagUnsigned != 0 {
+ return scanTypeUint8
+ }
+ return scanTypeInt8
+ }
+ return scanTypeNullInt
+
+ case fieldTypeShort, fieldTypeYear:
+ if mf.flags&flagNotNULL != 0 {
+ if mf.flags&flagUnsigned != 0 {
+ return scanTypeUint16
+ }
+ return scanTypeInt16
+ }
+ return scanTypeNullInt
+
+ case fieldTypeInt24, fieldTypeLong:
+ if mf.flags&flagNotNULL != 0 {
+ if mf.flags&flagUnsigned != 0 {
+ return scanTypeUint32
+ }
+ return scanTypeInt32
+ }
+ return scanTypeNullInt
+
+ case fieldTypeLongLong:
+ if mf.flags&flagNotNULL != 0 {
+ if mf.flags&flagUnsigned != 0 {
+ return scanTypeUint64
+ }
+ return scanTypeInt64
+ }
+ return scanTypeNullInt
+
+ case fieldTypeFloat:
+ if mf.flags&flagNotNULL != 0 {
+ return scanTypeFloat32
+ }
+ return scanTypeNullFloat
+
+ case fieldTypeDouble:
+ if mf.flags&flagNotNULL != 0 {
+ return scanTypeFloat64
+ }
+ return scanTypeNullFloat
+
+ case fieldTypeDecimal, fieldTypeNewDecimal, fieldTypeVarChar,
+ fieldTypeBit, fieldTypeEnum, fieldTypeSet, fieldTypeTinyBLOB,
+ fieldTypeMediumBLOB, fieldTypeLongBLOB, fieldTypeBLOB,
+ fieldTypeVarString, fieldTypeString, fieldTypeGeometry, fieldTypeJSON,
+ fieldTypeTime:
+ return scanTypeRawBytes
+
+ case fieldTypeDate, fieldTypeNewDate,
+ fieldTypeTimestamp, fieldTypeDateTime:
+ // NullTime is always returned for more consistent behavior as it can
+ // handle both cases of parseTime regardless if the field is nullable.
+ return scanTypeNullTime
+
+ default:
+ return scanTypeUnknown
+ }
+}
diff --git a/vendor/github.com/go-sql-driver/mysql/infile.go b/vendor/github.com/go-sql-driver/mysql/infile.go
new file mode 100644
index 0000000000000000000000000000000000000000..273cb0ba500c9c49acb844bbcbddb7ba99ae1d7e
--- /dev/null
+++ b/vendor/github.com/go-sql-driver/mysql/infile.go
@@ -0,0 +1,182 @@
+// Go MySQL Driver - A MySQL-Driver for Go's database/sql package
+//
+// Copyright 2013 The Go-MySQL-Driver Authors. All rights reserved.
+//
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this file,
+// You can obtain one at http://mozilla.org/MPL/2.0/.
+
+package mysql
+
+import (
+ "fmt"
+ "io"
+ "os"
+ "strings"
+ "sync"
+)
+
+var (
+ fileRegister map[string]bool
+ fileRegisterLock sync.RWMutex
+ readerRegister map[string]func() io.Reader
+ readerRegisterLock sync.RWMutex
+)
+
+// RegisterLocalFile adds the given file to the file whitelist,
+// so that it can be used by "LOAD DATA LOCAL INFILE ".
+// Alternatively you can allow the use of all local files with
+// the DSN parameter 'allowAllFiles=true'
+//
+// filePath := "/home/gopher/data.csv"
+// mysql.RegisterLocalFile(filePath)
+// err := db.Exec("LOAD DATA LOCAL INFILE '" + filePath + "' INTO TABLE foo")
+// if err != nil {
+// ...
+//
+func RegisterLocalFile(filePath string) {
+ fileRegisterLock.Lock()
+ // lazy map init
+ if fileRegister == nil {
+ fileRegister = make(map[string]bool)
+ }
+
+ fileRegister[strings.Trim(filePath, `"`)] = true
+ fileRegisterLock.Unlock()
+}
+
+// DeregisterLocalFile removes the given filepath from the whitelist.
+func DeregisterLocalFile(filePath string) {
+ fileRegisterLock.Lock()
+ delete(fileRegister, strings.Trim(filePath, `"`))
+ fileRegisterLock.Unlock()
+}
+
+// RegisterReaderHandler registers a handler function which is used
+// to receive a io.Reader.
+// The Reader can be used by "LOAD DATA LOCAL INFILE Reader::".
+// If the handler returns a io.ReadCloser Close() is called when the
+// request is finished.
+//
+// mysql.RegisterReaderHandler("data", func() io.Reader {
+// var csvReader io.Reader // Some Reader that returns CSV data
+// ... // Open Reader here
+// return csvReader
+// })
+// err := db.Exec("LOAD DATA LOCAL INFILE 'Reader::data' INTO TABLE foo")
+// if err != nil {
+// ...
+//
+func RegisterReaderHandler(name string, handler func() io.Reader) {
+ readerRegisterLock.Lock()
+ // lazy map init
+ if readerRegister == nil {
+ readerRegister = make(map[string]func() io.Reader)
+ }
+
+ readerRegister[name] = handler
+ readerRegisterLock.Unlock()
+}
+
+// DeregisterReaderHandler removes the ReaderHandler function with
+// the given name from the registry.
+func DeregisterReaderHandler(name string) {
+ readerRegisterLock.Lock()
+ delete(readerRegister, name)
+ readerRegisterLock.Unlock()
+}
+
+func deferredClose(err *error, closer io.Closer) {
+ closeErr := closer.Close()
+ if *err == nil {
+ *err = closeErr
+ }
+}
+
+func (mc *mysqlConn) handleInFileRequest(name string) (err error) {
+ var rdr io.Reader
+ var data []byte
+ packetSize := 16 * 1024 // 16KB is small enough for disk readahead and large enough for TCP
+ if mc.maxWriteSize < packetSize {
+ packetSize = mc.maxWriteSize
+ }
+
+ if idx := strings.Index(name, "Reader::"); idx == 0 || (idx > 0 && name[idx-1] == '/') { // io.Reader
+ // The server might return an an absolute path. See issue #355.
+ name = name[idx+8:]
+
+ readerRegisterLock.RLock()
+ handler, inMap := readerRegister[name]
+ readerRegisterLock.RUnlock()
+
+ if inMap {
+ rdr = handler()
+ if rdr != nil {
+ if cl, ok := rdr.(io.Closer); ok {
+ defer deferredClose(&err, cl)
+ }
+ } else {
+ err = fmt.Errorf("Reader '%s' is ", name)
+ }
+ } else {
+ err = fmt.Errorf("Reader '%s' is not registered", name)
+ }
+ } else { // File
+ name = strings.Trim(name, `"`)
+ fileRegisterLock.RLock()
+ fr := fileRegister[name]
+ fileRegisterLock.RUnlock()
+ if mc.cfg.AllowAllFiles || fr {
+ var file *os.File
+ var fi os.FileInfo
+
+ if file, err = os.Open(name); err == nil {
+ defer deferredClose(&err, file)
+
+ // get file size
+ if fi, err = file.Stat(); err == nil {
+ rdr = file
+ if fileSize := int(fi.Size()); fileSize < packetSize {
+ packetSize = fileSize
+ }
+ }
+ }
+ } else {
+ err = fmt.Errorf("local file '%s' is not registered", name)
+ }
+ }
+
+ // send content packets
+ // if packetSize == 0, the Reader contains no data
+ if err == nil && packetSize > 0 {
+ data := make([]byte, 4+packetSize)
+ var n int
+ for err == nil {
+ n, err = rdr.Read(data[4:])
+ if n > 0 {
+ if ioErr := mc.writePacket(data[:4+n]); ioErr != nil {
+ return ioErr
+ }
+ }
+ }
+ if err == io.EOF {
+ err = nil
+ }
+ }
+
+ // send empty packet (termination)
+ if data == nil {
+ data = make([]byte, 4)
+ }
+ if ioErr := mc.writePacket(data[:4]); ioErr != nil {
+ return ioErr
+ }
+
+ // read OK packet
+ if err == nil {
+ return mc.readResultOK()
+ }
+
+ mc.readPacket()
+ return err
+}
diff --git a/vendor/github.com/go-sql-driver/mysql/packets.go b/vendor/github.com/go-sql-driver/mysql/packets.go
new file mode 100644
index 0000000000000000000000000000000000000000..9ed64085092e489343a67095e110f13dee3ad4d2
--- /dev/null
+++ b/vendor/github.com/go-sql-driver/mysql/packets.go
@@ -0,0 +1,1286 @@
+// Go MySQL Driver - A MySQL-Driver for Go's database/sql package
+//
+// Copyright 2012 The Go-MySQL-Driver Authors. All rights reserved.
+//
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this file,
+// You can obtain one at http://mozilla.org/MPL/2.0/.
+
+package mysql
+
+import (
+ "bytes"
+ "crypto/tls"
+ "database/sql/driver"
+ "encoding/binary"
+ "errors"
+ "fmt"
+ "io"
+ "math"
+ "time"
+)
+
+// Packets documentation:
+// http://dev.mysql.com/doc/internals/en/client-server-protocol.html
+
+// Read packet to buffer 'data'
+func (mc *mysqlConn) readPacket() ([]byte, error) {
+ var prevData []byte
+ for {
+ // read packet header
+ data, err := mc.buf.readNext(4)
+ if err != nil {
+ if cerr := mc.canceled.Value(); cerr != nil {
+ return nil, cerr
+ }
+ errLog.Print(err)
+ mc.Close()
+ return nil, ErrInvalidConn
+ }
+
+ // packet length [24 bit]
+ pktLen := int(uint32(data[0]) | uint32(data[1])<<8 | uint32(data[2])<<16)
+
+ // check packet sync [8 bit]
+ if data[3] != mc.sequence {
+ if data[3] > mc.sequence {
+ return nil, ErrPktSyncMul
+ }
+ return nil, ErrPktSync
+ }
+ mc.sequence++
+
+ // packets with length 0 terminate a previous packet which is a
+ // multiple of (2^24)−1 bytes long
+ if pktLen == 0 {
+ // there was no previous packet
+ if prevData == nil {
+ errLog.Print(ErrMalformPkt)
+ mc.Close()
+ return nil, ErrInvalidConn
+ }
+
+ return prevData, nil
+ }
+
+ // read packet body [pktLen bytes]
+ data, err = mc.buf.readNext(pktLen)
+ if err != nil {
+ if cerr := mc.canceled.Value(); cerr != nil {
+ return nil, cerr
+ }
+ errLog.Print(err)
+ mc.Close()
+ return nil, ErrInvalidConn
+ }
+
+ // return data if this was the last packet
+ if pktLen < maxPacketSize {
+ // zero allocations for non-split packets
+ if prevData == nil {
+ return data, nil
+ }
+
+ return append(prevData, data...), nil
+ }
+
+ prevData = append(prevData, data...)
+ }
+}
+
+// Write packet buffer 'data'
+func (mc *mysqlConn) writePacket(data []byte) error {
+ pktLen := len(data) - 4
+
+ if pktLen > mc.maxAllowedPacket {
+ return ErrPktTooLarge
+ }
+
+ for {
+ var size int
+ if pktLen >= maxPacketSize {
+ data[0] = 0xff
+ data[1] = 0xff
+ data[2] = 0xff
+ size = maxPacketSize
+ } else {
+ data[0] = byte(pktLen)
+ data[1] = byte(pktLen >> 8)
+ data[2] = byte(pktLen >> 16)
+ size = pktLen
+ }
+ data[3] = mc.sequence
+
+ // Write packet
+ if mc.writeTimeout > 0 {
+ if err := mc.netConn.SetWriteDeadline(time.Now().Add(mc.writeTimeout)); err != nil {
+ return err
+ }
+ }
+
+ n, err := mc.netConn.Write(data[:4+size])
+ if err == nil && n == 4+size {
+ mc.sequence++
+ if size != maxPacketSize {
+ return nil
+ }
+ pktLen -= size
+ data = data[size:]
+ continue
+ }
+
+ // Handle error
+ if err == nil { // n != len(data)
+ mc.cleanup()
+ errLog.Print(ErrMalformPkt)
+ } else {
+ if cerr := mc.canceled.Value(); cerr != nil {
+ return cerr
+ }
+ if n == 0 && pktLen == len(data)-4 {
+ // only for the first loop iteration when nothing was written yet
+ return errBadConnNoWrite
+ }
+ mc.cleanup()
+ errLog.Print(err)
+ }
+ return ErrInvalidConn
+ }
+}
+
+/******************************************************************************
+* Initialization Process *
+******************************************************************************/
+
+// Handshake Initialization Packet
+// http://dev.mysql.com/doc/internals/en/connection-phase-packets.html#packet-Protocol::Handshake
+func (mc *mysqlConn) readHandshakePacket() (data []byte, plugin string, err error) {
+ data, err = mc.readPacket()
+ if err != nil {
+ // for init we can rewrite this to ErrBadConn for sql.Driver to retry, since
+ // in connection initialization we don't risk retrying non-idempotent actions.
+ if err == ErrInvalidConn {
+ return nil, "", driver.ErrBadConn
+ }
+ return
+ }
+
+ if data[0] == iERR {
+ return nil, "", mc.handleErrorPacket(data)
+ }
+
+ // protocol version [1 byte]
+ if data[0] < minProtocolVersion {
+ return nil, "", fmt.Errorf(
+ "unsupported protocol version %d. Version %d or higher is required",
+ data[0],
+ minProtocolVersion,
+ )
+ }
+
+ // server version [null terminated string]
+ // connection id [4 bytes]
+ pos := 1 + bytes.IndexByte(data[1:], 0x00) + 1 + 4
+
+ // first part of the password cipher [8 bytes]
+ authData := data[pos : pos+8]
+
+ // (filler) always 0x00 [1 byte]
+ pos += 8 + 1
+
+ // capability flags (lower 2 bytes) [2 bytes]
+ mc.flags = clientFlag(binary.LittleEndian.Uint16(data[pos : pos+2]))
+ if mc.flags&clientProtocol41 == 0 {
+ return nil, "", ErrOldProtocol
+ }
+ if mc.flags&clientSSL == 0 && mc.cfg.tls != nil {
+ return nil, "", ErrNoTLS
+ }
+ pos += 2
+
+ if len(data) > pos {
+ // character set [1 byte]
+ // status flags [2 bytes]
+ // capability flags (upper 2 bytes) [2 bytes]
+ // length of auth-plugin-data [1 byte]
+ // reserved (all [00]) [10 bytes]
+ pos += 1 + 2 + 2 + 1 + 10
+
+ // second part of the password cipher [mininum 13 bytes],
+ // where len=MAX(13, length of auth-plugin-data - 8)
+ //
+ // The web documentation is ambiguous about the length. However,
+ // according to mysql-5.7/sql/auth/sql_authentication.cc line 538,
+ // the 13th byte is "\0 byte, terminating the second part of
+ // a scramble". So the second part of the password cipher is
+ // a NULL terminated string that's at least 13 bytes with the
+ // last byte being NULL.
+ //
+ // The official Python library uses the fixed length 12
+ // which seems to work but technically could have a hidden bug.
+ authData = append(authData, data[pos:pos+12]...)
+ pos += 13
+
+ // EOF if version (>= 5.5.7 and < 5.5.10) or (>= 5.6.0 and < 5.6.2)
+ // \NUL otherwise
+ if end := bytes.IndexByte(data[pos:], 0x00); end != -1 {
+ plugin = string(data[pos : pos+end])
+ } else {
+ plugin = string(data[pos:])
+ }
+
+ // make a memory safe copy of the cipher slice
+ var b [20]byte
+ copy(b[:], authData)
+ return b[:], plugin, nil
+ }
+
+ // make a memory safe copy of the cipher slice
+ var b [8]byte
+ copy(b[:], authData)
+ return b[:], plugin, nil
+}
+
+// Client Authentication Packet
+// http://dev.mysql.com/doc/internals/en/connection-phase-packets.html#packet-Protocol::HandshakeResponse
+func (mc *mysqlConn) writeHandshakeResponsePacket(authResp []byte, plugin string) error {
+ // Adjust client flags based on server support
+ clientFlags := clientProtocol41 |
+ clientSecureConn |
+ clientLongPassword |
+ clientTransactions |
+ clientLocalFiles |
+ clientPluginAuth |
+ clientMultiResults |
+ mc.flags&clientLongFlag
+
+ if mc.cfg.ClientFoundRows {
+ clientFlags |= clientFoundRows
+ }
+
+ // To enable TLS / SSL
+ if mc.cfg.tls != nil {
+ clientFlags |= clientSSL
+ }
+
+ if mc.cfg.MultiStatements {
+ clientFlags |= clientMultiStatements
+ }
+
+ // encode length of the auth plugin data
+ var authRespLEIBuf [9]byte
+ authRespLen := len(authResp)
+ authRespLEI := appendLengthEncodedInteger(authRespLEIBuf[:0], uint64(authRespLen))
+ if len(authRespLEI) > 1 {
+ // if the length can not be written in 1 byte, it must be written as a
+ // length encoded integer
+ clientFlags |= clientPluginAuthLenEncClientData
+ }
+
+ pktLen := 4 + 4 + 1 + 23 + len(mc.cfg.User) + 1 + len(authRespLEI) + len(authResp) + 21 + 1
+
+ // To specify a db name
+ if n := len(mc.cfg.DBName); n > 0 {
+ clientFlags |= clientConnectWithDB
+ pktLen += n + 1
+ }
+
+ // Calculate packet length and get buffer with that size
+ data := mc.buf.takeSmallBuffer(pktLen + 4)
+ if data == nil {
+ // cannot take the buffer. Something must be wrong with the connection
+ errLog.Print(ErrBusyBuffer)
+ return errBadConnNoWrite
+ }
+
+ // ClientFlags [32 bit]
+ data[4] = byte(clientFlags)
+ data[5] = byte(clientFlags >> 8)
+ data[6] = byte(clientFlags >> 16)
+ data[7] = byte(clientFlags >> 24)
+
+ // MaxPacketSize [32 bit] (none)
+ data[8] = 0x00
+ data[9] = 0x00
+ data[10] = 0x00
+ data[11] = 0x00
+
+ // Charset [1 byte]
+ var found bool
+ data[12], found = collations[mc.cfg.Collation]
+ if !found {
+ // Note possibility for false negatives:
+ // could be triggered although the collation is valid if the
+ // collations map does not contain entries the server supports.
+ return errors.New("unknown collation")
+ }
+
+ // SSL Connection Request Packet
+ // http://dev.mysql.com/doc/internals/en/connection-phase-packets.html#packet-Protocol::SSLRequest
+ if mc.cfg.tls != nil {
+ // Send TLS / SSL request packet
+ if err := mc.writePacket(data[:(4+4+1+23)+4]); err != nil {
+ return err
+ }
+
+ // Switch to TLS
+ tlsConn := tls.Client(mc.netConn, mc.cfg.tls)
+ if err := tlsConn.Handshake(); err != nil {
+ return err
+ }
+ mc.netConn = tlsConn
+ mc.buf.nc = tlsConn
+ }
+
+ // Filler [23 bytes] (all 0x00)
+ pos := 13
+ for ; pos < 13+23; pos++ {
+ data[pos] = 0
+ }
+
+ // User [null terminated string]
+ if len(mc.cfg.User) > 0 {
+ pos += copy(data[pos:], mc.cfg.User)
+ }
+ data[pos] = 0x00
+ pos++
+
+ // Auth Data [length encoded integer]
+ pos += copy(data[pos:], authRespLEI)
+ pos += copy(data[pos:], authResp)
+
+ // Databasename [null terminated string]
+ if len(mc.cfg.DBName) > 0 {
+ pos += copy(data[pos:], mc.cfg.DBName)
+ data[pos] = 0x00
+ pos++
+ }
+
+ pos += copy(data[pos:], plugin)
+ data[pos] = 0x00
+ pos++
+
+ // Send Auth packet
+ return mc.writePacket(data[:pos])
+}
+
+// http://dev.mysql.com/doc/internals/en/connection-phase-packets.html#packet-Protocol::AuthSwitchResponse
+func (mc *mysqlConn) writeAuthSwitchPacket(authData []byte) error {
+ pktLen := 4 + len(authData)
+ data := mc.buf.takeSmallBuffer(pktLen)
+ if data == nil {
+ // cannot take the buffer. Something must be wrong with the connection
+ errLog.Print(ErrBusyBuffer)
+ return errBadConnNoWrite
+ }
+
+ // Add the auth data [EOF]
+ copy(data[4:], authData)
+ return mc.writePacket(data)
+}
+
+/******************************************************************************
+* Command Packets *
+******************************************************************************/
+
+func (mc *mysqlConn) writeCommandPacket(command byte) error {
+ // Reset Packet Sequence
+ mc.sequence = 0
+
+ data := mc.buf.takeSmallBuffer(4 + 1)
+ if data == nil {
+ // cannot take the buffer. Something must be wrong with the connection
+ errLog.Print(ErrBusyBuffer)
+ return errBadConnNoWrite
+ }
+
+ // Add command byte
+ data[4] = command
+
+ // Send CMD packet
+ return mc.writePacket(data)
+}
+
+func (mc *mysqlConn) writeCommandPacketStr(command byte, arg string) error {
+ // Reset Packet Sequence
+ mc.sequence = 0
+
+ pktLen := 1 + len(arg)
+ data := mc.buf.takeBuffer(pktLen + 4)
+ if data == nil {
+ // cannot take the buffer. Something must be wrong with the connection
+ errLog.Print(ErrBusyBuffer)
+ return errBadConnNoWrite
+ }
+
+ // Add command byte
+ data[4] = command
+
+ // Add arg
+ copy(data[5:], arg)
+
+ // Send CMD packet
+ return mc.writePacket(data)
+}
+
+func (mc *mysqlConn) writeCommandPacketUint32(command byte, arg uint32) error {
+ // Reset Packet Sequence
+ mc.sequence = 0
+
+ data := mc.buf.takeSmallBuffer(4 + 1 + 4)
+ if data == nil {
+ // cannot take the buffer. Something must be wrong with the connection
+ errLog.Print(ErrBusyBuffer)
+ return errBadConnNoWrite
+ }
+
+ // Add command byte
+ data[4] = command
+
+ // Add arg [32 bit]
+ data[5] = byte(arg)
+ data[6] = byte(arg >> 8)
+ data[7] = byte(arg >> 16)
+ data[8] = byte(arg >> 24)
+
+ // Send CMD packet
+ return mc.writePacket(data)
+}
+
+/******************************************************************************
+* Result Packets *
+******************************************************************************/
+
+func (mc *mysqlConn) readAuthResult() ([]byte, string, error) {
+ data, err := mc.readPacket()
+ if err != nil {
+ return nil, "", err
+ }
+
+ // packet indicator
+ switch data[0] {
+
+ case iOK:
+ return nil, "", mc.handleOkPacket(data)
+
+ case iAuthMoreData:
+ return data[1:], "", err
+
+ case iEOF:
+ if len(data) == 1 {
+ // https://dev.mysql.com/doc/internals/en/connection-phase-packets.html#packet-Protocol::OldAuthSwitchRequest
+ return nil, "mysql_old_password", nil
+ }
+ pluginEndIndex := bytes.IndexByte(data, 0x00)
+ if pluginEndIndex < 0 {
+ return nil, "", ErrMalformPkt
+ }
+ plugin := string(data[1:pluginEndIndex])
+ authData := data[pluginEndIndex+1:]
+ return authData, plugin, nil
+
+ default: // Error otherwise
+ return nil, "", mc.handleErrorPacket(data)
+ }
+}
+
+// Returns error if Packet is not an 'Result OK'-Packet
+func (mc *mysqlConn) readResultOK() error {
+ data, err := mc.readPacket()
+ if err != nil {
+ return err
+ }
+
+ if data[0] == iOK {
+ return mc.handleOkPacket(data)
+ }
+ return mc.handleErrorPacket(data)
+}
+
+// Result Set Header Packet
+// http://dev.mysql.com/doc/internals/en/com-query-response.html#packet-ProtocolText::Resultset
+func (mc *mysqlConn) readResultSetHeaderPacket() (int, error) {
+ data, err := mc.readPacket()
+ if err == nil {
+ switch data[0] {
+
+ case iOK:
+ return 0, mc.handleOkPacket(data)
+
+ case iERR:
+ return 0, mc.handleErrorPacket(data)
+
+ case iLocalInFile:
+ return 0, mc.handleInFileRequest(string(data[1:]))
+ }
+
+ // column count
+ num, _, n := readLengthEncodedInteger(data)
+ if n-len(data) == 0 {
+ return int(num), nil
+ }
+
+ return 0, ErrMalformPkt
+ }
+ return 0, err
+}
+
+// Error Packet
+// http://dev.mysql.com/doc/internals/en/generic-response-packets.html#packet-ERR_Packet
+func (mc *mysqlConn) handleErrorPacket(data []byte) error {
+ if data[0] != iERR {
+ return ErrMalformPkt
+ }
+
+ // 0xff [1 byte]
+
+ // Error Number [16 bit uint]
+ errno := binary.LittleEndian.Uint16(data[1:3])
+
+ // 1792: ER_CANT_EXECUTE_IN_READ_ONLY_TRANSACTION
+ // 1290: ER_OPTION_PREVENTS_STATEMENT (returned by Aurora during failover)
+ if (errno == 1792 || errno == 1290) && mc.cfg.RejectReadOnly {
+ // Oops; we are connected to a read-only connection, and won't be able
+ // to issue any write statements. Since RejectReadOnly is configured,
+ // we throw away this connection hoping this one would have write
+ // permission. This is specifically for a possible race condition
+ // during failover (e.g. on AWS Aurora). See README.md for more.
+ //
+ // We explicitly close the connection before returning
+ // driver.ErrBadConn to ensure that `database/sql` purges this
+ // connection and initiates a new one for next statement next time.
+ mc.Close()
+ return driver.ErrBadConn
+ }
+
+ pos := 3
+
+ // SQL State [optional: # + 5bytes string]
+ if data[3] == 0x23 {
+ //sqlstate := string(data[4 : 4+5])
+ pos = 9
+ }
+
+ // Error Message [string]
+ return &MySQLError{
+ Number: errno,
+ Message: string(data[pos:]),
+ }
+}
+
+func readStatus(b []byte) statusFlag {
+ return statusFlag(b[0]) | statusFlag(b[1])<<8
+}
+
+// Ok Packet
+// http://dev.mysql.com/doc/internals/en/generic-response-packets.html#packet-OK_Packet
+func (mc *mysqlConn) handleOkPacket(data []byte) error {
+ var n, m int
+
+ // 0x00 [1 byte]
+
+ // Affected rows [Length Coded Binary]
+ mc.affectedRows, _, n = readLengthEncodedInteger(data[1:])
+
+ // Insert id [Length Coded Binary]
+ mc.insertId, _, m = readLengthEncodedInteger(data[1+n:])
+
+ // server_status [2 bytes]
+ mc.status = readStatus(data[1+n+m : 1+n+m+2])
+ if mc.status&statusMoreResultsExists != 0 {
+ return nil
+ }
+
+ // warning count [2 bytes]
+
+ return nil
+}
+
+// Read Packets as Field Packets until EOF-Packet or an Error appears
+// http://dev.mysql.com/doc/internals/en/com-query-response.html#packet-Protocol::ColumnDefinition41
+func (mc *mysqlConn) readColumns(count int) ([]mysqlField, error) {
+ columns := make([]mysqlField, count)
+
+ for i := 0; ; i++ {
+ data, err := mc.readPacket()
+ if err != nil {
+ return nil, err
+ }
+
+ // EOF Packet
+ if data[0] == iEOF && (len(data) == 5 || len(data) == 1) {
+ if i == count {
+ return columns, nil
+ }
+ return nil, fmt.Errorf("column count mismatch n:%d len:%d", count, len(columns))
+ }
+
+ // Catalog
+ pos, err := skipLengthEncodedString(data)
+ if err != nil {
+ return nil, err
+ }
+
+ // Database [len coded string]
+ n, err := skipLengthEncodedString(data[pos:])
+ if err != nil {
+ return nil, err
+ }
+ pos += n
+
+ // Table [len coded string]
+ if mc.cfg.ColumnsWithAlias {
+ tableName, _, n, err := readLengthEncodedString(data[pos:])
+ if err != nil {
+ return nil, err
+ }
+ pos += n
+ columns[i].tableName = string(tableName)
+ } else {
+ n, err = skipLengthEncodedString(data[pos:])
+ if err != nil {
+ return nil, err
+ }
+ pos += n
+ }
+
+ // Original table [len coded string]
+ n, err = skipLengthEncodedString(data[pos:])
+ if err != nil {
+ return nil, err
+ }
+ pos += n
+
+ // Name [len coded string]
+ name, _, n, err := readLengthEncodedString(data[pos:])
+ if err != nil {
+ return nil, err
+ }
+ columns[i].name = string(name)
+ pos += n
+
+ // Original name [len coded string]
+ n, err = skipLengthEncodedString(data[pos:])
+ if err != nil {
+ return nil, err
+ }
+ pos += n
+
+ // Filler [uint8]
+ pos++
+
+ // Charset [charset, collation uint8]
+ columns[i].charSet = data[pos]
+ pos += 2
+
+ // Length [uint32]
+ columns[i].length = binary.LittleEndian.Uint32(data[pos : pos+4])
+ pos += 4
+
+ // Field type [uint8]
+ columns[i].fieldType = fieldType(data[pos])
+ pos++
+
+ // Flags [uint16]
+ columns[i].flags = fieldFlag(binary.LittleEndian.Uint16(data[pos : pos+2]))
+ pos += 2
+
+ // Decimals [uint8]
+ columns[i].decimals = data[pos]
+ //pos++
+
+ // Default value [len coded binary]
+ //if pos < len(data) {
+ // defaultVal, _, err = bytesToLengthCodedBinary(data[pos:])
+ //}
+ }
+}
+
+// Read Packets as Field Packets until EOF-Packet or an Error appears
+// http://dev.mysql.com/doc/internals/en/com-query-response.html#packet-ProtocolText::ResultsetRow
+func (rows *textRows) readRow(dest []driver.Value) error {
+ mc := rows.mc
+
+ if rows.rs.done {
+ return io.EOF
+ }
+
+ data, err := mc.readPacket()
+ if err != nil {
+ return err
+ }
+
+ // EOF Packet
+ if data[0] == iEOF && len(data) == 5 {
+ // server_status [2 bytes]
+ rows.mc.status = readStatus(data[3:])
+ rows.rs.done = true
+ if !rows.HasNextResultSet() {
+ rows.mc = nil
+ }
+ return io.EOF
+ }
+ if data[0] == iERR {
+ rows.mc = nil
+ return mc.handleErrorPacket(data)
+ }
+
+ // RowSet Packet
+ var n int
+ var isNull bool
+ pos := 0
+
+ for i := range dest {
+ // Read bytes and convert to string
+ dest[i], isNull, n, err = readLengthEncodedString(data[pos:])
+ pos += n
+ if err == nil {
+ if !isNull {
+ if !mc.parseTime {
+ continue
+ } else {
+ switch rows.rs.columns[i].fieldType {
+ case fieldTypeTimestamp, fieldTypeDateTime,
+ fieldTypeDate, fieldTypeNewDate:
+ dest[i], err = parseDateTime(
+ string(dest[i].([]byte)),
+ mc.cfg.Loc,
+ )
+ if err == nil {
+ continue
+ }
+ default:
+ continue
+ }
+ }
+
+ } else {
+ dest[i] = nil
+ continue
+ }
+ }
+ return err // err != nil
+ }
+
+ return nil
+}
+
+// Reads Packets until EOF-Packet or an Error appears. Returns count of Packets read
+func (mc *mysqlConn) readUntilEOF() error {
+ for {
+ data, err := mc.readPacket()
+ if err != nil {
+ return err
+ }
+
+ switch data[0] {
+ case iERR:
+ return mc.handleErrorPacket(data)
+ case iEOF:
+ if len(data) == 5 {
+ mc.status = readStatus(data[3:])
+ }
+ return nil
+ }
+ }
+}
+
+/******************************************************************************
+* Prepared Statements *
+******************************************************************************/
+
+// Prepare Result Packets
+// http://dev.mysql.com/doc/internals/en/com-stmt-prepare-response.html
+func (stmt *mysqlStmt) readPrepareResultPacket() (uint16, error) {
+ data, err := stmt.mc.readPacket()
+ if err == nil {
+ // packet indicator [1 byte]
+ if data[0] != iOK {
+ return 0, stmt.mc.handleErrorPacket(data)
+ }
+
+ // statement id [4 bytes]
+ stmt.id = binary.LittleEndian.Uint32(data[1:5])
+
+ // Column count [16 bit uint]
+ columnCount := binary.LittleEndian.Uint16(data[5:7])
+
+ // Param count [16 bit uint]
+ stmt.paramCount = int(binary.LittleEndian.Uint16(data[7:9]))
+
+ // Reserved [8 bit]
+
+ // Warning count [16 bit uint]
+
+ return columnCount, nil
+ }
+ return 0, err
+}
+
+// http://dev.mysql.com/doc/internals/en/com-stmt-send-long-data.html
+func (stmt *mysqlStmt) writeCommandLongData(paramID int, arg []byte) error {
+ maxLen := stmt.mc.maxAllowedPacket - 1
+ pktLen := maxLen
+
+ // After the header (bytes 0-3) follows before the data:
+ // 1 byte command
+ // 4 bytes stmtID
+ // 2 bytes paramID
+ const dataOffset = 1 + 4 + 2
+
+ // Cannot use the write buffer since
+ // a) the buffer is too small
+ // b) it is in use
+ data := make([]byte, 4+1+4+2+len(arg))
+
+ copy(data[4+dataOffset:], arg)
+
+ for argLen := len(arg); argLen > 0; argLen -= pktLen - dataOffset {
+ if dataOffset+argLen < maxLen {
+ pktLen = dataOffset + argLen
+ }
+
+ stmt.mc.sequence = 0
+ // Add command byte [1 byte]
+ data[4] = comStmtSendLongData
+
+ // Add stmtID [32 bit]
+ data[5] = byte(stmt.id)
+ data[6] = byte(stmt.id >> 8)
+ data[7] = byte(stmt.id >> 16)
+ data[8] = byte(stmt.id >> 24)
+
+ // Add paramID [16 bit]
+ data[9] = byte(paramID)
+ data[10] = byte(paramID >> 8)
+
+ // Send CMD packet
+ err := stmt.mc.writePacket(data[:4+pktLen])
+ if err == nil {
+ data = data[pktLen-dataOffset:]
+ continue
+ }
+ return err
+
+ }
+
+ // Reset Packet Sequence
+ stmt.mc.sequence = 0
+ return nil
+}
+
+// Execute Prepared Statement
+// http://dev.mysql.com/doc/internals/en/com-stmt-execute.html
+func (stmt *mysqlStmt) writeExecutePacket(args []driver.Value) error {
+ if len(args) != stmt.paramCount {
+ return fmt.Errorf(
+ "argument count mismatch (got: %d; has: %d)",
+ len(args),
+ stmt.paramCount,
+ )
+ }
+
+ const minPktLen = 4 + 1 + 4 + 1 + 4
+ mc := stmt.mc
+
+ // Determine threshould dynamically to avoid packet size shortage.
+ longDataSize := mc.maxAllowedPacket / (stmt.paramCount + 1)
+ if longDataSize < 64 {
+ longDataSize = 64
+ }
+
+ // Reset packet-sequence
+ mc.sequence = 0
+
+ var data []byte
+
+ if len(args) == 0 {
+ data = mc.buf.takeBuffer(minPktLen)
+ } else {
+ data = mc.buf.takeCompleteBuffer()
+ }
+ if data == nil {
+ // cannot take the buffer. Something must be wrong with the connection
+ errLog.Print(ErrBusyBuffer)
+ return errBadConnNoWrite
+ }
+
+ // command [1 byte]
+ data[4] = comStmtExecute
+
+ // statement_id [4 bytes]
+ data[5] = byte(stmt.id)
+ data[6] = byte(stmt.id >> 8)
+ data[7] = byte(stmt.id >> 16)
+ data[8] = byte(stmt.id >> 24)
+
+ // flags (0: CURSOR_TYPE_NO_CURSOR) [1 byte]
+ data[9] = 0x00
+
+ // iteration_count (uint32(1)) [4 bytes]
+ data[10] = 0x01
+ data[11] = 0x00
+ data[12] = 0x00
+ data[13] = 0x00
+
+ if len(args) > 0 {
+ pos := minPktLen
+
+ var nullMask []byte
+ if maskLen, typesLen := (len(args)+7)/8, 1+2*len(args); pos+maskLen+typesLen >= len(data) {
+ // buffer has to be extended but we don't know by how much so
+ // we depend on append after all data with known sizes fit.
+ // We stop at that because we deal with a lot of columns here
+ // which makes the required allocation size hard to guess.
+ tmp := make([]byte, pos+maskLen+typesLen)
+ copy(tmp[:pos], data[:pos])
+ data = tmp
+ nullMask = data[pos : pos+maskLen]
+ pos += maskLen
+ } else {
+ nullMask = data[pos : pos+maskLen]
+ for i := 0; i < maskLen; i++ {
+ nullMask[i] = 0
+ }
+ pos += maskLen
+ }
+
+ // newParameterBoundFlag 1 [1 byte]
+ data[pos] = 0x01
+ pos++
+
+ // type of each parameter [len(args)*2 bytes]
+ paramTypes := data[pos:]
+ pos += len(args) * 2
+
+ // value of each parameter [n bytes]
+ paramValues := data[pos:pos]
+ valuesCap := cap(paramValues)
+
+ for i, arg := range args {
+ // build NULL-bitmap
+ if arg == nil {
+ nullMask[i/8] |= 1 << (uint(i) & 7)
+ paramTypes[i+i] = byte(fieldTypeNULL)
+ paramTypes[i+i+1] = 0x00
+ continue
+ }
+
+ // cache types and values
+ switch v := arg.(type) {
+ case int64:
+ paramTypes[i+i] = byte(fieldTypeLongLong)
+ paramTypes[i+i+1] = 0x00
+
+ if cap(paramValues)-len(paramValues)-8 >= 0 {
+ paramValues = paramValues[:len(paramValues)+8]
+ binary.LittleEndian.PutUint64(
+ paramValues[len(paramValues)-8:],
+ uint64(v),
+ )
+ } else {
+ paramValues = append(paramValues,
+ uint64ToBytes(uint64(v))...,
+ )
+ }
+
+ case float64:
+ paramTypes[i+i] = byte(fieldTypeDouble)
+ paramTypes[i+i+1] = 0x00
+
+ if cap(paramValues)-len(paramValues)-8 >= 0 {
+ paramValues = paramValues[:len(paramValues)+8]
+ binary.LittleEndian.PutUint64(
+ paramValues[len(paramValues)-8:],
+ math.Float64bits(v),
+ )
+ } else {
+ paramValues = append(paramValues,
+ uint64ToBytes(math.Float64bits(v))...,
+ )
+ }
+
+ case bool:
+ paramTypes[i+i] = byte(fieldTypeTiny)
+ paramTypes[i+i+1] = 0x00
+
+ if v {
+ paramValues = append(paramValues, 0x01)
+ } else {
+ paramValues = append(paramValues, 0x00)
+ }
+
+ case []byte:
+ // Common case (non-nil value) first
+ if v != nil {
+ paramTypes[i+i] = byte(fieldTypeString)
+ paramTypes[i+i+1] = 0x00
+
+ if len(v) < longDataSize {
+ paramValues = appendLengthEncodedInteger(paramValues,
+ uint64(len(v)),
+ )
+ paramValues = append(paramValues, v...)
+ } else {
+ if err := stmt.writeCommandLongData(i, v); err != nil {
+ return err
+ }
+ }
+ continue
+ }
+
+ // Handle []byte(nil) as a NULL value
+ nullMask[i/8] |= 1 << (uint(i) & 7)
+ paramTypes[i+i] = byte(fieldTypeNULL)
+ paramTypes[i+i+1] = 0x00
+
+ case string:
+ paramTypes[i+i] = byte(fieldTypeString)
+ paramTypes[i+i+1] = 0x00
+
+ if len(v) < longDataSize {
+ paramValues = appendLengthEncodedInteger(paramValues,
+ uint64(len(v)),
+ )
+ paramValues = append(paramValues, v...)
+ } else {
+ if err := stmt.writeCommandLongData(i, []byte(v)); err != nil {
+ return err
+ }
+ }
+
+ case time.Time:
+ paramTypes[i+i] = byte(fieldTypeString)
+ paramTypes[i+i+1] = 0x00
+
+ var a [64]byte
+ var b = a[:0]
+
+ if v.IsZero() {
+ b = append(b, "0000-00-00"...)
+ } else {
+ b = v.In(mc.cfg.Loc).AppendFormat(b, timeFormat)
+ }
+
+ paramValues = appendLengthEncodedInteger(paramValues,
+ uint64(len(b)),
+ )
+ paramValues = append(paramValues, b...)
+
+ default:
+ return fmt.Errorf("cannot convert type: %T", arg)
+ }
+ }
+
+ // Check if param values exceeded the available buffer
+ // In that case we must build the data packet with the new values buffer
+ if valuesCap != cap(paramValues) {
+ data = append(data[:pos], paramValues...)
+ mc.buf.buf = data
+ }
+
+ pos += len(paramValues)
+ data = data[:pos]
+ }
+
+ return mc.writePacket(data)
+}
+
+func (mc *mysqlConn) discardResults() error {
+ for mc.status&statusMoreResultsExists != 0 {
+ resLen, err := mc.readResultSetHeaderPacket()
+ if err != nil {
+ return err
+ }
+ if resLen > 0 {
+ // columns
+ if err := mc.readUntilEOF(); err != nil {
+ return err
+ }
+ // rows
+ if err := mc.readUntilEOF(); err != nil {
+ return err
+ }
+ }
+ }
+ return nil
+}
+
+// http://dev.mysql.com/doc/internals/en/binary-protocol-resultset-row.html
+func (rows *binaryRows) readRow(dest []driver.Value) error {
+ data, err := rows.mc.readPacket()
+ if err != nil {
+ return err
+ }
+
+ // packet indicator [1 byte]
+ if data[0] != iOK {
+ // EOF Packet
+ if data[0] == iEOF && len(data) == 5 {
+ rows.mc.status = readStatus(data[3:])
+ rows.rs.done = true
+ if !rows.HasNextResultSet() {
+ rows.mc = nil
+ }
+ return io.EOF
+ }
+ mc := rows.mc
+ rows.mc = nil
+
+ // Error otherwise
+ return mc.handleErrorPacket(data)
+ }
+
+ // NULL-bitmap, [(column-count + 7 + 2) / 8 bytes]
+ pos := 1 + (len(dest)+7+2)>>3
+ nullMask := data[1:pos]
+
+ for i := range dest {
+ // Field is NULL
+ // (byte >> bit-pos) % 2 == 1
+ if ((nullMask[(i+2)>>3] >> uint((i+2)&7)) & 1) == 1 {
+ dest[i] = nil
+ continue
+ }
+
+ // Convert to byte-coded string
+ switch rows.rs.columns[i].fieldType {
+ case fieldTypeNULL:
+ dest[i] = nil
+ continue
+
+ // Numeric Types
+ case fieldTypeTiny:
+ if rows.rs.columns[i].flags&flagUnsigned != 0 {
+ dest[i] = int64(data[pos])
+ } else {
+ dest[i] = int64(int8(data[pos]))
+ }
+ pos++
+ continue
+
+ case fieldTypeShort, fieldTypeYear:
+ if rows.rs.columns[i].flags&flagUnsigned != 0 {
+ dest[i] = int64(binary.LittleEndian.Uint16(data[pos : pos+2]))
+ } else {
+ dest[i] = int64(int16(binary.LittleEndian.Uint16(data[pos : pos+2])))
+ }
+ pos += 2
+ continue
+
+ case fieldTypeInt24, fieldTypeLong:
+ if rows.rs.columns[i].flags&flagUnsigned != 0 {
+ dest[i] = int64(binary.LittleEndian.Uint32(data[pos : pos+4]))
+ } else {
+ dest[i] = int64(int32(binary.LittleEndian.Uint32(data[pos : pos+4])))
+ }
+ pos += 4
+ continue
+
+ case fieldTypeLongLong:
+ if rows.rs.columns[i].flags&flagUnsigned != 0 {
+ val := binary.LittleEndian.Uint64(data[pos : pos+8])
+ if val > math.MaxInt64 {
+ dest[i] = uint64ToString(val)
+ } else {
+ dest[i] = int64(val)
+ }
+ } else {
+ dest[i] = int64(binary.LittleEndian.Uint64(data[pos : pos+8]))
+ }
+ pos += 8
+ continue
+
+ case fieldTypeFloat:
+ dest[i] = math.Float32frombits(binary.LittleEndian.Uint32(data[pos : pos+4]))
+ pos += 4
+ continue
+
+ case fieldTypeDouble:
+ dest[i] = math.Float64frombits(binary.LittleEndian.Uint64(data[pos : pos+8]))
+ pos += 8
+ continue
+
+ // Length coded Binary Strings
+ case fieldTypeDecimal, fieldTypeNewDecimal, fieldTypeVarChar,
+ fieldTypeBit, fieldTypeEnum, fieldTypeSet, fieldTypeTinyBLOB,
+ fieldTypeMediumBLOB, fieldTypeLongBLOB, fieldTypeBLOB,
+ fieldTypeVarString, fieldTypeString, fieldTypeGeometry, fieldTypeJSON:
+ var isNull bool
+ var n int
+ dest[i], isNull, n, err = readLengthEncodedString(data[pos:])
+ pos += n
+ if err == nil {
+ if !isNull {
+ continue
+ } else {
+ dest[i] = nil
+ continue
+ }
+ }
+ return err
+
+ case
+ fieldTypeDate, fieldTypeNewDate, // Date YYYY-MM-DD
+ fieldTypeTime, // Time [-][H]HH:MM:SS[.fractal]
+ fieldTypeTimestamp, fieldTypeDateTime: // Timestamp YYYY-MM-DD HH:MM:SS[.fractal]
+
+ num, isNull, n := readLengthEncodedInteger(data[pos:])
+ pos += n
+
+ switch {
+ case isNull:
+ dest[i] = nil
+ continue
+ case rows.rs.columns[i].fieldType == fieldTypeTime:
+ // database/sql does not support an equivalent to TIME, return a string
+ var dstlen uint8
+ switch decimals := rows.rs.columns[i].decimals; decimals {
+ case 0x00, 0x1f:
+ dstlen = 8
+ case 1, 2, 3, 4, 5, 6:
+ dstlen = 8 + 1 + decimals
+ default:
+ return fmt.Errorf(
+ "protocol error, illegal decimals value %d",
+ rows.rs.columns[i].decimals,
+ )
+ }
+ dest[i], err = formatBinaryTime(data[pos:pos+int(num)], dstlen)
+ case rows.mc.parseTime:
+ dest[i], err = parseBinaryDateTime(num, data[pos:], rows.mc.cfg.Loc)
+ default:
+ var dstlen uint8
+ if rows.rs.columns[i].fieldType == fieldTypeDate {
+ dstlen = 10
+ } else {
+ switch decimals := rows.rs.columns[i].decimals; decimals {
+ case 0x00, 0x1f:
+ dstlen = 19
+ case 1, 2, 3, 4, 5, 6:
+ dstlen = 19 + 1 + decimals
+ default:
+ return fmt.Errorf(
+ "protocol error, illegal decimals value %d",
+ rows.rs.columns[i].decimals,
+ )
+ }
+ }
+ dest[i], err = formatBinaryDateTime(data[pos:pos+int(num)], dstlen)
+ }
+
+ if err == nil {
+ pos += int(num)
+ continue
+ } else {
+ return err
+ }
+
+ // Please report if this happens!
+ default:
+ return fmt.Errorf("unknown field type %d", rows.rs.columns[i].fieldType)
+ }
+ }
+
+ return nil
+}
diff --git a/vendor/github.com/go-sql-driver/mysql/result.go b/vendor/github.com/go-sql-driver/mysql/result.go
new file mode 100644
index 0000000000000000000000000000000000000000..c6438d0347db5c570524ba792975883631cce8e7
--- /dev/null
+++ b/vendor/github.com/go-sql-driver/mysql/result.go
@@ -0,0 +1,22 @@
+// Go MySQL Driver - A MySQL-Driver for Go's database/sql package
+//
+// Copyright 2012 The Go-MySQL-Driver Authors. All rights reserved.
+//
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this file,
+// You can obtain one at http://mozilla.org/MPL/2.0/.
+
+package mysql
+
+type mysqlResult struct {
+ affectedRows int64
+ insertId int64
+}
+
+func (res *mysqlResult) LastInsertId() (int64, error) {
+ return res.insertId, nil
+}
+
+func (res *mysqlResult) RowsAffected() (int64, error) {
+ return res.affectedRows, nil
+}
diff --git a/vendor/github.com/go-sql-driver/mysql/rows.go b/vendor/github.com/go-sql-driver/mysql/rows.go
new file mode 100644
index 0000000000000000000000000000000000000000..d3b1e28221765afd3c01b30c443ade9f4e2ce3ac
--- /dev/null
+++ b/vendor/github.com/go-sql-driver/mysql/rows.go
@@ -0,0 +1,216 @@
+// Go MySQL Driver - A MySQL-Driver for Go's database/sql package
+//
+// Copyright 2012 The Go-MySQL-Driver Authors. All rights reserved.
+//
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this file,
+// You can obtain one at http://mozilla.org/MPL/2.0/.
+
+package mysql
+
+import (
+ "database/sql/driver"
+ "io"
+ "math"
+ "reflect"
+)
+
+type resultSet struct {
+ columns []mysqlField
+ columnNames []string
+ done bool
+}
+
+type mysqlRows struct {
+ mc *mysqlConn
+ rs resultSet
+ finish func()
+}
+
+type binaryRows struct {
+ mysqlRows
+}
+
+type textRows struct {
+ mysqlRows
+}
+
+func (rows *mysqlRows) Columns() []string {
+ if rows.rs.columnNames != nil {
+ return rows.rs.columnNames
+ }
+
+ columns := make([]string, len(rows.rs.columns))
+ if rows.mc != nil && rows.mc.cfg.ColumnsWithAlias {
+ for i := range columns {
+ if tableName := rows.rs.columns[i].tableName; len(tableName) > 0 {
+ columns[i] = tableName + "." + rows.rs.columns[i].name
+ } else {
+ columns[i] = rows.rs.columns[i].name
+ }
+ }
+ } else {
+ for i := range columns {
+ columns[i] = rows.rs.columns[i].name
+ }
+ }
+
+ rows.rs.columnNames = columns
+ return columns
+}
+
+func (rows *mysqlRows) ColumnTypeDatabaseTypeName(i int) string {
+ return rows.rs.columns[i].typeDatabaseName()
+}
+
+// func (rows *mysqlRows) ColumnTypeLength(i int) (length int64, ok bool) {
+// return int64(rows.rs.columns[i].length), true
+// }
+
+func (rows *mysqlRows) ColumnTypeNullable(i int) (nullable, ok bool) {
+ return rows.rs.columns[i].flags&flagNotNULL == 0, true
+}
+
+func (rows *mysqlRows) ColumnTypePrecisionScale(i int) (int64, int64, bool) {
+ column := rows.rs.columns[i]
+ decimals := int64(column.decimals)
+
+ switch column.fieldType {
+ case fieldTypeDecimal, fieldTypeNewDecimal:
+ if decimals > 0 {
+ return int64(column.length) - 2, decimals, true
+ }
+ return int64(column.length) - 1, decimals, true
+ case fieldTypeTimestamp, fieldTypeDateTime, fieldTypeTime:
+ return decimals, decimals, true
+ case fieldTypeFloat, fieldTypeDouble:
+ if decimals == 0x1f {
+ return math.MaxInt64, math.MaxInt64, true
+ }
+ return math.MaxInt64, decimals, true
+ }
+
+ return 0, 0, false
+}
+
+func (rows *mysqlRows) ColumnTypeScanType(i int) reflect.Type {
+ return rows.rs.columns[i].scanType()
+}
+
+func (rows *mysqlRows) Close() (err error) {
+ if f := rows.finish; f != nil {
+ f()
+ rows.finish = nil
+ }
+
+ mc := rows.mc
+ if mc == nil {
+ return nil
+ }
+ if err := mc.error(); err != nil {
+ return err
+ }
+
+ // Remove unread packets from stream
+ if !rows.rs.done {
+ err = mc.readUntilEOF()
+ }
+ if err == nil {
+ if err = mc.discardResults(); err != nil {
+ return err
+ }
+ }
+
+ rows.mc = nil
+ return err
+}
+
+func (rows *mysqlRows) HasNextResultSet() (b bool) {
+ if rows.mc == nil {
+ return false
+ }
+ return rows.mc.status&statusMoreResultsExists != 0
+}
+
+func (rows *mysqlRows) nextResultSet() (int, error) {
+ if rows.mc == nil {
+ return 0, io.EOF
+ }
+ if err := rows.mc.error(); err != nil {
+ return 0, err
+ }
+
+ // Remove unread packets from stream
+ if !rows.rs.done {
+ if err := rows.mc.readUntilEOF(); err != nil {
+ return 0, err
+ }
+ rows.rs.done = true
+ }
+
+ if !rows.HasNextResultSet() {
+ rows.mc = nil
+ return 0, io.EOF
+ }
+ rows.rs = resultSet{}
+ return rows.mc.readResultSetHeaderPacket()
+}
+
+func (rows *mysqlRows) nextNotEmptyResultSet() (int, error) {
+ for {
+ resLen, err := rows.nextResultSet()
+ if err != nil {
+ return 0, err
+ }
+
+ if resLen > 0 {
+ return resLen, nil
+ }
+
+ rows.rs.done = true
+ }
+}
+
+func (rows *binaryRows) NextResultSet() error {
+ resLen, err := rows.nextNotEmptyResultSet()
+ if err != nil {
+ return err
+ }
+
+ rows.rs.columns, err = rows.mc.readColumns(resLen)
+ return err
+}
+
+func (rows *binaryRows) Next(dest []driver.Value) error {
+ if mc := rows.mc; mc != nil {
+ if err := mc.error(); err != nil {
+ return err
+ }
+
+ // Fetch next row from stream
+ return rows.readRow(dest)
+ }
+ return io.EOF
+}
+
+func (rows *textRows) NextResultSet() (err error) {
+ resLen, err := rows.nextNotEmptyResultSet()
+ if err != nil {
+ return err
+ }
+
+ rows.rs.columns, err = rows.mc.readColumns(resLen)
+ return err
+}
+
+func (rows *textRows) Next(dest []driver.Value) error {
+ if mc := rows.mc; mc != nil {
+ if err := mc.error(); err != nil {
+ return err
+ }
+
+ // Fetch next row from stream
+ return rows.readRow(dest)
+ }
+ return io.EOF
+}
diff --git a/vendor/github.com/go-sql-driver/mysql/statement.go b/vendor/github.com/go-sql-driver/mysql/statement.go
new file mode 100644
index 0000000000000000000000000000000000000000..ce7fe4cd049dace5c41639b732ee50e202c280bd
--- /dev/null
+++ b/vendor/github.com/go-sql-driver/mysql/statement.go
@@ -0,0 +1,211 @@
+// Go MySQL Driver - A MySQL-Driver for Go's database/sql package
+//
+// Copyright 2012 The Go-MySQL-Driver Authors. All rights reserved.
+//
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this file,
+// You can obtain one at http://mozilla.org/MPL/2.0/.
+
+package mysql
+
+import (
+ "database/sql/driver"
+ "fmt"
+ "io"
+ "reflect"
+ "strconv"
+)
+
+type mysqlStmt struct {
+ mc *mysqlConn
+ id uint32
+ paramCount int
+}
+
+func (stmt *mysqlStmt) Close() error {
+ if stmt.mc == nil || stmt.mc.closed.IsSet() {
+ // driver.Stmt.Close can be called more than once, thus this function
+ // has to be idempotent.
+ // See also Issue #450 and golang/go#16019.
+ //errLog.Print(ErrInvalidConn)
+ return driver.ErrBadConn
+ }
+
+ err := stmt.mc.writeCommandPacketUint32(comStmtClose, stmt.id)
+ stmt.mc = nil
+ return err
+}
+
+func (stmt *mysqlStmt) NumInput() int {
+ return stmt.paramCount
+}
+
+func (stmt *mysqlStmt) ColumnConverter(idx int) driver.ValueConverter {
+ return converter{}
+}
+
+func (stmt *mysqlStmt) Exec(args []driver.Value) (driver.Result, error) {
+ if stmt.mc.closed.IsSet() {
+ errLog.Print(ErrInvalidConn)
+ return nil, driver.ErrBadConn
+ }
+ // Send command
+ err := stmt.writeExecutePacket(args)
+ if err != nil {
+ return nil, stmt.mc.markBadConn(err)
+ }
+
+ mc := stmt.mc
+
+ mc.affectedRows = 0
+ mc.insertId = 0
+
+ // Read Result
+ resLen, err := mc.readResultSetHeaderPacket()
+ if err != nil {
+ return nil, err
+ }
+
+ if resLen > 0 {
+ // Columns
+ if err = mc.readUntilEOF(); err != nil {
+ return nil, err
+ }
+
+ // Rows
+ if err := mc.readUntilEOF(); err != nil {
+ return nil, err
+ }
+ }
+
+ if err := mc.discardResults(); err != nil {
+ return nil, err
+ }
+
+ return &mysqlResult{
+ affectedRows: int64(mc.affectedRows),
+ insertId: int64(mc.insertId),
+ }, nil
+}
+
+func (stmt *mysqlStmt) Query(args []driver.Value) (driver.Rows, error) {
+ return stmt.query(args)
+}
+
+func (stmt *mysqlStmt) query(args []driver.Value) (*binaryRows, error) {
+ if stmt.mc.closed.IsSet() {
+ errLog.Print(ErrInvalidConn)
+ return nil, driver.ErrBadConn
+ }
+ // Send command
+ err := stmt.writeExecutePacket(args)
+ if err != nil {
+ return nil, stmt.mc.markBadConn(err)
+ }
+
+ mc := stmt.mc
+
+ // Read Result
+ resLen, err := mc.readResultSetHeaderPacket()
+ if err != nil {
+ return nil, err
+ }
+
+ rows := new(binaryRows)
+
+ if resLen > 0 {
+ rows.mc = mc
+ rows.rs.columns, err = mc.readColumns(resLen)
+ } else {
+ rows.rs.done = true
+
+ switch err := rows.NextResultSet(); err {
+ case nil, io.EOF:
+ return rows, nil
+ default:
+ return nil, err
+ }
+ }
+
+ return rows, err
+}
+
+type converter struct{}
+
+// ConvertValue mirrors the reference/default converter in database/sql/driver
+// with _one_ exception. We support uint64 with their high bit and the default
+// implementation does not. This function should be kept in sync with
+// database/sql/driver defaultConverter.ConvertValue() except for that
+// deliberate difference.
+func (c converter) ConvertValue(v interface{}) (driver.Value, error) {
+ if driver.IsValue(v) {
+ return v, nil
+ }
+
+ if vr, ok := v.(driver.Valuer); ok {
+ sv, err := callValuerValue(vr)
+ if err != nil {
+ return nil, err
+ }
+ if !driver.IsValue(sv) {
+ return nil, fmt.Errorf("non-Value type %T returned from Value", sv)
+ }
+ return sv, nil
+ }
+
+ rv := reflect.ValueOf(v)
+ switch rv.Kind() {
+ case reflect.Ptr:
+ // indirect pointers
+ if rv.IsNil() {
+ return nil, nil
+ } else {
+ return c.ConvertValue(rv.Elem().Interface())
+ }
+ case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+ return rv.Int(), nil
+ case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32:
+ return int64(rv.Uint()), nil
+ case reflect.Uint64:
+ u64 := rv.Uint()
+ if u64 >= 1<<63 {
+ return strconv.FormatUint(u64, 10), nil
+ }
+ return int64(u64), nil
+ case reflect.Float32, reflect.Float64:
+ return rv.Float(), nil
+ case reflect.Bool:
+ return rv.Bool(), nil
+ case reflect.Slice:
+ ek := rv.Type().Elem().Kind()
+ if ek == reflect.Uint8 {
+ return rv.Bytes(), nil
+ }
+ return nil, fmt.Errorf("unsupported type %T, a slice of %s", v, ek)
+ case reflect.String:
+ return rv.String(), nil
+ }
+ return nil, fmt.Errorf("unsupported type %T, a %s", v, rv.Kind())
+}
+
+var valuerReflectType = reflect.TypeOf((*driver.Valuer)(nil)).Elem()
+
+// callValuerValue returns vr.Value(), with one exception:
+// If vr.Value is an auto-generated method on a pointer type and the
+// pointer is nil, it would panic at runtime in the panicwrap
+// method. Treat it like nil instead.
+//
+// This is so people can implement driver.Value on value types and
+// still use nil pointers to those types to mean nil/NULL, just like
+// string/*string.
+//
+// This is an exact copy of the same-named unexported function from the
+// database/sql package.
+func callValuerValue(vr driver.Valuer) (v driver.Value, err error) {
+ if rv := reflect.ValueOf(vr); rv.Kind() == reflect.Ptr &&
+ rv.IsNil() &&
+ rv.Type().Elem().Implements(valuerReflectType) {
+ return nil, nil
+ }
+ return vr.Value()
+}
diff --git a/vendor/github.com/go-sql-driver/mysql/transaction.go b/vendor/github.com/go-sql-driver/mysql/transaction.go
new file mode 100644
index 0000000000000000000000000000000000000000..417d72793b1f5a83a639716a9cd47dca25071766
--- /dev/null
+++ b/vendor/github.com/go-sql-driver/mysql/transaction.go
@@ -0,0 +1,31 @@
+// Go MySQL Driver - A MySQL-Driver for Go's database/sql package
+//
+// Copyright 2012 The Go-MySQL-Driver Authors. All rights reserved.
+//
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this file,
+// You can obtain one at http://mozilla.org/MPL/2.0/.
+
+package mysql
+
+type mysqlTx struct {
+ mc *mysqlConn
+}
+
+func (tx *mysqlTx) Commit() (err error) {
+ if tx.mc == nil || tx.mc.closed.IsSet() {
+ return ErrInvalidConn
+ }
+ err = tx.mc.exec("COMMIT")
+ tx.mc = nil
+ return
+}
+
+func (tx *mysqlTx) Rollback() (err error) {
+ if tx.mc == nil || tx.mc.closed.IsSet() {
+ return ErrInvalidConn
+ }
+ err = tx.mc.exec("ROLLBACK")
+ tx.mc = nil
+ return
+}
diff --git a/vendor/github.com/go-sql-driver/mysql/utils.go b/vendor/github.com/go-sql-driver/mysql/utils.go
new file mode 100644
index 0000000000000000000000000000000000000000..ca5d47d825d08c374c958d7b08a57c4c04b09796
--- /dev/null
+++ b/vendor/github.com/go-sql-driver/mysql/utils.go
@@ -0,0 +1,726 @@
+// Go MySQL Driver - A MySQL-Driver for Go's database/sql package
+//
+// Copyright 2012 The Go-MySQL-Driver Authors. All rights reserved.
+//
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this file,
+// You can obtain one at http://mozilla.org/MPL/2.0/.
+
+package mysql
+
+import (
+ "crypto/tls"
+ "database/sql/driver"
+ "encoding/binary"
+ "fmt"
+ "io"
+ "strconv"
+ "strings"
+ "sync"
+ "sync/atomic"
+ "time"
+)
+
+// Registry for custom tls.Configs
+var (
+ tlsConfigLock sync.RWMutex
+ tlsConfigRegistry map[string]*tls.Config
+)
+
+// RegisterTLSConfig registers a custom tls.Config to be used with sql.Open.
+// Use the key as a value in the DSN where tls=value.
+//
+// Note: The provided tls.Config is exclusively owned by the driver after
+// registering it.
+//
+// rootCertPool := x509.NewCertPool()
+// pem, err := ioutil.ReadFile("/path/ca-cert.pem")
+// if err != nil {
+// log.Fatal(err)
+// }
+// if ok := rootCertPool.AppendCertsFromPEM(pem); !ok {
+// log.Fatal("Failed to append PEM.")
+// }
+// clientCert := make([]tls.Certificate, 0, 1)
+// certs, err := tls.LoadX509KeyPair("/path/client-cert.pem", "/path/client-key.pem")
+// if err != nil {
+// log.Fatal(err)
+// }
+// clientCert = append(clientCert, certs)
+// mysql.RegisterTLSConfig("custom", &tls.Config{
+// RootCAs: rootCertPool,
+// Certificates: clientCert,
+// })
+// db, err := sql.Open("mysql", "user@tcp(localhost:3306)/test?tls=custom")
+//
+func RegisterTLSConfig(key string, config *tls.Config) error {
+ if _, isBool := readBool(key); isBool || strings.ToLower(key) == "skip-verify" {
+ return fmt.Errorf("key '%s' is reserved", key)
+ }
+
+ tlsConfigLock.Lock()
+ if tlsConfigRegistry == nil {
+ tlsConfigRegistry = make(map[string]*tls.Config)
+ }
+
+ tlsConfigRegistry[key] = config
+ tlsConfigLock.Unlock()
+ return nil
+}
+
+// DeregisterTLSConfig removes the tls.Config associated with key.
+func DeregisterTLSConfig(key string) {
+ tlsConfigLock.Lock()
+ if tlsConfigRegistry != nil {
+ delete(tlsConfigRegistry, key)
+ }
+ tlsConfigLock.Unlock()
+}
+
+func getTLSConfigClone(key string) (config *tls.Config) {
+ tlsConfigLock.RLock()
+ if v, ok := tlsConfigRegistry[key]; ok {
+ config = cloneTLSConfig(v)
+ }
+ tlsConfigLock.RUnlock()
+ return
+}
+
+// Returns the bool value of the input.
+// The 2nd return value indicates if the input was a valid bool value
+func readBool(input string) (value bool, valid bool) {
+ switch input {
+ case "1", "true", "TRUE", "True":
+ return true, true
+ case "0", "false", "FALSE", "False":
+ return false, true
+ }
+
+ // Not a valid bool value
+ return
+}
+
+/******************************************************************************
+* Time related utils *
+******************************************************************************/
+
+// NullTime represents a time.Time that may be NULL.
+// NullTime implements the Scanner interface so
+// it can be used as a scan destination:
+//
+// var nt NullTime
+// err := db.QueryRow("SELECT time FROM foo WHERE id=?", id).Scan(&nt)
+// ...
+// if nt.Valid {
+// // use nt.Time
+// } else {
+// // NULL value
+// }
+//
+// This NullTime implementation is not driver-specific
+type NullTime struct {
+ Time time.Time
+ Valid bool // Valid is true if Time is not NULL
+}
+
+// Scan implements the Scanner interface.
+// The value type must be time.Time or string / []byte (formatted time-string),
+// otherwise Scan fails.
+func (nt *NullTime) Scan(value interface{}) (err error) {
+ if value == nil {
+ nt.Time, nt.Valid = time.Time{}, false
+ return
+ }
+
+ switch v := value.(type) {
+ case time.Time:
+ nt.Time, nt.Valid = v, true
+ return
+ case []byte:
+ nt.Time, err = parseDateTime(string(v), time.UTC)
+ nt.Valid = (err == nil)
+ return
+ case string:
+ nt.Time, err = parseDateTime(v, time.UTC)
+ nt.Valid = (err == nil)
+ return
+ }
+
+ nt.Valid = false
+ return fmt.Errorf("Can't convert %T to time.Time", value)
+}
+
+// Value implements the driver Valuer interface.
+func (nt NullTime) Value() (driver.Value, error) {
+ if !nt.Valid {
+ return nil, nil
+ }
+ return nt.Time, nil
+}
+
+func parseDateTime(str string, loc *time.Location) (t time.Time, err error) {
+ base := "0000-00-00 00:00:00.0000000"
+ switch len(str) {
+ case 10, 19, 21, 22, 23, 24, 25, 26: // up to "YYYY-MM-DD HH:MM:SS.MMMMMM"
+ if str == base[:len(str)] {
+ return
+ }
+ t, err = time.Parse(timeFormat[:len(str)], str)
+ default:
+ err = fmt.Errorf("invalid time string: %s", str)
+ return
+ }
+
+ // Adjust location
+ if err == nil && loc != time.UTC {
+ y, mo, d := t.Date()
+ h, mi, s := t.Clock()
+ t, err = time.Date(y, mo, d, h, mi, s, t.Nanosecond(), loc), nil
+ }
+
+ return
+}
+
+func parseBinaryDateTime(num uint64, data []byte, loc *time.Location) (driver.Value, error) {
+ switch num {
+ case 0:
+ return time.Time{}, nil
+ case 4:
+ return time.Date(
+ int(binary.LittleEndian.Uint16(data[:2])), // year
+ time.Month(data[2]), // month
+ int(data[3]), // day
+ 0, 0, 0, 0,
+ loc,
+ ), nil
+ case 7:
+ return time.Date(
+ int(binary.LittleEndian.Uint16(data[:2])), // year
+ time.Month(data[2]), // month
+ int(data[3]), // day
+ int(data[4]), // hour
+ int(data[5]), // minutes
+ int(data[6]), // seconds
+ 0,
+ loc,
+ ), nil
+ case 11:
+ return time.Date(
+ int(binary.LittleEndian.Uint16(data[:2])), // year
+ time.Month(data[2]), // month
+ int(data[3]), // day
+ int(data[4]), // hour
+ int(data[5]), // minutes
+ int(data[6]), // seconds
+ int(binary.LittleEndian.Uint32(data[7:11]))*1000, // nanoseconds
+ loc,
+ ), nil
+ }
+ return nil, fmt.Errorf("invalid DATETIME packet length %d", num)
+}
+
+// zeroDateTime is used in formatBinaryDateTime to avoid an allocation
+// if the DATE or DATETIME has the zero value.
+// It must never be changed.
+// The current behavior depends on database/sql copying the result.
+var zeroDateTime = []byte("0000-00-00 00:00:00.000000")
+
+const digits01 = "0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789"
+const digits10 = "0000000000111111111122222222223333333333444444444455555555556666666666777777777788888888889999999999"
+
+func appendMicrosecs(dst, src []byte, decimals int) []byte {
+ if decimals <= 0 {
+ return dst
+ }
+ if len(src) == 0 {
+ return append(dst, ".000000"[:decimals+1]...)
+ }
+
+ microsecs := binary.LittleEndian.Uint32(src[:4])
+ p1 := byte(microsecs / 10000)
+ microsecs -= 10000 * uint32(p1)
+ p2 := byte(microsecs / 100)
+ microsecs -= 100 * uint32(p2)
+ p3 := byte(microsecs)
+
+ switch decimals {
+ default:
+ return append(dst, '.',
+ digits10[p1], digits01[p1],
+ digits10[p2], digits01[p2],
+ digits10[p3], digits01[p3],
+ )
+ case 1:
+ return append(dst, '.',
+ digits10[p1],
+ )
+ case 2:
+ return append(dst, '.',
+ digits10[p1], digits01[p1],
+ )
+ case 3:
+ return append(dst, '.',
+ digits10[p1], digits01[p1],
+ digits10[p2],
+ )
+ case 4:
+ return append(dst, '.',
+ digits10[p1], digits01[p1],
+ digits10[p2], digits01[p2],
+ )
+ case 5:
+ return append(dst, '.',
+ digits10[p1], digits01[p1],
+ digits10[p2], digits01[p2],
+ digits10[p3],
+ )
+ }
+}
+
+func formatBinaryDateTime(src []byte, length uint8) (driver.Value, error) {
+ // length expects the deterministic length of the zero value,
+ // negative time and 100+ hours are automatically added if needed
+ if len(src) == 0 {
+ return zeroDateTime[:length], nil
+ }
+ var dst []byte // return value
+ var p1, p2, p3 byte // current digit pair
+
+ switch length {
+ case 10, 19, 21, 22, 23, 24, 25, 26:
+ default:
+ t := "DATE"
+ if length > 10 {
+ t += "TIME"
+ }
+ return nil, fmt.Errorf("illegal %s length %d", t, length)
+ }
+ switch len(src) {
+ case 4, 7, 11:
+ default:
+ t := "DATE"
+ if length > 10 {
+ t += "TIME"
+ }
+ return nil, fmt.Errorf("illegal %s packet length %d", t, len(src))
+ }
+ dst = make([]byte, 0, length)
+ // start with the date
+ year := binary.LittleEndian.Uint16(src[:2])
+ pt := year / 100
+ p1 = byte(year - 100*uint16(pt))
+ p2, p3 = src[2], src[3]
+ dst = append(dst,
+ digits10[pt], digits01[pt],
+ digits10[p1], digits01[p1], '-',
+ digits10[p2], digits01[p2], '-',
+ digits10[p3], digits01[p3],
+ )
+ if length == 10 {
+ return dst, nil
+ }
+ if len(src) == 4 {
+ return append(dst, zeroDateTime[10:length]...), nil
+ }
+ dst = append(dst, ' ')
+ p1 = src[4] // hour
+ src = src[5:]
+
+ // p1 is 2-digit hour, src is after hour
+ p2, p3 = src[0], src[1]
+ dst = append(dst,
+ digits10[p1], digits01[p1], ':',
+ digits10[p2], digits01[p2], ':',
+ digits10[p3], digits01[p3],
+ )
+ return appendMicrosecs(dst, src[2:], int(length)-20), nil
+}
+
+func formatBinaryTime(src []byte, length uint8) (driver.Value, error) {
+ // length expects the deterministic length of the zero value,
+ // negative time and 100+ hours are automatically added if needed
+ if len(src) == 0 {
+ return zeroDateTime[11 : 11+length], nil
+ }
+ var dst []byte // return value
+
+ switch length {
+ case
+ 8, // time (can be up to 10 when negative and 100+ hours)
+ 10, 11, 12, 13, 14, 15: // time with fractional seconds
+ default:
+ return nil, fmt.Errorf("illegal TIME length %d", length)
+ }
+ switch len(src) {
+ case 8, 12:
+ default:
+ return nil, fmt.Errorf("invalid TIME packet length %d", len(src))
+ }
+ // +2 to enable negative time and 100+ hours
+ dst = make([]byte, 0, length+2)
+ if src[0] == 1 {
+ dst = append(dst, '-')
+ }
+ days := binary.LittleEndian.Uint32(src[1:5])
+ hours := int64(days)*24 + int64(src[5])
+
+ if hours >= 100 {
+ dst = strconv.AppendInt(dst, hours, 10)
+ } else {
+ dst = append(dst, digits10[hours], digits01[hours])
+ }
+
+ min, sec := src[6], src[7]
+ dst = append(dst, ':',
+ digits10[min], digits01[min], ':',
+ digits10[sec], digits01[sec],
+ )
+ return appendMicrosecs(dst, src[8:], int(length)-9), nil
+}
+
+/******************************************************************************
+* Convert from and to bytes *
+******************************************************************************/
+
+func uint64ToBytes(n uint64) []byte {
+ return []byte{
+ byte(n),
+ byte(n >> 8),
+ byte(n >> 16),
+ byte(n >> 24),
+ byte(n >> 32),
+ byte(n >> 40),
+ byte(n >> 48),
+ byte(n >> 56),
+ }
+}
+
+func uint64ToString(n uint64) []byte {
+ var a [20]byte
+ i := 20
+
+ // U+0030 = 0
+ // ...
+ // U+0039 = 9
+
+ var q uint64
+ for n >= 10 {
+ i--
+ q = n / 10
+ a[i] = uint8(n-q*10) + 0x30
+ n = q
+ }
+
+ i--
+ a[i] = uint8(n) + 0x30
+
+ return a[i:]
+}
+
+// treats string value as unsigned integer representation
+func stringToInt(b []byte) int {
+ val := 0
+ for i := range b {
+ val *= 10
+ val += int(b[i] - 0x30)
+ }
+ return val
+}
+
+// returns the string read as a bytes slice, wheter the value is NULL,
+// the number of bytes read and an error, in case the string is longer than
+// the input slice
+func readLengthEncodedString(b []byte) ([]byte, bool, int, error) {
+ // Get length
+ num, isNull, n := readLengthEncodedInteger(b)
+ if num < 1 {
+ return b[n:n], isNull, n, nil
+ }
+
+ n += int(num)
+
+ // Check data length
+ if len(b) >= n {
+ return b[n-int(num) : n : n], false, n, nil
+ }
+ return nil, false, n, io.EOF
+}
+
+// returns the number of bytes skipped and an error, in case the string is
+// longer than the input slice
+func skipLengthEncodedString(b []byte) (int, error) {
+ // Get length
+ num, _, n := readLengthEncodedInteger(b)
+ if num < 1 {
+ return n, nil
+ }
+
+ n += int(num)
+
+ // Check data length
+ if len(b) >= n {
+ return n, nil
+ }
+ return n, io.EOF
+}
+
+// returns the number read, whether the value is NULL and the number of bytes read
+func readLengthEncodedInteger(b []byte) (uint64, bool, int) {
+ // See issue #349
+ if len(b) == 0 {
+ return 0, true, 1
+ }
+
+ switch b[0] {
+ // 251: NULL
+ case 0xfb:
+ return 0, true, 1
+
+ // 252: value of following 2
+ case 0xfc:
+ return uint64(b[1]) | uint64(b[2])<<8, false, 3
+
+ // 253: value of following 3
+ case 0xfd:
+ return uint64(b[1]) | uint64(b[2])<<8 | uint64(b[3])<<16, false, 4
+
+ // 254: value of following 8
+ case 0xfe:
+ return uint64(b[1]) | uint64(b[2])<<8 | uint64(b[3])<<16 |
+ uint64(b[4])<<24 | uint64(b[5])<<32 | uint64(b[6])<<40 |
+ uint64(b[7])<<48 | uint64(b[8])<<56,
+ false, 9
+ }
+
+ // 0-250: value of first byte
+ return uint64(b[0]), false, 1
+}
+
+// encodes a uint64 value and appends it to the given bytes slice
+func appendLengthEncodedInteger(b []byte, n uint64) []byte {
+ switch {
+ case n <= 250:
+ return append(b, byte(n))
+
+ case n <= 0xffff:
+ return append(b, 0xfc, byte(n), byte(n>>8))
+
+ case n <= 0xffffff:
+ return append(b, 0xfd, byte(n), byte(n>>8), byte(n>>16))
+ }
+ return append(b, 0xfe, byte(n), byte(n>>8), byte(n>>16), byte(n>>24),
+ byte(n>>32), byte(n>>40), byte(n>>48), byte(n>>56))
+}
+
+// reserveBuffer checks cap(buf) and expand buffer to len(buf) + appendSize.
+// If cap(buf) is not enough, reallocate new buffer.
+func reserveBuffer(buf []byte, appendSize int) []byte {
+ newSize := len(buf) + appendSize
+ if cap(buf) < newSize {
+ // Grow buffer exponentially
+ newBuf := make([]byte, len(buf)*2+appendSize)
+ copy(newBuf, buf)
+ buf = newBuf
+ }
+ return buf[:newSize]
+}
+
+// escapeBytesBackslash escapes []byte with backslashes (\)
+// This escapes the contents of a string (provided as []byte) by adding backslashes before special
+// characters, and turning others into specific escape sequences, such as
+// turning newlines into \n and null bytes into \0.
+// https://github.com/mysql/mysql-server/blob/mysql-5.7.5/mysys/charset.c#L823-L932
+func escapeBytesBackslash(buf, v []byte) []byte {
+ pos := len(buf)
+ buf = reserveBuffer(buf, len(v)*2)
+
+ for _, c := range v {
+ switch c {
+ case '\x00':
+ buf[pos] = '\\'
+ buf[pos+1] = '0'
+ pos += 2
+ case '\n':
+ buf[pos] = '\\'
+ buf[pos+1] = 'n'
+ pos += 2
+ case '\r':
+ buf[pos] = '\\'
+ buf[pos+1] = 'r'
+ pos += 2
+ case '\x1a':
+ buf[pos] = '\\'
+ buf[pos+1] = 'Z'
+ pos += 2
+ case '\'':
+ buf[pos] = '\\'
+ buf[pos+1] = '\''
+ pos += 2
+ case '"':
+ buf[pos] = '\\'
+ buf[pos+1] = '"'
+ pos += 2
+ case '\\':
+ buf[pos] = '\\'
+ buf[pos+1] = '\\'
+ pos += 2
+ default:
+ buf[pos] = c
+ pos++
+ }
+ }
+
+ return buf[:pos]
+}
+
+// escapeStringBackslash is similar to escapeBytesBackslash but for string.
+func escapeStringBackslash(buf []byte, v string) []byte {
+ pos := len(buf)
+ buf = reserveBuffer(buf, len(v)*2)
+
+ for i := 0; i < len(v); i++ {
+ c := v[i]
+ switch c {
+ case '\x00':
+ buf[pos] = '\\'
+ buf[pos+1] = '0'
+ pos += 2
+ case '\n':
+ buf[pos] = '\\'
+ buf[pos+1] = 'n'
+ pos += 2
+ case '\r':
+ buf[pos] = '\\'
+ buf[pos+1] = 'r'
+ pos += 2
+ case '\x1a':
+ buf[pos] = '\\'
+ buf[pos+1] = 'Z'
+ pos += 2
+ case '\'':
+ buf[pos] = '\\'
+ buf[pos+1] = '\''
+ pos += 2
+ case '"':
+ buf[pos] = '\\'
+ buf[pos+1] = '"'
+ pos += 2
+ case '\\':
+ buf[pos] = '\\'
+ buf[pos+1] = '\\'
+ pos += 2
+ default:
+ buf[pos] = c
+ pos++
+ }
+ }
+
+ return buf[:pos]
+}
+
+// escapeBytesQuotes escapes apostrophes in []byte by doubling them up.
+// This escapes the contents of a string by doubling up any apostrophes that
+// it contains. This is used when the NO_BACKSLASH_ESCAPES SQL_MODE is in
+// effect on the server.
+// https://github.com/mysql/mysql-server/blob/mysql-5.7.5/mysys/charset.c#L963-L1038
+func escapeBytesQuotes(buf, v []byte) []byte {
+ pos := len(buf)
+ buf = reserveBuffer(buf, len(v)*2)
+
+ for _, c := range v {
+ if c == '\'' {
+ buf[pos] = '\''
+ buf[pos+1] = '\''
+ pos += 2
+ } else {
+ buf[pos] = c
+ pos++
+ }
+ }
+
+ return buf[:pos]
+}
+
+// escapeStringQuotes is similar to escapeBytesQuotes but for string.
+func escapeStringQuotes(buf []byte, v string) []byte {
+ pos := len(buf)
+ buf = reserveBuffer(buf, len(v)*2)
+
+ for i := 0; i < len(v); i++ {
+ c := v[i]
+ if c == '\'' {
+ buf[pos] = '\''
+ buf[pos+1] = '\''
+ pos += 2
+ } else {
+ buf[pos] = c
+ pos++
+ }
+ }
+
+ return buf[:pos]
+}
+
+/******************************************************************************
+* Sync utils *
+******************************************************************************/
+
+// noCopy may be embedded into structs which must not be copied
+// after the first use.
+//
+// See https://github.com/golang/go/issues/8005#issuecomment-190753527
+// for details.
+type noCopy struct{}
+
+// Lock is a no-op used by -copylocks checker from `go vet`.
+func (*noCopy) Lock() {}
+
+// atomicBool is a wrapper around uint32 for usage as a boolean value with
+// atomic access.
+type atomicBool struct {
+ _noCopy noCopy
+ value uint32
+}
+
+// IsSet returns wether the current boolean value is true
+func (ab *atomicBool) IsSet() bool {
+ return atomic.LoadUint32(&ab.value) > 0
+}
+
+// Set sets the value of the bool regardless of the previous value
+func (ab *atomicBool) Set(value bool) {
+ if value {
+ atomic.StoreUint32(&ab.value, 1)
+ } else {
+ atomic.StoreUint32(&ab.value, 0)
+ }
+}
+
+// TrySet sets the value of the bool and returns wether the value changed
+func (ab *atomicBool) TrySet(value bool) bool {
+ if value {
+ return atomic.SwapUint32(&ab.value, 1) == 0
+ }
+ return atomic.SwapUint32(&ab.value, 0) > 0
+}
+
+// atomicError is a wrapper for atomically accessed error values
+type atomicError struct {
+ _noCopy noCopy
+ value atomic.Value
+}
+
+// Set sets the error value regardless of the previous value.
+// The value must not be nil
+func (ae *atomicError) Set(value error) {
+ ae.value.Store(value)
+}
+
+// Value returns the current error value
+func (ae *atomicError) Value() error {
+ if v := ae.value.Load(); v != nil {
+ // this will panic if the value doesn't implement the error interface
+ return v.(error)
+ }
+ return nil
+}
diff --git a/vendor/github.com/go-sql-driver/mysql/utils_go17.go b/vendor/github.com/go-sql-driver/mysql/utils_go17.go
new file mode 100644
index 0000000000000000000000000000000000000000..f5956345674d68a9f83f18cfa40788801cccfc44
--- /dev/null
+++ b/vendor/github.com/go-sql-driver/mysql/utils_go17.go
@@ -0,0 +1,40 @@
+// Go MySQL Driver - A MySQL-Driver for Go's database/sql package
+//
+// Copyright 2017 The Go-MySQL-Driver Authors. All rights reserved.
+//
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this file,
+// You can obtain one at http://mozilla.org/MPL/2.0/.
+
+// +build go1.7
+// +build !go1.8
+
+package mysql
+
+import "crypto/tls"
+
+func cloneTLSConfig(c *tls.Config) *tls.Config {
+ return &tls.Config{
+ Rand: c.Rand,
+ Time: c.Time,
+ Certificates: c.Certificates,
+ NameToCertificate: c.NameToCertificate,
+ GetCertificate: c.GetCertificate,
+ RootCAs: c.RootCAs,
+ NextProtos: c.NextProtos,
+ ServerName: c.ServerName,
+ ClientAuth: c.ClientAuth,
+ ClientCAs: c.ClientCAs,
+ InsecureSkipVerify: c.InsecureSkipVerify,
+ CipherSuites: c.CipherSuites,
+ PreferServerCipherSuites: c.PreferServerCipherSuites,
+ SessionTicketsDisabled: c.SessionTicketsDisabled,
+ SessionTicketKey: c.SessionTicketKey,
+ ClientSessionCache: c.ClientSessionCache,
+ MinVersion: c.MinVersion,
+ MaxVersion: c.MaxVersion,
+ CurvePreferences: c.CurvePreferences,
+ DynamicRecordSizingDisabled: c.DynamicRecordSizingDisabled,
+ Renegotiation: c.Renegotiation,
+ }
+}
diff --git a/vendor/github.com/go-sql-driver/mysql/utils_go18.go b/vendor/github.com/go-sql-driver/mysql/utils_go18.go
new file mode 100644
index 0000000000000000000000000000000000000000..c35c2a6aabfef0b4c48832c1edf274cdb96d3c0b
--- /dev/null
+++ b/vendor/github.com/go-sql-driver/mysql/utils_go18.go
@@ -0,0 +1,50 @@
+// Go MySQL Driver - A MySQL-Driver for Go's database/sql package
+//
+// Copyright 2017 The Go-MySQL-Driver Authors. All rights reserved.
+//
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this file,
+// You can obtain one at http://mozilla.org/MPL/2.0/.
+
+// +build go1.8
+
+package mysql
+
+import (
+ "crypto/tls"
+ "database/sql"
+ "database/sql/driver"
+ "errors"
+ "fmt"
+)
+
+func cloneTLSConfig(c *tls.Config) *tls.Config {
+ return c.Clone()
+}
+
+func namedValueToValue(named []driver.NamedValue) ([]driver.Value, error) {
+ dargs := make([]driver.Value, len(named))
+ for n, param := range named {
+ if len(param.Name) > 0 {
+ // TODO: support the use of Named Parameters #561
+ return nil, errors.New("mysql: driver does not support the use of Named Parameters")
+ }
+ dargs[n] = param.Value
+ }
+ return dargs, nil
+}
+
+func mapIsolationLevel(level driver.IsolationLevel) (string, error) {
+ switch sql.IsolationLevel(level) {
+ case sql.LevelRepeatableRead:
+ return "REPEATABLE READ", nil
+ case sql.LevelReadCommitted:
+ return "READ COMMITTED", nil
+ case sql.LevelReadUncommitted:
+ return "READ UNCOMMITTED", nil
+ case sql.LevelSerializable:
+ return "SERIALIZABLE", nil
+ default:
+ return "", fmt.Errorf("mysql: unsupported isolation level: %v", level)
+ }
+}
diff --git a/vendor/github.com/golang/glog/LICENSE b/vendor/github.com/golang/glog/LICENSE
new file mode 100644
index 0000000000000000000000000000000000000000..37ec93a14fdcd0d6e525d97c0cfa6b314eaa98d8
--- /dev/null
+++ b/vendor/github.com/golang/glog/LICENSE
@@ -0,0 +1,191 @@
+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:
+
+You must give any other recipients of the Work or Derivative Works a copy of
+this License; and
+You must cause any modified files to carry prominent notices stating that You
+changed the files; and
+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
+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.
diff --git a/vendor/github.com/golang/glog/README b/vendor/github.com/golang/glog/README
new file mode 100644
index 0000000000000000000000000000000000000000..387b4eb68909bf950a1c9d334ea8710d06c1854a
--- /dev/null
+++ b/vendor/github.com/golang/glog/README
@@ -0,0 +1,44 @@
+glog
+====
+
+Leveled execution logs for Go.
+
+This is an efficient pure Go implementation of leveled logs in the
+manner of the open source C++ package
+ https://github.com/google/glog
+
+By binding methods to booleans it is possible to use the log package
+without paying the expense of evaluating the arguments to the log.
+Through the -vmodule flag, the package also provides fine-grained
+control over logging at the file level.
+
+The comment from glog.go introduces the ideas:
+
+ Package glog implements logging analogous to the Google-internal
+ C++ INFO/ERROR/V setup. It provides functions Info, Warning,
+ Error, Fatal, plus formatting variants such as Infof. It
+ also provides V-style logging controlled by the -v and
+ -vmodule=file=2 flags.
+
+ Basic examples:
+
+ glog.Info("Prepare to repel boarders")
+
+ glog.Fatalf("Initialization failed: %s", err)
+
+ See the documentation for the V function for an explanation
+ of these examples:
+
+ if glog.V(2) {
+ glog.Info("Starting transaction...")
+ }
+
+ glog.V(2).Infoln("Processed", nItems, "elements")
+
+
+The repository contains an open source version of the log package
+used inside Google. The master copy of the source lives inside
+Google, not here. The code in this repo is for export only and is not itself
+under development. Feature requests will be ignored.
+
+Send bug reports to golang-nuts@googlegroups.com.
diff --git a/vendor/github.com/golang/glog/glog.go b/vendor/github.com/golang/glog/glog.go
new file mode 100644
index 0000000000000000000000000000000000000000..54bd7afdcabec4769e849f2c067b53e24a139fd8
--- /dev/null
+++ b/vendor/github.com/golang/glog/glog.go
@@ -0,0 +1,1180 @@
+// Go support for leveled logs, analogous to https://code.google.com/p/google-glog/
+//
+// Copyright 2013 Google Inc. All Rights Reserved.
+//
+// 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 glog implements logging analogous to the Google-internal C++ INFO/ERROR/V setup.
+// It provides functions Info, Warning, Error, Fatal, plus formatting variants such as
+// Infof. It also provides V-style logging controlled by the -v and -vmodule=file=2 flags.
+//
+// Basic examples:
+//
+// glog.Info("Prepare to repel boarders")
+//
+// glog.Fatalf("Initialization failed: %s", err)
+//
+// See the documentation for the V function for an explanation of these examples:
+//
+// if glog.V(2) {
+// glog.Info("Starting transaction...")
+// }
+//
+// glog.V(2).Infoln("Processed", nItems, "elements")
+//
+// Log output is buffered and written periodically using Flush. Programs
+// should call Flush before exiting to guarantee all log output is written.
+//
+// By default, all log statements write to files in a temporary directory.
+// This package provides several flags that modify this behavior.
+// As a result, flag.Parse must be called before any logging is done.
+//
+// -logtostderr=false
+// Logs are written to standard error instead of to files.
+// -alsologtostderr=false
+// Logs are written to standard error as well as to files.
+// -stderrthreshold=ERROR
+// Log events at or above this severity are logged to standard
+// error as well as to files.
+// -log_dir=""
+// Log files will be written to this directory instead of the
+// default temporary directory.
+//
+// Other flags provide aids to debugging.
+//
+// -log_backtrace_at=""
+// When set to a file and line number holding a logging statement,
+// such as
+// -log_backtrace_at=gopherflakes.go:234
+// a stack trace will be written to the Info log whenever execution
+// hits that statement. (Unlike with -vmodule, the ".go" must be
+// present.)
+// -v=0
+// Enable V-leveled logging at the specified level.
+// -vmodule=""
+// The syntax of the argument is a comma-separated list of pattern=N,
+// where pattern is a literal file name (minus the ".go" suffix) or
+// "glob" pattern and N is a V level. For instance,
+// -vmodule=gopher*=3
+// sets the V level to 3 in all Go files whose names begin "gopher".
+//
+package glog
+
+import (
+ "bufio"
+ "bytes"
+ "errors"
+ "flag"
+ "fmt"
+ "io"
+ stdLog "log"
+ "os"
+ "path/filepath"
+ "runtime"
+ "strconv"
+ "strings"
+ "sync"
+ "sync/atomic"
+ "time"
+)
+
+// severity identifies the sort of log: info, warning etc. It also implements
+// the flag.Value interface. The -stderrthreshold flag is of type severity and
+// should be modified only through the flag.Value interface. The values match
+// the corresponding constants in C++.
+type severity int32 // sync/atomic int32
+
+// These constants identify the log levels in order of increasing severity.
+// A message written to a high-severity log file is also written to each
+// lower-severity log file.
+const (
+ infoLog severity = iota
+ warningLog
+ errorLog
+ fatalLog
+ numSeverity = 4
+)
+
+const severityChar = "IWEF"
+
+var severityName = []string{
+ infoLog: "INFO",
+ warningLog: "WARNING",
+ errorLog: "ERROR",
+ fatalLog: "FATAL",
+}
+
+// get returns the value of the severity.
+func (s *severity) get() severity {
+ return severity(atomic.LoadInt32((*int32)(s)))
+}
+
+// set sets the value of the severity.
+func (s *severity) set(val severity) {
+ atomic.StoreInt32((*int32)(s), int32(val))
+}
+
+// String is part of the flag.Value interface.
+func (s *severity) String() string {
+ return strconv.FormatInt(int64(*s), 10)
+}
+
+// Get is part of the flag.Value interface.
+func (s *severity) Get() interface{} {
+ return *s
+}
+
+// Set is part of the flag.Value interface.
+func (s *severity) Set(value string) error {
+ var threshold severity
+ // Is it a known name?
+ if v, ok := severityByName(value); ok {
+ threshold = v
+ } else {
+ v, err := strconv.Atoi(value)
+ if err != nil {
+ return err
+ }
+ threshold = severity(v)
+ }
+ logging.stderrThreshold.set(threshold)
+ return nil
+}
+
+func severityByName(s string) (severity, bool) {
+ s = strings.ToUpper(s)
+ for i, name := range severityName {
+ if name == s {
+ return severity(i), true
+ }
+ }
+ return 0, false
+}
+
+// OutputStats tracks the number of output lines and bytes written.
+type OutputStats struct {
+ lines int64
+ bytes int64
+}
+
+// Lines returns the number of lines written.
+func (s *OutputStats) Lines() int64 {
+ return atomic.LoadInt64(&s.lines)
+}
+
+// Bytes returns the number of bytes written.
+func (s *OutputStats) Bytes() int64 {
+ return atomic.LoadInt64(&s.bytes)
+}
+
+// Stats tracks the number of lines of output and number of bytes
+// per severity level. Values must be read with atomic.LoadInt64.
+var Stats struct {
+ Info, Warning, Error OutputStats
+}
+
+var severityStats = [numSeverity]*OutputStats{
+ infoLog: &Stats.Info,
+ warningLog: &Stats.Warning,
+ errorLog: &Stats.Error,
+}
+
+// Level is exported because it appears in the arguments to V and is
+// the type of the v flag, which can be set programmatically.
+// It's a distinct type because we want to discriminate it from logType.
+// Variables of type level are only changed under logging.mu.
+// The -v flag is read only with atomic ops, so the state of the logging
+// module is consistent.
+
+// Level is treated as a sync/atomic int32.
+
+// Level specifies a level of verbosity for V logs. *Level implements
+// flag.Value; the -v flag is of type Level and should be modified
+// only through the flag.Value interface.
+type Level int32
+
+// get returns the value of the Level.
+func (l *Level) get() Level {
+ return Level(atomic.LoadInt32((*int32)(l)))
+}
+
+// set sets the value of the Level.
+func (l *Level) set(val Level) {
+ atomic.StoreInt32((*int32)(l), int32(val))
+}
+
+// String is part of the flag.Value interface.
+func (l *Level) String() string {
+ return strconv.FormatInt(int64(*l), 10)
+}
+
+// Get is part of the flag.Value interface.
+func (l *Level) Get() interface{} {
+ return *l
+}
+
+// Set is part of the flag.Value interface.
+func (l *Level) Set(value string) error {
+ v, err := strconv.Atoi(value)
+ if err != nil {
+ return err
+ }
+ logging.mu.Lock()
+ defer logging.mu.Unlock()
+ logging.setVState(Level(v), logging.vmodule.filter, false)
+ return nil
+}
+
+// moduleSpec represents the setting of the -vmodule flag.
+type moduleSpec struct {
+ filter []modulePat
+}
+
+// modulePat contains a filter for the -vmodule flag.
+// It holds a verbosity level and a file pattern to match.
+type modulePat struct {
+ pattern string
+ literal bool // The pattern is a literal string
+ level Level
+}
+
+// match reports whether the file matches the pattern. It uses a string
+// comparison if the pattern contains no metacharacters.
+func (m *modulePat) match(file string) bool {
+ if m.literal {
+ return file == m.pattern
+ }
+ match, _ := filepath.Match(m.pattern, file)
+ return match
+}
+
+func (m *moduleSpec) String() string {
+ // Lock because the type is not atomic. TODO: clean this up.
+ logging.mu.Lock()
+ defer logging.mu.Unlock()
+ var b bytes.Buffer
+ for i, f := range m.filter {
+ if i > 0 {
+ b.WriteRune(',')
+ }
+ fmt.Fprintf(&b, "%s=%d", f.pattern, f.level)
+ }
+ return b.String()
+}
+
+// Get is part of the (Go 1.2) flag.Getter interface. It always returns nil for this flag type since the
+// struct is not exported.
+func (m *moduleSpec) Get() interface{} {
+ return nil
+}
+
+var errVmoduleSyntax = errors.New("syntax error: expect comma-separated list of filename=N")
+
+// Syntax: -vmodule=recordio=2,file=1,gfs*=3
+func (m *moduleSpec) Set(value string) error {
+ var filter []modulePat
+ for _, pat := range strings.Split(value, ",") {
+ if len(pat) == 0 {
+ // Empty strings such as from a trailing comma can be ignored.
+ continue
+ }
+ patLev := strings.Split(pat, "=")
+ if len(patLev) != 2 || len(patLev[0]) == 0 || len(patLev[1]) == 0 {
+ return errVmoduleSyntax
+ }
+ pattern := patLev[0]
+ v, err := strconv.Atoi(patLev[1])
+ if err != nil {
+ return errors.New("syntax error: expect comma-separated list of filename=N")
+ }
+ if v < 0 {
+ return errors.New("negative value for vmodule level")
+ }
+ if v == 0 {
+ continue // Ignore. It's harmless but no point in paying the overhead.
+ }
+ // TODO: check syntax of filter?
+ filter = append(filter, modulePat{pattern, isLiteral(pattern), Level(v)})
+ }
+ logging.mu.Lock()
+ defer logging.mu.Unlock()
+ logging.setVState(logging.verbosity, filter, true)
+ return nil
+}
+
+// isLiteral reports whether the pattern is a literal string, that is, has no metacharacters
+// that require filepath.Match to be called to match the pattern.
+func isLiteral(pattern string) bool {
+ return !strings.ContainsAny(pattern, `\*?[]`)
+}
+
+// traceLocation represents the setting of the -log_backtrace_at flag.
+type traceLocation struct {
+ file string
+ line int
+}
+
+// isSet reports whether the trace location has been specified.
+// logging.mu is held.
+func (t *traceLocation) isSet() bool {
+ return t.line > 0
+}
+
+// match reports whether the specified file and line matches the trace location.
+// The argument file name is the full path, not the basename specified in the flag.
+// logging.mu is held.
+func (t *traceLocation) match(file string, line int) bool {
+ if t.line != line {
+ return false
+ }
+ if i := strings.LastIndex(file, "/"); i >= 0 {
+ file = file[i+1:]
+ }
+ return t.file == file
+}
+
+func (t *traceLocation) String() string {
+ // Lock because the type is not atomic. TODO: clean this up.
+ logging.mu.Lock()
+ defer logging.mu.Unlock()
+ return fmt.Sprintf("%s:%d", t.file, t.line)
+}
+
+// Get is part of the (Go 1.2) flag.Getter interface. It always returns nil for this flag type since the
+// struct is not exported
+func (t *traceLocation) Get() interface{} {
+ return nil
+}
+
+var errTraceSyntax = errors.New("syntax error: expect file.go:234")
+
+// Syntax: -log_backtrace_at=gopherflakes.go:234
+// Note that unlike vmodule the file extension is included here.
+func (t *traceLocation) Set(value string) error {
+ if value == "" {
+ // Unset.
+ t.line = 0
+ t.file = ""
+ }
+ fields := strings.Split(value, ":")
+ if len(fields) != 2 {
+ return errTraceSyntax
+ }
+ file, line := fields[0], fields[1]
+ if !strings.Contains(file, ".") {
+ return errTraceSyntax
+ }
+ v, err := strconv.Atoi(line)
+ if err != nil {
+ return errTraceSyntax
+ }
+ if v <= 0 {
+ return errors.New("negative or zero value for level")
+ }
+ logging.mu.Lock()
+ defer logging.mu.Unlock()
+ t.line = v
+ t.file = file
+ return nil
+}
+
+// flushSyncWriter is the interface satisfied by logging destinations.
+type flushSyncWriter interface {
+ Flush() error
+ Sync() error
+ io.Writer
+}
+
+func init() {
+ flag.BoolVar(&logging.toStderr, "logtostderr", false, "log to standard error instead of files")
+ flag.BoolVar(&logging.alsoToStderr, "alsologtostderr", false, "log to standard error as well as files")
+ flag.Var(&logging.verbosity, "v", "log level for V logs")
+ flag.Var(&logging.stderrThreshold, "stderrthreshold", "logs at or above this threshold go to stderr")
+ flag.Var(&logging.vmodule, "vmodule", "comma-separated list of pattern=N settings for file-filtered logging")
+ flag.Var(&logging.traceLocation, "log_backtrace_at", "when logging hits line file:N, emit a stack trace")
+
+ // Default stderrThreshold is ERROR.
+ logging.stderrThreshold = errorLog
+
+ logging.setVState(0, nil, false)
+ go logging.flushDaemon()
+}
+
+// Flush flushes all pending log I/O.
+func Flush() {
+ logging.lockAndFlushAll()
+}
+
+// loggingT collects all the global state of the logging setup.
+type loggingT struct {
+ // Boolean flags. Not handled atomically because the flag.Value interface
+ // does not let us avoid the =true, and that shorthand is necessary for
+ // compatibility. TODO: does this matter enough to fix? Seems unlikely.
+ toStderr bool // The -logtostderr flag.
+ alsoToStderr bool // The -alsologtostderr flag.
+
+ // Level flag. Handled atomically.
+ stderrThreshold severity // The -stderrthreshold flag.
+
+ // freeList is a list of byte buffers, maintained under freeListMu.
+ freeList *buffer
+ // freeListMu maintains the free list. It is separate from the main mutex
+ // so buffers can be grabbed and printed to without holding the main lock,
+ // for better parallelization.
+ freeListMu sync.Mutex
+
+ // mu protects the remaining elements of this structure and is
+ // used to synchronize logging.
+ mu sync.Mutex
+ // file holds writer for each of the log types.
+ file [numSeverity]flushSyncWriter
+ // pcs is used in V to avoid an allocation when computing the caller's PC.
+ pcs [1]uintptr
+ // vmap is a cache of the V Level for each V() call site, identified by PC.
+ // It is wiped whenever the vmodule flag changes state.
+ vmap map[uintptr]Level
+ // filterLength stores the length of the vmodule filter chain. If greater
+ // than zero, it means vmodule is enabled. It may be read safely
+ // using sync.LoadInt32, but is only modified under mu.
+ filterLength int32
+ // traceLocation is the state of the -log_backtrace_at flag.
+ traceLocation traceLocation
+ // These flags are modified only under lock, although verbosity may be fetched
+ // safely using atomic.LoadInt32.
+ vmodule moduleSpec // The state of the -vmodule flag.
+ verbosity Level // V logging level, the value of the -v flag/
+}
+
+// buffer holds a byte Buffer for reuse. The zero value is ready for use.
+type buffer struct {
+ bytes.Buffer
+ tmp [64]byte // temporary byte array for creating headers.
+ next *buffer
+}
+
+var logging loggingT
+
+// setVState sets a consistent state for V logging.
+// l.mu is held.
+func (l *loggingT) setVState(verbosity Level, filter []modulePat, setFilter bool) {
+ // Turn verbosity off so V will not fire while we are in transition.
+ logging.verbosity.set(0)
+ // Ditto for filter length.
+ atomic.StoreInt32(&logging.filterLength, 0)
+
+ // Set the new filters and wipe the pc->Level map if the filter has changed.
+ if setFilter {
+ logging.vmodule.filter = filter
+ logging.vmap = make(map[uintptr]Level)
+ }
+
+ // Things are consistent now, so enable filtering and verbosity.
+ // They are enabled in order opposite to that in V.
+ atomic.StoreInt32(&logging.filterLength, int32(len(filter)))
+ logging.verbosity.set(verbosity)
+}
+
+// getBuffer returns a new, ready-to-use buffer.
+func (l *loggingT) getBuffer() *buffer {
+ l.freeListMu.Lock()
+ b := l.freeList
+ if b != nil {
+ l.freeList = b.next
+ }
+ l.freeListMu.Unlock()
+ if b == nil {
+ b = new(buffer)
+ } else {
+ b.next = nil
+ b.Reset()
+ }
+ return b
+}
+
+// putBuffer returns a buffer to the free list.
+func (l *loggingT) putBuffer(b *buffer) {
+ if b.Len() >= 256 {
+ // Let big buffers die a natural death.
+ return
+ }
+ l.freeListMu.Lock()
+ b.next = l.freeList
+ l.freeList = b
+ l.freeListMu.Unlock()
+}
+
+var timeNow = time.Now // Stubbed out for testing.
+
+/*
+header formats a log header as defined by the C++ implementation.
+It returns a buffer containing the formatted header and the user's file and line number.
+The depth specifies how many stack frames above lives the source line to be identified in the log message.
+
+Log lines have this form:
+ Lmmdd hh:mm:ss.uuuuuu threadid file:line] msg...
+where the fields are defined as follows:
+ L A single character, representing the log level (eg 'I' for INFO)
+ mm The month (zero padded; ie May is '05')
+ dd The day (zero padded)
+ hh:mm:ss.uuuuuu Time in hours, minutes and fractional seconds
+ threadid The space-padded thread ID as returned by GetTID()
+ file The file name
+ line The line number
+ msg The user-supplied message
+*/
+func (l *loggingT) header(s severity, depth int) (*buffer, string, int) {
+ _, file, line, ok := runtime.Caller(3 + depth)
+ if !ok {
+ file = "???"
+ line = 1
+ } else {
+ slash := strings.LastIndex(file, "/")
+ if slash >= 0 {
+ file = file[slash+1:]
+ }
+ }
+ return l.formatHeader(s, file, line), file, line
+}
+
+// formatHeader formats a log header using the provided file name and line number.
+func (l *loggingT) formatHeader(s severity, file string, line int) *buffer {
+ now := timeNow()
+ if line < 0 {
+ line = 0 // not a real line number, but acceptable to someDigits
+ }
+ if s > fatalLog {
+ s = infoLog // for safety.
+ }
+ buf := l.getBuffer()
+
+ // Avoid Fprintf, for speed. The format is so simple that we can do it quickly by hand.
+ // It's worth about 3X. Fprintf is hard.
+ _, month, day := now.Date()
+ hour, minute, second := now.Clock()
+ // Lmmdd hh:mm:ss.uuuuuu threadid file:line]
+ buf.tmp[0] = severityChar[s]
+ buf.twoDigits(1, int(month))
+ buf.twoDigits(3, day)
+ buf.tmp[5] = ' '
+ buf.twoDigits(6, hour)
+ buf.tmp[8] = ':'
+ buf.twoDigits(9, minute)
+ buf.tmp[11] = ':'
+ buf.twoDigits(12, second)
+ buf.tmp[14] = '.'
+ buf.nDigits(6, 15, now.Nanosecond()/1000, '0')
+ buf.tmp[21] = ' '
+ buf.nDigits(7, 22, pid, ' ') // TODO: should be TID
+ buf.tmp[29] = ' '
+ buf.Write(buf.tmp[:30])
+ buf.WriteString(file)
+ buf.tmp[0] = ':'
+ n := buf.someDigits(1, line)
+ buf.tmp[n+1] = ']'
+ buf.tmp[n+2] = ' '
+ buf.Write(buf.tmp[:n+3])
+ return buf
+}
+
+// Some custom tiny helper functions to print the log header efficiently.
+
+const digits = "0123456789"
+
+// twoDigits formats a zero-prefixed two-digit integer at buf.tmp[i].
+func (buf *buffer) twoDigits(i, d int) {
+ buf.tmp[i+1] = digits[d%10]
+ d /= 10
+ buf.tmp[i] = digits[d%10]
+}
+
+// nDigits formats an n-digit integer at buf.tmp[i],
+// padding with pad on the left.
+// It assumes d >= 0.
+func (buf *buffer) nDigits(n, i, d int, pad byte) {
+ j := n - 1
+ for ; j >= 0 && d > 0; j-- {
+ buf.tmp[i+j] = digits[d%10]
+ d /= 10
+ }
+ for ; j >= 0; j-- {
+ buf.tmp[i+j] = pad
+ }
+}
+
+// someDigits formats a zero-prefixed variable-width integer at buf.tmp[i].
+func (buf *buffer) someDigits(i, d int) int {
+ // Print into the top, then copy down. We know there's space for at least
+ // a 10-digit number.
+ j := len(buf.tmp)
+ for {
+ j--
+ buf.tmp[j] = digits[d%10]
+ d /= 10
+ if d == 0 {
+ break
+ }
+ }
+ return copy(buf.tmp[i:], buf.tmp[j:])
+}
+
+func (l *loggingT) println(s severity, args ...interface{}) {
+ buf, file, line := l.header(s, 0)
+ fmt.Fprintln(buf, args...)
+ l.output(s, buf, file, line, false)
+}
+
+func (l *loggingT) print(s severity, args ...interface{}) {
+ l.printDepth(s, 1, args...)
+}
+
+func (l *loggingT) printDepth(s severity, depth int, args ...interface{}) {
+ buf, file, line := l.header(s, depth)
+ fmt.Fprint(buf, args...)
+ if buf.Bytes()[buf.Len()-1] != '\n' {
+ buf.WriteByte('\n')
+ }
+ l.output(s, buf, file, line, false)
+}
+
+func (l *loggingT) printf(s severity, format string, args ...interface{}) {
+ buf, file, line := l.header(s, 0)
+ fmt.Fprintf(buf, format, args...)
+ if buf.Bytes()[buf.Len()-1] != '\n' {
+ buf.WriteByte('\n')
+ }
+ l.output(s, buf, file, line, false)
+}
+
+// printWithFileLine behaves like print but uses the provided file and line number. If
+// alsoLogToStderr is true, the log message always appears on standard error; it
+// will also appear in the log file unless --logtostderr is set.
+func (l *loggingT) printWithFileLine(s severity, file string, line int, alsoToStderr bool, args ...interface{}) {
+ buf := l.formatHeader(s, file, line)
+ fmt.Fprint(buf, args...)
+ if buf.Bytes()[buf.Len()-1] != '\n' {
+ buf.WriteByte('\n')
+ }
+ l.output(s, buf, file, line, alsoToStderr)
+}
+
+// output writes the data to the log files and releases the buffer.
+func (l *loggingT) output(s severity, buf *buffer, file string, line int, alsoToStderr bool) {
+ l.mu.Lock()
+ if l.traceLocation.isSet() {
+ if l.traceLocation.match(file, line) {
+ buf.Write(stacks(false))
+ }
+ }
+ data := buf.Bytes()
+ if !flag.Parsed() {
+ os.Stderr.Write([]byte("ERROR: logging before flag.Parse: "))
+ os.Stderr.Write(data)
+ } else if l.toStderr {
+ os.Stderr.Write(data)
+ } else {
+ if alsoToStderr || l.alsoToStderr || s >= l.stderrThreshold.get() {
+ os.Stderr.Write(data)
+ }
+ if l.file[s] == nil {
+ if err := l.createFiles(s); err != nil {
+ os.Stderr.Write(data) // Make sure the message appears somewhere.
+ l.exit(err)
+ }
+ }
+ switch s {
+ case fatalLog:
+ l.file[fatalLog].Write(data)
+ fallthrough
+ case errorLog:
+ l.file[errorLog].Write(data)
+ fallthrough
+ case warningLog:
+ l.file[warningLog].Write(data)
+ fallthrough
+ case infoLog:
+ l.file[infoLog].Write(data)
+ }
+ }
+ if s == fatalLog {
+ // If we got here via Exit rather than Fatal, print no stacks.
+ if atomic.LoadUint32(&fatalNoStacks) > 0 {
+ l.mu.Unlock()
+ timeoutFlush(10 * time.Second)
+ os.Exit(1)
+ }
+ // Dump all goroutine stacks before exiting.
+ // First, make sure we see the trace for the current goroutine on standard error.
+ // If -logtostderr has been specified, the loop below will do that anyway
+ // as the first stack in the full dump.
+ if !l.toStderr {
+ os.Stderr.Write(stacks(false))
+ }
+ // Write the stack trace for all goroutines to the files.
+ trace := stacks(true)
+ logExitFunc = func(error) {} // If we get a write error, we'll still exit below.
+ for log := fatalLog; log >= infoLog; log-- {
+ if f := l.file[log]; f != nil { // Can be nil if -logtostderr is set.
+ f.Write(trace)
+ }
+ }
+ l.mu.Unlock()
+ timeoutFlush(10 * time.Second)
+ os.Exit(255) // C++ uses -1, which is silly because it's anded with 255 anyway.
+ }
+ l.putBuffer(buf)
+ l.mu.Unlock()
+ if stats := severityStats[s]; stats != nil {
+ atomic.AddInt64(&stats.lines, 1)
+ atomic.AddInt64(&stats.bytes, int64(len(data)))
+ }
+}
+
+// timeoutFlush calls Flush and returns when it completes or after timeout
+// elapses, whichever happens first. This is needed because the hooks invoked
+// by Flush may deadlock when glog.Fatal is called from a hook that holds
+// a lock.
+func timeoutFlush(timeout time.Duration) {
+ done := make(chan bool, 1)
+ go func() {
+ Flush() // calls logging.lockAndFlushAll()
+ done <- true
+ }()
+ select {
+ case <-done:
+ case <-time.After(timeout):
+ fmt.Fprintln(os.Stderr, "glog: Flush took longer than", timeout)
+ }
+}
+
+// stacks is a wrapper for runtime.Stack that attempts to recover the data for all goroutines.
+func stacks(all bool) []byte {
+ // We don't know how big the traces are, so grow a few times if they don't fit. Start large, though.
+ n := 10000
+ if all {
+ n = 100000
+ }
+ var trace []byte
+ for i := 0; i < 5; i++ {
+ trace = make([]byte, n)
+ nbytes := runtime.Stack(trace, all)
+ if nbytes < len(trace) {
+ return trace[:nbytes]
+ }
+ n *= 2
+ }
+ return trace
+}
+
+// logExitFunc provides a simple mechanism to override the default behavior
+// of exiting on error. Used in testing and to guarantee we reach a required exit
+// for fatal logs. Instead, exit could be a function rather than a method but that
+// would make its use clumsier.
+var logExitFunc func(error)
+
+// exit is called if there is trouble creating or writing log files.
+// It flushes the logs and exits the program; there's no point in hanging around.
+// l.mu is held.
+func (l *loggingT) exit(err error) {
+ fmt.Fprintf(os.Stderr, "log: exiting because of error: %s\n", err)
+ // If logExitFunc is set, we do that instead of exiting.
+ if logExitFunc != nil {
+ logExitFunc(err)
+ return
+ }
+ l.flushAll()
+ os.Exit(2)
+}
+
+// syncBuffer joins a bufio.Writer to its underlying file, providing access to the
+// file's Sync method and providing a wrapper for the Write method that provides log
+// file rotation. There are conflicting methods, so the file cannot be embedded.
+// l.mu is held for all its methods.
+type syncBuffer struct {
+ logger *loggingT
+ *bufio.Writer
+ file *os.File
+ sev severity
+ nbytes uint64 // The number of bytes written to this file
+}
+
+func (sb *syncBuffer) Sync() error {
+ return sb.file.Sync()
+}
+
+func (sb *syncBuffer) Write(p []byte) (n int, err error) {
+ if sb.nbytes+uint64(len(p)) >= MaxSize {
+ if err := sb.rotateFile(time.Now()); err != nil {
+ sb.logger.exit(err)
+ }
+ }
+ n, err = sb.Writer.Write(p)
+ sb.nbytes += uint64(n)
+ if err != nil {
+ sb.logger.exit(err)
+ }
+ return
+}
+
+// rotateFile closes the syncBuffer's file and starts a new one.
+func (sb *syncBuffer) rotateFile(now time.Time) error {
+ if sb.file != nil {
+ sb.Flush()
+ sb.file.Close()
+ }
+ var err error
+ sb.file, _, err = create(severityName[sb.sev], now)
+ sb.nbytes = 0
+ if err != nil {
+ return err
+ }
+
+ sb.Writer = bufio.NewWriterSize(sb.file, bufferSize)
+
+ // Write header.
+ var buf bytes.Buffer
+ fmt.Fprintf(&buf, "Log file created at: %s\n", now.Format("2006/01/02 15:04:05"))
+ fmt.Fprintf(&buf, "Running on machine: %s\n", host)
+ fmt.Fprintf(&buf, "Binary: Built with %s %s for %s/%s\n", runtime.Compiler, runtime.Version(), runtime.GOOS, runtime.GOARCH)
+ fmt.Fprintf(&buf, "Log line format: [IWEF]mmdd hh:mm:ss.uuuuuu threadid file:line] msg\n")
+ n, err := sb.file.Write(buf.Bytes())
+ sb.nbytes += uint64(n)
+ return err
+}
+
+// bufferSize sizes the buffer associated with each log file. It's large
+// so that log records can accumulate without the logging thread blocking
+// on disk I/O. The flushDaemon will block instead.
+const bufferSize = 256 * 1024
+
+// createFiles creates all the log files for severity from sev down to infoLog.
+// l.mu is held.
+func (l *loggingT) createFiles(sev severity) error {
+ now := time.Now()
+ // Files are created in decreasing severity order, so as soon as we find one
+ // has already been created, we can stop.
+ for s := sev; s >= infoLog && l.file[s] == nil; s-- {
+ sb := &syncBuffer{
+ logger: l,
+ sev: s,
+ }
+ if err := sb.rotateFile(now); err != nil {
+ return err
+ }
+ l.file[s] = sb
+ }
+ return nil
+}
+
+const flushInterval = 30 * time.Second
+
+// flushDaemon periodically flushes the log file buffers.
+func (l *loggingT) flushDaemon() {
+ for _ = range time.NewTicker(flushInterval).C {
+ l.lockAndFlushAll()
+ }
+}
+
+// lockAndFlushAll is like flushAll but locks l.mu first.
+func (l *loggingT) lockAndFlushAll() {
+ l.mu.Lock()
+ l.flushAll()
+ l.mu.Unlock()
+}
+
+// flushAll flushes all the logs and attempts to "sync" their data to disk.
+// l.mu is held.
+func (l *loggingT) flushAll() {
+ // Flush from fatal down, in case there's trouble flushing.
+ for s := fatalLog; s >= infoLog; s-- {
+ file := l.file[s]
+ if file != nil {
+ file.Flush() // ignore error
+ file.Sync() // ignore error
+ }
+ }
+}
+
+// CopyStandardLogTo arranges for messages written to the Go "log" package's
+// default logs to also appear in the Google logs for the named and lower
+// severities. Subsequent changes to the standard log's default output location
+// or format may break this behavior.
+//
+// Valid names are "INFO", "WARNING", "ERROR", and "FATAL". If the name is not
+// recognized, CopyStandardLogTo panics.
+func CopyStandardLogTo(name string) {
+ sev, ok := severityByName(name)
+ if !ok {
+ panic(fmt.Sprintf("log.CopyStandardLogTo(%q): unrecognized severity name", name))
+ }
+ // Set a log format that captures the user's file and line:
+ // d.go:23: message
+ stdLog.SetFlags(stdLog.Lshortfile)
+ stdLog.SetOutput(logBridge(sev))
+}
+
+// logBridge provides the Write method that enables CopyStandardLogTo to connect
+// Go's standard logs to the logs provided by this package.
+type logBridge severity
+
+// Write parses the standard logging line and passes its components to the
+// logger for severity(lb).
+func (lb logBridge) Write(b []byte) (n int, err error) {
+ var (
+ file = "???"
+ line = 1
+ text string
+ )
+ // Split "d.go:23: message" into "d.go", "23", and "message".
+ if parts := bytes.SplitN(b, []byte{':'}, 3); len(parts) != 3 || len(parts[0]) < 1 || len(parts[2]) < 1 {
+ text = fmt.Sprintf("bad log format: %s", b)
+ } else {
+ file = string(parts[0])
+ text = string(parts[2][1:]) // skip leading space
+ line, err = strconv.Atoi(string(parts[1]))
+ if err != nil {
+ text = fmt.Sprintf("bad line number: %s", b)
+ line = 1
+ }
+ }
+ // printWithFileLine with alsoToStderr=true, so standard log messages
+ // always appear on standard error.
+ logging.printWithFileLine(severity(lb), file, line, true, text)
+ return len(b), nil
+}
+
+// setV computes and remembers the V level for a given PC
+// when vmodule is enabled.
+// File pattern matching takes the basename of the file, stripped
+// of its .go suffix, and uses filepath.Match, which is a little more
+// general than the *? matching used in C++.
+// l.mu is held.
+func (l *loggingT) setV(pc uintptr) Level {
+ fn := runtime.FuncForPC(pc)
+ file, _ := fn.FileLine(pc)
+ // The file is something like /a/b/c/d.go. We want just the d.
+ if strings.HasSuffix(file, ".go") {
+ file = file[:len(file)-3]
+ }
+ if slash := strings.LastIndex(file, "/"); slash >= 0 {
+ file = file[slash+1:]
+ }
+ for _, filter := range l.vmodule.filter {
+ if filter.match(file) {
+ l.vmap[pc] = filter.level
+ return filter.level
+ }
+ }
+ l.vmap[pc] = 0
+ return 0
+}
+
+// Verbose is a boolean type that implements Infof (like Printf) etc.
+// See the documentation of V for more information.
+type Verbose bool
+
+// V reports whether verbosity at the call site is at least the requested level.
+// The returned value is a boolean of type Verbose, which implements Info, Infoln
+// and Infof. These methods will write to the Info log if called.
+// Thus, one may write either
+// if glog.V(2) { glog.Info("log this") }
+// or
+// glog.V(2).Info("log this")
+// The second form is shorter but the first is cheaper if logging is off because it does
+// not evaluate its arguments.
+//
+// Whether an individual call to V generates a log record depends on the setting of
+// the -v and --vmodule flags; both are off by default. If the level in the call to
+// V is at least the value of -v, or of -vmodule for the source file containing the
+// call, the V call will log.
+func V(level Level) Verbose {
+ // This function tries hard to be cheap unless there's work to do.
+ // The fast path is two atomic loads and compares.
+
+ // Here is a cheap but safe test to see if V logging is enabled globally.
+ if logging.verbosity.get() >= level {
+ return Verbose(true)
+ }
+
+ // It's off globally but it vmodule may still be set.
+ // Here is another cheap but safe test to see if vmodule is enabled.
+ if atomic.LoadInt32(&logging.filterLength) > 0 {
+ // Now we need a proper lock to use the logging structure. The pcs field
+ // is shared so we must lock before accessing it. This is fairly expensive,
+ // but if V logging is enabled we're slow anyway.
+ logging.mu.Lock()
+ defer logging.mu.Unlock()
+ if runtime.Callers(2, logging.pcs[:]) == 0 {
+ return Verbose(false)
+ }
+ v, ok := logging.vmap[logging.pcs[0]]
+ if !ok {
+ v = logging.setV(logging.pcs[0])
+ }
+ return Verbose(v >= level)
+ }
+ return Verbose(false)
+}
+
+// Info is equivalent to the global Info function, guarded by the value of v.
+// See the documentation of V for usage.
+func (v Verbose) Info(args ...interface{}) {
+ if v {
+ logging.print(infoLog, args...)
+ }
+}
+
+// Infoln is equivalent to the global Infoln function, guarded by the value of v.
+// See the documentation of V for usage.
+func (v Verbose) Infoln(args ...interface{}) {
+ if v {
+ logging.println(infoLog, args...)
+ }
+}
+
+// Infof is equivalent to the global Infof function, guarded by the value of v.
+// See the documentation of V for usage.
+func (v Verbose) Infof(format string, args ...interface{}) {
+ if v {
+ logging.printf(infoLog, format, args...)
+ }
+}
+
+// Info logs to the INFO log.
+// Arguments are handled in the manner of fmt.Print; a newline is appended if missing.
+func Info(args ...interface{}) {
+ logging.print(infoLog, args...)
+}
+
+// InfoDepth acts as Info but uses depth to determine which call frame to log.
+// InfoDepth(0, "msg") is the same as Info("msg").
+func InfoDepth(depth int, args ...interface{}) {
+ logging.printDepth(infoLog, depth, args...)
+}
+
+// Infoln logs to the INFO log.
+// Arguments are handled in the manner of fmt.Println; a newline is appended if missing.
+func Infoln(args ...interface{}) {
+ logging.println(infoLog, args...)
+}
+
+// Infof logs to the INFO log.
+// Arguments are handled in the manner of fmt.Printf; a newline is appended if missing.
+func Infof(format string, args ...interface{}) {
+ logging.printf(infoLog, format, args...)
+}
+
+// Warning logs to the WARNING and INFO logs.
+// Arguments are handled in the manner of fmt.Print; a newline is appended if missing.
+func Warning(args ...interface{}) {
+ logging.print(warningLog, args...)
+}
+
+// WarningDepth acts as Warning but uses depth to determine which call frame to log.
+// WarningDepth(0, "msg") is the same as Warning("msg").
+func WarningDepth(depth int, args ...interface{}) {
+ logging.printDepth(warningLog, depth, args...)
+}
+
+// Warningln logs to the WARNING and INFO logs.
+// Arguments are handled in the manner of fmt.Println; a newline is appended if missing.
+func Warningln(args ...interface{}) {
+ logging.println(warningLog, args...)
+}
+
+// Warningf logs to the WARNING and INFO logs.
+// Arguments are handled in the manner of fmt.Printf; a newline is appended if missing.
+func Warningf(format string, args ...interface{}) {
+ logging.printf(warningLog, format, args...)
+}
+
+// Error logs to the ERROR, WARNING, and INFO logs.
+// Arguments are handled in the manner of fmt.Print; a newline is appended if missing.
+func Error(args ...interface{}) {
+ logging.print(errorLog, args...)
+}
+
+// ErrorDepth acts as Error but uses depth to determine which call frame to log.
+// ErrorDepth(0, "msg") is the same as Error("msg").
+func ErrorDepth(depth int, args ...interface{}) {
+ logging.printDepth(errorLog, depth, args...)
+}
+
+// Errorln logs to the ERROR, WARNING, and INFO logs.
+// Arguments are handled in the manner of fmt.Println; a newline is appended if missing.
+func Errorln(args ...interface{}) {
+ logging.println(errorLog, args...)
+}
+
+// Errorf logs to the ERROR, WARNING, and INFO logs.
+// Arguments are handled in the manner of fmt.Printf; a newline is appended if missing.
+func Errorf(format string, args ...interface{}) {
+ logging.printf(errorLog, format, args...)
+}
+
+// Fatal logs to the FATAL, ERROR, WARNING, and INFO logs,
+// including a stack trace of all running goroutines, then calls os.Exit(255).
+// Arguments are handled in the manner of fmt.Print; a newline is appended if missing.
+func Fatal(args ...interface{}) {
+ logging.print(fatalLog, args...)
+}
+
+// FatalDepth acts as Fatal but uses depth to determine which call frame to log.
+// FatalDepth(0, "msg") is the same as Fatal("msg").
+func FatalDepth(depth int, args ...interface{}) {
+ logging.printDepth(fatalLog, depth, args...)
+}
+
+// Fatalln logs to the FATAL, ERROR, WARNING, and INFO logs,
+// including a stack trace of all running goroutines, then calls os.Exit(255).
+// Arguments are handled in the manner of fmt.Println; a newline is appended if missing.
+func Fatalln(args ...interface{}) {
+ logging.println(fatalLog, args...)
+}
+
+// Fatalf logs to the FATAL, ERROR, WARNING, and INFO logs,
+// including a stack trace of all running goroutines, then calls os.Exit(255).
+// Arguments are handled in the manner of fmt.Printf; a newline is appended if missing.
+func Fatalf(format string, args ...interface{}) {
+ logging.printf(fatalLog, format, args...)
+}
+
+// fatalNoStacks is non-zero if we are to exit without dumping goroutine stacks.
+// It allows Exit and relatives to use the Fatal logs.
+var fatalNoStacks uint32
+
+// Exit logs to the FATAL, ERROR, WARNING, and INFO logs, then calls os.Exit(1).
+// Arguments are handled in the manner of fmt.Print; a newline is appended if missing.
+func Exit(args ...interface{}) {
+ atomic.StoreUint32(&fatalNoStacks, 1)
+ logging.print(fatalLog, args...)
+}
+
+// ExitDepth acts as Exit but uses depth to determine which call frame to log.
+// ExitDepth(0, "msg") is the same as Exit("msg").
+func ExitDepth(depth int, args ...interface{}) {
+ atomic.StoreUint32(&fatalNoStacks, 1)
+ logging.printDepth(fatalLog, depth, args...)
+}
+
+// Exitln logs to the FATAL, ERROR, WARNING, and INFO logs, then calls os.Exit(1).
+func Exitln(args ...interface{}) {
+ atomic.StoreUint32(&fatalNoStacks, 1)
+ logging.println(fatalLog, args...)
+}
+
+// Exitf logs to the FATAL, ERROR, WARNING, and INFO logs, then calls os.Exit(1).
+// Arguments are handled in the manner of fmt.Printf; a newline is appended if missing.
+func Exitf(format string, args ...interface{}) {
+ atomic.StoreUint32(&fatalNoStacks, 1)
+ logging.printf(fatalLog, format, args...)
+}
diff --git a/vendor/github.com/golang/glog/glog_file.go b/vendor/github.com/golang/glog/glog_file.go
new file mode 100644
index 0000000000000000000000000000000000000000..65075d281110cf445418640936d7c08d315512db
--- /dev/null
+++ b/vendor/github.com/golang/glog/glog_file.go
@@ -0,0 +1,124 @@
+// Go support for leveled logs, analogous to https://code.google.com/p/google-glog/
+//
+// Copyright 2013 Google Inc. All Rights Reserved.
+//
+// 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.
+
+// File I/O for logs.
+
+package glog
+
+import (
+ "errors"
+ "flag"
+ "fmt"
+ "os"
+ "os/user"
+ "path/filepath"
+ "strings"
+ "sync"
+ "time"
+)
+
+// MaxSize is the maximum size of a log file in bytes.
+var MaxSize uint64 = 1024 * 1024 * 1800
+
+// logDirs lists the candidate directories for new log files.
+var logDirs []string
+
+// If non-empty, overrides the choice of directory in which to write logs.
+// See createLogDirs for the full list of possible destinations.
+var logDir = flag.String("log_dir", "", "If non-empty, write log files in this directory")
+
+func createLogDirs() {
+ if *logDir != "" {
+ logDirs = append(logDirs, *logDir)
+ }
+ logDirs = append(logDirs, os.TempDir())
+}
+
+var (
+ pid = os.Getpid()
+ program = filepath.Base(os.Args[0])
+ host = "unknownhost"
+ userName = "unknownuser"
+)
+
+func init() {
+ h, err := os.Hostname()
+ if err == nil {
+ host = shortHostname(h)
+ }
+
+ current, err := user.Current()
+ if err == nil {
+ userName = current.Username
+ }
+
+ // Sanitize userName since it may contain filepath separators on Windows.
+ userName = strings.Replace(userName, `\`, "_", -1)
+}
+
+// shortHostname returns its argument, truncating at the first period.
+// For instance, given "www.google.com" it returns "www".
+func shortHostname(hostname string) string {
+ if i := strings.Index(hostname, "."); i >= 0 {
+ return hostname[:i]
+ }
+ return hostname
+}
+
+// logName returns a new log file name containing tag, with start time t, and
+// the name for the symlink for tag.
+func logName(tag string, t time.Time) (name, link string) {
+ name = fmt.Sprintf("%s.%s.%s.log.%s.%04d%02d%02d-%02d%02d%02d.%d",
+ program,
+ host,
+ userName,
+ tag,
+ t.Year(),
+ t.Month(),
+ t.Day(),
+ t.Hour(),
+ t.Minute(),
+ t.Second(),
+ pid)
+ return name, program + "." + tag
+}
+
+var onceLogDirs sync.Once
+
+// create creates a new log file and returns the file and its filename, which
+// contains tag ("INFO", "FATAL", etc.) and t. If the file is created
+// successfully, create also attempts to update the symlink for that tag, ignoring
+// errors.
+func create(tag string, t time.Time) (f *os.File, filename string, err error) {
+ onceLogDirs.Do(createLogDirs)
+ if len(logDirs) == 0 {
+ return nil, "", errors.New("log: no log dirs")
+ }
+ name, link := logName(tag, t)
+ var lastErr error
+ for _, dir := range logDirs {
+ fname := filepath.Join(dir, name)
+ f, err := os.Create(fname)
+ if err == nil {
+ symlink := filepath.Join(dir, link)
+ os.Remove(symlink) // ignore err
+ os.Symlink(name, symlink) // ignore err
+ return f, fname, nil
+ }
+ lastErr = err
+ }
+ return nil, "", fmt.Errorf("log: cannot create log: %v", lastErr)
+}
diff --git a/vendor/github.com/golang/protobuf/AUTHORS b/vendor/github.com/golang/protobuf/AUTHORS
new file mode 100644
index 0000000000000000000000000000000000000000..15167cd746c560e5b3d3b233a169aa64d3e9101e
--- /dev/null
+++ b/vendor/github.com/golang/protobuf/AUTHORS
@@ -0,0 +1,3 @@
+# This source code refers to The Go Authors for copyright purposes.
+# The master list of authors is in the main Go distribution,
+# visible at http://tip.golang.org/AUTHORS.
diff --git a/vendor/github.com/golang/protobuf/CONTRIBUTORS b/vendor/github.com/golang/protobuf/CONTRIBUTORS
new file mode 100644
index 0000000000000000000000000000000000000000..1c4577e9680611383f46044d17fa343a96997c3c
--- /dev/null
+++ b/vendor/github.com/golang/protobuf/CONTRIBUTORS
@@ -0,0 +1,3 @@
+# This source code was written by the Go contributors.
+# The master list of contributors is in the main Go distribution,
+# visible at http://tip.golang.org/CONTRIBUTORS.
diff --git a/vendor/github.com/golang/protobuf/LICENSE b/vendor/github.com/golang/protobuf/LICENSE
new file mode 100644
index 0000000000000000000000000000000000000000..0f646931a4627fbe7c4259f3fb0337d04d798d8e
--- /dev/null
+++ b/vendor/github.com/golang/protobuf/LICENSE
@@ -0,0 +1,28 @@
+Copyright 2010 The Go Authors. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+ * Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above
+copyright notice, this list of conditions and the following disclaimer
+in the documentation and/or other materials provided with the
+distribution.
+ * Neither the name of Google Inc. nor the names of its
+contributors may be used to endorse or promote products derived from
+this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
diff --git a/vendor/github.com/golang/protobuf/proto/clone.go b/vendor/github.com/golang/protobuf/proto/clone.go
new file mode 100644
index 0000000000000000000000000000000000000000..3cd3249f706241d57b2b79f36de043bfac488449
--- /dev/null
+++ b/vendor/github.com/golang/protobuf/proto/clone.go
@@ -0,0 +1,253 @@
+// Go support for Protocol Buffers - Google's data interchange format
+//
+// Copyright 2011 The Go Authors. All rights reserved.
+// https://github.com/golang/protobuf
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Protocol buffer deep copy and merge.
+// TODO: RawMessage.
+
+package proto
+
+import (
+ "fmt"
+ "log"
+ "reflect"
+ "strings"
+)
+
+// Clone returns a deep copy of a protocol buffer.
+func Clone(src Message) Message {
+ in := reflect.ValueOf(src)
+ if in.IsNil() {
+ return src
+ }
+ out := reflect.New(in.Type().Elem())
+ dst := out.Interface().(Message)
+ Merge(dst, src)
+ return dst
+}
+
+// Merger is the interface representing objects that can merge messages of the same type.
+type Merger interface {
+ // Merge merges src into this message.
+ // Required and optional fields that are set in src will be set to that value in dst.
+ // Elements of repeated fields will be appended.
+ //
+ // Merge may panic if called with a different argument type than the receiver.
+ Merge(src Message)
+}
+
+// generatedMerger is the custom merge method that generated protos will have.
+// We must add this method since a generate Merge method will conflict with
+// many existing protos that have a Merge data field already defined.
+type generatedMerger interface {
+ XXX_Merge(src Message)
+}
+
+// Merge merges src into dst.
+// Required and optional fields that are set in src will be set to that value in dst.
+// Elements of repeated fields will be appended.
+// Merge panics if src and dst are not the same type, or if dst is nil.
+func Merge(dst, src Message) {
+ if m, ok := dst.(Merger); ok {
+ m.Merge(src)
+ return
+ }
+
+ in := reflect.ValueOf(src)
+ out := reflect.ValueOf(dst)
+ if out.IsNil() {
+ panic("proto: nil destination")
+ }
+ if in.Type() != out.Type() {
+ panic(fmt.Sprintf("proto.Merge(%T, %T) type mismatch", dst, src))
+ }
+ if in.IsNil() {
+ return // Merge from nil src is a noop
+ }
+ if m, ok := dst.(generatedMerger); ok {
+ m.XXX_Merge(src)
+ return
+ }
+ mergeStruct(out.Elem(), in.Elem())
+}
+
+func mergeStruct(out, in reflect.Value) {
+ sprop := GetProperties(in.Type())
+ for i := 0; i < in.NumField(); i++ {
+ f := in.Type().Field(i)
+ if strings.HasPrefix(f.Name, "XXX_") {
+ continue
+ }
+ mergeAny(out.Field(i), in.Field(i), false, sprop.Prop[i])
+ }
+
+ if emIn, err := extendable(in.Addr().Interface()); err == nil {
+ emOut, _ := extendable(out.Addr().Interface())
+ mIn, muIn := emIn.extensionsRead()
+ if mIn != nil {
+ mOut := emOut.extensionsWrite()
+ muIn.Lock()
+ mergeExtension(mOut, mIn)
+ muIn.Unlock()
+ }
+ }
+
+ uf := in.FieldByName("XXX_unrecognized")
+ if !uf.IsValid() {
+ return
+ }
+ uin := uf.Bytes()
+ if len(uin) > 0 {
+ out.FieldByName("XXX_unrecognized").SetBytes(append([]byte(nil), uin...))
+ }
+}
+
+// mergeAny performs a merge between two values of the same type.
+// viaPtr indicates whether the values were indirected through a pointer (implying proto2).
+// prop is set if this is a struct field (it may be nil).
+func mergeAny(out, in reflect.Value, viaPtr bool, prop *Properties) {
+ if in.Type() == protoMessageType {
+ if !in.IsNil() {
+ if out.IsNil() {
+ out.Set(reflect.ValueOf(Clone(in.Interface().(Message))))
+ } else {
+ Merge(out.Interface().(Message), in.Interface().(Message))
+ }
+ }
+ return
+ }
+ switch in.Kind() {
+ case reflect.Bool, reflect.Float32, reflect.Float64, reflect.Int32, reflect.Int64,
+ reflect.String, reflect.Uint32, reflect.Uint64:
+ if !viaPtr && isProto3Zero(in) {
+ return
+ }
+ out.Set(in)
+ case reflect.Interface:
+ // Probably a oneof field; copy non-nil values.
+ if in.IsNil() {
+ return
+ }
+ // Allocate destination if it is not set, or set to a different type.
+ // Otherwise we will merge as normal.
+ if out.IsNil() || out.Elem().Type() != in.Elem().Type() {
+ out.Set(reflect.New(in.Elem().Elem().Type())) // interface -> *T -> T -> new(T)
+ }
+ mergeAny(out.Elem(), in.Elem(), false, nil)
+ case reflect.Map:
+ if in.Len() == 0 {
+ return
+ }
+ if out.IsNil() {
+ out.Set(reflect.MakeMap(in.Type()))
+ }
+ // For maps with value types of *T or []byte we need to deep copy each value.
+ elemKind := in.Type().Elem().Kind()
+ for _, key := range in.MapKeys() {
+ var val reflect.Value
+ switch elemKind {
+ case reflect.Ptr:
+ val = reflect.New(in.Type().Elem().Elem())
+ mergeAny(val, in.MapIndex(key), false, nil)
+ case reflect.Slice:
+ val = in.MapIndex(key)
+ val = reflect.ValueOf(append([]byte{}, val.Bytes()...))
+ default:
+ val = in.MapIndex(key)
+ }
+ out.SetMapIndex(key, val)
+ }
+ case reflect.Ptr:
+ if in.IsNil() {
+ return
+ }
+ if out.IsNil() {
+ out.Set(reflect.New(in.Elem().Type()))
+ }
+ mergeAny(out.Elem(), in.Elem(), true, nil)
+ case reflect.Slice:
+ if in.IsNil() {
+ return
+ }
+ if in.Type().Elem().Kind() == reflect.Uint8 {
+ // []byte is a scalar bytes field, not a repeated field.
+
+ // Edge case: if this is in a proto3 message, a zero length
+ // bytes field is considered the zero value, and should not
+ // be merged.
+ if prop != nil && prop.proto3 && in.Len() == 0 {
+ return
+ }
+
+ // Make a deep copy.
+ // Append to []byte{} instead of []byte(nil) so that we never end up
+ // with a nil result.
+ out.SetBytes(append([]byte{}, in.Bytes()...))
+ return
+ }
+ n := in.Len()
+ if out.IsNil() {
+ out.Set(reflect.MakeSlice(in.Type(), 0, n))
+ }
+ switch in.Type().Elem().Kind() {
+ case reflect.Bool, reflect.Float32, reflect.Float64, reflect.Int32, reflect.Int64,
+ reflect.String, reflect.Uint32, reflect.Uint64:
+ out.Set(reflect.AppendSlice(out, in))
+ default:
+ for i := 0; i < n; i++ {
+ x := reflect.Indirect(reflect.New(in.Type().Elem()))
+ mergeAny(x, in.Index(i), false, nil)
+ out.Set(reflect.Append(out, x))
+ }
+ }
+ case reflect.Struct:
+ mergeStruct(out, in)
+ default:
+ // unknown type, so not a protocol buffer
+ log.Printf("proto: don't know how to copy %v", in)
+ }
+}
+
+func mergeExtension(out, in map[int32]Extension) {
+ for extNum, eIn := range in {
+ eOut := Extension{desc: eIn.desc}
+ if eIn.value != nil {
+ v := reflect.New(reflect.TypeOf(eIn.value)).Elem()
+ mergeAny(v, reflect.ValueOf(eIn.value), false, nil)
+ eOut.value = v.Interface()
+ }
+ if eIn.enc != nil {
+ eOut.enc = make([]byte, len(eIn.enc))
+ copy(eOut.enc, eIn.enc)
+ }
+
+ out[extNum] = eOut
+ }
+}
diff --git a/vendor/github.com/golang/protobuf/proto/decode.go b/vendor/github.com/golang/protobuf/proto/decode.go
new file mode 100644
index 0000000000000000000000000000000000000000..63b0f08bef2a0bbadd27d64221e8b8a486fda969
--- /dev/null
+++ b/vendor/github.com/golang/protobuf/proto/decode.go
@@ -0,0 +1,427 @@
+// Go support for Protocol Buffers - Google's data interchange format
+//
+// Copyright 2010 The Go Authors. All rights reserved.
+// https://github.com/golang/protobuf
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package proto
+
+/*
+ * Routines for decoding protocol buffer data to construct in-memory representations.
+ */
+
+import (
+ "errors"
+ "fmt"
+ "io"
+)
+
+// errOverflow is returned when an integer is too large to be represented.
+var errOverflow = errors.New("proto: integer overflow")
+
+// ErrInternalBadWireType is returned by generated code when an incorrect
+// wire type is encountered. It does not get returned to user code.
+var ErrInternalBadWireType = errors.New("proto: internal error: bad wiretype for oneof")
+
+// DecodeVarint reads a varint-encoded integer from the slice.
+// It returns the integer and the number of bytes consumed, or
+// zero if there is not enough.
+// This is the format for the
+// int32, int64, uint32, uint64, bool, and enum
+// protocol buffer types.
+func DecodeVarint(buf []byte) (x uint64, n int) {
+ for shift := uint(0); shift < 64; shift += 7 {
+ if n >= len(buf) {
+ return 0, 0
+ }
+ b := uint64(buf[n])
+ n++
+ x |= (b & 0x7F) << shift
+ if (b & 0x80) == 0 {
+ return x, n
+ }
+ }
+
+ // The number is too large to represent in a 64-bit value.
+ return 0, 0
+}
+
+func (p *Buffer) decodeVarintSlow() (x uint64, err error) {
+ i := p.index
+ l := len(p.buf)
+
+ for shift := uint(0); shift < 64; shift += 7 {
+ if i >= l {
+ err = io.ErrUnexpectedEOF
+ return
+ }
+ b := p.buf[i]
+ i++
+ x |= (uint64(b) & 0x7F) << shift
+ if b < 0x80 {
+ p.index = i
+ return
+ }
+ }
+
+ // The number is too large to represent in a 64-bit value.
+ err = errOverflow
+ return
+}
+
+// DecodeVarint reads a varint-encoded integer from the Buffer.
+// This is the format for the
+// int32, int64, uint32, uint64, bool, and enum
+// protocol buffer types.
+func (p *Buffer) DecodeVarint() (x uint64, err error) {
+ i := p.index
+ buf := p.buf
+
+ if i >= len(buf) {
+ return 0, io.ErrUnexpectedEOF
+ } else if buf[i] < 0x80 {
+ p.index++
+ return uint64(buf[i]), nil
+ } else if len(buf)-i < 10 {
+ return p.decodeVarintSlow()
+ }
+
+ var b uint64
+ // we already checked the first byte
+ x = uint64(buf[i]) - 0x80
+ i++
+
+ b = uint64(buf[i])
+ i++
+ x += b << 7
+ if b&0x80 == 0 {
+ goto done
+ }
+ x -= 0x80 << 7
+
+ b = uint64(buf[i])
+ i++
+ x += b << 14
+ if b&0x80 == 0 {
+ goto done
+ }
+ x -= 0x80 << 14
+
+ b = uint64(buf[i])
+ i++
+ x += b << 21
+ if b&0x80 == 0 {
+ goto done
+ }
+ x -= 0x80 << 21
+
+ b = uint64(buf[i])
+ i++
+ x += b << 28
+ if b&0x80 == 0 {
+ goto done
+ }
+ x -= 0x80 << 28
+
+ b = uint64(buf[i])
+ i++
+ x += b << 35
+ if b&0x80 == 0 {
+ goto done
+ }
+ x -= 0x80 << 35
+
+ b = uint64(buf[i])
+ i++
+ x += b << 42
+ if b&0x80 == 0 {
+ goto done
+ }
+ x -= 0x80 << 42
+
+ b = uint64(buf[i])
+ i++
+ x += b << 49
+ if b&0x80 == 0 {
+ goto done
+ }
+ x -= 0x80 << 49
+
+ b = uint64(buf[i])
+ i++
+ x += b << 56
+ if b&0x80 == 0 {
+ goto done
+ }
+ x -= 0x80 << 56
+
+ b = uint64(buf[i])
+ i++
+ x += b << 63
+ if b&0x80 == 0 {
+ goto done
+ }
+
+ return 0, errOverflow
+
+done:
+ p.index = i
+ return x, nil
+}
+
+// DecodeFixed64 reads a 64-bit integer from the Buffer.
+// This is the format for the
+// fixed64, sfixed64, and double protocol buffer types.
+func (p *Buffer) DecodeFixed64() (x uint64, err error) {
+ // x, err already 0
+ i := p.index + 8
+ if i < 0 || i > len(p.buf) {
+ err = io.ErrUnexpectedEOF
+ return
+ }
+ p.index = i
+
+ x = uint64(p.buf[i-8])
+ x |= uint64(p.buf[i-7]) << 8
+ x |= uint64(p.buf[i-6]) << 16
+ x |= uint64(p.buf[i-5]) << 24
+ x |= uint64(p.buf[i-4]) << 32
+ x |= uint64(p.buf[i-3]) << 40
+ x |= uint64(p.buf[i-2]) << 48
+ x |= uint64(p.buf[i-1]) << 56
+ return
+}
+
+// DecodeFixed32 reads a 32-bit integer from the Buffer.
+// This is the format for the
+// fixed32, sfixed32, and float protocol buffer types.
+func (p *Buffer) DecodeFixed32() (x uint64, err error) {
+ // x, err already 0
+ i := p.index + 4
+ if i < 0 || i > len(p.buf) {
+ err = io.ErrUnexpectedEOF
+ return
+ }
+ p.index = i
+
+ x = uint64(p.buf[i-4])
+ x |= uint64(p.buf[i-3]) << 8
+ x |= uint64(p.buf[i-2]) << 16
+ x |= uint64(p.buf[i-1]) << 24
+ return
+}
+
+// DecodeZigzag64 reads a zigzag-encoded 64-bit integer
+// from the Buffer.
+// This is the format used for the sint64 protocol buffer type.
+func (p *Buffer) DecodeZigzag64() (x uint64, err error) {
+ x, err = p.DecodeVarint()
+ if err != nil {
+ return
+ }
+ x = (x >> 1) ^ uint64((int64(x&1)<<63)>>63)
+ return
+}
+
+// DecodeZigzag32 reads a zigzag-encoded 32-bit integer
+// from the Buffer.
+// This is the format used for the sint32 protocol buffer type.
+func (p *Buffer) DecodeZigzag32() (x uint64, err error) {
+ x, err = p.DecodeVarint()
+ if err != nil {
+ return
+ }
+ x = uint64((uint32(x) >> 1) ^ uint32((int32(x&1)<<31)>>31))
+ return
+}
+
+// DecodeRawBytes reads a count-delimited byte buffer from the Buffer.
+// This is the format used for the bytes protocol buffer
+// type and for embedded messages.
+func (p *Buffer) DecodeRawBytes(alloc bool) (buf []byte, err error) {
+ n, err := p.DecodeVarint()
+ if err != nil {
+ return nil, err
+ }
+
+ nb := int(n)
+ if nb < 0 {
+ return nil, fmt.Errorf("proto: bad byte length %d", nb)
+ }
+ end := p.index + nb
+ if end < p.index || end > len(p.buf) {
+ return nil, io.ErrUnexpectedEOF
+ }
+
+ if !alloc {
+ // todo: check if can get more uses of alloc=false
+ buf = p.buf[p.index:end]
+ p.index += nb
+ return
+ }
+
+ buf = make([]byte, nb)
+ copy(buf, p.buf[p.index:])
+ p.index += nb
+ return
+}
+
+// DecodeStringBytes reads an encoded string from the Buffer.
+// This is the format used for the proto2 string type.
+func (p *Buffer) DecodeStringBytes() (s string, err error) {
+ buf, err := p.DecodeRawBytes(false)
+ if err != nil {
+ return
+ }
+ return string(buf), nil
+}
+
+// Unmarshaler is the interface representing objects that can
+// unmarshal themselves. The argument points to data that may be
+// overwritten, so implementations should not keep references to the
+// buffer.
+// Unmarshal implementations should not clear the receiver.
+// Any unmarshaled data should be merged into the receiver.
+// Callers of Unmarshal that do not want to retain existing data
+// should Reset the receiver before calling Unmarshal.
+type Unmarshaler interface {
+ Unmarshal([]byte) error
+}
+
+// newUnmarshaler is the interface representing objects that can
+// unmarshal themselves. The semantics are identical to Unmarshaler.
+//
+// This exists to support protoc-gen-go generated messages.
+// The proto package will stop type-asserting to this interface in the future.
+//
+// DO NOT DEPEND ON THIS.
+type newUnmarshaler interface {
+ XXX_Unmarshal([]byte) error
+}
+
+// Unmarshal parses the protocol buffer representation in buf and places the
+// decoded result in pb. If the struct underlying pb does not match
+// the data in buf, the results can be unpredictable.
+//
+// Unmarshal resets pb before starting to unmarshal, so any
+// existing data in pb is always removed. Use UnmarshalMerge
+// to preserve and append to existing data.
+func Unmarshal(buf []byte, pb Message) error {
+ pb.Reset()
+ if u, ok := pb.(newUnmarshaler); ok {
+ return u.XXX_Unmarshal(buf)
+ }
+ if u, ok := pb.(Unmarshaler); ok {
+ return u.Unmarshal(buf)
+ }
+ return NewBuffer(buf).Unmarshal(pb)
+}
+
+// UnmarshalMerge parses the protocol buffer representation in buf and
+// writes the decoded result to pb. If the struct underlying pb does not match
+// the data in buf, the results can be unpredictable.
+//
+// UnmarshalMerge merges into existing data in pb.
+// Most code should use Unmarshal instead.
+func UnmarshalMerge(buf []byte, pb Message) error {
+ if u, ok := pb.(newUnmarshaler); ok {
+ return u.XXX_Unmarshal(buf)
+ }
+ if u, ok := pb.(Unmarshaler); ok {
+ // NOTE: The history of proto have unfortunately been inconsistent
+ // whether Unmarshaler should or should not implicitly clear itself.
+ // Some implementations do, most do not.
+ // Thus, calling this here may or may not do what people want.
+ //
+ // See https://github.com/golang/protobuf/issues/424
+ return u.Unmarshal(buf)
+ }
+ return NewBuffer(buf).Unmarshal(pb)
+}
+
+// DecodeMessage reads a count-delimited message from the Buffer.
+func (p *Buffer) DecodeMessage(pb Message) error {
+ enc, err := p.DecodeRawBytes(false)
+ if err != nil {
+ return err
+ }
+ return NewBuffer(enc).Unmarshal(pb)
+}
+
+// DecodeGroup reads a tag-delimited group from the Buffer.
+// StartGroup tag is already consumed. This function consumes
+// EndGroup tag.
+func (p *Buffer) DecodeGroup(pb Message) error {
+ b := p.buf[p.index:]
+ x, y := findEndGroup(b)
+ if x < 0 {
+ return io.ErrUnexpectedEOF
+ }
+ err := Unmarshal(b[:x], pb)
+ p.index += y
+ return err
+}
+
+// Unmarshal parses the protocol buffer representation in the
+// Buffer and places the decoded result in pb. If the struct
+// underlying pb does not match the data in the buffer, the results can be
+// unpredictable.
+//
+// Unlike proto.Unmarshal, this does not reset pb before starting to unmarshal.
+func (p *Buffer) Unmarshal(pb Message) error {
+ // If the object can unmarshal itself, let it.
+ if u, ok := pb.(newUnmarshaler); ok {
+ err := u.XXX_Unmarshal(p.buf[p.index:])
+ p.index = len(p.buf)
+ return err
+ }
+ if u, ok := pb.(Unmarshaler); ok {
+ // NOTE: The history of proto have unfortunately been inconsistent
+ // whether Unmarshaler should or should not implicitly clear itself.
+ // Some implementations do, most do not.
+ // Thus, calling this here may or may not do what people want.
+ //
+ // See https://github.com/golang/protobuf/issues/424
+ err := u.Unmarshal(p.buf[p.index:])
+ p.index = len(p.buf)
+ return err
+ }
+
+ // Slow workaround for messages that aren't Unmarshalers.
+ // This includes some hand-coded .pb.go files and
+ // bootstrap protos.
+ // TODO: fix all of those and then add Unmarshal to
+ // the Message interface. Then:
+ // The cast above and code below can be deleted.
+ // The old unmarshaler can be deleted.
+ // Clients can call Unmarshal directly (can already do that, actually).
+ var info InternalMessageInfo
+ err := info.Unmarshal(pb, p.buf[p.index:])
+ p.index = len(p.buf)
+ return err
+}
diff --git a/vendor/github.com/golang/protobuf/proto/deprecated.go b/vendor/github.com/golang/protobuf/proto/deprecated.go
new file mode 100644
index 0000000000000000000000000000000000000000..35b882c09aaf900fbd03018d0a0b6d8c1713d5f3
--- /dev/null
+++ b/vendor/github.com/golang/protobuf/proto/deprecated.go
@@ -0,0 +1,63 @@
+// Go support for Protocol Buffers - Google's data interchange format
+//
+// Copyright 2018 The Go Authors. All rights reserved.
+// https://github.com/golang/protobuf
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package proto
+
+import "errors"
+
+// Deprecated: do not use.
+type Stats struct{ Emalloc, Dmalloc, Encode, Decode, Chit, Cmiss, Size uint64 }
+
+// Deprecated: do not use.
+func GetStats() Stats { return Stats{} }
+
+// Deprecated: do not use.
+func MarshalMessageSet(interface{}) ([]byte, error) {
+ return nil, errors.New("proto: not implemented")
+}
+
+// Deprecated: do not use.
+func UnmarshalMessageSet([]byte, interface{}) error {
+ return errors.New("proto: not implemented")
+}
+
+// Deprecated: do not use.
+func MarshalMessageSetJSON(interface{}) ([]byte, error) {
+ return nil, errors.New("proto: not implemented")
+}
+
+// Deprecated: do not use.
+func UnmarshalMessageSetJSON([]byte, interface{}) error {
+ return errors.New("proto: not implemented")
+}
+
+// Deprecated: do not use.
+func RegisterMessageSetType(Message, int32, string) {}
diff --git a/vendor/github.com/golang/protobuf/proto/discard.go b/vendor/github.com/golang/protobuf/proto/discard.go
new file mode 100644
index 0000000000000000000000000000000000000000..dea2617ced346ec98565c75713bbf71a0ffd0254
--- /dev/null
+++ b/vendor/github.com/golang/protobuf/proto/discard.go
@@ -0,0 +1,350 @@
+// Go support for Protocol Buffers - Google's data interchange format
+//
+// Copyright 2017 The Go Authors. All rights reserved.
+// https://github.com/golang/protobuf
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package proto
+
+import (
+ "fmt"
+ "reflect"
+ "strings"
+ "sync"
+ "sync/atomic"
+)
+
+type generatedDiscarder interface {
+ XXX_DiscardUnknown()
+}
+
+// DiscardUnknown recursively discards all unknown fields from this message
+// and all embedded messages.
+//
+// When unmarshaling a message with unrecognized fields, the tags and values
+// of such fields are preserved in the Message. This allows a later call to
+// marshal to be able to produce a message that continues to have those
+// unrecognized fields. To avoid this, DiscardUnknown is used to
+// explicitly clear the unknown fields after unmarshaling.
+//
+// For proto2 messages, the unknown fields of message extensions are only
+// discarded from messages that have been accessed via GetExtension.
+func DiscardUnknown(m Message) {
+ if m, ok := m.(generatedDiscarder); ok {
+ m.XXX_DiscardUnknown()
+ return
+ }
+ // TODO: Dynamically populate a InternalMessageInfo for legacy messages,
+ // but the master branch has no implementation for InternalMessageInfo,
+ // so it would be more work to replicate that approach.
+ discardLegacy(m)
+}
+
+// DiscardUnknown recursively discards all unknown fields.
+func (a *InternalMessageInfo) DiscardUnknown(m Message) {
+ di := atomicLoadDiscardInfo(&a.discard)
+ if di == nil {
+ di = getDiscardInfo(reflect.TypeOf(m).Elem())
+ atomicStoreDiscardInfo(&a.discard, di)
+ }
+ di.discard(toPointer(&m))
+}
+
+type discardInfo struct {
+ typ reflect.Type
+
+ initialized int32 // 0: only typ is valid, 1: everything is valid
+ lock sync.Mutex
+
+ fields []discardFieldInfo
+ unrecognized field
+}
+
+type discardFieldInfo struct {
+ field field // Offset of field, guaranteed to be valid
+ discard func(src pointer)
+}
+
+var (
+ discardInfoMap = map[reflect.Type]*discardInfo{}
+ discardInfoLock sync.Mutex
+)
+
+func getDiscardInfo(t reflect.Type) *discardInfo {
+ discardInfoLock.Lock()
+ defer discardInfoLock.Unlock()
+ di := discardInfoMap[t]
+ if di == nil {
+ di = &discardInfo{typ: t}
+ discardInfoMap[t] = di
+ }
+ return di
+}
+
+func (di *discardInfo) discard(src pointer) {
+ if src.isNil() {
+ return // Nothing to do.
+ }
+
+ if atomic.LoadInt32(&di.initialized) == 0 {
+ di.computeDiscardInfo()
+ }
+
+ for _, fi := range di.fields {
+ sfp := src.offset(fi.field)
+ fi.discard(sfp)
+ }
+
+ // For proto2 messages, only discard unknown fields in message extensions
+ // that have been accessed via GetExtension.
+ if em, err := extendable(src.asPointerTo(di.typ).Interface()); err == nil {
+ // Ignore lock since DiscardUnknown is not concurrency safe.
+ emm, _ := em.extensionsRead()
+ for _, mx := range emm {
+ if m, ok := mx.value.(Message); ok {
+ DiscardUnknown(m)
+ }
+ }
+ }
+
+ if di.unrecognized.IsValid() {
+ *src.offset(di.unrecognized).toBytes() = nil
+ }
+}
+
+func (di *discardInfo) computeDiscardInfo() {
+ di.lock.Lock()
+ defer di.lock.Unlock()
+ if di.initialized != 0 {
+ return
+ }
+ t := di.typ
+ n := t.NumField()
+
+ for i := 0; i < n; i++ {
+ f := t.Field(i)
+ if strings.HasPrefix(f.Name, "XXX_") {
+ continue
+ }
+
+ dfi := discardFieldInfo{field: toField(&f)}
+ tf := f.Type
+
+ // Unwrap tf to get its most basic type.
+ var isPointer, isSlice bool
+ if tf.Kind() == reflect.Slice && tf.Elem().Kind() != reflect.Uint8 {
+ isSlice = true
+ tf = tf.Elem()
+ }
+ if tf.Kind() == reflect.Ptr {
+ isPointer = true
+ tf = tf.Elem()
+ }
+ if isPointer && isSlice && tf.Kind() != reflect.Struct {
+ panic(fmt.Sprintf("%v.%s cannot be a slice of pointers to primitive types", t, f.Name))
+ }
+
+ switch tf.Kind() {
+ case reflect.Struct:
+ switch {
+ case !isPointer:
+ panic(fmt.Sprintf("%v.%s cannot be a direct struct value", t, f.Name))
+ case isSlice: // E.g., []*pb.T
+ di := getDiscardInfo(tf)
+ dfi.discard = func(src pointer) {
+ sps := src.getPointerSlice()
+ for _, sp := range sps {
+ if !sp.isNil() {
+ di.discard(sp)
+ }
+ }
+ }
+ default: // E.g., *pb.T
+ di := getDiscardInfo(tf)
+ dfi.discard = func(src pointer) {
+ sp := src.getPointer()
+ if !sp.isNil() {
+ di.discard(sp)
+ }
+ }
+ }
+ case reflect.Map:
+ switch {
+ case isPointer || isSlice:
+ panic(fmt.Sprintf("%v.%s cannot be a pointer to a map or a slice of map values", t, f.Name))
+ default: // E.g., map[K]V
+ if tf.Elem().Kind() == reflect.Ptr { // Proto struct (e.g., *T)
+ dfi.discard = func(src pointer) {
+ sm := src.asPointerTo(tf).Elem()
+ if sm.Len() == 0 {
+ return
+ }
+ for _, key := range sm.MapKeys() {
+ val := sm.MapIndex(key)
+ DiscardUnknown(val.Interface().(Message))
+ }
+ }
+ } else {
+ dfi.discard = func(pointer) {} // Noop
+ }
+ }
+ case reflect.Interface:
+ // Must be oneof field.
+ switch {
+ case isPointer || isSlice:
+ panic(fmt.Sprintf("%v.%s cannot be a pointer to a interface or a slice of interface values", t, f.Name))
+ default: // E.g., interface{}
+ // TODO: Make this faster?
+ dfi.discard = func(src pointer) {
+ su := src.asPointerTo(tf).Elem()
+ if !su.IsNil() {
+ sv := su.Elem().Elem().Field(0)
+ if sv.Kind() == reflect.Ptr && sv.IsNil() {
+ return
+ }
+ switch sv.Type().Kind() {
+ case reflect.Ptr: // Proto struct (e.g., *T)
+ DiscardUnknown(sv.Interface().(Message))
+ }
+ }
+ }
+ }
+ default:
+ continue
+ }
+ di.fields = append(di.fields, dfi)
+ }
+
+ di.unrecognized = invalidField
+ if f, ok := t.FieldByName("XXX_unrecognized"); ok {
+ if f.Type != reflect.TypeOf([]byte{}) {
+ panic("expected XXX_unrecognized to be of type []byte")
+ }
+ di.unrecognized = toField(&f)
+ }
+
+ atomic.StoreInt32(&di.initialized, 1)
+}
+
+func discardLegacy(m Message) {
+ v := reflect.ValueOf(m)
+ if v.Kind() != reflect.Ptr || v.IsNil() {
+ return
+ }
+ v = v.Elem()
+ if v.Kind() != reflect.Struct {
+ return
+ }
+ t := v.Type()
+
+ for i := 0; i < v.NumField(); i++ {
+ f := t.Field(i)
+ if strings.HasPrefix(f.Name, "XXX_") {
+ continue
+ }
+ vf := v.Field(i)
+ tf := f.Type
+
+ // Unwrap tf to get its most basic type.
+ var isPointer, isSlice bool
+ if tf.Kind() == reflect.Slice && tf.Elem().Kind() != reflect.Uint8 {
+ isSlice = true
+ tf = tf.Elem()
+ }
+ if tf.Kind() == reflect.Ptr {
+ isPointer = true
+ tf = tf.Elem()
+ }
+ if isPointer && isSlice && tf.Kind() != reflect.Struct {
+ panic(fmt.Sprintf("%T.%s cannot be a slice of pointers to primitive types", m, f.Name))
+ }
+
+ switch tf.Kind() {
+ case reflect.Struct:
+ switch {
+ case !isPointer:
+ panic(fmt.Sprintf("%T.%s cannot be a direct struct value", m, f.Name))
+ case isSlice: // E.g., []*pb.T
+ for j := 0; j < vf.Len(); j++ {
+ discardLegacy(vf.Index(j).Interface().(Message))
+ }
+ default: // E.g., *pb.T
+ discardLegacy(vf.Interface().(Message))
+ }
+ case reflect.Map:
+ switch {
+ case isPointer || isSlice:
+ panic(fmt.Sprintf("%T.%s cannot be a pointer to a map or a slice of map values", m, f.Name))
+ default: // E.g., map[K]V
+ tv := vf.Type().Elem()
+ if tv.Kind() == reflect.Ptr && tv.Implements(protoMessageType) { // Proto struct (e.g., *T)
+ for _, key := range vf.MapKeys() {
+ val := vf.MapIndex(key)
+ discardLegacy(val.Interface().(Message))
+ }
+ }
+ }
+ case reflect.Interface:
+ // Must be oneof field.
+ switch {
+ case isPointer || isSlice:
+ panic(fmt.Sprintf("%T.%s cannot be a pointer to a interface or a slice of interface values", m, f.Name))
+ default: // E.g., test_proto.isCommunique_Union interface
+ if !vf.IsNil() && f.Tag.Get("protobuf_oneof") != "" {
+ vf = vf.Elem() // E.g., *test_proto.Communique_Msg
+ if !vf.IsNil() {
+ vf = vf.Elem() // E.g., test_proto.Communique_Msg
+ vf = vf.Field(0) // E.g., Proto struct (e.g., *T) or primitive value
+ if vf.Kind() == reflect.Ptr {
+ discardLegacy(vf.Interface().(Message))
+ }
+ }
+ }
+ }
+ }
+ }
+
+ if vf := v.FieldByName("XXX_unrecognized"); vf.IsValid() {
+ if vf.Type() != reflect.TypeOf([]byte{}) {
+ panic("expected XXX_unrecognized to be of type []byte")
+ }
+ vf.Set(reflect.ValueOf([]byte(nil)))
+ }
+
+ // For proto2 messages, only discard unknown fields in message extensions
+ // that have been accessed via GetExtension.
+ if em, err := extendable(m); err == nil {
+ // Ignore lock since discardLegacy is not concurrency safe.
+ emm, _ := em.extensionsRead()
+ for _, mx := range emm {
+ if m, ok := mx.value.(Message); ok {
+ discardLegacy(m)
+ }
+ }
+ }
+}
diff --git a/vendor/github.com/golang/protobuf/proto/encode.go b/vendor/github.com/golang/protobuf/proto/encode.go
new file mode 100644
index 0000000000000000000000000000000000000000..3abfed2cff04bdf3bb72517b6f1807b82a151570
--- /dev/null
+++ b/vendor/github.com/golang/protobuf/proto/encode.go
@@ -0,0 +1,203 @@
+// Go support for Protocol Buffers - Google's data interchange format
+//
+// Copyright 2010 The Go Authors. All rights reserved.
+// https://github.com/golang/protobuf
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package proto
+
+/*
+ * Routines for encoding data into the wire format for protocol buffers.
+ */
+
+import (
+ "errors"
+ "reflect"
+)
+
+var (
+ // errRepeatedHasNil is the error returned if Marshal is called with
+ // a struct with a repeated field containing a nil element.
+ errRepeatedHasNil = errors.New("proto: repeated field has nil element")
+
+ // errOneofHasNil is the error returned if Marshal is called with
+ // a struct with a oneof field containing a nil element.
+ errOneofHasNil = errors.New("proto: oneof field has nil value")
+
+ // ErrNil is the error returned if Marshal is called with nil.
+ ErrNil = errors.New("proto: Marshal called with nil")
+
+ // ErrTooLarge is the error returned if Marshal is called with a
+ // message that encodes to >2GB.
+ ErrTooLarge = errors.New("proto: message encodes to over 2 GB")
+)
+
+// The fundamental encoders that put bytes on the wire.
+// Those that take integer types all accept uint64 and are
+// therefore of type valueEncoder.
+
+const maxVarintBytes = 10 // maximum length of a varint
+
+// EncodeVarint returns the varint encoding of x.
+// This is the format for the
+// int32, int64, uint32, uint64, bool, and enum
+// protocol buffer types.
+// Not used by the package itself, but helpful to clients
+// wishing to use the same encoding.
+func EncodeVarint(x uint64) []byte {
+ var buf [maxVarintBytes]byte
+ var n int
+ for n = 0; x > 127; n++ {
+ buf[n] = 0x80 | uint8(x&0x7F)
+ x >>= 7
+ }
+ buf[n] = uint8(x)
+ n++
+ return buf[0:n]
+}
+
+// EncodeVarint writes a varint-encoded integer to the Buffer.
+// This is the format for the
+// int32, int64, uint32, uint64, bool, and enum
+// protocol buffer types.
+func (p *Buffer) EncodeVarint(x uint64) error {
+ for x >= 1<<7 {
+ p.buf = append(p.buf, uint8(x&0x7f|0x80))
+ x >>= 7
+ }
+ p.buf = append(p.buf, uint8(x))
+ return nil
+}
+
+// SizeVarint returns the varint encoding size of an integer.
+func SizeVarint(x uint64) int {
+ switch {
+ case x < 1<<7:
+ return 1
+ case x < 1<<14:
+ return 2
+ case x < 1<<21:
+ return 3
+ case x < 1<<28:
+ return 4
+ case x < 1<<35:
+ return 5
+ case x < 1<<42:
+ return 6
+ case x < 1<<49:
+ return 7
+ case x < 1<<56:
+ return 8
+ case x < 1<<63:
+ return 9
+ }
+ return 10
+}
+
+// EncodeFixed64 writes a 64-bit integer to the Buffer.
+// This is the format for the
+// fixed64, sfixed64, and double protocol buffer types.
+func (p *Buffer) EncodeFixed64(x uint64) error {
+ p.buf = append(p.buf,
+ uint8(x),
+ uint8(x>>8),
+ uint8(x>>16),
+ uint8(x>>24),
+ uint8(x>>32),
+ uint8(x>>40),
+ uint8(x>>48),
+ uint8(x>>56))
+ return nil
+}
+
+// EncodeFixed32 writes a 32-bit integer to the Buffer.
+// This is the format for the
+// fixed32, sfixed32, and float protocol buffer types.
+func (p *Buffer) EncodeFixed32(x uint64) error {
+ p.buf = append(p.buf,
+ uint8(x),
+ uint8(x>>8),
+ uint8(x>>16),
+ uint8(x>>24))
+ return nil
+}
+
+// EncodeZigzag64 writes a zigzag-encoded 64-bit integer
+// to the Buffer.
+// This is the format used for the sint64 protocol buffer type.
+func (p *Buffer) EncodeZigzag64(x uint64) error {
+ // use signed number to get arithmetic right shift.
+ return p.EncodeVarint(uint64((x << 1) ^ uint64((int64(x) >> 63))))
+}
+
+// EncodeZigzag32 writes a zigzag-encoded 32-bit integer
+// to the Buffer.
+// This is the format used for the sint32 protocol buffer type.
+func (p *Buffer) EncodeZigzag32(x uint64) error {
+ // use signed number to get arithmetic right shift.
+ return p.EncodeVarint(uint64((uint32(x) << 1) ^ uint32((int32(x) >> 31))))
+}
+
+// EncodeRawBytes writes a count-delimited byte buffer to the Buffer.
+// This is the format used for the bytes protocol buffer
+// type and for embedded messages.
+func (p *Buffer) EncodeRawBytes(b []byte) error {
+ p.EncodeVarint(uint64(len(b)))
+ p.buf = append(p.buf, b...)
+ return nil
+}
+
+// EncodeStringBytes writes an encoded string to the Buffer.
+// This is the format used for the proto2 string type.
+func (p *Buffer) EncodeStringBytes(s string) error {
+ p.EncodeVarint(uint64(len(s)))
+ p.buf = append(p.buf, s...)
+ return nil
+}
+
+// Marshaler is the interface representing objects that can marshal themselves.
+type Marshaler interface {
+ Marshal() ([]byte, error)
+}
+
+// EncodeMessage writes the protocol buffer to the Buffer,
+// prefixed by a varint-encoded length.
+func (p *Buffer) EncodeMessage(pb Message) error {
+ siz := Size(pb)
+ p.EncodeVarint(uint64(siz))
+ return p.Marshal(pb)
+}
+
+// All protocol buffer fields are nillable, but be careful.
+func isNil(v reflect.Value) bool {
+ switch v.Kind() {
+ case reflect.Interface, reflect.Map, reflect.Ptr, reflect.Slice:
+ return v.IsNil()
+ }
+ return false
+}
diff --git a/vendor/github.com/golang/protobuf/proto/equal.go b/vendor/github.com/golang/protobuf/proto/equal.go
new file mode 100644
index 0000000000000000000000000000000000000000..f9b6e41b3c1087a0f8a7adc1e36143b241d6a016
--- /dev/null
+++ b/vendor/github.com/golang/protobuf/proto/equal.go
@@ -0,0 +1,301 @@
+// Go support for Protocol Buffers - Google's data interchange format
+//
+// Copyright 2011 The Go Authors. All rights reserved.
+// https://github.com/golang/protobuf
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Protocol buffer comparison.
+
+package proto
+
+import (
+ "bytes"
+ "log"
+ "reflect"
+ "strings"
+)
+
+/*
+Equal returns true iff protocol buffers a and b are equal.
+The arguments must both be pointers to protocol buffer structs.
+
+Equality is defined in this way:
+ - Two messages are equal iff they are the same type,
+ corresponding fields are equal, unknown field sets
+ are equal, and extensions sets are equal.
+ - Two set scalar fields are equal iff their values are equal.
+ If the fields are of a floating-point type, remember that
+ NaN != x for all x, including NaN. If the message is defined
+ in a proto3 .proto file, fields are not "set"; specifically,
+ zero length proto3 "bytes" fields are equal (nil == {}).
+ - Two repeated fields are equal iff their lengths are the same,
+ and their corresponding elements are equal. Note a "bytes" field,
+ although represented by []byte, is not a repeated field and the
+ rule for the scalar fields described above applies.
+ - Two unset fields are equal.
+ - Two unknown field sets are equal if their current
+ encoded state is equal.
+ - Two extension sets are equal iff they have corresponding
+ elements that are pairwise equal.
+ - Two map fields are equal iff their lengths are the same,
+ and they contain the same set of elements. Zero-length map
+ fields are equal.
+ - Every other combination of things are not equal.
+
+The return value is undefined if a and b are not protocol buffers.
+*/
+func Equal(a, b Message) bool {
+ if a == nil || b == nil {
+ return a == b
+ }
+ v1, v2 := reflect.ValueOf(a), reflect.ValueOf(b)
+ if v1.Type() != v2.Type() {
+ return false
+ }
+ if v1.Kind() == reflect.Ptr {
+ if v1.IsNil() {
+ return v2.IsNil()
+ }
+ if v2.IsNil() {
+ return false
+ }
+ v1, v2 = v1.Elem(), v2.Elem()
+ }
+ if v1.Kind() != reflect.Struct {
+ return false
+ }
+ return equalStruct(v1, v2)
+}
+
+// v1 and v2 are known to have the same type.
+func equalStruct(v1, v2 reflect.Value) bool {
+ sprop := GetProperties(v1.Type())
+ for i := 0; i < v1.NumField(); i++ {
+ f := v1.Type().Field(i)
+ if strings.HasPrefix(f.Name, "XXX_") {
+ continue
+ }
+ f1, f2 := v1.Field(i), v2.Field(i)
+ if f.Type.Kind() == reflect.Ptr {
+ if n1, n2 := f1.IsNil(), f2.IsNil(); n1 && n2 {
+ // both unset
+ continue
+ } else if n1 != n2 {
+ // set/unset mismatch
+ return false
+ }
+ f1, f2 = f1.Elem(), f2.Elem()
+ }
+ if !equalAny(f1, f2, sprop.Prop[i]) {
+ return false
+ }
+ }
+
+ if em1 := v1.FieldByName("XXX_InternalExtensions"); em1.IsValid() {
+ em2 := v2.FieldByName("XXX_InternalExtensions")
+ if !equalExtensions(v1.Type(), em1.Interface().(XXX_InternalExtensions), em2.Interface().(XXX_InternalExtensions)) {
+ return false
+ }
+ }
+
+ if em1 := v1.FieldByName("XXX_extensions"); em1.IsValid() {
+ em2 := v2.FieldByName("XXX_extensions")
+ if !equalExtMap(v1.Type(), em1.Interface().(map[int32]Extension), em2.Interface().(map[int32]Extension)) {
+ return false
+ }
+ }
+
+ uf := v1.FieldByName("XXX_unrecognized")
+ if !uf.IsValid() {
+ return true
+ }
+
+ u1 := uf.Bytes()
+ u2 := v2.FieldByName("XXX_unrecognized").Bytes()
+ return bytes.Equal(u1, u2)
+}
+
+// v1 and v2 are known to have the same type.
+// prop may be nil.
+func equalAny(v1, v2 reflect.Value, prop *Properties) bool {
+ if v1.Type() == protoMessageType {
+ m1, _ := v1.Interface().(Message)
+ m2, _ := v2.Interface().(Message)
+ return Equal(m1, m2)
+ }
+ switch v1.Kind() {
+ case reflect.Bool:
+ return v1.Bool() == v2.Bool()
+ case reflect.Float32, reflect.Float64:
+ return v1.Float() == v2.Float()
+ case reflect.Int32, reflect.Int64:
+ return v1.Int() == v2.Int()
+ case reflect.Interface:
+ // Probably a oneof field; compare the inner values.
+ n1, n2 := v1.IsNil(), v2.IsNil()
+ if n1 || n2 {
+ return n1 == n2
+ }
+ e1, e2 := v1.Elem(), v2.Elem()
+ if e1.Type() != e2.Type() {
+ return false
+ }
+ return equalAny(e1, e2, nil)
+ case reflect.Map:
+ if v1.Len() != v2.Len() {
+ return false
+ }
+ for _, key := range v1.MapKeys() {
+ val2 := v2.MapIndex(key)
+ if !val2.IsValid() {
+ // This key was not found in the second map.
+ return false
+ }
+ if !equalAny(v1.MapIndex(key), val2, nil) {
+ return false
+ }
+ }
+ return true
+ case reflect.Ptr:
+ // Maps may have nil values in them, so check for nil.
+ if v1.IsNil() && v2.IsNil() {
+ return true
+ }
+ if v1.IsNil() != v2.IsNil() {
+ return false
+ }
+ return equalAny(v1.Elem(), v2.Elem(), prop)
+ case reflect.Slice:
+ if v1.Type().Elem().Kind() == reflect.Uint8 {
+ // short circuit: []byte
+
+ // Edge case: if this is in a proto3 message, a zero length
+ // bytes field is considered the zero value.
+ if prop != nil && prop.proto3 && v1.Len() == 0 && v2.Len() == 0 {
+ return true
+ }
+ if v1.IsNil() != v2.IsNil() {
+ return false
+ }
+ return bytes.Equal(v1.Interface().([]byte), v2.Interface().([]byte))
+ }
+
+ if v1.Len() != v2.Len() {
+ return false
+ }
+ for i := 0; i < v1.Len(); i++ {
+ if !equalAny(v1.Index(i), v2.Index(i), prop) {
+ return false
+ }
+ }
+ return true
+ case reflect.String:
+ return v1.Interface().(string) == v2.Interface().(string)
+ case reflect.Struct:
+ return equalStruct(v1, v2)
+ case reflect.Uint32, reflect.Uint64:
+ return v1.Uint() == v2.Uint()
+ }
+
+ // unknown type, so not a protocol buffer
+ log.Printf("proto: don't know how to compare %v", v1)
+ return false
+}
+
+// base is the struct type that the extensions are based on.
+// x1 and x2 are InternalExtensions.
+func equalExtensions(base reflect.Type, x1, x2 XXX_InternalExtensions) bool {
+ em1, _ := x1.extensionsRead()
+ em2, _ := x2.extensionsRead()
+ return equalExtMap(base, em1, em2)
+}
+
+func equalExtMap(base reflect.Type, em1, em2 map[int32]Extension) bool {
+ if len(em1) != len(em2) {
+ return false
+ }
+
+ for extNum, e1 := range em1 {
+ e2, ok := em2[extNum]
+ if !ok {
+ return false
+ }
+
+ m1 := extensionAsLegacyType(e1.value)
+ m2 := extensionAsLegacyType(e2.value)
+
+ if m1 == nil && m2 == nil {
+ // Both have only encoded form.
+ if bytes.Equal(e1.enc, e2.enc) {
+ continue
+ }
+ // The bytes are different, but the extensions might still be
+ // equal. We need to decode them to compare.
+ }
+
+ if m1 != nil && m2 != nil {
+ // Both are unencoded.
+ if !equalAny(reflect.ValueOf(m1), reflect.ValueOf(m2), nil) {
+ return false
+ }
+ continue
+ }
+
+ // At least one is encoded. To do a semantically correct comparison
+ // we need to unmarshal them first.
+ var desc *ExtensionDesc
+ if m := extensionMaps[base]; m != nil {
+ desc = m[extNum]
+ }
+ if desc == nil {
+ // If both have only encoded form and the bytes are the same,
+ // it is handled above. We get here when the bytes are different.
+ // We don't know how to decode it, so just compare them as byte
+ // slices.
+ log.Printf("proto: don't know how to compare extension %d of %v", extNum, base)
+ return false
+ }
+ var err error
+ if m1 == nil {
+ m1, err = decodeExtension(e1.enc, desc)
+ }
+ if m2 == nil && err == nil {
+ m2, err = decodeExtension(e2.enc, desc)
+ }
+ if err != nil {
+ // The encoded form is invalid.
+ log.Printf("proto: badly encoded extension %d of %v: %v", extNum, base, err)
+ return false
+ }
+ if !equalAny(reflect.ValueOf(m1), reflect.ValueOf(m2), nil) {
+ return false
+ }
+ }
+
+ return true
+}
diff --git a/vendor/github.com/golang/protobuf/proto/extensions.go b/vendor/github.com/golang/protobuf/proto/extensions.go
new file mode 100644
index 0000000000000000000000000000000000000000..fa88add30a41f881fd5445ea8581ff26e7c12432
--- /dev/null
+++ b/vendor/github.com/golang/protobuf/proto/extensions.go
@@ -0,0 +1,607 @@
+// Go support for Protocol Buffers - Google's data interchange format
+//
+// Copyright 2010 The Go Authors. All rights reserved.
+// https://github.com/golang/protobuf
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package proto
+
+/*
+ * Types and routines for supporting protocol buffer extensions.
+ */
+
+import (
+ "errors"
+ "fmt"
+ "io"
+ "reflect"
+ "strconv"
+ "sync"
+)
+
+// ErrMissingExtension is the error returned by GetExtension if the named extension is not in the message.
+var ErrMissingExtension = errors.New("proto: missing extension")
+
+// ExtensionRange represents a range of message extensions for a protocol buffer.
+// Used in code generated by the protocol compiler.
+type ExtensionRange struct {
+ Start, End int32 // both inclusive
+}
+
+// extendableProto is an interface implemented by any protocol buffer generated by the current
+// proto compiler that may be extended.
+type extendableProto interface {
+ Message
+ ExtensionRangeArray() []ExtensionRange
+ extensionsWrite() map[int32]Extension
+ extensionsRead() (map[int32]Extension, sync.Locker)
+}
+
+// extendableProtoV1 is an interface implemented by a protocol buffer generated by the previous
+// version of the proto compiler that may be extended.
+type extendableProtoV1 interface {
+ Message
+ ExtensionRangeArray() []ExtensionRange
+ ExtensionMap() map[int32]Extension
+}
+
+// extensionAdapter is a wrapper around extendableProtoV1 that implements extendableProto.
+type extensionAdapter struct {
+ extendableProtoV1
+}
+
+func (e extensionAdapter) extensionsWrite() map[int32]Extension {
+ return e.ExtensionMap()
+}
+
+func (e extensionAdapter) extensionsRead() (map[int32]Extension, sync.Locker) {
+ return e.ExtensionMap(), notLocker{}
+}
+
+// notLocker is a sync.Locker whose Lock and Unlock methods are nops.
+type notLocker struct{}
+
+func (n notLocker) Lock() {}
+func (n notLocker) Unlock() {}
+
+// extendable returns the extendableProto interface for the given generated proto message.
+// If the proto message has the old extension format, it returns a wrapper that implements
+// the extendableProto interface.
+func extendable(p interface{}) (extendableProto, error) {
+ switch p := p.(type) {
+ case extendableProto:
+ if isNilPtr(p) {
+ return nil, fmt.Errorf("proto: nil %T is not extendable", p)
+ }
+ return p, nil
+ case extendableProtoV1:
+ if isNilPtr(p) {
+ return nil, fmt.Errorf("proto: nil %T is not extendable", p)
+ }
+ return extensionAdapter{p}, nil
+ }
+ // Don't allocate a specific error containing %T:
+ // this is the hot path for Clone and MarshalText.
+ return nil, errNotExtendable
+}
+
+var errNotExtendable = errors.New("proto: not an extendable proto.Message")
+
+func isNilPtr(x interface{}) bool {
+ v := reflect.ValueOf(x)
+ return v.Kind() == reflect.Ptr && v.IsNil()
+}
+
+// XXX_InternalExtensions is an internal representation of proto extensions.
+//
+// Each generated message struct type embeds an anonymous XXX_InternalExtensions field,
+// thus gaining the unexported 'extensions' method, which can be called only from the proto package.
+//
+// The methods of XXX_InternalExtensions are not concurrency safe in general,
+// but calls to logically read-only methods such as has and get may be executed concurrently.
+type XXX_InternalExtensions struct {
+ // The struct must be indirect so that if a user inadvertently copies a
+ // generated message and its embedded XXX_InternalExtensions, they
+ // avoid the mayhem of a copied mutex.
+ //
+ // The mutex serializes all logically read-only operations to p.extensionMap.
+ // It is up to the client to ensure that write operations to p.extensionMap are
+ // mutually exclusive with other accesses.
+ p *struct {
+ mu sync.Mutex
+ extensionMap map[int32]Extension
+ }
+}
+
+// extensionsWrite returns the extension map, creating it on first use.
+func (e *XXX_InternalExtensions) extensionsWrite() map[int32]Extension {
+ if e.p == nil {
+ e.p = new(struct {
+ mu sync.Mutex
+ extensionMap map[int32]Extension
+ })
+ e.p.extensionMap = make(map[int32]Extension)
+ }
+ return e.p.extensionMap
+}
+
+// extensionsRead returns the extensions map for read-only use. It may be nil.
+// The caller must hold the returned mutex's lock when accessing Elements within the map.
+func (e *XXX_InternalExtensions) extensionsRead() (map[int32]Extension, sync.Locker) {
+ if e.p == nil {
+ return nil, nil
+ }
+ return e.p.extensionMap, &e.p.mu
+}
+
+// ExtensionDesc represents an extension specification.
+// Used in generated code from the protocol compiler.
+type ExtensionDesc struct {
+ ExtendedType Message // nil pointer to the type that is being extended
+ ExtensionType interface{} // nil pointer to the extension type
+ Field int32 // field number
+ Name string // fully-qualified name of extension, for text formatting
+ Tag string // protobuf tag style
+ Filename string // name of the file in which the extension is defined
+}
+
+func (ed *ExtensionDesc) repeated() bool {
+ t := reflect.TypeOf(ed.ExtensionType)
+ return t.Kind() == reflect.Slice && t.Elem().Kind() != reflect.Uint8
+}
+
+// Extension represents an extension in a message.
+type Extension struct {
+ // When an extension is stored in a message using SetExtension
+ // only desc and value are set. When the message is marshaled
+ // enc will be set to the encoded form of the message.
+ //
+ // When a message is unmarshaled and contains extensions, each
+ // extension will have only enc set. When such an extension is
+ // accessed using GetExtension (or GetExtensions) desc and value
+ // will be set.
+ desc *ExtensionDesc
+
+ // value is a concrete value for the extension field. Let the type of
+ // desc.ExtensionType be the "API type" and the type of Extension.value
+ // be the "storage type". The API type and storage type are the same except:
+ // * For scalars (except []byte), the API type uses *T,
+ // while the storage type uses T.
+ // * For repeated fields, the API type uses []T, while the storage type
+ // uses *[]T.
+ //
+ // The reason for the divergence is so that the storage type more naturally
+ // matches what is expected of when retrieving the values through the
+ // protobuf reflection APIs.
+ //
+ // The value may only be populated if desc is also populated.
+ value interface{}
+
+ // enc is the raw bytes for the extension field.
+ enc []byte
+}
+
+// SetRawExtension is for testing only.
+func SetRawExtension(base Message, id int32, b []byte) {
+ epb, err := extendable(base)
+ if err != nil {
+ return
+ }
+ extmap := epb.extensionsWrite()
+ extmap[id] = Extension{enc: b}
+}
+
+// isExtensionField returns true iff the given field number is in an extension range.
+func isExtensionField(pb extendableProto, field int32) bool {
+ for _, er := range pb.ExtensionRangeArray() {
+ if er.Start <= field && field <= er.End {
+ return true
+ }
+ }
+ return false
+}
+
+// checkExtensionTypes checks that the given extension is valid for pb.
+func checkExtensionTypes(pb extendableProto, extension *ExtensionDesc) error {
+ var pbi interface{} = pb
+ // Check the extended type.
+ if ea, ok := pbi.(extensionAdapter); ok {
+ pbi = ea.extendableProtoV1
+ }
+ if a, b := reflect.TypeOf(pbi), reflect.TypeOf(extension.ExtendedType); a != b {
+ return fmt.Errorf("proto: bad extended type; %v does not extend %v", b, a)
+ }
+ // Check the range.
+ if !isExtensionField(pb, extension.Field) {
+ return errors.New("proto: bad extension number; not in declared ranges")
+ }
+ return nil
+}
+
+// extPropKey is sufficient to uniquely identify an extension.
+type extPropKey struct {
+ base reflect.Type
+ field int32
+}
+
+var extProp = struct {
+ sync.RWMutex
+ m map[extPropKey]*Properties
+}{
+ m: make(map[extPropKey]*Properties),
+}
+
+func extensionProperties(ed *ExtensionDesc) *Properties {
+ key := extPropKey{base: reflect.TypeOf(ed.ExtendedType), field: ed.Field}
+
+ extProp.RLock()
+ if prop, ok := extProp.m[key]; ok {
+ extProp.RUnlock()
+ return prop
+ }
+ extProp.RUnlock()
+
+ extProp.Lock()
+ defer extProp.Unlock()
+ // Check again.
+ if prop, ok := extProp.m[key]; ok {
+ return prop
+ }
+
+ prop := new(Properties)
+ prop.Init(reflect.TypeOf(ed.ExtensionType), "unknown_name", ed.Tag, nil)
+ extProp.m[key] = prop
+ return prop
+}
+
+// HasExtension returns whether the given extension is present in pb.
+func HasExtension(pb Message, extension *ExtensionDesc) bool {
+ // TODO: Check types, field numbers, etc.?
+ epb, err := extendable(pb)
+ if err != nil {
+ return false
+ }
+ extmap, mu := epb.extensionsRead()
+ if extmap == nil {
+ return false
+ }
+ mu.Lock()
+ _, ok := extmap[extension.Field]
+ mu.Unlock()
+ return ok
+}
+
+// ClearExtension removes the given extension from pb.
+func ClearExtension(pb Message, extension *ExtensionDesc) {
+ epb, err := extendable(pb)
+ if err != nil {
+ return
+ }
+ // TODO: Check types, field numbers, etc.?
+ extmap := epb.extensionsWrite()
+ delete(extmap, extension.Field)
+}
+
+// GetExtension retrieves a proto2 extended field from pb.
+//
+// If the descriptor is type complete (i.e., ExtensionDesc.ExtensionType is non-nil),
+// then GetExtension parses the encoded field and returns a Go value of the specified type.
+// If the field is not present, then the default value is returned (if one is specified),
+// otherwise ErrMissingExtension is reported.
+//
+// If the descriptor is not type complete (i.e., ExtensionDesc.ExtensionType is nil),
+// then GetExtension returns the raw encoded bytes of the field extension.
+func GetExtension(pb Message, extension *ExtensionDesc) (interface{}, error) {
+ epb, err := extendable(pb)
+ if err != nil {
+ return nil, err
+ }
+
+ if extension.ExtendedType != nil {
+ // can only check type if this is a complete descriptor
+ if err := checkExtensionTypes(epb, extension); err != nil {
+ return nil, err
+ }
+ }
+
+ emap, mu := epb.extensionsRead()
+ if emap == nil {
+ return defaultExtensionValue(extension)
+ }
+ mu.Lock()
+ defer mu.Unlock()
+ e, ok := emap[extension.Field]
+ if !ok {
+ // defaultExtensionValue returns the default value or
+ // ErrMissingExtension if there is no default.
+ return defaultExtensionValue(extension)
+ }
+
+ if e.value != nil {
+ // Already decoded. Check the descriptor, though.
+ if e.desc != extension {
+ // This shouldn't happen. If it does, it means that
+ // GetExtension was called twice with two different
+ // descriptors with the same field number.
+ return nil, errors.New("proto: descriptor conflict")
+ }
+ return extensionAsLegacyType(e.value), nil
+ }
+
+ if extension.ExtensionType == nil {
+ // incomplete descriptor
+ return e.enc, nil
+ }
+
+ v, err := decodeExtension(e.enc, extension)
+ if err != nil {
+ return nil, err
+ }
+
+ // Remember the decoded version and drop the encoded version.
+ // That way it is safe to mutate what we return.
+ e.value = extensionAsStorageType(v)
+ e.desc = extension
+ e.enc = nil
+ emap[extension.Field] = e
+ return extensionAsLegacyType(e.value), nil
+}
+
+// defaultExtensionValue returns the default value for extension.
+// If no default for an extension is defined ErrMissingExtension is returned.
+func defaultExtensionValue(extension *ExtensionDesc) (interface{}, error) {
+ if extension.ExtensionType == nil {
+ // incomplete descriptor, so no default
+ return nil, ErrMissingExtension
+ }
+
+ t := reflect.TypeOf(extension.ExtensionType)
+ props := extensionProperties(extension)
+
+ sf, _, err := fieldDefault(t, props)
+ if err != nil {
+ return nil, err
+ }
+
+ if sf == nil || sf.value == nil {
+ // There is no default value.
+ return nil, ErrMissingExtension
+ }
+
+ if t.Kind() != reflect.Ptr {
+ // We do not need to return a Ptr, we can directly return sf.value.
+ return sf.value, nil
+ }
+
+ // We need to return an interface{} that is a pointer to sf.value.
+ value := reflect.New(t).Elem()
+ value.Set(reflect.New(value.Type().Elem()))
+ if sf.kind == reflect.Int32 {
+ // We may have an int32 or an enum, but the underlying data is int32.
+ // Since we can't set an int32 into a non int32 reflect.value directly
+ // set it as a int32.
+ value.Elem().SetInt(int64(sf.value.(int32)))
+ } else {
+ value.Elem().Set(reflect.ValueOf(sf.value))
+ }
+ return value.Interface(), nil
+}
+
+// decodeExtension decodes an extension encoded in b.
+func decodeExtension(b []byte, extension *ExtensionDesc) (interface{}, error) {
+ t := reflect.TypeOf(extension.ExtensionType)
+ unmarshal := typeUnmarshaler(t, extension.Tag)
+
+ // t is a pointer to a struct, pointer to basic type or a slice.
+ // Allocate space to store the pointer/slice.
+ value := reflect.New(t).Elem()
+
+ var err error
+ for {
+ x, n := decodeVarint(b)
+ if n == 0 {
+ return nil, io.ErrUnexpectedEOF
+ }
+ b = b[n:]
+ wire := int(x) & 7
+
+ b, err = unmarshal(b, valToPointer(value.Addr()), wire)
+ if err != nil {
+ return nil, err
+ }
+
+ if len(b) == 0 {
+ break
+ }
+ }
+ return value.Interface(), nil
+}
+
+// GetExtensions returns a slice of the extensions present in pb that are also listed in es.
+// The returned slice has the same length as es; missing extensions will appear as nil elements.
+func GetExtensions(pb Message, es []*ExtensionDesc) (extensions []interface{}, err error) {
+ epb, err := extendable(pb)
+ if err != nil {
+ return nil, err
+ }
+ extensions = make([]interface{}, len(es))
+ for i, e := range es {
+ extensions[i], err = GetExtension(epb, e)
+ if err == ErrMissingExtension {
+ err = nil
+ }
+ if err != nil {
+ return
+ }
+ }
+ return
+}
+
+// ExtensionDescs returns a new slice containing pb's extension descriptors, in undefined order.
+// For non-registered extensions, ExtensionDescs returns an incomplete descriptor containing
+// just the Field field, which defines the extension's field number.
+func ExtensionDescs(pb Message) ([]*ExtensionDesc, error) {
+ epb, err := extendable(pb)
+ if err != nil {
+ return nil, err
+ }
+ registeredExtensions := RegisteredExtensions(pb)
+
+ emap, mu := epb.extensionsRead()
+ if emap == nil {
+ return nil, nil
+ }
+ mu.Lock()
+ defer mu.Unlock()
+ extensions := make([]*ExtensionDesc, 0, len(emap))
+ for extid, e := range emap {
+ desc := e.desc
+ if desc == nil {
+ desc = registeredExtensions[extid]
+ if desc == nil {
+ desc = &ExtensionDesc{Field: extid}
+ }
+ }
+
+ extensions = append(extensions, desc)
+ }
+ return extensions, nil
+}
+
+// SetExtension sets the specified extension of pb to the specified value.
+func SetExtension(pb Message, extension *ExtensionDesc, value interface{}) error {
+ epb, err := extendable(pb)
+ if err != nil {
+ return err
+ }
+ if err := checkExtensionTypes(epb, extension); err != nil {
+ return err
+ }
+ typ := reflect.TypeOf(extension.ExtensionType)
+ if typ != reflect.TypeOf(value) {
+ return fmt.Errorf("proto: bad extension value type. got: %T, want: %T", value, extension.ExtensionType)
+ }
+ // nil extension values need to be caught early, because the
+ // encoder can't distinguish an ErrNil due to a nil extension
+ // from an ErrNil due to a missing field. Extensions are
+ // always optional, so the encoder would just swallow the error
+ // and drop all the extensions from the encoded message.
+ if reflect.ValueOf(value).IsNil() {
+ return fmt.Errorf("proto: SetExtension called with nil value of type %T", value)
+ }
+
+ extmap := epb.extensionsWrite()
+ extmap[extension.Field] = Extension{desc: extension, value: extensionAsStorageType(value)}
+ return nil
+}
+
+// ClearAllExtensions clears all extensions from pb.
+func ClearAllExtensions(pb Message) {
+ epb, err := extendable(pb)
+ if err != nil {
+ return
+ }
+ m := epb.extensionsWrite()
+ for k := range m {
+ delete(m, k)
+ }
+}
+
+// A global registry of extensions.
+// The generated code will register the generated descriptors by calling RegisterExtension.
+
+var extensionMaps = make(map[reflect.Type]map[int32]*ExtensionDesc)
+
+// RegisterExtension is called from the generated code.
+func RegisterExtension(desc *ExtensionDesc) {
+ st := reflect.TypeOf(desc.ExtendedType).Elem()
+ m := extensionMaps[st]
+ if m == nil {
+ m = make(map[int32]*ExtensionDesc)
+ extensionMaps[st] = m
+ }
+ if _, ok := m[desc.Field]; ok {
+ panic("proto: duplicate extension registered: " + st.String() + " " + strconv.Itoa(int(desc.Field)))
+ }
+ m[desc.Field] = desc
+}
+
+// RegisteredExtensions returns a map of the registered extensions of a
+// protocol buffer struct, indexed by the extension number.
+// The argument pb should be a nil pointer to the struct type.
+func RegisteredExtensions(pb Message) map[int32]*ExtensionDesc {
+ return extensionMaps[reflect.TypeOf(pb).Elem()]
+}
+
+// extensionAsLegacyType converts an value in the storage type as the API type.
+// See Extension.value.
+func extensionAsLegacyType(v interface{}) interface{} {
+ switch rv := reflect.ValueOf(v); rv.Kind() {
+ case reflect.Bool, reflect.Int32, reflect.Int64, reflect.Uint32, reflect.Uint64, reflect.Float32, reflect.Float64, reflect.String:
+ // Represent primitive types as a pointer to the value.
+ rv2 := reflect.New(rv.Type())
+ rv2.Elem().Set(rv)
+ v = rv2.Interface()
+ case reflect.Ptr:
+ // Represent slice types as the value itself.
+ switch rv.Type().Elem().Kind() {
+ case reflect.Slice:
+ if rv.IsNil() {
+ v = reflect.Zero(rv.Type().Elem()).Interface()
+ } else {
+ v = rv.Elem().Interface()
+ }
+ }
+ }
+ return v
+}
+
+// extensionAsStorageType converts an value in the API type as the storage type.
+// See Extension.value.
+func extensionAsStorageType(v interface{}) interface{} {
+ switch rv := reflect.ValueOf(v); rv.Kind() {
+ case reflect.Ptr:
+ // Represent slice types as the value itself.
+ switch rv.Type().Elem().Kind() {
+ case reflect.Bool, reflect.Int32, reflect.Int64, reflect.Uint32, reflect.Uint64, reflect.Float32, reflect.Float64, reflect.String:
+ if rv.IsNil() {
+ v = reflect.Zero(rv.Type().Elem()).Interface()
+ } else {
+ v = rv.Elem().Interface()
+ }
+ }
+ case reflect.Slice:
+ // Represent slice types as a pointer to the value.
+ if rv.Type().Elem().Kind() != reflect.Uint8 {
+ rv2 := reflect.New(rv.Type())
+ rv2.Elem().Set(rv)
+ v = rv2.Interface()
+ }
+ }
+ return v
+}
diff --git a/vendor/github.com/golang/protobuf/proto/lib.go b/vendor/github.com/golang/protobuf/proto/lib.go
new file mode 100644
index 0000000000000000000000000000000000000000..fdd328bb7f541e68813bb369e21e26ec3c096725
--- /dev/null
+++ b/vendor/github.com/golang/protobuf/proto/lib.go
@@ -0,0 +1,965 @@
+// Go support for Protocol Buffers - Google's data interchange format
+//
+// Copyright 2010 The Go Authors. All rights reserved.
+// https://github.com/golang/protobuf
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+/*
+Package proto converts data structures to and from the wire format of
+protocol buffers. It works in concert with the Go source code generated
+for .proto files by the protocol compiler.
+
+A summary of the properties of the protocol buffer interface
+for a protocol buffer variable v:
+
+ - Names are turned from camel_case to CamelCase for export.
+ - There are no methods on v to set fields; just treat
+ them as structure fields.
+ - There are getters that return a field's value if set,
+ and return the field's default value if unset.
+ The getters work even if the receiver is a nil message.
+ - The zero value for a struct is its correct initialization state.
+ All desired fields must be set before marshaling.
+ - A Reset() method will restore a protobuf struct to its zero state.
+ - Non-repeated fields are pointers to the values; nil means unset.
+ That is, optional or required field int32 f becomes F *int32.
+ - Repeated fields are slices.
+ - Helper functions are available to aid the setting of fields.
+ msg.Foo = proto.String("hello") // set field
+ - Constants are defined to hold the default values of all fields that
+ have them. They have the form Default_StructName_FieldName.
+ Because the getter methods handle defaulted values,
+ direct use of these constants should be rare.
+ - Enums are given type names and maps from names to values.
+ Enum values are prefixed by the enclosing message's name, or by the
+ enum's type name if it is a top-level enum. Enum types have a String
+ method, and a Enum method to assist in message construction.
+ - Nested messages, groups and enums have type names prefixed with the name of
+ the surrounding message type.
+ - Extensions are given descriptor names that start with E_,
+ followed by an underscore-delimited list of the nested messages
+ that contain it (if any) followed by the CamelCased name of the
+ extension field itself. HasExtension, ClearExtension, GetExtension
+ and SetExtension are functions for manipulating extensions.
+ - Oneof field sets are given a single field in their message,
+ with distinguished wrapper types for each possible field value.
+ - Marshal and Unmarshal are functions to encode and decode the wire format.
+
+When the .proto file specifies `syntax="proto3"`, there are some differences:
+
+ - Non-repeated fields of non-message type are values instead of pointers.
+ - Enum types do not get an Enum method.
+
+The simplest way to describe this is to see an example.
+Given file test.proto, containing
+
+ package example;
+
+ enum FOO { X = 17; }
+
+ message Test {
+ required string label = 1;
+ optional int32 type = 2 [default=77];
+ repeated int64 reps = 3;
+ optional group OptionalGroup = 4 {
+ required string RequiredField = 5;
+ }
+ oneof union {
+ int32 number = 6;
+ string name = 7;
+ }
+ }
+
+The resulting file, test.pb.go, is:
+
+ package example
+
+ import proto "github.com/golang/protobuf/proto"
+ import math "math"
+
+ type FOO int32
+ const (
+ FOO_X FOO = 17
+ )
+ var FOO_name = map[int32]string{
+ 17: "X",
+ }
+ var FOO_value = map[string]int32{
+ "X": 17,
+ }
+
+ func (x FOO) Enum() *FOO {
+ p := new(FOO)
+ *p = x
+ return p
+ }
+ func (x FOO) String() string {
+ return proto.EnumName(FOO_name, int32(x))
+ }
+ func (x *FOO) UnmarshalJSON(data []byte) error {
+ value, err := proto.UnmarshalJSONEnum(FOO_value, data)
+ if err != nil {
+ return err
+ }
+ *x = FOO(value)
+ return nil
+ }
+
+ type Test struct {
+ Label *string `protobuf:"bytes,1,req,name=label" json:"label,omitempty"`
+ Type *int32 `protobuf:"varint,2,opt,name=type,def=77" json:"type,omitempty"`
+ Reps []int64 `protobuf:"varint,3,rep,name=reps" json:"reps,omitempty"`
+ Optionalgroup *Test_OptionalGroup `protobuf:"group,4,opt,name=OptionalGroup" json:"optionalgroup,omitempty"`
+ // Types that are valid to be assigned to Union:
+ // *Test_Number
+ // *Test_Name
+ Union isTest_Union `protobuf_oneof:"union"`
+ XXX_unrecognized []byte `json:"-"`
+ }
+ func (m *Test) Reset() { *m = Test{} }
+ func (m *Test) String() string { return proto.CompactTextString(m) }
+ func (*Test) ProtoMessage() {}
+
+ type isTest_Union interface {
+ isTest_Union()
+ }
+
+ type Test_Number struct {
+ Number int32 `protobuf:"varint,6,opt,name=number"`
+ }
+ type Test_Name struct {
+ Name string `protobuf:"bytes,7,opt,name=name"`
+ }
+
+ func (*Test_Number) isTest_Union() {}
+ func (*Test_Name) isTest_Union() {}
+
+ func (m *Test) GetUnion() isTest_Union {
+ if m != nil {
+ return m.Union
+ }
+ return nil
+ }
+ const Default_Test_Type int32 = 77
+
+ func (m *Test) GetLabel() string {
+ if m != nil && m.Label != nil {
+ return *m.Label
+ }
+ return ""
+ }
+
+ func (m *Test) GetType() int32 {
+ if m != nil && m.Type != nil {
+ return *m.Type
+ }
+ return Default_Test_Type
+ }
+
+ func (m *Test) GetOptionalgroup() *Test_OptionalGroup {
+ if m != nil {
+ return m.Optionalgroup
+ }
+ return nil
+ }
+
+ type Test_OptionalGroup struct {
+ RequiredField *string `protobuf:"bytes,5,req" json:"RequiredField,omitempty"`
+ }
+ func (m *Test_OptionalGroup) Reset() { *m = Test_OptionalGroup{} }
+ func (m *Test_OptionalGroup) String() string { return proto.CompactTextString(m) }
+
+ func (m *Test_OptionalGroup) GetRequiredField() string {
+ if m != nil && m.RequiredField != nil {
+ return *m.RequiredField
+ }
+ return ""
+ }
+
+ func (m *Test) GetNumber() int32 {
+ if x, ok := m.GetUnion().(*Test_Number); ok {
+ return x.Number
+ }
+ return 0
+ }
+
+ func (m *Test) GetName() string {
+ if x, ok := m.GetUnion().(*Test_Name); ok {
+ return x.Name
+ }
+ return ""
+ }
+
+ func init() {
+ proto.RegisterEnum("example.FOO", FOO_name, FOO_value)
+ }
+
+To create and play with a Test object:
+
+ package main
+
+ import (
+ "log"
+
+ "github.com/golang/protobuf/proto"
+ pb "./example.pb"
+ )
+
+ func main() {
+ test := &pb.Test{
+ Label: proto.String("hello"),
+ Type: proto.Int32(17),
+ Reps: []int64{1, 2, 3},
+ Optionalgroup: &pb.Test_OptionalGroup{
+ RequiredField: proto.String("good bye"),
+ },
+ Union: &pb.Test_Name{"fred"},
+ }
+ data, err := proto.Marshal(test)
+ if err != nil {
+ log.Fatal("marshaling error: ", err)
+ }
+ newTest := &pb.Test{}
+ err = proto.Unmarshal(data, newTest)
+ if err != nil {
+ log.Fatal("unmarshaling error: ", err)
+ }
+ // Now test and newTest contain the same data.
+ if test.GetLabel() != newTest.GetLabel() {
+ log.Fatalf("data mismatch %q != %q", test.GetLabel(), newTest.GetLabel())
+ }
+ // Use a type switch to determine which oneof was set.
+ switch u := test.Union.(type) {
+ case *pb.Test_Number: // u.Number contains the number.
+ case *pb.Test_Name: // u.Name contains the string.
+ }
+ // etc.
+ }
+*/
+package proto
+
+import (
+ "encoding/json"
+ "fmt"
+ "log"
+ "reflect"
+ "sort"
+ "strconv"
+ "sync"
+)
+
+// RequiredNotSetError is an error type returned by either Marshal or Unmarshal.
+// Marshal reports this when a required field is not initialized.
+// Unmarshal reports this when a required field is missing from the wire data.
+type RequiredNotSetError struct{ field string }
+
+func (e *RequiredNotSetError) Error() string {
+ if e.field == "" {
+ return fmt.Sprintf("proto: required field not set")
+ }
+ return fmt.Sprintf("proto: required field %q not set", e.field)
+}
+func (e *RequiredNotSetError) RequiredNotSet() bool {
+ return true
+}
+
+type invalidUTF8Error struct{ field string }
+
+func (e *invalidUTF8Error) Error() string {
+ if e.field == "" {
+ return "proto: invalid UTF-8 detected"
+ }
+ return fmt.Sprintf("proto: field %q contains invalid UTF-8", e.field)
+}
+func (e *invalidUTF8Error) InvalidUTF8() bool {
+ return true
+}
+
+// errInvalidUTF8 is a sentinel error to identify fields with invalid UTF-8.
+// This error should not be exposed to the external API as such errors should
+// be recreated with the field information.
+var errInvalidUTF8 = &invalidUTF8Error{}
+
+// isNonFatal reports whether the error is either a RequiredNotSet error
+// or a InvalidUTF8 error.
+func isNonFatal(err error) bool {
+ if re, ok := err.(interface{ RequiredNotSet() bool }); ok && re.RequiredNotSet() {
+ return true
+ }
+ if re, ok := err.(interface{ InvalidUTF8() bool }); ok && re.InvalidUTF8() {
+ return true
+ }
+ return false
+}
+
+type nonFatal struct{ E error }
+
+// Merge merges err into nf and reports whether it was successful.
+// Otherwise it returns false for any fatal non-nil errors.
+func (nf *nonFatal) Merge(err error) (ok bool) {
+ if err == nil {
+ return true // not an error
+ }
+ if !isNonFatal(err) {
+ return false // fatal error
+ }
+ if nf.E == nil {
+ nf.E = err // store first instance of non-fatal error
+ }
+ return true
+}
+
+// Message is implemented by generated protocol buffer messages.
+type Message interface {
+ Reset()
+ String() string
+ ProtoMessage()
+}
+
+// A Buffer is a buffer manager for marshaling and unmarshaling
+// protocol buffers. It may be reused between invocations to
+// reduce memory usage. It is not necessary to use a Buffer;
+// the global functions Marshal and Unmarshal create a
+// temporary Buffer and are fine for most applications.
+type Buffer struct {
+ buf []byte // encode/decode byte stream
+ index int // read point
+
+ deterministic bool
+}
+
+// NewBuffer allocates a new Buffer and initializes its internal data to
+// the contents of the argument slice.
+func NewBuffer(e []byte) *Buffer {
+ return &Buffer{buf: e}
+}
+
+// Reset resets the Buffer, ready for marshaling a new protocol buffer.
+func (p *Buffer) Reset() {
+ p.buf = p.buf[0:0] // for reading/writing
+ p.index = 0 // for reading
+}
+
+// SetBuf replaces the internal buffer with the slice,
+// ready for unmarshaling the contents of the slice.
+func (p *Buffer) SetBuf(s []byte) {
+ p.buf = s
+ p.index = 0
+}
+
+// Bytes returns the contents of the Buffer.
+func (p *Buffer) Bytes() []byte { return p.buf }
+
+// SetDeterministic sets whether to use deterministic serialization.
+//
+// Deterministic serialization guarantees that for a given binary, equal
+// messages will always be serialized to the same bytes. This implies:
+//
+// - Repeated serialization of a message will return the same bytes.
+// - Different processes of the same binary (which may be executing on
+// different machines) will serialize equal messages to the same bytes.
+//
+// Note that the deterministic serialization is NOT canonical across
+// languages. It is not guaranteed to remain stable over time. It is unstable
+// across different builds with schema changes due to unknown fields.
+// Users who need canonical serialization (e.g., persistent storage in a
+// canonical form, fingerprinting, etc.) should define their own
+// canonicalization specification and implement their own serializer rather
+// than relying on this API.
+//
+// If deterministic serialization is requested, map entries will be sorted
+// by keys in lexographical order. This is an implementation detail and
+// subject to change.
+func (p *Buffer) SetDeterministic(deterministic bool) {
+ p.deterministic = deterministic
+}
+
+/*
+ * Helper routines for simplifying the creation of optional fields of basic type.
+ */
+
+// Bool is a helper routine that allocates a new bool value
+// to store v and returns a pointer to it.
+func Bool(v bool) *bool {
+ return &v
+}
+
+// Int32 is a helper routine that allocates a new int32 value
+// to store v and returns a pointer to it.
+func Int32(v int32) *int32 {
+ return &v
+}
+
+// Int is a helper routine that allocates a new int32 value
+// to store v and returns a pointer to it, but unlike Int32
+// its argument value is an int.
+func Int(v int) *int32 {
+ p := new(int32)
+ *p = int32(v)
+ return p
+}
+
+// Int64 is a helper routine that allocates a new int64 value
+// to store v and returns a pointer to it.
+func Int64(v int64) *int64 {
+ return &v
+}
+
+// Float32 is a helper routine that allocates a new float32 value
+// to store v and returns a pointer to it.
+func Float32(v float32) *float32 {
+ return &v
+}
+
+// Float64 is a helper routine that allocates a new float64 value
+// to store v and returns a pointer to it.
+func Float64(v float64) *float64 {
+ return &v
+}
+
+// Uint32 is a helper routine that allocates a new uint32 value
+// to store v and returns a pointer to it.
+func Uint32(v uint32) *uint32 {
+ return &v
+}
+
+// Uint64 is a helper routine that allocates a new uint64 value
+// to store v and returns a pointer to it.
+func Uint64(v uint64) *uint64 {
+ return &v
+}
+
+// String is a helper routine that allocates a new string value
+// to store v and returns a pointer to it.
+func String(v string) *string {
+ return &v
+}
+
+// EnumName is a helper function to simplify printing protocol buffer enums
+// by name. Given an enum map and a value, it returns a useful string.
+func EnumName(m map[int32]string, v int32) string {
+ s, ok := m[v]
+ if ok {
+ return s
+ }
+ return strconv.Itoa(int(v))
+}
+
+// UnmarshalJSONEnum is a helper function to simplify recovering enum int values
+// from their JSON-encoded representation. Given a map from the enum's symbolic
+// names to its int values, and a byte buffer containing the JSON-encoded
+// value, it returns an int32 that can be cast to the enum type by the caller.
+//
+// The function can deal with both JSON representations, numeric and symbolic.
+func UnmarshalJSONEnum(m map[string]int32, data []byte, enumName string) (int32, error) {
+ if data[0] == '"' {
+ // New style: enums are strings.
+ var repr string
+ if err := json.Unmarshal(data, &repr); err != nil {
+ return -1, err
+ }
+ val, ok := m[repr]
+ if !ok {
+ return 0, fmt.Errorf("unrecognized enum %s value %q", enumName, repr)
+ }
+ return val, nil
+ }
+ // Old style: enums are ints.
+ var val int32
+ if err := json.Unmarshal(data, &val); err != nil {
+ return 0, fmt.Errorf("cannot unmarshal %#q into enum %s", data, enumName)
+ }
+ return val, nil
+}
+
+// DebugPrint dumps the encoded data in b in a debugging format with a header
+// including the string s. Used in testing but made available for general debugging.
+func (p *Buffer) DebugPrint(s string, b []byte) {
+ var u uint64
+
+ obuf := p.buf
+ index := p.index
+ p.buf = b
+ p.index = 0
+ depth := 0
+
+ fmt.Printf("\n--- %s ---\n", s)
+
+out:
+ for {
+ for i := 0; i < depth; i++ {
+ fmt.Print(" ")
+ }
+
+ index := p.index
+ if index == len(p.buf) {
+ break
+ }
+
+ op, err := p.DecodeVarint()
+ if err != nil {
+ fmt.Printf("%3d: fetching op err %v\n", index, err)
+ break out
+ }
+ tag := op >> 3
+ wire := op & 7
+
+ switch wire {
+ default:
+ fmt.Printf("%3d: t=%3d unknown wire=%d\n",
+ index, tag, wire)
+ break out
+
+ case WireBytes:
+ var r []byte
+
+ r, err = p.DecodeRawBytes(false)
+ if err != nil {
+ break out
+ }
+ fmt.Printf("%3d: t=%3d bytes [%d]", index, tag, len(r))
+ if len(r) <= 6 {
+ for i := 0; i < len(r); i++ {
+ fmt.Printf(" %.2x", r[i])
+ }
+ } else {
+ for i := 0; i < 3; i++ {
+ fmt.Printf(" %.2x", r[i])
+ }
+ fmt.Printf(" ..")
+ for i := len(r) - 3; i < len(r); i++ {
+ fmt.Printf(" %.2x", r[i])
+ }
+ }
+ fmt.Printf("\n")
+
+ case WireFixed32:
+ u, err = p.DecodeFixed32()
+ if err != nil {
+ fmt.Printf("%3d: t=%3d fix32 err %v\n", index, tag, err)
+ break out
+ }
+ fmt.Printf("%3d: t=%3d fix32 %d\n", index, tag, u)
+
+ case WireFixed64:
+ u, err = p.DecodeFixed64()
+ if err != nil {
+ fmt.Printf("%3d: t=%3d fix64 err %v\n", index, tag, err)
+ break out
+ }
+ fmt.Printf("%3d: t=%3d fix64 %d\n", index, tag, u)
+
+ case WireVarint:
+ u, err = p.DecodeVarint()
+ if err != nil {
+ fmt.Printf("%3d: t=%3d varint err %v\n", index, tag, err)
+ break out
+ }
+ fmt.Printf("%3d: t=%3d varint %d\n", index, tag, u)
+
+ case WireStartGroup:
+ fmt.Printf("%3d: t=%3d start\n", index, tag)
+ depth++
+
+ case WireEndGroup:
+ depth--
+ fmt.Printf("%3d: t=%3d end\n", index, tag)
+ }
+ }
+
+ if depth != 0 {
+ fmt.Printf("%3d: start-end not balanced %d\n", p.index, depth)
+ }
+ fmt.Printf("\n")
+
+ p.buf = obuf
+ p.index = index
+}
+
+// SetDefaults sets unset protocol buffer fields to their default values.
+// It only modifies fields that are both unset and have defined defaults.
+// It recursively sets default values in any non-nil sub-messages.
+func SetDefaults(pb Message) {
+ setDefaults(reflect.ValueOf(pb), true, false)
+}
+
+// v is a pointer to a struct.
+func setDefaults(v reflect.Value, recur, zeros bool) {
+ v = v.Elem()
+
+ defaultMu.RLock()
+ dm, ok := defaults[v.Type()]
+ defaultMu.RUnlock()
+ if !ok {
+ dm = buildDefaultMessage(v.Type())
+ defaultMu.Lock()
+ defaults[v.Type()] = dm
+ defaultMu.Unlock()
+ }
+
+ for _, sf := range dm.scalars {
+ f := v.Field(sf.index)
+ if !f.IsNil() {
+ // field already set
+ continue
+ }
+ dv := sf.value
+ if dv == nil && !zeros {
+ // no explicit default, and don't want to set zeros
+ continue
+ }
+ fptr := f.Addr().Interface() // **T
+ // TODO: Consider batching the allocations we do here.
+ switch sf.kind {
+ case reflect.Bool:
+ b := new(bool)
+ if dv != nil {
+ *b = dv.(bool)
+ }
+ *(fptr.(**bool)) = b
+ case reflect.Float32:
+ f := new(float32)
+ if dv != nil {
+ *f = dv.(float32)
+ }
+ *(fptr.(**float32)) = f
+ case reflect.Float64:
+ f := new(float64)
+ if dv != nil {
+ *f = dv.(float64)
+ }
+ *(fptr.(**float64)) = f
+ case reflect.Int32:
+ // might be an enum
+ if ft := f.Type(); ft != int32PtrType {
+ // enum
+ f.Set(reflect.New(ft.Elem()))
+ if dv != nil {
+ f.Elem().SetInt(int64(dv.(int32)))
+ }
+ } else {
+ // int32 field
+ i := new(int32)
+ if dv != nil {
+ *i = dv.(int32)
+ }
+ *(fptr.(**int32)) = i
+ }
+ case reflect.Int64:
+ i := new(int64)
+ if dv != nil {
+ *i = dv.(int64)
+ }
+ *(fptr.(**int64)) = i
+ case reflect.String:
+ s := new(string)
+ if dv != nil {
+ *s = dv.(string)
+ }
+ *(fptr.(**string)) = s
+ case reflect.Uint8:
+ // exceptional case: []byte
+ var b []byte
+ if dv != nil {
+ db := dv.([]byte)
+ b = make([]byte, len(db))
+ copy(b, db)
+ } else {
+ b = []byte{}
+ }
+ *(fptr.(*[]byte)) = b
+ case reflect.Uint32:
+ u := new(uint32)
+ if dv != nil {
+ *u = dv.(uint32)
+ }
+ *(fptr.(**uint32)) = u
+ case reflect.Uint64:
+ u := new(uint64)
+ if dv != nil {
+ *u = dv.(uint64)
+ }
+ *(fptr.(**uint64)) = u
+ default:
+ log.Printf("proto: can't set default for field %v (sf.kind=%v)", f, sf.kind)
+ }
+ }
+
+ for _, ni := range dm.nested {
+ f := v.Field(ni)
+ // f is *T or []*T or map[T]*T
+ switch f.Kind() {
+ case reflect.Ptr:
+ if f.IsNil() {
+ continue
+ }
+ setDefaults(f, recur, zeros)
+
+ case reflect.Slice:
+ for i := 0; i < f.Len(); i++ {
+ e := f.Index(i)
+ if e.IsNil() {
+ continue
+ }
+ setDefaults(e, recur, zeros)
+ }
+
+ case reflect.Map:
+ for _, k := range f.MapKeys() {
+ e := f.MapIndex(k)
+ if e.IsNil() {
+ continue
+ }
+ setDefaults(e, recur, zeros)
+ }
+ }
+ }
+}
+
+var (
+ // defaults maps a protocol buffer struct type to a slice of the fields,
+ // with its scalar fields set to their proto-declared non-zero default values.
+ defaultMu sync.RWMutex
+ defaults = make(map[reflect.Type]defaultMessage)
+
+ int32PtrType = reflect.TypeOf((*int32)(nil))
+)
+
+// defaultMessage represents information about the default values of a message.
+type defaultMessage struct {
+ scalars []scalarField
+ nested []int // struct field index of nested messages
+}
+
+type scalarField struct {
+ index int // struct field index
+ kind reflect.Kind // element type (the T in *T or []T)
+ value interface{} // the proto-declared default value, or nil
+}
+
+// t is a struct type.
+func buildDefaultMessage(t reflect.Type) (dm defaultMessage) {
+ sprop := GetProperties(t)
+ for _, prop := range sprop.Prop {
+ fi, ok := sprop.decoderTags.get(prop.Tag)
+ if !ok {
+ // XXX_unrecognized
+ continue
+ }
+ ft := t.Field(fi).Type
+
+ sf, nested, err := fieldDefault(ft, prop)
+ switch {
+ case err != nil:
+ log.Print(err)
+ case nested:
+ dm.nested = append(dm.nested, fi)
+ case sf != nil:
+ sf.index = fi
+ dm.scalars = append(dm.scalars, *sf)
+ }
+ }
+
+ return dm
+}
+
+// fieldDefault returns the scalarField for field type ft.
+// sf will be nil if the field can not have a default.
+// nestedMessage will be true if this is a nested message.
+// Note that sf.index is not set on return.
+func fieldDefault(ft reflect.Type, prop *Properties) (sf *scalarField, nestedMessage bool, err error) {
+ var canHaveDefault bool
+ switch ft.Kind() {
+ case reflect.Ptr:
+ if ft.Elem().Kind() == reflect.Struct {
+ nestedMessage = true
+ } else {
+ canHaveDefault = true // proto2 scalar field
+ }
+
+ case reflect.Slice:
+ switch ft.Elem().Kind() {
+ case reflect.Ptr:
+ nestedMessage = true // repeated message
+ case reflect.Uint8:
+ canHaveDefault = true // bytes field
+ }
+
+ case reflect.Map:
+ if ft.Elem().Kind() == reflect.Ptr {
+ nestedMessage = true // map with message values
+ }
+ }
+
+ if !canHaveDefault {
+ if nestedMessage {
+ return nil, true, nil
+ }
+ return nil, false, nil
+ }
+
+ // We now know that ft is a pointer or slice.
+ sf = &scalarField{kind: ft.Elem().Kind()}
+
+ // scalar fields without defaults
+ if !prop.HasDefault {
+ return sf, false, nil
+ }
+
+ // a scalar field: either *T or []byte
+ switch ft.Elem().Kind() {
+ case reflect.Bool:
+ x, err := strconv.ParseBool(prop.Default)
+ if err != nil {
+ return nil, false, fmt.Errorf("proto: bad default bool %q: %v", prop.Default, err)
+ }
+ sf.value = x
+ case reflect.Float32:
+ x, err := strconv.ParseFloat(prop.Default, 32)
+ if err != nil {
+ return nil, false, fmt.Errorf("proto: bad default float32 %q: %v", prop.Default, err)
+ }
+ sf.value = float32(x)
+ case reflect.Float64:
+ x, err := strconv.ParseFloat(prop.Default, 64)
+ if err != nil {
+ return nil, false, fmt.Errorf("proto: bad default float64 %q: %v", prop.Default, err)
+ }
+ sf.value = x
+ case reflect.Int32:
+ x, err := strconv.ParseInt(prop.Default, 10, 32)
+ if err != nil {
+ return nil, false, fmt.Errorf("proto: bad default int32 %q: %v", prop.Default, err)
+ }
+ sf.value = int32(x)
+ case reflect.Int64:
+ x, err := strconv.ParseInt(prop.Default, 10, 64)
+ if err != nil {
+ return nil, false, fmt.Errorf("proto: bad default int64 %q: %v", prop.Default, err)
+ }
+ sf.value = x
+ case reflect.String:
+ sf.value = prop.Default
+ case reflect.Uint8:
+ // []byte (not *uint8)
+ sf.value = []byte(prop.Default)
+ case reflect.Uint32:
+ x, err := strconv.ParseUint(prop.Default, 10, 32)
+ if err != nil {
+ return nil, false, fmt.Errorf("proto: bad default uint32 %q: %v", prop.Default, err)
+ }
+ sf.value = uint32(x)
+ case reflect.Uint64:
+ x, err := strconv.ParseUint(prop.Default, 10, 64)
+ if err != nil {
+ return nil, false, fmt.Errorf("proto: bad default uint64 %q: %v", prop.Default, err)
+ }
+ sf.value = x
+ default:
+ return nil, false, fmt.Errorf("proto: unhandled def kind %v", ft.Elem().Kind())
+ }
+
+ return sf, false, nil
+}
+
+// mapKeys returns a sort.Interface to be used for sorting the map keys.
+// Map fields may have key types of non-float scalars, strings and enums.
+func mapKeys(vs []reflect.Value) sort.Interface {
+ s := mapKeySorter{vs: vs}
+
+ // Type specialization per https://developers.google.com/protocol-buffers/docs/proto#maps.
+ if len(vs) == 0 {
+ return s
+ }
+ switch vs[0].Kind() {
+ case reflect.Int32, reflect.Int64:
+ s.less = func(a, b reflect.Value) bool { return a.Int() < b.Int() }
+ case reflect.Uint32, reflect.Uint64:
+ s.less = func(a, b reflect.Value) bool { return a.Uint() < b.Uint() }
+ case reflect.Bool:
+ s.less = func(a, b reflect.Value) bool { return !a.Bool() && b.Bool() } // false < true
+ case reflect.String:
+ s.less = func(a, b reflect.Value) bool { return a.String() < b.String() }
+ default:
+ panic(fmt.Sprintf("unsupported map key type: %v", vs[0].Kind()))
+ }
+
+ return s
+}
+
+type mapKeySorter struct {
+ vs []reflect.Value
+ less func(a, b reflect.Value) bool
+}
+
+func (s mapKeySorter) Len() int { return len(s.vs) }
+func (s mapKeySorter) Swap(i, j int) { s.vs[i], s.vs[j] = s.vs[j], s.vs[i] }
+func (s mapKeySorter) Less(i, j int) bool {
+ return s.less(s.vs[i], s.vs[j])
+}
+
+// isProto3Zero reports whether v is a zero proto3 value.
+func isProto3Zero(v reflect.Value) bool {
+ switch v.Kind() {
+ case reflect.Bool:
+ return !v.Bool()
+ case reflect.Int32, reflect.Int64:
+ return v.Int() == 0
+ case reflect.Uint32, reflect.Uint64:
+ return v.Uint() == 0
+ case reflect.Float32, reflect.Float64:
+ return v.Float() == 0
+ case reflect.String:
+ return v.String() == ""
+ }
+ return false
+}
+
+const (
+ // ProtoPackageIsVersion3 is referenced from generated protocol buffer files
+ // to assert that that code is compatible with this version of the proto package.
+ ProtoPackageIsVersion3 = true
+
+ // ProtoPackageIsVersion2 is referenced from generated protocol buffer files
+ // to assert that that code is compatible with this version of the proto package.
+ ProtoPackageIsVersion2 = true
+
+ // ProtoPackageIsVersion1 is referenced from generated protocol buffer files
+ // to assert that that code is compatible with this version of the proto package.
+ ProtoPackageIsVersion1 = true
+)
+
+// InternalMessageInfo is a type used internally by generated .pb.go files.
+// This type is not intended to be used by non-generated code.
+// This type is not subject to any compatibility guarantee.
+type InternalMessageInfo struct {
+ marshal *marshalInfo
+ unmarshal *unmarshalInfo
+ merge *mergeInfo
+ discard *discardInfo
+}
diff --git a/vendor/github.com/golang/protobuf/proto/message_set.go b/vendor/github.com/golang/protobuf/proto/message_set.go
new file mode 100644
index 0000000000000000000000000000000000000000..f48a756761eade8ded2dd3f747602d20fa3b2a60
--- /dev/null
+++ b/vendor/github.com/golang/protobuf/proto/message_set.go
@@ -0,0 +1,181 @@
+// Go support for Protocol Buffers - Google's data interchange format
+//
+// Copyright 2010 The Go Authors. All rights reserved.
+// https://github.com/golang/protobuf
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package proto
+
+/*
+ * Support for message sets.
+ */
+
+import (
+ "errors"
+)
+
+// errNoMessageTypeID occurs when a protocol buffer does not have a message type ID.
+// A message type ID is required for storing a protocol buffer in a message set.
+var errNoMessageTypeID = errors.New("proto does not have a message type ID")
+
+// The first two types (_MessageSet_Item and messageSet)
+// model what the protocol compiler produces for the following protocol message:
+// message MessageSet {
+// repeated group Item = 1 {
+// required int32 type_id = 2;
+// required string message = 3;
+// };
+// }
+// That is the MessageSet wire format. We can't use a proto to generate these
+// because that would introduce a circular dependency between it and this package.
+
+type _MessageSet_Item struct {
+ TypeId *int32 `protobuf:"varint,2,req,name=type_id"`
+ Message []byte `protobuf:"bytes,3,req,name=message"`
+}
+
+type messageSet struct {
+ Item []*_MessageSet_Item `protobuf:"group,1,rep"`
+ XXX_unrecognized []byte
+ // TODO: caching?
+}
+
+// Make sure messageSet is a Message.
+var _ Message = (*messageSet)(nil)
+
+// messageTypeIder is an interface satisfied by a protocol buffer type
+// that may be stored in a MessageSet.
+type messageTypeIder interface {
+ MessageTypeId() int32
+}
+
+func (ms *messageSet) find(pb Message) *_MessageSet_Item {
+ mti, ok := pb.(messageTypeIder)
+ if !ok {
+ return nil
+ }
+ id := mti.MessageTypeId()
+ for _, item := range ms.Item {
+ if *item.TypeId == id {
+ return item
+ }
+ }
+ return nil
+}
+
+func (ms *messageSet) Has(pb Message) bool {
+ return ms.find(pb) != nil
+}
+
+func (ms *messageSet) Unmarshal(pb Message) error {
+ if item := ms.find(pb); item != nil {
+ return Unmarshal(item.Message, pb)
+ }
+ if _, ok := pb.(messageTypeIder); !ok {
+ return errNoMessageTypeID
+ }
+ return nil // TODO: return error instead?
+}
+
+func (ms *messageSet) Marshal(pb Message) error {
+ msg, err := Marshal(pb)
+ if err != nil {
+ return err
+ }
+ if item := ms.find(pb); item != nil {
+ // reuse existing item
+ item.Message = msg
+ return nil
+ }
+
+ mti, ok := pb.(messageTypeIder)
+ if !ok {
+ return errNoMessageTypeID
+ }
+
+ mtid := mti.MessageTypeId()
+ ms.Item = append(ms.Item, &_MessageSet_Item{
+ TypeId: &mtid,
+ Message: msg,
+ })
+ return nil
+}
+
+func (ms *messageSet) Reset() { *ms = messageSet{} }
+func (ms *messageSet) String() string { return CompactTextString(ms) }
+func (*messageSet) ProtoMessage() {}
+
+// Support for the message_set_wire_format message option.
+
+func skipVarint(buf []byte) []byte {
+ i := 0
+ for ; buf[i]&0x80 != 0; i++ {
+ }
+ return buf[i+1:]
+}
+
+// unmarshalMessageSet decodes the extension map encoded in buf in the message set wire format.
+// It is called by Unmarshal methods on protocol buffer messages with the message_set_wire_format option.
+func unmarshalMessageSet(buf []byte, exts interface{}) error {
+ var m map[int32]Extension
+ switch exts := exts.(type) {
+ case *XXX_InternalExtensions:
+ m = exts.extensionsWrite()
+ case map[int32]Extension:
+ m = exts
+ default:
+ return errors.New("proto: not an extension map")
+ }
+
+ ms := new(messageSet)
+ if err := Unmarshal(buf, ms); err != nil {
+ return err
+ }
+ for _, item := range ms.Item {
+ id := *item.TypeId
+ msg := item.Message
+
+ // Restore wire type and field number varint, plus length varint.
+ // Be careful to preserve duplicate items.
+ b := EncodeVarint(uint64(id)<<3 | WireBytes)
+ if ext, ok := m[id]; ok {
+ // Existing data; rip off the tag and length varint
+ // so we join the new data correctly.
+ // We can assume that ext.enc is set because we are unmarshaling.
+ o := ext.enc[len(b):] // skip wire type and field number
+ _, n := DecodeVarint(o) // calculate length of length varint
+ o = o[n:] // skip length varint
+ msg = append(o, msg...) // join old data and new data
+ }
+ b = append(b, EncodeVarint(uint64(len(msg)))...)
+ b = append(b, msg...)
+
+ m[id] = Extension{enc: b}
+ }
+ return nil
+}
diff --git a/vendor/github.com/golang/protobuf/proto/pointer_reflect.go b/vendor/github.com/golang/protobuf/proto/pointer_reflect.go
new file mode 100644
index 0000000000000000000000000000000000000000..94fa9194a88231988051f270dfdffe0c7a29572c
--- /dev/null
+++ b/vendor/github.com/golang/protobuf/proto/pointer_reflect.go
@@ -0,0 +1,360 @@
+// Go support for Protocol Buffers - Google's data interchange format
+//
+// Copyright 2012 The Go Authors. All rights reserved.
+// https://github.com/golang/protobuf
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// +build purego appengine js
+
+// This file contains an implementation of proto field accesses using package reflect.
+// It is slower than the code in pointer_unsafe.go but it avoids package unsafe and can
+// be used on App Engine.
+
+package proto
+
+import (
+ "reflect"
+ "sync"
+)
+
+const unsafeAllowed = false
+
+// A field identifies a field in a struct, accessible from a pointer.
+// In this implementation, a field is identified by the sequence of field indices
+// passed to reflect's FieldByIndex.
+type field []int
+
+// toField returns a field equivalent to the given reflect field.
+func toField(f *reflect.StructField) field {
+ return f.Index
+}
+
+// invalidField is an invalid field identifier.
+var invalidField = field(nil)
+
+// zeroField is a noop when calling pointer.offset.
+var zeroField = field([]int{})
+
+// IsValid reports whether the field identifier is valid.
+func (f field) IsValid() bool { return f != nil }
+
+// The pointer type is for the table-driven decoder.
+// The implementation here uses a reflect.Value of pointer type to
+// create a generic pointer. In pointer_unsafe.go we use unsafe
+// instead of reflect to implement the same (but faster) interface.
+type pointer struct {
+ v reflect.Value
+}
+
+// toPointer converts an interface of pointer type to a pointer
+// that points to the same target.
+func toPointer(i *Message) pointer {
+ return pointer{v: reflect.ValueOf(*i)}
+}
+
+// toAddrPointer converts an interface to a pointer that points to
+// the interface data.
+func toAddrPointer(i *interface{}, isptr, deref bool) pointer {
+ v := reflect.ValueOf(*i)
+ u := reflect.New(v.Type())
+ u.Elem().Set(v)
+ if deref {
+ u = u.Elem()
+ }
+ return pointer{v: u}
+}
+
+// valToPointer converts v to a pointer. v must be of pointer type.
+func valToPointer(v reflect.Value) pointer {
+ return pointer{v: v}
+}
+
+// offset converts from a pointer to a structure to a pointer to
+// one of its fields.
+func (p pointer) offset(f field) pointer {
+ return pointer{v: p.v.Elem().FieldByIndex(f).Addr()}
+}
+
+func (p pointer) isNil() bool {
+ return p.v.IsNil()
+}
+
+// grow updates the slice s in place to make it one element longer.
+// s must be addressable.
+// Returns the (addressable) new element.
+func grow(s reflect.Value) reflect.Value {
+ n, m := s.Len(), s.Cap()
+ if n < m {
+ s.SetLen(n + 1)
+ } else {
+ s.Set(reflect.Append(s, reflect.Zero(s.Type().Elem())))
+ }
+ return s.Index(n)
+}
+
+func (p pointer) toInt64() *int64 {
+ return p.v.Interface().(*int64)
+}
+func (p pointer) toInt64Ptr() **int64 {
+ return p.v.Interface().(**int64)
+}
+func (p pointer) toInt64Slice() *[]int64 {
+ return p.v.Interface().(*[]int64)
+}
+
+var int32ptr = reflect.TypeOf((*int32)(nil))
+
+func (p pointer) toInt32() *int32 {
+ return p.v.Convert(int32ptr).Interface().(*int32)
+}
+
+// The toInt32Ptr/Slice methods don't work because of enums.
+// Instead, we must use set/get methods for the int32ptr/slice case.
+/*
+ func (p pointer) toInt32Ptr() **int32 {
+ return p.v.Interface().(**int32)
+}
+ func (p pointer) toInt32Slice() *[]int32 {
+ return p.v.Interface().(*[]int32)
+}
+*/
+func (p pointer) getInt32Ptr() *int32 {
+ if p.v.Type().Elem().Elem() == reflect.TypeOf(int32(0)) {
+ // raw int32 type
+ return p.v.Elem().Interface().(*int32)
+ }
+ // an enum
+ return p.v.Elem().Convert(int32PtrType).Interface().(*int32)
+}
+func (p pointer) setInt32Ptr(v int32) {
+ // Allocate value in a *int32. Possibly convert that to a *enum.
+ // Then assign it to a **int32 or **enum.
+ // Note: we can convert *int32 to *enum, but we can't convert
+ // **int32 to **enum!
+ p.v.Elem().Set(reflect.ValueOf(&v).Convert(p.v.Type().Elem()))
+}
+
+// getInt32Slice copies []int32 from p as a new slice.
+// This behavior differs from the implementation in pointer_unsafe.go.
+func (p pointer) getInt32Slice() []int32 {
+ if p.v.Type().Elem().Elem() == reflect.TypeOf(int32(0)) {
+ // raw int32 type
+ return p.v.Elem().Interface().([]int32)
+ }
+ // an enum
+ // Allocate a []int32, then assign []enum's values into it.
+ // Note: we can't convert []enum to []int32.
+ slice := p.v.Elem()
+ s := make([]int32, slice.Len())
+ for i := 0; i < slice.Len(); i++ {
+ s[i] = int32(slice.Index(i).Int())
+ }
+ return s
+}
+
+// setInt32Slice copies []int32 into p as a new slice.
+// This behavior differs from the implementation in pointer_unsafe.go.
+func (p pointer) setInt32Slice(v []int32) {
+ if p.v.Type().Elem().Elem() == reflect.TypeOf(int32(0)) {
+ // raw int32 type
+ p.v.Elem().Set(reflect.ValueOf(v))
+ return
+ }
+ // an enum
+ // Allocate a []enum, then assign []int32's values into it.
+ // Note: we can't convert []enum to []int32.
+ slice := reflect.MakeSlice(p.v.Type().Elem(), len(v), cap(v))
+ for i, x := range v {
+ slice.Index(i).SetInt(int64(x))
+ }
+ p.v.Elem().Set(slice)
+}
+func (p pointer) appendInt32Slice(v int32) {
+ grow(p.v.Elem()).SetInt(int64(v))
+}
+
+func (p pointer) toUint64() *uint64 {
+ return p.v.Interface().(*uint64)
+}
+func (p pointer) toUint64Ptr() **uint64 {
+ return p.v.Interface().(**uint64)
+}
+func (p pointer) toUint64Slice() *[]uint64 {
+ return p.v.Interface().(*[]uint64)
+}
+func (p pointer) toUint32() *uint32 {
+ return p.v.Interface().(*uint32)
+}
+func (p pointer) toUint32Ptr() **uint32 {
+ return p.v.Interface().(**uint32)
+}
+func (p pointer) toUint32Slice() *[]uint32 {
+ return p.v.Interface().(*[]uint32)
+}
+func (p pointer) toBool() *bool {
+ return p.v.Interface().(*bool)
+}
+func (p pointer) toBoolPtr() **bool {
+ return p.v.Interface().(**bool)
+}
+func (p pointer) toBoolSlice() *[]bool {
+ return p.v.Interface().(*[]bool)
+}
+func (p pointer) toFloat64() *float64 {
+ return p.v.Interface().(*float64)
+}
+func (p pointer) toFloat64Ptr() **float64 {
+ return p.v.Interface().(**float64)
+}
+func (p pointer) toFloat64Slice() *[]float64 {
+ return p.v.Interface().(*[]float64)
+}
+func (p pointer) toFloat32() *float32 {
+ return p.v.Interface().(*float32)
+}
+func (p pointer) toFloat32Ptr() **float32 {
+ return p.v.Interface().(**float32)
+}
+func (p pointer) toFloat32Slice() *[]float32 {
+ return p.v.Interface().(*[]float32)
+}
+func (p pointer) toString() *string {
+ return p.v.Interface().(*string)
+}
+func (p pointer) toStringPtr() **string {
+ return p.v.Interface().(**string)
+}
+func (p pointer) toStringSlice() *[]string {
+ return p.v.Interface().(*[]string)
+}
+func (p pointer) toBytes() *[]byte {
+ return p.v.Interface().(*[]byte)
+}
+func (p pointer) toBytesSlice() *[][]byte {
+ return p.v.Interface().(*[][]byte)
+}
+func (p pointer) toExtensions() *XXX_InternalExtensions {
+ return p.v.Interface().(*XXX_InternalExtensions)
+}
+func (p pointer) toOldExtensions() *map[int32]Extension {
+ return p.v.Interface().(*map[int32]Extension)
+}
+func (p pointer) getPointer() pointer {
+ return pointer{v: p.v.Elem()}
+}
+func (p pointer) setPointer(q pointer) {
+ p.v.Elem().Set(q.v)
+}
+func (p pointer) appendPointer(q pointer) {
+ grow(p.v.Elem()).Set(q.v)
+}
+
+// getPointerSlice copies []*T from p as a new []pointer.
+// This behavior differs from the implementation in pointer_unsafe.go.
+func (p pointer) getPointerSlice() []pointer {
+ if p.v.IsNil() {
+ return nil
+ }
+ n := p.v.Elem().Len()
+ s := make([]pointer, n)
+ for i := 0; i < n; i++ {
+ s[i] = pointer{v: p.v.Elem().Index(i)}
+ }
+ return s
+}
+
+// setPointerSlice copies []pointer into p as a new []*T.
+// This behavior differs from the implementation in pointer_unsafe.go.
+func (p pointer) setPointerSlice(v []pointer) {
+ if v == nil {
+ p.v.Elem().Set(reflect.New(p.v.Elem().Type()).Elem())
+ return
+ }
+ s := reflect.MakeSlice(p.v.Elem().Type(), 0, len(v))
+ for _, p := range v {
+ s = reflect.Append(s, p.v)
+ }
+ p.v.Elem().Set(s)
+}
+
+// getInterfacePointer returns a pointer that points to the
+// interface data of the interface pointed by p.
+func (p pointer) getInterfacePointer() pointer {
+ if p.v.Elem().IsNil() {
+ return pointer{v: p.v.Elem()}
+ }
+ return pointer{v: p.v.Elem().Elem().Elem().Field(0).Addr()} // *interface -> interface -> *struct -> struct
+}
+
+func (p pointer) asPointerTo(t reflect.Type) reflect.Value {
+ // TODO: check that p.v.Type().Elem() == t?
+ return p.v
+}
+
+func atomicLoadUnmarshalInfo(p **unmarshalInfo) *unmarshalInfo {
+ atomicLock.Lock()
+ defer atomicLock.Unlock()
+ return *p
+}
+func atomicStoreUnmarshalInfo(p **unmarshalInfo, v *unmarshalInfo) {
+ atomicLock.Lock()
+ defer atomicLock.Unlock()
+ *p = v
+}
+func atomicLoadMarshalInfo(p **marshalInfo) *marshalInfo {
+ atomicLock.Lock()
+ defer atomicLock.Unlock()
+ return *p
+}
+func atomicStoreMarshalInfo(p **marshalInfo, v *marshalInfo) {
+ atomicLock.Lock()
+ defer atomicLock.Unlock()
+ *p = v
+}
+func atomicLoadMergeInfo(p **mergeInfo) *mergeInfo {
+ atomicLock.Lock()
+ defer atomicLock.Unlock()
+ return *p
+}
+func atomicStoreMergeInfo(p **mergeInfo, v *mergeInfo) {
+ atomicLock.Lock()
+ defer atomicLock.Unlock()
+ *p = v
+}
+func atomicLoadDiscardInfo(p **discardInfo) *discardInfo {
+ atomicLock.Lock()
+ defer atomicLock.Unlock()
+ return *p
+}
+func atomicStoreDiscardInfo(p **discardInfo, v *discardInfo) {
+ atomicLock.Lock()
+ defer atomicLock.Unlock()
+ *p = v
+}
+
+var atomicLock sync.Mutex
diff --git a/vendor/github.com/golang/protobuf/proto/pointer_unsafe.go b/vendor/github.com/golang/protobuf/proto/pointer_unsafe.go
new file mode 100644
index 0000000000000000000000000000000000000000..dbfffe071b82aabab10a91d5b0c084bf7327b89a
--- /dev/null
+++ b/vendor/github.com/golang/protobuf/proto/pointer_unsafe.go
@@ -0,0 +1,313 @@
+// Go support for Protocol Buffers - Google's data interchange format
+//
+// Copyright 2012 The Go Authors. All rights reserved.
+// https://github.com/golang/protobuf
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// +build !purego,!appengine,!js
+
+// This file contains the implementation of the proto field accesses using package unsafe.
+
+package proto
+
+import (
+ "reflect"
+ "sync/atomic"
+ "unsafe"
+)
+
+const unsafeAllowed = true
+
+// A field identifies a field in a struct, accessible from a pointer.
+// In this implementation, a field is identified by its byte offset from the start of the struct.
+type field uintptr
+
+// toField returns a field equivalent to the given reflect field.
+func toField(f *reflect.StructField) field {
+ return field(f.Offset)
+}
+
+// invalidField is an invalid field identifier.
+const invalidField = ^field(0)
+
+// zeroField is a noop when calling pointer.offset.
+const zeroField = field(0)
+
+// IsValid reports whether the field identifier is valid.
+func (f field) IsValid() bool {
+ return f != invalidField
+}
+
+// The pointer type below is for the new table-driven encoder/decoder.
+// The implementation here uses unsafe.Pointer to create a generic pointer.
+// In pointer_reflect.go we use reflect instead of unsafe to implement
+// the same (but slower) interface.
+type pointer struct {
+ p unsafe.Pointer
+}
+
+// size of pointer
+var ptrSize = unsafe.Sizeof(uintptr(0))
+
+// toPointer converts an interface of pointer type to a pointer
+// that points to the same target.
+func toPointer(i *Message) pointer {
+ // Super-tricky - read pointer out of data word of interface value.
+ // Saves ~25ns over the equivalent:
+ // return valToPointer(reflect.ValueOf(*i))
+ return pointer{p: (*[2]unsafe.Pointer)(unsafe.Pointer(i))[1]}
+}
+
+// toAddrPointer converts an interface to a pointer that points to
+// the interface data.
+func toAddrPointer(i *interface{}, isptr, deref bool) (p pointer) {
+ // Super-tricky - read or get the address of data word of interface value.
+ if isptr {
+ // The interface is of pointer type, thus it is a direct interface.
+ // The data word is the pointer data itself. We take its address.
+ p = pointer{p: unsafe.Pointer(uintptr(unsafe.Pointer(i)) + ptrSize)}
+ } else {
+ // The interface is not of pointer type. The data word is the pointer
+ // to the data.
+ p = pointer{p: (*[2]unsafe.Pointer)(unsafe.Pointer(i))[1]}
+ }
+ if deref {
+ p.p = *(*unsafe.Pointer)(p.p)
+ }
+ return p
+}
+
+// valToPointer converts v to a pointer. v must be of pointer type.
+func valToPointer(v reflect.Value) pointer {
+ return pointer{p: unsafe.Pointer(v.Pointer())}
+}
+
+// offset converts from a pointer to a structure to a pointer to
+// one of its fields.
+func (p pointer) offset(f field) pointer {
+ // For safety, we should panic if !f.IsValid, however calling panic causes
+ // this to no longer be inlineable, which is a serious performance cost.
+ /*
+ if !f.IsValid() {
+ panic("invalid field")
+ }
+ */
+ return pointer{p: unsafe.Pointer(uintptr(p.p) + uintptr(f))}
+}
+
+func (p pointer) isNil() bool {
+ return p.p == nil
+}
+
+func (p pointer) toInt64() *int64 {
+ return (*int64)(p.p)
+}
+func (p pointer) toInt64Ptr() **int64 {
+ return (**int64)(p.p)
+}
+func (p pointer) toInt64Slice() *[]int64 {
+ return (*[]int64)(p.p)
+}
+func (p pointer) toInt32() *int32 {
+ return (*int32)(p.p)
+}
+
+// See pointer_reflect.go for why toInt32Ptr/Slice doesn't exist.
+/*
+ func (p pointer) toInt32Ptr() **int32 {
+ return (**int32)(p.p)
+ }
+ func (p pointer) toInt32Slice() *[]int32 {
+ return (*[]int32)(p.p)
+ }
+*/
+func (p pointer) getInt32Ptr() *int32 {
+ return *(**int32)(p.p)
+}
+func (p pointer) setInt32Ptr(v int32) {
+ *(**int32)(p.p) = &v
+}
+
+// getInt32Slice loads a []int32 from p.
+// The value returned is aliased with the original slice.
+// This behavior differs from the implementation in pointer_reflect.go.
+func (p pointer) getInt32Slice() []int32 {
+ return *(*[]int32)(p.p)
+}
+
+// setInt32Slice stores a []int32 to p.
+// The value set is aliased with the input slice.
+// This behavior differs from the implementation in pointer_reflect.go.
+func (p pointer) setInt32Slice(v []int32) {
+ *(*[]int32)(p.p) = v
+}
+
+// TODO: Can we get rid of appendInt32Slice and use setInt32Slice instead?
+func (p pointer) appendInt32Slice(v int32) {
+ s := (*[]int32)(p.p)
+ *s = append(*s, v)
+}
+
+func (p pointer) toUint64() *uint64 {
+ return (*uint64)(p.p)
+}
+func (p pointer) toUint64Ptr() **uint64 {
+ return (**uint64)(p.p)
+}
+func (p pointer) toUint64Slice() *[]uint64 {
+ return (*[]uint64)(p.p)
+}
+func (p pointer) toUint32() *uint32 {
+ return (*uint32)(p.p)
+}
+func (p pointer) toUint32Ptr() **uint32 {
+ return (**uint32)(p.p)
+}
+func (p pointer) toUint32Slice() *[]uint32 {
+ return (*[]uint32)(p.p)
+}
+func (p pointer) toBool() *bool {
+ return (*bool)(p.p)
+}
+func (p pointer) toBoolPtr() **bool {
+ return (**bool)(p.p)
+}
+func (p pointer) toBoolSlice() *[]bool {
+ return (*[]bool)(p.p)
+}
+func (p pointer) toFloat64() *float64 {
+ return (*float64)(p.p)
+}
+func (p pointer) toFloat64Ptr() **float64 {
+ return (**float64)(p.p)
+}
+func (p pointer) toFloat64Slice() *[]float64 {
+ return (*[]float64)(p.p)
+}
+func (p pointer) toFloat32() *float32 {
+ return (*float32)(p.p)
+}
+func (p pointer) toFloat32Ptr() **float32 {
+ return (**float32)(p.p)
+}
+func (p pointer) toFloat32Slice() *[]float32 {
+ return (*[]float32)(p.p)
+}
+func (p pointer) toString() *string {
+ return (*string)(p.p)
+}
+func (p pointer) toStringPtr() **string {
+ return (**string)(p.p)
+}
+func (p pointer) toStringSlice() *[]string {
+ return (*[]string)(p.p)
+}
+func (p pointer) toBytes() *[]byte {
+ return (*[]byte)(p.p)
+}
+func (p pointer) toBytesSlice() *[][]byte {
+ return (*[][]byte)(p.p)
+}
+func (p pointer) toExtensions() *XXX_InternalExtensions {
+ return (*XXX_InternalExtensions)(p.p)
+}
+func (p pointer) toOldExtensions() *map[int32]Extension {
+ return (*map[int32]Extension)(p.p)
+}
+
+// getPointerSlice loads []*T from p as a []pointer.
+// The value returned is aliased with the original slice.
+// This behavior differs from the implementation in pointer_reflect.go.
+func (p pointer) getPointerSlice() []pointer {
+ // Super-tricky - p should point to a []*T where T is a
+ // message type. We load it as []pointer.
+ return *(*[]pointer)(p.p)
+}
+
+// setPointerSlice stores []pointer into p as a []*T.
+// The value set is aliased with the input slice.
+// This behavior differs from the implementation in pointer_reflect.go.
+func (p pointer) setPointerSlice(v []pointer) {
+ // Super-tricky - p should point to a []*T where T is a
+ // message type. We store it as []pointer.
+ *(*[]pointer)(p.p) = v
+}
+
+// getPointer loads the pointer at p and returns it.
+func (p pointer) getPointer() pointer {
+ return pointer{p: *(*unsafe.Pointer)(p.p)}
+}
+
+// setPointer stores the pointer q at p.
+func (p pointer) setPointer(q pointer) {
+ *(*unsafe.Pointer)(p.p) = q.p
+}
+
+// append q to the slice pointed to by p.
+func (p pointer) appendPointer(q pointer) {
+ s := (*[]unsafe.Pointer)(p.p)
+ *s = append(*s, q.p)
+}
+
+// getInterfacePointer returns a pointer that points to the
+// interface data of the interface pointed by p.
+func (p pointer) getInterfacePointer() pointer {
+ // Super-tricky - read pointer out of data word of interface value.
+ return pointer{p: (*(*[2]unsafe.Pointer)(p.p))[1]}
+}
+
+// asPointerTo returns a reflect.Value that is a pointer to an
+// object of type t stored at p.
+func (p pointer) asPointerTo(t reflect.Type) reflect.Value {
+ return reflect.NewAt(t, p.p)
+}
+
+func atomicLoadUnmarshalInfo(p **unmarshalInfo) *unmarshalInfo {
+ return (*unmarshalInfo)(atomic.LoadPointer((*unsafe.Pointer)(unsafe.Pointer(p))))
+}
+func atomicStoreUnmarshalInfo(p **unmarshalInfo, v *unmarshalInfo) {
+ atomic.StorePointer((*unsafe.Pointer)(unsafe.Pointer(p)), unsafe.Pointer(v))
+}
+func atomicLoadMarshalInfo(p **marshalInfo) *marshalInfo {
+ return (*marshalInfo)(atomic.LoadPointer((*unsafe.Pointer)(unsafe.Pointer(p))))
+}
+func atomicStoreMarshalInfo(p **marshalInfo, v *marshalInfo) {
+ atomic.StorePointer((*unsafe.Pointer)(unsafe.Pointer(p)), unsafe.Pointer(v))
+}
+func atomicLoadMergeInfo(p **mergeInfo) *mergeInfo {
+ return (*mergeInfo)(atomic.LoadPointer((*unsafe.Pointer)(unsafe.Pointer(p))))
+}
+func atomicStoreMergeInfo(p **mergeInfo, v *mergeInfo) {
+ atomic.StorePointer((*unsafe.Pointer)(unsafe.Pointer(p)), unsafe.Pointer(v))
+}
+func atomicLoadDiscardInfo(p **discardInfo) *discardInfo {
+ return (*discardInfo)(atomic.LoadPointer((*unsafe.Pointer)(unsafe.Pointer(p))))
+}
+func atomicStoreDiscardInfo(p **discardInfo, v *discardInfo) {
+ atomic.StorePointer((*unsafe.Pointer)(unsafe.Pointer(p)), unsafe.Pointer(v))
+}
diff --git a/vendor/github.com/golang/protobuf/proto/properties.go b/vendor/github.com/golang/protobuf/proto/properties.go
new file mode 100644
index 0000000000000000000000000000000000000000..a4b8c0cd3a86127e43f249771bc85e381fa711d3
--- /dev/null
+++ b/vendor/github.com/golang/protobuf/proto/properties.go
@@ -0,0 +1,544 @@
+// Go support for Protocol Buffers - Google's data interchange format
+//
+// Copyright 2010 The Go Authors. All rights reserved.
+// https://github.com/golang/protobuf
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package proto
+
+/*
+ * Routines for encoding data into the wire format for protocol buffers.
+ */
+
+import (
+ "fmt"
+ "log"
+ "reflect"
+ "sort"
+ "strconv"
+ "strings"
+ "sync"
+)
+
+const debug bool = false
+
+// Constants that identify the encoding of a value on the wire.
+const (
+ WireVarint = 0
+ WireFixed64 = 1
+ WireBytes = 2
+ WireStartGroup = 3
+ WireEndGroup = 4
+ WireFixed32 = 5
+)
+
+// tagMap is an optimization over map[int]int for typical protocol buffer
+// use-cases. Encoded protocol buffers are often in tag order with small tag
+// numbers.
+type tagMap struct {
+ fastTags []int
+ slowTags map[int]int
+}
+
+// tagMapFastLimit is the upper bound on the tag number that will be stored in
+// the tagMap slice rather than its map.
+const tagMapFastLimit = 1024
+
+func (p *tagMap) get(t int) (int, bool) {
+ if t > 0 && t < tagMapFastLimit {
+ if t >= len(p.fastTags) {
+ return 0, false
+ }
+ fi := p.fastTags[t]
+ return fi, fi >= 0
+ }
+ fi, ok := p.slowTags[t]
+ return fi, ok
+}
+
+func (p *tagMap) put(t int, fi int) {
+ if t > 0 && t < tagMapFastLimit {
+ for len(p.fastTags) < t+1 {
+ p.fastTags = append(p.fastTags, -1)
+ }
+ p.fastTags[t] = fi
+ return
+ }
+ if p.slowTags == nil {
+ p.slowTags = make(map[int]int)
+ }
+ p.slowTags[t] = fi
+}
+
+// StructProperties represents properties for all the fields of a struct.
+// decoderTags and decoderOrigNames should only be used by the decoder.
+type StructProperties struct {
+ Prop []*Properties // properties for each field
+ reqCount int // required count
+ decoderTags tagMap // map from proto tag to struct field number
+ decoderOrigNames map[string]int // map from original name to struct field number
+ order []int // list of struct field numbers in tag order
+
+ // OneofTypes contains information about the oneof fields in this message.
+ // It is keyed by the original name of a field.
+ OneofTypes map[string]*OneofProperties
+}
+
+// OneofProperties represents information about a specific field in a oneof.
+type OneofProperties struct {
+ Type reflect.Type // pointer to generated struct type for this oneof field
+ Field int // struct field number of the containing oneof in the message
+ Prop *Properties
+}
+
+// Implement the sorting interface so we can sort the fields in tag order, as recommended by the spec.
+// See encode.go, (*Buffer).enc_struct.
+
+func (sp *StructProperties) Len() int { return len(sp.order) }
+func (sp *StructProperties) Less(i, j int) bool {
+ return sp.Prop[sp.order[i]].Tag < sp.Prop[sp.order[j]].Tag
+}
+func (sp *StructProperties) Swap(i, j int) { sp.order[i], sp.order[j] = sp.order[j], sp.order[i] }
+
+// Properties represents the protocol-specific behavior of a single struct field.
+type Properties struct {
+ Name string // name of the field, for error messages
+ OrigName string // original name before protocol compiler (always set)
+ JSONName string // name to use for JSON; determined by protoc
+ Wire string
+ WireType int
+ Tag int
+ Required bool
+ Optional bool
+ Repeated bool
+ Packed bool // relevant for repeated primitives only
+ Enum string // set for enum types only
+ proto3 bool // whether this is known to be a proto3 field
+ oneof bool // whether this is a oneof field
+
+ Default string // default value
+ HasDefault bool // whether an explicit default was provided
+
+ stype reflect.Type // set for struct types only
+ sprop *StructProperties // set for struct types only
+
+ mtype reflect.Type // set for map types only
+ MapKeyProp *Properties // set for map types only
+ MapValProp *Properties // set for map types only
+}
+
+// String formats the properties in the protobuf struct field tag style.
+func (p *Properties) String() string {
+ s := p.Wire
+ s += ","
+ s += strconv.Itoa(p.Tag)
+ if p.Required {
+ s += ",req"
+ }
+ if p.Optional {
+ s += ",opt"
+ }
+ if p.Repeated {
+ s += ",rep"
+ }
+ if p.Packed {
+ s += ",packed"
+ }
+ s += ",name=" + p.OrigName
+ if p.JSONName != p.OrigName {
+ s += ",json=" + p.JSONName
+ }
+ if p.proto3 {
+ s += ",proto3"
+ }
+ if p.oneof {
+ s += ",oneof"
+ }
+ if len(p.Enum) > 0 {
+ s += ",enum=" + p.Enum
+ }
+ if p.HasDefault {
+ s += ",def=" + p.Default
+ }
+ return s
+}
+
+// Parse populates p by parsing a string in the protobuf struct field tag style.
+func (p *Properties) Parse(s string) {
+ // "bytes,49,opt,name=foo,def=hello!"
+ fields := strings.Split(s, ",") // breaks def=, but handled below.
+ if len(fields) < 2 {
+ log.Printf("proto: tag has too few fields: %q", s)
+ return
+ }
+
+ p.Wire = fields[0]
+ switch p.Wire {
+ case "varint":
+ p.WireType = WireVarint
+ case "fixed32":
+ p.WireType = WireFixed32
+ case "fixed64":
+ p.WireType = WireFixed64
+ case "zigzag32":
+ p.WireType = WireVarint
+ case "zigzag64":
+ p.WireType = WireVarint
+ case "bytes", "group":
+ p.WireType = WireBytes
+ // no numeric converter for non-numeric types
+ default:
+ log.Printf("proto: tag has unknown wire type: %q", s)
+ return
+ }
+
+ var err error
+ p.Tag, err = strconv.Atoi(fields[1])
+ if err != nil {
+ return
+ }
+
+outer:
+ for i := 2; i < len(fields); i++ {
+ f := fields[i]
+ switch {
+ case f == "req":
+ p.Required = true
+ case f == "opt":
+ p.Optional = true
+ case f == "rep":
+ p.Repeated = true
+ case f == "packed":
+ p.Packed = true
+ case strings.HasPrefix(f, "name="):
+ p.OrigName = f[5:]
+ case strings.HasPrefix(f, "json="):
+ p.JSONName = f[5:]
+ case strings.HasPrefix(f, "enum="):
+ p.Enum = f[5:]
+ case f == "proto3":
+ p.proto3 = true
+ case f == "oneof":
+ p.oneof = true
+ case strings.HasPrefix(f, "def="):
+ p.HasDefault = true
+ p.Default = f[4:] // rest of string
+ if i+1 < len(fields) {
+ // Commas aren't escaped, and def is always last.
+ p.Default += "," + strings.Join(fields[i+1:], ",")
+ break outer
+ }
+ }
+ }
+}
+
+var protoMessageType = reflect.TypeOf((*Message)(nil)).Elem()
+
+// setFieldProps initializes the field properties for submessages and maps.
+func (p *Properties) setFieldProps(typ reflect.Type, f *reflect.StructField, lockGetProp bool) {
+ switch t1 := typ; t1.Kind() {
+ case reflect.Ptr:
+ if t1.Elem().Kind() == reflect.Struct {
+ p.stype = t1.Elem()
+ }
+
+ case reflect.Slice:
+ if t2 := t1.Elem(); t2.Kind() == reflect.Ptr && t2.Elem().Kind() == reflect.Struct {
+ p.stype = t2.Elem()
+ }
+
+ case reflect.Map:
+ p.mtype = t1
+ p.MapKeyProp = &Properties{}
+ p.MapKeyProp.init(reflect.PtrTo(p.mtype.Key()), "Key", f.Tag.Get("protobuf_key"), nil, lockGetProp)
+ p.MapValProp = &Properties{}
+ vtype := p.mtype.Elem()
+ if vtype.Kind() != reflect.Ptr && vtype.Kind() != reflect.Slice {
+ // The value type is not a message (*T) or bytes ([]byte),
+ // so we need encoders for the pointer to this type.
+ vtype = reflect.PtrTo(vtype)
+ }
+ p.MapValProp.init(vtype, "Value", f.Tag.Get("protobuf_val"), nil, lockGetProp)
+ }
+
+ if p.stype != nil {
+ if lockGetProp {
+ p.sprop = GetProperties(p.stype)
+ } else {
+ p.sprop = getPropertiesLocked(p.stype)
+ }
+ }
+}
+
+var (
+ marshalerType = reflect.TypeOf((*Marshaler)(nil)).Elem()
+)
+
+// Init populates the properties from a protocol buffer struct tag.
+func (p *Properties) Init(typ reflect.Type, name, tag string, f *reflect.StructField) {
+ p.init(typ, name, tag, f, true)
+}
+
+func (p *Properties) init(typ reflect.Type, name, tag string, f *reflect.StructField, lockGetProp bool) {
+ // "bytes,49,opt,def=hello!"
+ p.Name = name
+ p.OrigName = name
+ if tag == "" {
+ return
+ }
+ p.Parse(tag)
+ p.setFieldProps(typ, f, lockGetProp)
+}
+
+var (
+ propertiesMu sync.RWMutex
+ propertiesMap = make(map[reflect.Type]*StructProperties)
+)
+
+// GetProperties returns the list of properties for the type represented by t.
+// t must represent a generated struct type of a protocol message.
+func GetProperties(t reflect.Type) *StructProperties {
+ if t.Kind() != reflect.Struct {
+ panic("proto: type must have kind struct")
+ }
+
+ // Most calls to GetProperties in a long-running program will be
+ // retrieving details for types we have seen before.
+ propertiesMu.RLock()
+ sprop, ok := propertiesMap[t]
+ propertiesMu.RUnlock()
+ if ok {
+ return sprop
+ }
+
+ propertiesMu.Lock()
+ sprop = getPropertiesLocked(t)
+ propertiesMu.Unlock()
+ return sprop
+}
+
+type (
+ oneofFuncsIface interface {
+ XXX_OneofFuncs() (func(Message, *Buffer) error, func(Message, int, int, *Buffer) (bool, error), func(Message) int, []interface{})
+ }
+ oneofWrappersIface interface {
+ XXX_OneofWrappers() []interface{}
+ }
+)
+
+// getPropertiesLocked requires that propertiesMu is held.
+func getPropertiesLocked(t reflect.Type) *StructProperties {
+ if prop, ok := propertiesMap[t]; ok {
+ return prop
+ }
+
+ prop := new(StructProperties)
+ // in case of recursive protos, fill this in now.
+ propertiesMap[t] = prop
+
+ // build properties
+ prop.Prop = make([]*Properties, t.NumField())
+ prop.order = make([]int, t.NumField())
+
+ for i := 0; i < t.NumField(); i++ {
+ f := t.Field(i)
+ p := new(Properties)
+ name := f.Name
+ p.init(f.Type, name, f.Tag.Get("protobuf"), &f, false)
+
+ oneof := f.Tag.Get("protobuf_oneof") // special case
+ if oneof != "" {
+ // Oneof fields don't use the traditional protobuf tag.
+ p.OrigName = oneof
+ }
+ prop.Prop[i] = p
+ prop.order[i] = i
+ if debug {
+ print(i, " ", f.Name, " ", t.String(), " ")
+ if p.Tag > 0 {
+ print(p.String())
+ }
+ print("\n")
+ }
+ }
+
+ // Re-order prop.order.
+ sort.Sort(prop)
+
+ var oots []interface{}
+ switch m := reflect.Zero(reflect.PtrTo(t)).Interface().(type) {
+ case oneofFuncsIface:
+ _, _, _, oots = m.XXX_OneofFuncs()
+ case oneofWrappersIface:
+ oots = m.XXX_OneofWrappers()
+ }
+ if len(oots) > 0 {
+ // Interpret oneof metadata.
+ prop.OneofTypes = make(map[string]*OneofProperties)
+ for _, oot := range oots {
+ oop := &OneofProperties{
+ Type: reflect.ValueOf(oot).Type(), // *T
+ Prop: new(Properties),
+ }
+ sft := oop.Type.Elem().Field(0)
+ oop.Prop.Name = sft.Name
+ oop.Prop.Parse(sft.Tag.Get("protobuf"))
+ // There will be exactly one interface field that
+ // this new value is assignable to.
+ for i := 0; i < t.NumField(); i++ {
+ f := t.Field(i)
+ if f.Type.Kind() != reflect.Interface {
+ continue
+ }
+ if !oop.Type.AssignableTo(f.Type) {
+ continue
+ }
+ oop.Field = i
+ break
+ }
+ prop.OneofTypes[oop.Prop.OrigName] = oop
+ }
+ }
+
+ // build required counts
+ // build tags
+ reqCount := 0
+ prop.decoderOrigNames = make(map[string]int)
+ for i, p := range prop.Prop {
+ if strings.HasPrefix(p.Name, "XXX_") {
+ // Internal fields should not appear in tags/origNames maps.
+ // They are handled specially when encoding and decoding.
+ continue
+ }
+ if p.Required {
+ reqCount++
+ }
+ prop.decoderTags.put(p.Tag, i)
+ prop.decoderOrigNames[p.OrigName] = i
+ }
+ prop.reqCount = reqCount
+
+ return prop
+}
+
+// A global registry of enum types.
+// The generated code will register the generated maps by calling RegisterEnum.
+
+var enumValueMaps = make(map[string]map[string]int32)
+
+// RegisterEnum is called from the generated code to install the enum descriptor
+// maps into the global table to aid parsing text format protocol buffers.
+func RegisterEnum(typeName string, unusedNameMap map[int32]string, valueMap map[string]int32) {
+ if _, ok := enumValueMaps[typeName]; ok {
+ panic("proto: duplicate enum registered: " + typeName)
+ }
+ enumValueMaps[typeName] = valueMap
+}
+
+// EnumValueMap returns the mapping from names to integers of the
+// enum type enumType, or a nil if not found.
+func EnumValueMap(enumType string) map[string]int32 {
+ return enumValueMaps[enumType]
+}
+
+// A registry of all linked message types.
+// The string is a fully-qualified proto name ("pkg.Message").
+var (
+ protoTypedNils = make(map[string]Message) // a map from proto names to typed nil pointers
+ protoMapTypes = make(map[string]reflect.Type) // a map from proto names to map types
+ revProtoTypes = make(map[reflect.Type]string)
+)
+
+// RegisterType is called from generated code and maps from the fully qualified
+// proto name to the type (pointer to struct) of the protocol buffer.
+func RegisterType(x Message, name string) {
+ if _, ok := protoTypedNils[name]; ok {
+ // TODO: Some day, make this a panic.
+ log.Printf("proto: duplicate proto type registered: %s", name)
+ return
+ }
+ t := reflect.TypeOf(x)
+ if v := reflect.ValueOf(x); v.Kind() == reflect.Ptr && v.Pointer() == 0 {
+ // Generated code always calls RegisterType with nil x.
+ // This check is just for extra safety.
+ protoTypedNils[name] = x
+ } else {
+ protoTypedNils[name] = reflect.Zero(t).Interface().(Message)
+ }
+ revProtoTypes[t] = name
+}
+
+// RegisterMapType is called from generated code and maps from the fully qualified
+// proto name to the native map type of the proto map definition.
+func RegisterMapType(x interface{}, name string) {
+ if reflect.TypeOf(x).Kind() != reflect.Map {
+ panic(fmt.Sprintf("RegisterMapType(%T, %q); want map", x, name))
+ }
+ if _, ok := protoMapTypes[name]; ok {
+ log.Printf("proto: duplicate proto type registered: %s", name)
+ return
+ }
+ t := reflect.TypeOf(x)
+ protoMapTypes[name] = t
+ revProtoTypes[t] = name
+}
+
+// MessageName returns the fully-qualified proto name for the given message type.
+func MessageName(x Message) string {
+ type xname interface {
+ XXX_MessageName() string
+ }
+ if m, ok := x.(xname); ok {
+ return m.XXX_MessageName()
+ }
+ return revProtoTypes[reflect.TypeOf(x)]
+}
+
+// MessageType returns the message type (pointer to struct) for a named message.
+// The type is not guaranteed to implement proto.Message if the name refers to a
+// map entry.
+func MessageType(name string) reflect.Type {
+ if t, ok := protoTypedNils[name]; ok {
+ return reflect.TypeOf(t)
+ }
+ return protoMapTypes[name]
+}
+
+// A registry of all linked proto files.
+var (
+ protoFiles = make(map[string][]byte) // file name => fileDescriptor
+)
+
+// RegisterFile is called from generated code and maps from the
+// full file name of a .proto file to its compressed FileDescriptorProto.
+func RegisterFile(filename string, fileDescriptor []byte) {
+ protoFiles[filename] = fileDescriptor
+}
+
+// FileDescriptor returns the compressed FileDescriptorProto for a .proto file.
+func FileDescriptor(filename string) []byte { return protoFiles[filename] }
diff --git a/vendor/github.com/golang/protobuf/proto/table_marshal.go b/vendor/github.com/golang/protobuf/proto/table_marshal.go
new file mode 100644
index 0000000000000000000000000000000000000000..5cb11fa955e4d087c7579f4f018b25270a88de47
--- /dev/null
+++ b/vendor/github.com/golang/protobuf/proto/table_marshal.go
@@ -0,0 +1,2776 @@
+// Go support for Protocol Buffers - Google's data interchange format
+//
+// Copyright 2016 The Go Authors. All rights reserved.
+// https://github.com/golang/protobuf
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package proto
+
+import (
+ "errors"
+ "fmt"
+ "math"
+ "reflect"
+ "sort"
+ "strconv"
+ "strings"
+ "sync"
+ "sync/atomic"
+ "unicode/utf8"
+)
+
+// a sizer takes a pointer to a field and the size of its tag, computes the size of
+// the encoded data.
+type sizer func(pointer, int) int
+
+// a marshaler takes a byte slice, a pointer to a field, and its tag (in wire format),
+// marshals the field to the end of the slice, returns the slice and error (if any).
+type marshaler func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error)
+
+// marshalInfo is the information used for marshaling a message.
+type marshalInfo struct {
+ typ reflect.Type
+ fields []*marshalFieldInfo
+ unrecognized field // offset of XXX_unrecognized
+ extensions field // offset of XXX_InternalExtensions
+ v1extensions field // offset of XXX_extensions
+ sizecache field // offset of XXX_sizecache
+ initialized int32 // 0 -- only typ is set, 1 -- fully initialized
+ messageset bool // uses message set wire format
+ hasmarshaler bool // has custom marshaler
+ sync.RWMutex // protect extElems map, also for initialization
+ extElems map[int32]*marshalElemInfo // info of extension elements
+}
+
+// marshalFieldInfo is the information used for marshaling a field of a message.
+type marshalFieldInfo struct {
+ field field
+ wiretag uint64 // tag in wire format
+ tagsize int // size of tag in wire format
+ sizer sizer
+ marshaler marshaler
+ isPointer bool
+ required bool // field is required
+ name string // name of the field, for error reporting
+ oneofElems map[reflect.Type]*marshalElemInfo // info of oneof elements
+}
+
+// marshalElemInfo is the information used for marshaling an extension or oneof element.
+type marshalElemInfo struct {
+ wiretag uint64 // tag in wire format
+ tagsize int // size of tag in wire format
+ sizer sizer
+ marshaler marshaler
+ isptr bool // elem is pointer typed, thus interface of this type is a direct interface (extension only)
+ deref bool // dereference the pointer before operating on it; implies isptr
+}
+
+var (
+ marshalInfoMap = map[reflect.Type]*marshalInfo{}
+ marshalInfoLock sync.Mutex
+)
+
+// getMarshalInfo returns the information to marshal a given type of message.
+// The info it returns may not necessarily initialized.
+// t is the type of the message (NOT the pointer to it).
+func getMarshalInfo(t reflect.Type) *marshalInfo {
+ marshalInfoLock.Lock()
+ u, ok := marshalInfoMap[t]
+ if !ok {
+ u = &marshalInfo{typ: t}
+ marshalInfoMap[t] = u
+ }
+ marshalInfoLock.Unlock()
+ return u
+}
+
+// Size is the entry point from generated code,
+// and should be ONLY called by generated code.
+// It computes the size of encoded data of msg.
+// a is a pointer to a place to store cached marshal info.
+func (a *InternalMessageInfo) Size(msg Message) int {
+ u := getMessageMarshalInfo(msg, a)
+ ptr := toPointer(&msg)
+ if ptr.isNil() {
+ // We get here if msg is a typed nil ((*SomeMessage)(nil)),
+ // so it satisfies the interface, and msg == nil wouldn't
+ // catch it. We don't want crash in this case.
+ return 0
+ }
+ return u.size(ptr)
+}
+
+// Marshal is the entry point from generated code,
+// and should be ONLY called by generated code.
+// It marshals msg to the end of b.
+// a is a pointer to a place to store cached marshal info.
+func (a *InternalMessageInfo) Marshal(b []byte, msg Message, deterministic bool) ([]byte, error) {
+ u := getMessageMarshalInfo(msg, a)
+ ptr := toPointer(&msg)
+ if ptr.isNil() {
+ // We get here if msg is a typed nil ((*SomeMessage)(nil)),
+ // so it satisfies the interface, and msg == nil wouldn't
+ // catch it. We don't want crash in this case.
+ return b, ErrNil
+ }
+ return u.marshal(b, ptr, deterministic)
+}
+
+func getMessageMarshalInfo(msg interface{}, a *InternalMessageInfo) *marshalInfo {
+ // u := a.marshal, but atomically.
+ // We use an atomic here to ensure memory consistency.
+ u := atomicLoadMarshalInfo(&a.marshal)
+ if u == nil {
+ // Get marshal information from type of message.
+ t := reflect.ValueOf(msg).Type()
+ if t.Kind() != reflect.Ptr {
+ panic(fmt.Sprintf("cannot handle non-pointer message type %v", t))
+ }
+ u = getMarshalInfo(t.Elem())
+ // Store it in the cache for later users.
+ // a.marshal = u, but atomically.
+ atomicStoreMarshalInfo(&a.marshal, u)
+ }
+ return u
+}
+
+// size is the main function to compute the size of the encoded data of a message.
+// ptr is the pointer to the message.
+func (u *marshalInfo) size(ptr pointer) int {
+ if atomic.LoadInt32(&u.initialized) == 0 {
+ u.computeMarshalInfo()
+ }
+
+ // If the message can marshal itself, let it do it, for compatibility.
+ // NOTE: This is not efficient.
+ if u.hasmarshaler {
+ m := ptr.asPointerTo(u.typ).Interface().(Marshaler)
+ b, _ := m.Marshal()
+ return len(b)
+ }
+
+ n := 0
+ for _, f := range u.fields {
+ if f.isPointer && ptr.offset(f.field).getPointer().isNil() {
+ // nil pointer always marshals to nothing
+ continue
+ }
+ n += f.sizer(ptr.offset(f.field), f.tagsize)
+ }
+ if u.extensions.IsValid() {
+ e := ptr.offset(u.extensions).toExtensions()
+ if u.messageset {
+ n += u.sizeMessageSet(e)
+ } else {
+ n += u.sizeExtensions(e)
+ }
+ }
+ if u.v1extensions.IsValid() {
+ m := *ptr.offset(u.v1extensions).toOldExtensions()
+ n += u.sizeV1Extensions(m)
+ }
+ if u.unrecognized.IsValid() {
+ s := *ptr.offset(u.unrecognized).toBytes()
+ n += len(s)
+ }
+ // cache the result for use in marshal
+ if u.sizecache.IsValid() {
+ atomic.StoreInt32(ptr.offset(u.sizecache).toInt32(), int32(n))
+ }
+ return n
+}
+
+// cachedsize gets the size from cache. If there is no cache (i.e. message is not generated),
+// fall back to compute the size.
+func (u *marshalInfo) cachedsize(ptr pointer) int {
+ if u.sizecache.IsValid() {
+ return int(atomic.LoadInt32(ptr.offset(u.sizecache).toInt32()))
+ }
+ return u.size(ptr)
+}
+
+// marshal is the main function to marshal a message. It takes a byte slice and appends
+// the encoded data to the end of the slice, returns the slice and error (if any).
+// ptr is the pointer to the message.
+// If deterministic is true, map is marshaled in deterministic order.
+func (u *marshalInfo) marshal(b []byte, ptr pointer, deterministic bool) ([]byte, error) {
+ if atomic.LoadInt32(&u.initialized) == 0 {
+ u.computeMarshalInfo()
+ }
+
+ // If the message can marshal itself, let it do it, for compatibility.
+ // NOTE: This is not efficient.
+ if u.hasmarshaler {
+ m := ptr.asPointerTo(u.typ).Interface().(Marshaler)
+ b1, err := m.Marshal()
+ b = append(b, b1...)
+ return b, err
+ }
+
+ var err, errLater error
+ // The old marshaler encodes extensions at beginning.
+ if u.extensions.IsValid() {
+ e := ptr.offset(u.extensions).toExtensions()
+ if u.messageset {
+ b, err = u.appendMessageSet(b, e, deterministic)
+ } else {
+ b, err = u.appendExtensions(b, e, deterministic)
+ }
+ if err != nil {
+ return b, err
+ }
+ }
+ if u.v1extensions.IsValid() {
+ m := *ptr.offset(u.v1extensions).toOldExtensions()
+ b, err = u.appendV1Extensions(b, m, deterministic)
+ if err != nil {
+ return b, err
+ }
+ }
+ for _, f := range u.fields {
+ if f.required {
+ if ptr.offset(f.field).getPointer().isNil() {
+ // Required field is not set.
+ // We record the error but keep going, to give a complete marshaling.
+ if errLater == nil {
+ errLater = &RequiredNotSetError{f.name}
+ }
+ continue
+ }
+ }
+ if f.isPointer && ptr.offset(f.field).getPointer().isNil() {
+ // nil pointer always marshals to nothing
+ continue
+ }
+ b, err = f.marshaler(b, ptr.offset(f.field), f.wiretag, deterministic)
+ if err != nil {
+ if err1, ok := err.(*RequiredNotSetError); ok {
+ // Required field in submessage is not set.
+ // We record the error but keep going, to give a complete marshaling.
+ if errLater == nil {
+ errLater = &RequiredNotSetError{f.name + "." + err1.field}
+ }
+ continue
+ }
+ if err == errRepeatedHasNil {
+ err = errors.New("proto: repeated field " + f.name + " has nil element")
+ }
+ if err == errInvalidUTF8 {
+ if errLater == nil {
+ fullName := revProtoTypes[reflect.PtrTo(u.typ)] + "." + f.name
+ errLater = &invalidUTF8Error{fullName}
+ }
+ continue
+ }
+ return b, err
+ }
+ }
+ if u.unrecognized.IsValid() {
+ s := *ptr.offset(u.unrecognized).toBytes()
+ b = append(b, s...)
+ }
+ return b, errLater
+}
+
+// computeMarshalInfo initializes the marshal info.
+func (u *marshalInfo) computeMarshalInfo() {
+ u.Lock()
+ defer u.Unlock()
+ if u.initialized != 0 { // non-atomic read is ok as it is protected by the lock
+ return
+ }
+
+ t := u.typ
+ u.unrecognized = invalidField
+ u.extensions = invalidField
+ u.v1extensions = invalidField
+ u.sizecache = invalidField
+
+ // If the message can marshal itself, let it do it, for compatibility.
+ // NOTE: This is not efficient.
+ if reflect.PtrTo(t).Implements(marshalerType) {
+ u.hasmarshaler = true
+ atomic.StoreInt32(&u.initialized, 1)
+ return
+ }
+
+ // get oneof implementers
+ var oneofImplementers []interface{}
+ switch m := reflect.Zero(reflect.PtrTo(t)).Interface().(type) {
+ case oneofFuncsIface:
+ _, _, _, oneofImplementers = m.XXX_OneofFuncs()
+ case oneofWrappersIface:
+ oneofImplementers = m.XXX_OneofWrappers()
+ }
+
+ n := t.NumField()
+
+ // deal with XXX fields first
+ for i := 0; i < t.NumField(); i++ {
+ f := t.Field(i)
+ if !strings.HasPrefix(f.Name, "XXX_") {
+ continue
+ }
+ switch f.Name {
+ case "XXX_sizecache":
+ u.sizecache = toField(&f)
+ case "XXX_unrecognized":
+ u.unrecognized = toField(&f)
+ case "XXX_InternalExtensions":
+ u.extensions = toField(&f)
+ u.messageset = f.Tag.Get("protobuf_messageset") == "1"
+ case "XXX_extensions":
+ u.v1extensions = toField(&f)
+ case "XXX_NoUnkeyedLiteral":
+ // nothing to do
+ default:
+ panic("unknown XXX field: " + f.Name)
+ }
+ n--
+ }
+
+ // normal fields
+ fields := make([]marshalFieldInfo, n) // batch allocation
+ u.fields = make([]*marshalFieldInfo, 0, n)
+ for i, j := 0, 0; i < t.NumField(); i++ {
+ f := t.Field(i)
+
+ if strings.HasPrefix(f.Name, "XXX_") {
+ continue
+ }
+ field := &fields[j]
+ j++
+ field.name = f.Name
+ u.fields = append(u.fields, field)
+ if f.Tag.Get("protobuf_oneof") != "" {
+ field.computeOneofFieldInfo(&f, oneofImplementers)
+ continue
+ }
+ if f.Tag.Get("protobuf") == "" {
+ // field has no tag (not in generated message), ignore it
+ u.fields = u.fields[:len(u.fields)-1]
+ j--
+ continue
+ }
+ field.computeMarshalFieldInfo(&f)
+ }
+
+ // fields are marshaled in tag order on the wire.
+ sort.Sort(byTag(u.fields))
+
+ atomic.StoreInt32(&u.initialized, 1)
+}
+
+// helper for sorting fields by tag
+type byTag []*marshalFieldInfo
+
+func (a byTag) Len() int { return len(a) }
+func (a byTag) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
+func (a byTag) Less(i, j int) bool { return a[i].wiretag < a[j].wiretag }
+
+// getExtElemInfo returns the information to marshal an extension element.
+// The info it returns is initialized.
+func (u *marshalInfo) getExtElemInfo(desc *ExtensionDesc) *marshalElemInfo {
+ // get from cache first
+ u.RLock()
+ e, ok := u.extElems[desc.Field]
+ u.RUnlock()
+ if ok {
+ return e
+ }
+
+ t := reflect.TypeOf(desc.ExtensionType) // pointer or slice to basic type or struct
+ tags := strings.Split(desc.Tag, ",")
+ tag, err := strconv.Atoi(tags[1])
+ if err != nil {
+ panic("tag is not an integer")
+ }
+ wt := wiretype(tags[0])
+ if t.Kind() == reflect.Ptr && t.Elem().Kind() != reflect.Struct {
+ t = t.Elem()
+ }
+ sizer, marshaler := typeMarshaler(t, tags, false, false)
+ var deref bool
+ if t.Kind() == reflect.Slice && t.Elem().Kind() != reflect.Uint8 {
+ t = reflect.PtrTo(t)
+ deref = true
+ }
+ e = &marshalElemInfo{
+ wiretag: uint64(tag)<<3 | wt,
+ tagsize: SizeVarint(uint64(tag) << 3),
+ sizer: sizer,
+ marshaler: marshaler,
+ isptr: t.Kind() == reflect.Ptr,
+ deref: deref,
+ }
+
+ // update cache
+ u.Lock()
+ if u.extElems == nil {
+ u.extElems = make(map[int32]*marshalElemInfo)
+ }
+ u.extElems[desc.Field] = e
+ u.Unlock()
+ return e
+}
+
+// computeMarshalFieldInfo fills up the information to marshal a field.
+func (fi *marshalFieldInfo) computeMarshalFieldInfo(f *reflect.StructField) {
+ // parse protobuf tag of the field.
+ // tag has format of "bytes,49,opt,name=foo,def=hello!"
+ tags := strings.Split(f.Tag.Get("protobuf"), ",")
+ if tags[0] == "" {
+ return
+ }
+ tag, err := strconv.Atoi(tags[1])
+ if err != nil {
+ panic("tag is not an integer")
+ }
+ wt := wiretype(tags[0])
+ if tags[2] == "req" {
+ fi.required = true
+ }
+ fi.setTag(f, tag, wt)
+ fi.setMarshaler(f, tags)
+}
+
+func (fi *marshalFieldInfo) computeOneofFieldInfo(f *reflect.StructField, oneofImplementers []interface{}) {
+ fi.field = toField(f)
+ fi.wiretag = math.MaxInt32 // Use a large tag number, make oneofs sorted at the end. This tag will not appear on the wire.
+ fi.isPointer = true
+ fi.sizer, fi.marshaler = makeOneOfMarshaler(fi, f)
+ fi.oneofElems = make(map[reflect.Type]*marshalElemInfo)
+
+ ityp := f.Type // interface type
+ for _, o := range oneofImplementers {
+ t := reflect.TypeOf(o)
+ if !t.Implements(ityp) {
+ continue
+ }
+ sf := t.Elem().Field(0) // oneof implementer is a struct with a single field
+ tags := strings.Split(sf.Tag.Get("protobuf"), ",")
+ tag, err := strconv.Atoi(tags[1])
+ if err != nil {
+ panic("tag is not an integer")
+ }
+ wt := wiretype(tags[0])
+ sizer, marshaler := typeMarshaler(sf.Type, tags, false, true) // oneof should not omit any zero value
+ fi.oneofElems[t.Elem()] = &marshalElemInfo{
+ wiretag: uint64(tag)<<3 | wt,
+ tagsize: SizeVarint(uint64(tag) << 3),
+ sizer: sizer,
+ marshaler: marshaler,
+ }
+ }
+}
+
+// wiretype returns the wire encoding of the type.
+func wiretype(encoding string) uint64 {
+ switch encoding {
+ case "fixed32":
+ return WireFixed32
+ case "fixed64":
+ return WireFixed64
+ case "varint", "zigzag32", "zigzag64":
+ return WireVarint
+ case "bytes":
+ return WireBytes
+ case "group":
+ return WireStartGroup
+ }
+ panic("unknown wire type " + encoding)
+}
+
+// setTag fills up the tag (in wire format) and its size in the info of a field.
+func (fi *marshalFieldInfo) setTag(f *reflect.StructField, tag int, wt uint64) {
+ fi.field = toField(f)
+ fi.wiretag = uint64(tag)<<3 | wt
+ fi.tagsize = SizeVarint(uint64(tag) << 3)
+}
+
+// setMarshaler fills up the sizer and marshaler in the info of a field.
+func (fi *marshalFieldInfo) setMarshaler(f *reflect.StructField, tags []string) {
+ switch f.Type.Kind() {
+ case reflect.Map:
+ // map field
+ fi.isPointer = true
+ fi.sizer, fi.marshaler = makeMapMarshaler(f)
+ return
+ case reflect.Ptr, reflect.Slice:
+ fi.isPointer = true
+ }
+ fi.sizer, fi.marshaler = typeMarshaler(f.Type, tags, true, false)
+}
+
+// typeMarshaler returns the sizer and marshaler of a given field.
+// t is the type of the field.
+// tags is the generated "protobuf" tag of the field.
+// If nozero is true, zero value is not marshaled to the wire.
+// If oneof is true, it is a oneof field.
+func typeMarshaler(t reflect.Type, tags []string, nozero, oneof bool) (sizer, marshaler) {
+ encoding := tags[0]
+
+ pointer := false
+ slice := false
+ if t.Kind() == reflect.Slice && t.Elem().Kind() != reflect.Uint8 {
+ slice = true
+ t = t.Elem()
+ }
+ if t.Kind() == reflect.Ptr {
+ pointer = true
+ t = t.Elem()
+ }
+
+ packed := false
+ proto3 := false
+ validateUTF8 := true
+ for i := 2; i < len(tags); i++ {
+ if tags[i] == "packed" {
+ packed = true
+ }
+ if tags[i] == "proto3" {
+ proto3 = true
+ }
+ }
+ validateUTF8 = validateUTF8 && proto3
+
+ switch t.Kind() {
+ case reflect.Bool:
+ if pointer {
+ return sizeBoolPtr, appendBoolPtr
+ }
+ if slice {
+ if packed {
+ return sizeBoolPackedSlice, appendBoolPackedSlice
+ }
+ return sizeBoolSlice, appendBoolSlice
+ }
+ if nozero {
+ return sizeBoolValueNoZero, appendBoolValueNoZero
+ }
+ return sizeBoolValue, appendBoolValue
+ case reflect.Uint32:
+ switch encoding {
+ case "fixed32":
+ if pointer {
+ return sizeFixed32Ptr, appendFixed32Ptr
+ }
+ if slice {
+ if packed {
+ return sizeFixed32PackedSlice, appendFixed32PackedSlice
+ }
+ return sizeFixed32Slice, appendFixed32Slice
+ }
+ if nozero {
+ return sizeFixed32ValueNoZero, appendFixed32ValueNoZero
+ }
+ return sizeFixed32Value, appendFixed32Value
+ case "varint":
+ if pointer {
+ return sizeVarint32Ptr, appendVarint32Ptr
+ }
+ if slice {
+ if packed {
+ return sizeVarint32PackedSlice, appendVarint32PackedSlice
+ }
+ return sizeVarint32Slice, appendVarint32Slice
+ }
+ if nozero {
+ return sizeVarint32ValueNoZero, appendVarint32ValueNoZero
+ }
+ return sizeVarint32Value, appendVarint32Value
+ }
+ case reflect.Int32:
+ switch encoding {
+ case "fixed32":
+ if pointer {
+ return sizeFixedS32Ptr, appendFixedS32Ptr
+ }
+ if slice {
+ if packed {
+ return sizeFixedS32PackedSlice, appendFixedS32PackedSlice
+ }
+ return sizeFixedS32Slice, appendFixedS32Slice
+ }
+ if nozero {
+ return sizeFixedS32ValueNoZero, appendFixedS32ValueNoZero
+ }
+ return sizeFixedS32Value, appendFixedS32Value
+ case "varint":
+ if pointer {
+ return sizeVarintS32Ptr, appendVarintS32Ptr
+ }
+ if slice {
+ if packed {
+ return sizeVarintS32PackedSlice, appendVarintS32PackedSlice
+ }
+ return sizeVarintS32Slice, appendVarintS32Slice
+ }
+ if nozero {
+ return sizeVarintS32ValueNoZero, appendVarintS32ValueNoZero
+ }
+ return sizeVarintS32Value, appendVarintS32Value
+ case "zigzag32":
+ if pointer {
+ return sizeZigzag32Ptr, appendZigzag32Ptr
+ }
+ if slice {
+ if packed {
+ return sizeZigzag32PackedSlice, appendZigzag32PackedSlice
+ }
+ return sizeZigzag32Slice, appendZigzag32Slice
+ }
+ if nozero {
+ return sizeZigzag32ValueNoZero, appendZigzag32ValueNoZero
+ }
+ return sizeZigzag32Value, appendZigzag32Value
+ }
+ case reflect.Uint64:
+ switch encoding {
+ case "fixed64":
+ if pointer {
+ return sizeFixed64Ptr, appendFixed64Ptr
+ }
+ if slice {
+ if packed {
+ return sizeFixed64PackedSlice, appendFixed64PackedSlice
+ }
+ return sizeFixed64Slice, appendFixed64Slice
+ }
+ if nozero {
+ return sizeFixed64ValueNoZero, appendFixed64ValueNoZero
+ }
+ return sizeFixed64Value, appendFixed64Value
+ case "varint":
+ if pointer {
+ return sizeVarint64Ptr, appendVarint64Ptr
+ }
+ if slice {
+ if packed {
+ return sizeVarint64PackedSlice, appendVarint64PackedSlice
+ }
+ return sizeVarint64Slice, appendVarint64Slice
+ }
+ if nozero {
+ return sizeVarint64ValueNoZero, appendVarint64ValueNoZero
+ }
+ return sizeVarint64Value, appendVarint64Value
+ }
+ case reflect.Int64:
+ switch encoding {
+ case "fixed64":
+ if pointer {
+ return sizeFixedS64Ptr, appendFixedS64Ptr
+ }
+ if slice {
+ if packed {
+ return sizeFixedS64PackedSlice, appendFixedS64PackedSlice
+ }
+ return sizeFixedS64Slice, appendFixedS64Slice
+ }
+ if nozero {
+ return sizeFixedS64ValueNoZero, appendFixedS64ValueNoZero
+ }
+ return sizeFixedS64Value, appendFixedS64Value
+ case "varint":
+ if pointer {
+ return sizeVarintS64Ptr, appendVarintS64Ptr
+ }
+ if slice {
+ if packed {
+ return sizeVarintS64PackedSlice, appendVarintS64PackedSlice
+ }
+ return sizeVarintS64Slice, appendVarintS64Slice
+ }
+ if nozero {
+ return sizeVarintS64ValueNoZero, appendVarintS64ValueNoZero
+ }
+ return sizeVarintS64Value, appendVarintS64Value
+ case "zigzag64":
+ if pointer {
+ return sizeZigzag64Ptr, appendZigzag64Ptr
+ }
+ if slice {
+ if packed {
+ return sizeZigzag64PackedSlice, appendZigzag64PackedSlice
+ }
+ return sizeZigzag64Slice, appendZigzag64Slice
+ }
+ if nozero {
+ return sizeZigzag64ValueNoZero, appendZigzag64ValueNoZero
+ }
+ return sizeZigzag64Value, appendZigzag64Value
+ }
+ case reflect.Float32:
+ if pointer {
+ return sizeFloat32Ptr, appendFloat32Ptr
+ }
+ if slice {
+ if packed {
+ return sizeFloat32PackedSlice, appendFloat32PackedSlice
+ }
+ return sizeFloat32Slice, appendFloat32Slice
+ }
+ if nozero {
+ return sizeFloat32ValueNoZero, appendFloat32ValueNoZero
+ }
+ return sizeFloat32Value, appendFloat32Value
+ case reflect.Float64:
+ if pointer {
+ return sizeFloat64Ptr, appendFloat64Ptr
+ }
+ if slice {
+ if packed {
+ return sizeFloat64PackedSlice, appendFloat64PackedSlice
+ }
+ return sizeFloat64Slice, appendFloat64Slice
+ }
+ if nozero {
+ return sizeFloat64ValueNoZero, appendFloat64ValueNoZero
+ }
+ return sizeFloat64Value, appendFloat64Value
+ case reflect.String:
+ if validateUTF8 {
+ if pointer {
+ return sizeStringPtr, appendUTF8StringPtr
+ }
+ if slice {
+ return sizeStringSlice, appendUTF8StringSlice
+ }
+ if nozero {
+ return sizeStringValueNoZero, appendUTF8StringValueNoZero
+ }
+ return sizeStringValue, appendUTF8StringValue
+ }
+ if pointer {
+ return sizeStringPtr, appendStringPtr
+ }
+ if slice {
+ return sizeStringSlice, appendStringSlice
+ }
+ if nozero {
+ return sizeStringValueNoZero, appendStringValueNoZero
+ }
+ return sizeStringValue, appendStringValue
+ case reflect.Slice:
+ if slice {
+ return sizeBytesSlice, appendBytesSlice
+ }
+ if oneof {
+ // Oneof bytes field may also have "proto3" tag.
+ // We want to marshal it as a oneof field. Do this
+ // check before the proto3 check.
+ return sizeBytesOneof, appendBytesOneof
+ }
+ if proto3 {
+ return sizeBytes3, appendBytes3
+ }
+ return sizeBytes, appendBytes
+ case reflect.Struct:
+ switch encoding {
+ case "group":
+ if slice {
+ return makeGroupSliceMarshaler(getMarshalInfo(t))
+ }
+ return makeGroupMarshaler(getMarshalInfo(t))
+ case "bytes":
+ if slice {
+ return makeMessageSliceMarshaler(getMarshalInfo(t))
+ }
+ return makeMessageMarshaler(getMarshalInfo(t))
+ }
+ }
+ panic(fmt.Sprintf("unknown or mismatched type: type: %v, wire type: %v", t, encoding))
+}
+
+// Below are functions to size/marshal a specific type of a field.
+// They are stored in the field's info, and called by function pointers.
+// They have type sizer or marshaler.
+
+func sizeFixed32Value(_ pointer, tagsize int) int {
+ return 4 + tagsize
+}
+func sizeFixed32ValueNoZero(ptr pointer, tagsize int) int {
+ v := *ptr.toUint32()
+ if v == 0 {
+ return 0
+ }
+ return 4 + tagsize
+}
+func sizeFixed32Ptr(ptr pointer, tagsize int) int {
+ p := *ptr.toUint32Ptr()
+ if p == nil {
+ return 0
+ }
+ return 4 + tagsize
+}
+func sizeFixed32Slice(ptr pointer, tagsize int) int {
+ s := *ptr.toUint32Slice()
+ return (4 + tagsize) * len(s)
+}
+func sizeFixed32PackedSlice(ptr pointer, tagsize int) int {
+ s := *ptr.toUint32Slice()
+ if len(s) == 0 {
+ return 0
+ }
+ return 4*len(s) + SizeVarint(uint64(4*len(s))) + tagsize
+}
+func sizeFixedS32Value(_ pointer, tagsize int) int {
+ return 4 + tagsize
+}
+func sizeFixedS32ValueNoZero(ptr pointer, tagsize int) int {
+ v := *ptr.toInt32()
+ if v == 0 {
+ return 0
+ }
+ return 4 + tagsize
+}
+func sizeFixedS32Ptr(ptr pointer, tagsize int) int {
+ p := ptr.getInt32Ptr()
+ if p == nil {
+ return 0
+ }
+ return 4 + tagsize
+}
+func sizeFixedS32Slice(ptr pointer, tagsize int) int {
+ s := ptr.getInt32Slice()
+ return (4 + tagsize) * len(s)
+}
+func sizeFixedS32PackedSlice(ptr pointer, tagsize int) int {
+ s := ptr.getInt32Slice()
+ if len(s) == 0 {
+ return 0
+ }
+ return 4*len(s) + SizeVarint(uint64(4*len(s))) + tagsize
+}
+func sizeFloat32Value(_ pointer, tagsize int) int {
+ return 4 + tagsize
+}
+func sizeFloat32ValueNoZero(ptr pointer, tagsize int) int {
+ v := math.Float32bits(*ptr.toFloat32())
+ if v == 0 {
+ return 0
+ }
+ return 4 + tagsize
+}
+func sizeFloat32Ptr(ptr pointer, tagsize int) int {
+ p := *ptr.toFloat32Ptr()
+ if p == nil {
+ return 0
+ }
+ return 4 + tagsize
+}
+func sizeFloat32Slice(ptr pointer, tagsize int) int {
+ s := *ptr.toFloat32Slice()
+ return (4 + tagsize) * len(s)
+}
+func sizeFloat32PackedSlice(ptr pointer, tagsize int) int {
+ s := *ptr.toFloat32Slice()
+ if len(s) == 0 {
+ return 0
+ }
+ return 4*len(s) + SizeVarint(uint64(4*len(s))) + tagsize
+}
+func sizeFixed64Value(_ pointer, tagsize int) int {
+ return 8 + tagsize
+}
+func sizeFixed64ValueNoZero(ptr pointer, tagsize int) int {
+ v := *ptr.toUint64()
+ if v == 0 {
+ return 0
+ }
+ return 8 + tagsize
+}
+func sizeFixed64Ptr(ptr pointer, tagsize int) int {
+ p := *ptr.toUint64Ptr()
+ if p == nil {
+ return 0
+ }
+ return 8 + tagsize
+}
+func sizeFixed64Slice(ptr pointer, tagsize int) int {
+ s := *ptr.toUint64Slice()
+ return (8 + tagsize) * len(s)
+}
+func sizeFixed64PackedSlice(ptr pointer, tagsize int) int {
+ s := *ptr.toUint64Slice()
+ if len(s) == 0 {
+ return 0
+ }
+ return 8*len(s) + SizeVarint(uint64(8*len(s))) + tagsize
+}
+func sizeFixedS64Value(_ pointer, tagsize int) int {
+ return 8 + tagsize
+}
+func sizeFixedS64ValueNoZero(ptr pointer, tagsize int) int {
+ v := *ptr.toInt64()
+ if v == 0 {
+ return 0
+ }
+ return 8 + tagsize
+}
+func sizeFixedS64Ptr(ptr pointer, tagsize int) int {
+ p := *ptr.toInt64Ptr()
+ if p == nil {
+ return 0
+ }
+ return 8 + tagsize
+}
+func sizeFixedS64Slice(ptr pointer, tagsize int) int {
+ s := *ptr.toInt64Slice()
+ return (8 + tagsize) * len(s)
+}
+func sizeFixedS64PackedSlice(ptr pointer, tagsize int) int {
+ s := *ptr.toInt64Slice()
+ if len(s) == 0 {
+ return 0
+ }
+ return 8*len(s) + SizeVarint(uint64(8*len(s))) + tagsize
+}
+func sizeFloat64Value(_ pointer, tagsize int) int {
+ return 8 + tagsize
+}
+func sizeFloat64ValueNoZero(ptr pointer, tagsize int) int {
+ v := math.Float64bits(*ptr.toFloat64())
+ if v == 0 {
+ return 0
+ }
+ return 8 + tagsize
+}
+func sizeFloat64Ptr(ptr pointer, tagsize int) int {
+ p := *ptr.toFloat64Ptr()
+ if p == nil {
+ return 0
+ }
+ return 8 + tagsize
+}
+func sizeFloat64Slice(ptr pointer, tagsize int) int {
+ s := *ptr.toFloat64Slice()
+ return (8 + tagsize) * len(s)
+}
+func sizeFloat64PackedSlice(ptr pointer, tagsize int) int {
+ s := *ptr.toFloat64Slice()
+ if len(s) == 0 {
+ return 0
+ }
+ return 8*len(s) + SizeVarint(uint64(8*len(s))) + tagsize
+}
+func sizeVarint32Value(ptr pointer, tagsize int) int {
+ v := *ptr.toUint32()
+ return SizeVarint(uint64(v)) + tagsize
+}
+func sizeVarint32ValueNoZero(ptr pointer, tagsize int) int {
+ v := *ptr.toUint32()
+ if v == 0 {
+ return 0
+ }
+ return SizeVarint(uint64(v)) + tagsize
+}
+func sizeVarint32Ptr(ptr pointer, tagsize int) int {
+ p := *ptr.toUint32Ptr()
+ if p == nil {
+ return 0
+ }
+ return SizeVarint(uint64(*p)) + tagsize
+}
+func sizeVarint32Slice(ptr pointer, tagsize int) int {
+ s := *ptr.toUint32Slice()
+ n := 0
+ for _, v := range s {
+ n += SizeVarint(uint64(v)) + tagsize
+ }
+ return n
+}
+func sizeVarint32PackedSlice(ptr pointer, tagsize int) int {
+ s := *ptr.toUint32Slice()
+ if len(s) == 0 {
+ return 0
+ }
+ n := 0
+ for _, v := range s {
+ n += SizeVarint(uint64(v))
+ }
+ return n + SizeVarint(uint64(n)) + tagsize
+}
+func sizeVarintS32Value(ptr pointer, tagsize int) int {
+ v := *ptr.toInt32()
+ return SizeVarint(uint64(v)) + tagsize
+}
+func sizeVarintS32ValueNoZero(ptr pointer, tagsize int) int {
+ v := *ptr.toInt32()
+ if v == 0 {
+ return 0
+ }
+ return SizeVarint(uint64(v)) + tagsize
+}
+func sizeVarintS32Ptr(ptr pointer, tagsize int) int {
+ p := ptr.getInt32Ptr()
+ if p == nil {
+ return 0
+ }
+ return SizeVarint(uint64(*p)) + tagsize
+}
+func sizeVarintS32Slice(ptr pointer, tagsize int) int {
+ s := ptr.getInt32Slice()
+ n := 0
+ for _, v := range s {
+ n += SizeVarint(uint64(v)) + tagsize
+ }
+ return n
+}
+func sizeVarintS32PackedSlice(ptr pointer, tagsize int) int {
+ s := ptr.getInt32Slice()
+ if len(s) == 0 {
+ return 0
+ }
+ n := 0
+ for _, v := range s {
+ n += SizeVarint(uint64(v))
+ }
+ return n + SizeVarint(uint64(n)) + tagsize
+}
+func sizeVarint64Value(ptr pointer, tagsize int) int {
+ v := *ptr.toUint64()
+ return SizeVarint(v) + tagsize
+}
+func sizeVarint64ValueNoZero(ptr pointer, tagsize int) int {
+ v := *ptr.toUint64()
+ if v == 0 {
+ return 0
+ }
+ return SizeVarint(v) + tagsize
+}
+func sizeVarint64Ptr(ptr pointer, tagsize int) int {
+ p := *ptr.toUint64Ptr()
+ if p == nil {
+ return 0
+ }
+ return SizeVarint(*p) + tagsize
+}
+func sizeVarint64Slice(ptr pointer, tagsize int) int {
+ s := *ptr.toUint64Slice()
+ n := 0
+ for _, v := range s {
+ n += SizeVarint(v) + tagsize
+ }
+ return n
+}
+func sizeVarint64PackedSlice(ptr pointer, tagsize int) int {
+ s := *ptr.toUint64Slice()
+ if len(s) == 0 {
+ return 0
+ }
+ n := 0
+ for _, v := range s {
+ n += SizeVarint(v)
+ }
+ return n + SizeVarint(uint64(n)) + tagsize
+}
+func sizeVarintS64Value(ptr pointer, tagsize int) int {
+ v := *ptr.toInt64()
+ return SizeVarint(uint64(v)) + tagsize
+}
+func sizeVarintS64ValueNoZero(ptr pointer, tagsize int) int {
+ v := *ptr.toInt64()
+ if v == 0 {
+ return 0
+ }
+ return SizeVarint(uint64(v)) + tagsize
+}
+func sizeVarintS64Ptr(ptr pointer, tagsize int) int {
+ p := *ptr.toInt64Ptr()
+ if p == nil {
+ return 0
+ }
+ return SizeVarint(uint64(*p)) + tagsize
+}
+func sizeVarintS64Slice(ptr pointer, tagsize int) int {
+ s := *ptr.toInt64Slice()
+ n := 0
+ for _, v := range s {
+ n += SizeVarint(uint64(v)) + tagsize
+ }
+ return n
+}
+func sizeVarintS64PackedSlice(ptr pointer, tagsize int) int {
+ s := *ptr.toInt64Slice()
+ if len(s) == 0 {
+ return 0
+ }
+ n := 0
+ for _, v := range s {
+ n += SizeVarint(uint64(v))
+ }
+ return n + SizeVarint(uint64(n)) + tagsize
+}
+func sizeZigzag32Value(ptr pointer, tagsize int) int {
+ v := *ptr.toInt32()
+ return SizeVarint(uint64((uint32(v)<<1)^uint32((int32(v)>>31)))) + tagsize
+}
+func sizeZigzag32ValueNoZero(ptr pointer, tagsize int) int {
+ v := *ptr.toInt32()
+ if v == 0 {
+ return 0
+ }
+ return SizeVarint(uint64((uint32(v)<<1)^uint32((int32(v)>>31)))) + tagsize
+}
+func sizeZigzag32Ptr(ptr pointer, tagsize int) int {
+ p := ptr.getInt32Ptr()
+ if p == nil {
+ return 0
+ }
+ v := *p
+ return SizeVarint(uint64((uint32(v)<<1)^uint32((int32(v)>>31)))) + tagsize
+}
+func sizeZigzag32Slice(ptr pointer, tagsize int) int {
+ s := ptr.getInt32Slice()
+ n := 0
+ for _, v := range s {
+ n += SizeVarint(uint64((uint32(v)<<1)^uint32((int32(v)>>31)))) + tagsize
+ }
+ return n
+}
+func sizeZigzag32PackedSlice(ptr pointer, tagsize int) int {
+ s := ptr.getInt32Slice()
+ if len(s) == 0 {
+ return 0
+ }
+ n := 0
+ for _, v := range s {
+ n += SizeVarint(uint64((uint32(v) << 1) ^ uint32((int32(v) >> 31))))
+ }
+ return n + SizeVarint(uint64(n)) + tagsize
+}
+func sizeZigzag64Value(ptr pointer, tagsize int) int {
+ v := *ptr.toInt64()
+ return SizeVarint(uint64(v<<1)^uint64((int64(v)>>63))) + tagsize
+}
+func sizeZigzag64ValueNoZero(ptr pointer, tagsize int) int {
+ v := *ptr.toInt64()
+ if v == 0 {
+ return 0
+ }
+ return SizeVarint(uint64(v<<1)^uint64((int64(v)>>63))) + tagsize
+}
+func sizeZigzag64Ptr(ptr pointer, tagsize int) int {
+ p := *ptr.toInt64Ptr()
+ if p == nil {
+ return 0
+ }
+ v := *p
+ return SizeVarint(uint64(v<<1)^uint64((int64(v)>>63))) + tagsize
+}
+func sizeZigzag64Slice(ptr pointer, tagsize int) int {
+ s := *ptr.toInt64Slice()
+ n := 0
+ for _, v := range s {
+ n += SizeVarint(uint64(v<<1)^uint64((int64(v)>>63))) + tagsize
+ }
+ return n
+}
+func sizeZigzag64PackedSlice(ptr pointer, tagsize int) int {
+ s := *ptr.toInt64Slice()
+ if len(s) == 0 {
+ return 0
+ }
+ n := 0
+ for _, v := range s {
+ n += SizeVarint(uint64(v<<1) ^ uint64((int64(v) >> 63)))
+ }
+ return n + SizeVarint(uint64(n)) + tagsize
+}
+func sizeBoolValue(_ pointer, tagsize int) int {
+ return 1 + tagsize
+}
+func sizeBoolValueNoZero(ptr pointer, tagsize int) int {
+ v := *ptr.toBool()
+ if !v {
+ return 0
+ }
+ return 1 + tagsize
+}
+func sizeBoolPtr(ptr pointer, tagsize int) int {
+ p := *ptr.toBoolPtr()
+ if p == nil {
+ return 0
+ }
+ return 1 + tagsize
+}
+func sizeBoolSlice(ptr pointer, tagsize int) int {
+ s := *ptr.toBoolSlice()
+ return (1 + tagsize) * len(s)
+}
+func sizeBoolPackedSlice(ptr pointer, tagsize int) int {
+ s := *ptr.toBoolSlice()
+ if len(s) == 0 {
+ return 0
+ }
+ return len(s) + SizeVarint(uint64(len(s))) + tagsize
+}
+func sizeStringValue(ptr pointer, tagsize int) int {
+ v := *ptr.toString()
+ return len(v) + SizeVarint(uint64(len(v))) + tagsize
+}
+func sizeStringValueNoZero(ptr pointer, tagsize int) int {
+ v := *ptr.toString()
+ if v == "" {
+ return 0
+ }
+ return len(v) + SizeVarint(uint64(len(v))) + tagsize
+}
+func sizeStringPtr(ptr pointer, tagsize int) int {
+ p := *ptr.toStringPtr()
+ if p == nil {
+ return 0
+ }
+ v := *p
+ return len(v) + SizeVarint(uint64(len(v))) + tagsize
+}
+func sizeStringSlice(ptr pointer, tagsize int) int {
+ s := *ptr.toStringSlice()
+ n := 0
+ for _, v := range s {
+ n += len(v) + SizeVarint(uint64(len(v))) + tagsize
+ }
+ return n
+}
+func sizeBytes(ptr pointer, tagsize int) int {
+ v := *ptr.toBytes()
+ if v == nil {
+ return 0
+ }
+ return len(v) + SizeVarint(uint64(len(v))) + tagsize
+}
+func sizeBytes3(ptr pointer, tagsize int) int {
+ v := *ptr.toBytes()
+ if len(v) == 0 {
+ return 0
+ }
+ return len(v) + SizeVarint(uint64(len(v))) + tagsize
+}
+func sizeBytesOneof(ptr pointer, tagsize int) int {
+ v := *ptr.toBytes()
+ return len(v) + SizeVarint(uint64(len(v))) + tagsize
+}
+func sizeBytesSlice(ptr pointer, tagsize int) int {
+ s := *ptr.toBytesSlice()
+ n := 0
+ for _, v := range s {
+ n += len(v) + SizeVarint(uint64(len(v))) + tagsize
+ }
+ return n
+}
+
+// appendFixed32 appends an encoded fixed32 to b.
+func appendFixed32(b []byte, v uint32) []byte {
+ b = append(b,
+ byte(v),
+ byte(v>>8),
+ byte(v>>16),
+ byte(v>>24))
+ return b
+}
+
+// appendFixed64 appends an encoded fixed64 to b.
+func appendFixed64(b []byte, v uint64) []byte {
+ b = append(b,
+ byte(v),
+ byte(v>>8),
+ byte(v>>16),
+ byte(v>>24),
+ byte(v>>32),
+ byte(v>>40),
+ byte(v>>48),
+ byte(v>>56))
+ return b
+}
+
+// appendVarint appends an encoded varint to b.
+func appendVarint(b []byte, v uint64) []byte {
+ // TODO: make 1-byte (maybe 2-byte) case inline-able, once we
+ // have non-leaf inliner.
+ switch {
+ case v < 1<<7:
+ b = append(b, byte(v))
+ case v < 1<<14:
+ b = append(b,
+ byte(v&0x7f|0x80),
+ byte(v>>7))
+ case v < 1<<21:
+ b = append(b,
+ byte(v&0x7f|0x80),
+ byte((v>>7)&0x7f|0x80),
+ byte(v>>14))
+ case v < 1<<28:
+ b = append(b,
+ byte(v&0x7f|0x80),
+ byte((v>>7)&0x7f|0x80),
+ byte((v>>14)&0x7f|0x80),
+ byte(v>>21))
+ case v < 1<<35:
+ b = append(b,
+ byte(v&0x7f|0x80),
+ byte((v>>7)&0x7f|0x80),
+ byte((v>>14)&0x7f|0x80),
+ byte((v>>21)&0x7f|0x80),
+ byte(v>>28))
+ case v < 1<<42:
+ b = append(b,
+ byte(v&0x7f|0x80),
+ byte((v>>7)&0x7f|0x80),
+ byte((v>>14)&0x7f|0x80),
+ byte((v>>21)&0x7f|0x80),
+ byte((v>>28)&0x7f|0x80),
+ byte(v>>35))
+ case v < 1<<49:
+ b = append(b,
+ byte(v&0x7f|0x80),
+ byte((v>>7)&0x7f|0x80),
+ byte((v>>14)&0x7f|0x80),
+ byte((v>>21)&0x7f|0x80),
+ byte((v>>28)&0x7f|0x80),
+ byte((v>>35)&0x7f|0x80),
+ byte(v>>42))
+ case v < 1<<56:
+ b = append(b,
+ byte(v&0x7f|0x80),
+ byte((v>>7)&0x7f|0x80),
+ byte((v>>14)&0x7f|0x80),
+ byte((v>>21)&0x7f|0x80),
+ byte((v>>28)&0x7f|0x80),
+ byte((v>>35)&0x7f|0x80),
+ byte((v>>42)&0x7f|0x80),
+ byte(v>>49))
+ case v < 1<<63:
+ b = append(b,
+ byte(v&0x7f|0x80),
+ byte((v>>7)&0x7f|0x80),
+ byte((v>>14)&0x7f|0x80),
+ byte((v>>21)&0x7f|0x80),
+ byte((v>>28)&0x7f|0x80),
+ byte((v>>35)&0x7f|0x80),
+ byte((v>>42)&0x7f|0x80),
+ byte((v>>49)&0x7f|0x80),
+ byte(v>>56))
+ default:
+ b = append(b,
+ byte(v&0x7f|0x80),
+ byte((v>>7)&0x7f|0x80),
+ byte((v>>14)&0x7f|0x80),
+ byte((v>>21)&0x7f|0x80),
+ byte((v>>28)&0x7f|0x80),
+ byte((v>>35)&0x7f|0x80),
+ byte((v>>42)&0x7f|0x80),
+ byte((v>>49)&0x7f|0x80),
+ byte((v>>56)&0x7f|0x80),
+ 1)
+ }
+ return b
+}
+
+func appendFixed32Value(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
+ v := *ptr.toUint32()
+ b = appendVarint(b, wiretag)
+ b = appendFixed32(b, v)
+ return b, nil
+}
+func appendFixed32ValueNoZero(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
+ v := *ptr.toUint32()
+ if v == 0 {
+ return b, nil
+ }
+ b = appendVarint(b, wiretag)
+ b = appendFixed32(b, v)
+ return b, nil
+}
+func appendFixed32Ptr(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
+ p := *ptr.toUint32Ptr()
+ if p == nil {
+ return b, nil
+ }
+ b = appendVarint(b, wiretag)
+ b = appendFixed32(b, *p)
+ return b, nil
+}
+func appendFixed32Slice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
+ s := *ptr.toUint32Slice()
+ for _, v := range s {
+ b = appendVarint(b, wiretag)
+ b = appendFixed32(b, v)
+ }
+ return b, nil
+}
+func appendFixed32PackedSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
+ s := *ptr.toUint32Slice()
+ if len(s) == 0 {
+ return b, nil
+ }
+ b = appendVarint(b, wiretag&^7|WireBytes)
+ b = appendVarint(b, uint64(4*len(s)))
+ for _, v := range s {
+ b = appendFixed32(b, v)
+ }
+ return b, nil
+}
+func appendFixedS32Value(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
+ v := *ptr.toInt32()
+ b = appendVarint(b, wiretag)
+ b = appendFixed32(b, uint32(v))
+ return b, nil
+}
+func appendFixedS32ValueNoZero(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
+ v := *ptr.toInt32()
+ if v == 0 {
+ return b, nil
+ }
+ b = appendVarint(b, wiretag)
+ b = appendFixed32(b, uint32(v))
+ return b, nil
+}
+func appendFixedS32Ptr(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
+ p := ptr.getInt32Ptr()
+ if p == nil {
+ return b, nil
+ }
+ b = appendVarint(b, wiretag)
+ b = appendFixed32(b, uint32(*p))
+ return b, nil
+}
+func appendFixedS32Slice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
+ s := ptr.getInt32Slice()
+ for _, v := range s {
+ b = appendVarint(b, wiretag)
+ b = appendFixed32(b, uint32(v))
+ }
+ return b, nil
+}
+func appendFixedS32PackedSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
+ s := ptr.getInt32Slice()
+ if len(s) == 0 {
+ return b, nil
+ }
+ b = appendVarint(b, wiretag&^7|WireBytes)
+ b = appendVarint(b, uint64(4*len(s)))
+ for _, v := range s {
+ b = appendFixed32(b, uint32(v))
+ }
+ return b, nil
+}
+func appendFloat32Value(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
+ v := math.Float32bits(*ptr.toFloat32())
+ b = appendVarint(b, wiretag)
+ b = appendFixed32(b, v)
+ return b, nil
+}
+func appendFloat32ValueNoZero(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
+ v := math.Float32bits(*ptr.toFloat32())
+ if v == 0 {
+ return b, nil
+ }
+ b = appendVarint(b, wiretag)
+ b = appendFixed32(b, v)
+ return b, nil
+}
+func appendFloat32Ptr(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
+ p := *ptr.toFloat32Ptr()
+ if p == nil {
+ return b, nil
+ }
+ b = appendVarint(b, wiretag)
+ b = appendFixed32(b, math.Float32bits(*p))
+ return b, nil
+}
+func appendFloat32Slice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
+ s := *ptr.toFloat32Slice()
+ for _, v := range s {
+ b = appendVarint(b, wiretag)
+ b = appendFixed32(b, math.Float32bits(v))
+ }
+ return b, nil
+}
+func appendFloat32PackedSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
+ s := *ptr.toFloat32Slice()
+ if len(s) == 0 {
+ return b, nil
+ }
+ b = appendVarint(b, wiretag&^7|WireBytes)
+ b = appendVarint(b, uint64(4*len(s)))
+ for _, v := range s {
+ b = appendFixed32(b, math.Float32bits(v))
+ }
+ return b, nil
+}
+func appendFixed64Value(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
+ v := *ptr.toUint64()
+ b = appendVarint(b, wiretag)
+ b = appendFixed64(b, v)
+ return b, nil
+}
+func appendFixed64ValueNoZero(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
+ v := *ptr.toUint64()
+ if v == 0 {
+ return b, nil
+ }
+ b = appendVarint(b, wiretag)
+ b = appendFixed64(b, v)
+ return b, nil
+}
+func appendFixed64Ptr(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
+ p := *ptr.toUint64Ptr()
+ if p == nil {
+ return b, nil
+ }
+ b = appendVarint(b, wiretag)
+ b = appendFixed64(b, *p)
+ return b, nil
+}
+func appendFixed64Slice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
+ s := *ptr.toUint64Slice()
+ for _, v := range s {
+ b = appendVarint(b, wiretag)
+ b = appendFixed64(b, v)
+ }
+ return b, nil
+}
+func appendFixed64PackedSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
+ s := *ptr.toUint64Slice()
+ if len(s) == 0 {
+ return b, nil
+ }
+ b = appendVarint(b, wiretag&^7|WireBytes)
+ b = appendVarint(b, uint64(8*len(s)))
+ for _, v := range s {
+ b = appendFixed64(b, v)
+ }
+ return b, nil
+}
+func appendFixedS64Value(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
+ v := *ptr.toInt64()
+ b = appendVarint(b, wiretag)
+ b = appendFixed64(b, uint64(v))
+ return b, nil
+}
+func appendFixedS64ValueNoZero(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
+ v := *ptr.toInt64()
+ if v == 0 {
+ return b, nil
+ }
+ b = appendVarint(b, wiretag)
+ b = appendFixed64(b, uint64(v))
+ return b, nil
+}
+func appendFixedS64Ptr(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
+ p := *ptr.toInt64Ptr()
+ if p == nil {
+ return b, nil
+ }
+ b = appendVarint(b, wiretag)
+ b = appendFixed64(b, uint64(*p))
+ return b, nil
+}
+func appendFixedS64Slice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
+ s := *ptr.toInt64Slice()
+ for _, v := range s {
+ b = appendVarint(b, wiretag)
+ b = appendFixed64(b, uint64(v))
+ }
+ return b, nil
+}
+func appendFixedS64PackedSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
+ s := *ptr.toInt64Slice()
+ if len(s) == 0 {
+ return b, nil
+ }
+ b = appendVarint(b, wiretag&^7|WireBytes)
+ b = appendVarint(b, uint64(8*len(s)))
+ for _, v := range s {
+ b = appendFixed64(b, uint64(v))
+ }
+ return b, nil
+}
+func appendFloat64Value(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
+ v := math.Float64bits(*ptr.toFloat64())
+ b = appendVarint(b, wiretag)
+ b = appendFixed64(b, v)
+ return b, nil
+}
+func appendFloat64ValueNoZero(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
+ v := math.Float64bits(*ptr.toFloat64())
+ if v == 0 {
+ return b, nil
+ }
+ b = appendVarint(b, wiretag)
+ b = appendFixed64(b, v)
+ return b, nil
+}
+func appendFloat64Ptr(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
+ p := *ptr.toFloat64Ptr()
+ if p == nil {
+ return b, nil
+ }
+ b = appendVarint(b, wiretag)
+ b = appendFixed64(b, math.Float64bits(*p))
+ return b, nil
+}
+func appendFloat64Slice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
+ s := *ptr.toFloat64Slice()
+ for _, v := range s {
+ b = appendVarint(b, wiretag)
+ b = appendFixed64(b, math.Float64bits(v))
+ }
+ return b, nil
+}
+func appendFloat64PackedSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
+ s := *ptr.toFloat64Slice()
+ if len(s) == 0 {
+ return b, nil
+ }
+ b = appendVarint(b, wiretag&^7|WireBytes)
+ b = appendVarint(b, uint64(8*len(s)))
+ for _, v := range s {
+ b = appendFixed64(b, math.Float64bits(v))
+ }
+ return b, nil
+}
+func appendVarint32Value(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
+ v := *ptr.toUint32()
+ b = appendVarint(b, wiretag)
+ b = appendVarint(b, uint64(v))
+ return b, nil
+}
+func appendVarint32ValueNoZero(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
+ v := *ptr.toUint32()
+ if v == 0 {
+ return b, nil
+ }
+ b = appendVarint(b, wiretag)
+ b = appendVarint(b, uint64(v))
+ return b, nil
+}
+func appendVarint32Ptr(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
+ p := *ptr.toUint32Ptr()
+ if p == nil {
+ return b, nil
+ }
+ b = appendVarint(b, wiretag)
+ b = appendVarint(b, uint64(*p))
+ return b, nil
+}
+func appendVarint32Slice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
+ s := *ptr.toUint32Slice()
+ for _, v := range s {
+ b = appendVarint(b, wiretag)
+ b = appendVarint(b, uint64(v))
+ }
+ return b, nil
+}
+func appendVarint32PackedSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
+ s := *ptr.toUint32Slice()
+ if len(s) == 0 {
+ return b, nil
+ }
+ b = appendVarint(b, wiretag&^7|WireBytes)
+ // compute size
+ n := 0
+ for _, v := range s {
+ n += SizeVarint(uint64(v))
+ }
+ b = appendVarint(b, uint64(n))
+ for _, v := range s {
+ b = appendVarint(b, uint64(v))
+ }
+ return b, nil
+}
+func appendVarintS32Value(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
+ v := *ptr.toInt32()
+ b = appendVarint(b, wiretag)
+ b = appendVarint(b, uint64(v))
+ return b, nil
+}
+func appendVarintS32ValueNoZero(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
+ v := *ptr.toInt32()
+ if v == 0 {
+ return b, nil
+ }
+ b = appendVarint(b, wiretag)
+ b = appendVarint(b, uint64(v))
+ return b, nil
+}
+func appendVarintS32Ptr(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
+ p := ptr.getInt32Ptr()
+ if p == nil {
+ return b, nil
+ }
+ b = appendVarint(b, wiretag)
+ b = appendVarint(b, uint64(*p))
+ return b, nil
+}
+func appendVarintS32Slice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
+ s := ptr.getInt32Slice()
+ for _, v := range s {
+ b = appendVarint(b, wiretag)
+ b = appendVarint(b, uint64(v))
+ }
+ return b, nil
+}
+func appendVarintS32PackedSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
+ s := ptr.getInt32Slice()
+ if len(s) == 0 {
+ return b, nil
+ }
+ b = appendVarint(b, wiretag&^7|WireBytes)
+ // compute size
+ n := 0
+ for _, v := range s {
+ n += SizeVarint(uint64(v))
+ }
+ b = appendVarint(b, uint64(n))
+ for _, v := range s {
+ b = appendVarint(b, uint64(v))
+ }
+ return b, nil
+}
+func appendVarint64Value(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
+ v := *ptr.toUint64()
+ b = appendVarint(b, wiretag)
+ b = appendVarint(b, v)
+ return b, nil
+}
+func appendVarint64ValueNoZero(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
+ v := *ptr.toUint64()
+ if v == 0 {
+ return b, nil
+ }
+ b = appendVarint(b, wiretag)
+ b = appendVarint(b, v)
+ return b, nil
+}
+func appendVarint64Ptr(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
+ p := *ptr.toUint64Ptr()
+ if p == nil {
+ return b, nil
+ }
+ b = appendVarint(b, wiretag)
+ b = appendVarint(b, *p)
+ return b, nil
+}
+func appendVarint64Slice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
+ s := *ptr.toUint64Slice()
+ for _, v := range s {
+ b = appendVarint(b, wiretag)
+ b = appendVarint(b, v)
+ }
+ return b, nil
+}
+func appendVarint64PackedSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
+ s := *ptr.toUint64Slice()
+ if len(s) == 0 {
+ return b, nil
+ }
+ b = appendVarint(b, wiretag&^7|WireBytes)
+ // compute size
+ n := 0
+ for _, v := range s {
+ n += SizeVarint(v)
+ }
+ b = appendVarint(b, uint64(n))
+ for _, v := range s {
+ b = appendVarint(b, v)
+ }
+ return b, nil
+}
+func appendVarintS64Value(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
+ v := *ptr.toInt64()
+ b = appendVarint(b, wiretag)
+ b = appendVarint(b, uint64(v))
+ return b, nil
+}
+func appendVarintS64ValueNoZero(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
+ v := *ptr.toInt64()
+ if v == 0 {
+ return b, nil
+ }
+ b = appendVarint(b, wiretag)
+ b = appendVarint(b, uint64(v))
+ return b, nil
+}
+func appendVarintS64Ptr(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
+ p := *ptr.toInt64Ptr()
+ if p == nil {
+ return b, nil
+ }
+ b = appendVarint(b, wiretag)
+ b = appendVarint(b, uint64(*p))
+ return b, nil
+}
+func appendVarintS64Slice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
+ s := *ptr.toInt64Slice()
+ for _, v := range s {
+ b = appendVarint(b, wiretag)
+ b = appendVarint(b, uint64(v))
+ }
+ return b, nil
+}
+func appendVarintS64PackedSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
+ s := *ptr.toInt64Slice()
+ if len(s) == 0 {
+ return b, nil
+ }
+ b = appendVarint(b, wiretag&^7|WireBytes)
+ // compute size
+ n := 0
+ for _, v := range s {
+ n += SizeVarint(uint64(v))
+ }
+ b = appendVarint(b, uint64(n))
+ for _, v := range s {
+ b = appendVarint(b, uint64(v))
+ }
+ return b, nil
+}
+func appendZigzag32Value(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
+ v := *ptr.toInt32()
+ b = appendVarint(b, wiretag)
+ b = appendVarint(b, uint64((uint32(v)<<1)^uint32((int32(v)>>31))))
+ return b, nil
+}
+func appendZigzag32ValueNoZero(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
+ v := *ptr.toInt32()
+ if v == 0 {
+ return b, nil
+ }
+ b = appendVarint(b, wiretag)
+ b = appendVarint(b, uint64((uint32(v)<<1)^uint32((int32(v)>>31))))
+ return b, nil
+}
+func appendZigzag32Ptr(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
+ p := ptr.getInt32Ptr()
+ if p == nil {
+ return b, nil
+ }
+ b = appendVarint(b, wiretag)
+ v := *p
+ b = appendVarint(b, uint64((uint32(v)<<1)^uint32((int32(v)>>31))))
+ return b, nil
+}
+func appendZigzag32Slice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
+ s := ptr.getInt32Slice()
+ for _, v := range s {
+ b = appendVarint(b, wiretag)
+ b = appendVarint(b, uint64((uint32(v)<<1)^uint32((int32(v)>>31))))
+ }
+ return b, nil
+}
+func appendZigzag32PackedSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
+ s := ptr.getInt32Slice()
+ if len(s) == 0 {
+ return b, nil
+ }
+ b = appendVarint(b, wiretag&^7|WireBytes)
+ // compute size
+ n := 0
+ for _, v := range s {
+ n += SizeVarint(uint64((uint32(v) << 1) ^ uint32((int32(v) >> 31))))
+ }
+ b = appendVarint(b, uint64(n))
+ for _, v := range s {
+ b = appendVarint(b, uint64((uint32(v)<<1)^uint32((int32(v)>>31))))
+ }
+ return b, nil
+}
+func appendZigzag64Value(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
+ v := *ptr.toInt64()
+ b = appendVarint(b, wiretag)
+ b = appendVarint(b, uint64(v<<1)^uint64((int64(v)>>63)))
+ return b, nil
+}
+func appendZigzag64ValueNoZero(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
+ v := *ptr.toInt64()
+ if v == 0 {
+ return b, nil
+ }
+ b = appendVarint(b, wiretag)
+ b = appendVarint(b, uint64(v<<1)^uint64((int64(v)>>63)))
+ return b, nil
+}
+func appendZigzag64Ptr(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
+ p := *ptr.toInt64Ptr()
+ if p == nil {
+ return b, nil
+ }
+ b = appendVarint(b, wiretag)
+ v := *p
+ b = appendVarint(b, uint64(v<<1)^uint64((int64(v)>>63)))
+ return b, nil
+}
+func appendZigzag64Slice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
+ s := *ptr.toInt64Slice()
+ for _, v := range s {
+ b = appendVarint(b, wiretag)
+ b = appendVarint(b, uint64(v<<1)^uint64((int64(v)>>63)))
+ }
+ return b, nil
+}
+func appendZigzag64PackedSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
+ s := *ptr.toInt64Slice()
+ if len(s) == 0 {
+ return b, nil
+ }
+ b = appendVarint(b, wiretag&^7|WireBytes)
+ // compute size
+ n := 0
+ for _, v := range s {
+ n += SizeVarint(uint64(v<<1) ^ uint64((int64(v) >> 63)))
+ }
+ b = appendVarint(b, uint64(n))
+ for _, v := range s {
+ b = appendVarint(b, uint64(v<<1)^uint64((int64(v)>>63)))
+ }
+ return b, nil
+}
+func appendBoolValue(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
+ v := *ptr.toBool()
+ b = appendVarint(b, wiretag)
+ if v {
+ b = append(b, 1)
+ } else {
+ b = append(b, 0)
+ }
+ return b, nil
+}
+func appendBoolValueNoZero(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
+ v := *ptr.toBool()
+ if !v {
+ return b, nil
+ }
+ b = appendVarint(b, wiretag)
+ b = append(b, 1)
+ return b, nil
+}
+
+func appendBoolPtr(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
+ p := *ptr.toBoolPtr()
+ if p == nil {
+ return b, nil
+ }
+ b = appendVarint(b, wiretag)
+ if *p {
+ b = append(b, 1)
+ } else {
+ b = append(b, 0)
+ }
+ return b, nil
+}
+func appendBoolSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
+ s := *ptr.toBoolSlice()
+ for _, v := range s {
+ b = appendVarint(b, wiretag)
+ if v {
+ b = append(b, 1)
+ } else {
+ b = append(b, 0)
+ }
+ }
+ return b, nil
+}
+func appendBoolPackedSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
+ s := *ptr.toBoolSlice()
+ if len(s) == 0 {
+ return b, nil
+ }
+ b = appendVarint(b, wiretag&^7|WireBytes)
+ b = appendVarint(b, uint64(len(s)))
+ for _, v := range s {
+ if v {
+ b = append(b, 1)
+ } else {
+ b = append(b, 0)
+ }
+ }
+ return b, nil
+}
+func appendStringValue(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
+ v := *ptr.toString()
+ b = appendVarint(b, wiretag)
+ b = appendVarint(b, uint64(len(v)))
+ b = append(b, v...)
+ return b, nil
+}
+func appendStringValueNoZero(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
+ v := *ptr.toString()
+ if v == "" {
+ return b, nil
+ }
+ b = appendVarint(b, wiretag)
+ b = appendVarint(b, uint64(len(v)))
+ b = append(b, v...)
+ return b, nil
+}
+func appendStringPtr(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
+ p := *ptr.toStringPtr()
+ if p == nil {
+ return b, nil
+ }
+ v := *p
+ b = appendVarint(b, wiretag)
+ b = appendVarint(b, uint64(len(v)))
+ b = append(b, v...)
+ return b, nil
+}
+func appendStringSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
+ s := *ptr.toStringSlice()
+ for _, v := range s {
+ b = appendVarint(b, wiretag)
+ b = appendVarint(b, uint64(len(v)))
+ b = append(b, v...)
+ }
+ return b, nil
+}
+func appendUTF8StringValue(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
+ var invalidUTF8 bool
+ v := *ptr.toString()
+ if !utf8.ValidString(v) {
+ invalidUTF8 = true
+ }
+ b = appendVarint(b, wiretag)
+ b = appendVarint(b, uint64(len(v)))
+ b = append(b, v...)
+ if invalidUTF8 {
+ return b, errInvalidUTF8
+ }
+ return b, nil
+}
+func appendUTF8StringValueNoZero(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
+ var invalidUTF8 bool
+ v := *ptr.toString()
+ if v == "" {
+ return b, nil
+ }
+ if !utf8.ValidString(v) {
+ invalidUTF8 = true
+ }
+ b = appendVarint(b, wiretag)
+ b = appendVarint(b, uint64(len(v)))
+ b = append(b, v...)
+ if invalidUTF8 {
+ return b, errInvalidUTF8
+ }
+ return b, nil
+}
+func appendUTF8StringPtr(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
+ var invalidUTF8 bool
+ p := *ptr.toStringPtr()
+ if p == nil {
+ return b, nil
+ }
+ v := *p
+ if !utf8.ValidString(v) {
+ invalidUTF8 = true
+ }
+ b = appendVarint(b, wiretag)
+ b = appendVarint(b, uint64(len(v)))
+ b = append(b, v...)
+ if invalidUTF8 {
+ return b, errInvalidUTF8
+ }
+ return b, nil
+}
+func appendUTF8StringSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
+ var invalidUTF8 bool
+ s := *ptr.toStringSlice()
+ for _, v := range s {
+ if !utf8.ValidString(v) {
+ invalidUTF8 = true
+ }
+ b = appendVarint(b, wiretag)
+ b = appendVarint(b, uint64(len(v)))
+ b = append(b, v...)
+ }
+ if invalidUTF8 {
+ return b, errInvalidUTF8
+ }
+ return b, nil
+}
+func appendBytes(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
+ v := *ptr.toBytes()
+ if v == nil {
+ return b, nil
+ }
+ b = appendVarint(b, wiretag)
+ b = appendVarint(b, uint64(len(v)))
+ b = append(b, v...)
+ return b, nil
+}
+func appendBytes3(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
+ v := *ptr.toBytes()
+ if len(v) == 0 {
+ return b, nil
+ }
+ b = appendVarint(b, wiretag)
+ b = appendVarint(b, uint64(len(v)))
+ b = append(b, v...)
+ return b, nil
+}
+func appendBytesOneof(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
+ v := *ptr.toBytes()
+ b = appendVarint(b, wiretag)
+ b = appendVarint(b, uint64(len(v)))
+ b = append(b, v...)
+ return b, nil
+}
+func appendBytesSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
+ s := *ptr.toBytesSlice()
+ for _, v := range s {
+ b = appendVarint(b, wiretag)
+ b = appendVarint(b, uint64(len(v)))
+ b = append(b, v...)
+ }
+ return b, nil
+}
+
+// makeGroupMarshaler returns the sizer and marshaler for a group.
+// u is the marshal info of the underlying message.
+func makeGroupMarshaler(u *marshalInfo) (sizer, marshaler) {
+ return func(ptr pointer, tagsize int) int {
+ p := ptr.getPointer()
+ if p.isNil() {
+ return 0
+ }
+ return u.size(p) + 2*tagsize
+ },
+ func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) {
+ p := ptr.getPointer()
+ if p.isNil() {
+ return b, nil
+ }
+ var err error
+ b = appendVarint(b, wiretag) // start group
+ b, err = u.marshal(b, p, deterministic)
+ b = appendVarint(b, wiretag+(WireEndGroup-WireStartGroup)) // end group
+ return b, err
+ }
+}
+
+// makeGroupSliceMarshaler returns the sizer and marshaler for a group slice.
+// u is the marshal info of the underlying message.
+func makeGroupSliceMarshaler(u *marshalInfo) (sizer, marshaler) {
+ return func(ptr pointer, tagsize int) int {
+ s := ptr.getPointerSlice()
+ n := 0
+ for _, v := range s {
+ if v.isNil() {
+ continue
+ }
+ n += u.size(v) + 2*tagsize
+ }
+ return n
+ },
+ func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) {
+ s := ptr.getPointerSlice()
+ var err error
+ var nerr nonFatal
+ for _, v := range s {
+ if v.isNil() {
+ return b, errRepeatedHasNil
+ }
+ b = appendVarint(b, wiretag) // start group
+ b, err = u.marshal(b, v, deterministic)
+ b = appendVarint(b, wiretag+(WireEndGroup-WireStartGroup)) // end group
+ if !nerr.Merge(err) {
+ if err == ErrNil {
+ err = errRepeatedHasNil
+ }
+ return b, err
+ }
+ }
+ return b, nerr.E
+ }
+}
+
+// makeMessageMarshaler returns the sizer and marshaler for a message field.
+// u is the marshal info of the message.
+func makeMessageMarshaler(u *marshalInfo) (sizer, marshaler) {
+ return func(ptr pointer, tagsize int) int {
+ p := ptr.getPointer()
+ if p.isNil() {
+ return 0
+ }
+ siz := u.size(p)
+ return siz + SizeVarint(uint64(siz)) + tagsize
+ },
+ func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) {
+ p := ptr.getPointer()
+ if p.isNil() {
+ return b, nil
+ }
+ b = appendVarint(b, wiretag)
+ siz := u.cachedsize(p)
+ b = appendVarint(b, uint64(siz))
+ return u.marshal(b, p, deterministic)
+ }
+}
+
+// makeMessageSliceMarshaler returns the sizer and marshaler for a message slice.
+// u is the marshal info of the message.
+func makeMessageSliceMarshaler(u *marshalInfo) (sizer, marshaler) {
+ return func(ptr pointer, tagsize int) int {
+ s := ptr.getPointerSlice()
+ n := 0
+ for _, v := range s {
+ if v.isNil() {
+ continue
+ }
+ siz := u.size(v)
+ n += siz + SizeVarint(uint64(siz)) + tagsize
+ }
+ return n
+ },
+ func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) {
+ s := ptr.getPointerSlice()
+ var err error
+ var nerr nonFatal
+ for _, v := range s {
+ if v.isNil() {
+ return b, errRepeatedHasNil
+ }
+ b = appendVarint(b, wiretag)
+ siz := u.cachedsize(v)
+ b = appendVarint(b, uint64(siz))
+ b, err = u.marshal(b, v, deterministic)
+
+ if !nerr.Merge(err) {
+ if err == ErrNil {
+ err = errRepeatedHasNil
+ }
+ return b, err
+ }
+ }
+ return b, nerr.E
+ }
+}
+
+// makeMapMarshaler returns the sizer and marshaler for a map field.
+// f is the pointer to the reflect data structure of the field.
+func makeMapMarshaler(f *reflect.StructField) (sizer, marshaler) {
+ // figure out key and value type
+ t := f.Type
+ keyType := t.Key()
+ valType := t.Elem()
+ keyTags := strings.Split(f.Tag.Get("protobuf_key"), ",")
+ valTags := strings.Split(f.Tag.Get("protobuf_val"), ",")
+ keySizer, keyMarshaler := typeMarshaler(keyType, keyTags, false, false) // don't omit zero value in map
+ valSizer, valMarshaler := typeMarshaler(valType, valTags, false, false) // don't omit zero value in map
+ keyWireTag := 1<<3 | wiretype(keyTags[0])
+ valWireTag := 2<<3 | wiretype(valTags[0])
+
+ // We create an interface to get the addresses of the map key and value.
+ // If value is pointer-typed, the interface is a direct interface, the
+ // idata itself is the value. Otherwise, the idata is the pointer to the
+ // value.
+ // Key cannot be pointer-typed.
+ valIsPtr := valType.Kind() == reflect.Ptr
+
+ // If value is a message with nested maps, calling
+ // valSizer in marshal may be quadratic. We should use
+ // cached version in marshal (but not in size).
+ // If value is not message type, we don't have size cache,
+ // but it cannot be nested either. Just use valSizer.
+ valCachedSizer := valSizer
+ if valIsPtr && valType.Elem().Kind() == reflect.Struct {
+ u := getMarshalInfo(valType.Elem())
+ valCachedSizer = func(ptr pointer, tagsize int) int {
+ // Same as message sizer, but use cache.
+ p := ptr.getPointer()
+ if p.isNil() {
+ return 0
+ }
+ siz := u.cachedsize(p)
+ return siz + SizeVarint(uint64(siz)) + tagsize
+ }
+ }
+ return func(ptr pointer, tagsize int) int {
+ m := ptr.asPointerTo(t).Elem() // the map
+ n := 0
+ for _, k := range m.MapKeys() {
+ ki := k.Interface()
+ vi := m.MapIndex(k).Interface()
+ kaddr := toAddrPointer(&ki, false, false) // pointer to key
+ vaddr := toAddrPointer(&vi, valIsPtr, false) // pointer to value
+ siz := keySizer(kaddr, 1) + valSizer(vaddr, 1) // tag of key = 1 (size=1), tag of val = 2 (size=1)
+ n += siz + SizeVarint(uint64(siz)) + tagsize
+ }
+ return n
+ },
+ func(b []byte, ptr pointer, tag uint64, deterministic bool) ([]byte, error) {
+ m := ptr.asPointerTo(t).Elem() // the map
+ var err error
+ keys := m.MapKeys()
+ if len(keys) > 1 && deterministic {
+ sort.Sort(mapKeys(keys))
+ }
+
+ var nerr nonFatal
+ for _, k := range keys {
+ ki := k.Interface()
+ vi := m.MapIndex(k).Interface()
+ kaddr := toAddrPointer(&ki, false, false) // pointer to key
+ vaddr := toAddrPointer(&vi, valIsPtr, false) // pointer to value
+ b = appendVarint(b, tag)
+ siz := keySizer(kaddr, 1) + valCachedSizer(vaddr, 1) // tag of key = 1 (size=1), tag of val = 2 (size=1)
+ b = appendVarint(b, uint64(siz))
+ b, err = keyMarshaler(b, kaddr, keyWireTag, deterministic)
+ if !nerr.Merge(err) {
+ return b, err
+ }
+ b, err = valMarshaler(b, vaddr, valWireTag, deterministic)
+ if err != ErrNil && !nerr.Merge(err) { // allow nil value in map
+ return b, err
+ }
+ }
+ return b, nerr.E
+ }
+}
+
+// makeOneOfMarshaler returns the sizer and marshaler for a oneof field.
+// fi is the marshal info of the field.
+// f is the pointer to the reflect data structure of the field.
+func makeOneOfMarshaler(fi *marshalFieldInfo, f *reflect.StructField) (sizer, marshaler) {
+ // Oneof field is an interface. We need to get the actual data type on the fly.
+ t := f.Type
+ return func(ptr pointer, _ int) int {
+ p := ptr.getInterfacePointer()
+ if p.isNil() {
+ return 0
+ }
+ v := ptr.asPointerTo(t).Elem().Elem().Elem() // *interface -> interface -> *struct -> struct
+ telem := v.Type()
+ e := fi.oneofElems[telem]
+ return e.sizer(p, e.tagsize)
+ },
+ func(b []byte, ptr pointer, _ uint64, deterministic bool) ([]byte, error) {
+ p := ptr.getInterfacePointer()
+ if p.isNil() {
+ return b, nil
+ }
+ v := ptr.asPointerTo(t).Elem().Elem().Elem() // *interface -> interface -> *struct -> struct
+ telem := v.Type()
+ if telem.Field(0).Type.Kind() == reflect.Ptr && p.getPointer().isNil() {
+ return b, errOneofHasNil
+ }
+ e := fi.oneofElems[telem]
+ return e.marshaler(b, p, e.wiretag, deterministic)
+ }
+}
+
+// sizeExtensions computes the size of encoded data for a XXX_InternalExtensions field.
+func (u *marshalInfo) sizeExtensions(ext *XXX_InternalExtensions) int {
+ m, mu := ext.extensionsRead()
+ if m == nil {
+ return 0
+ }
+ mu.Lock()
+
+ n := 0
+ for _, e := range m {
+ if e.value == nil || e.desc == nil {
+ // Extension is only in its encoded form.
+ n += len(e.enc)
+ continue
+ }
+
+ // We don't skip extensions that have an encoded form set,
+ // because the extension value may have been mutated after
+ // the last time this function was called.
+ ei := u.getExtElemInfo(e.desc)
+ v := e.value
+ p := toAddrPointer(&v, ei.isptr, ei.deref)
+ n += ei.sizer(p, ei.tagsize)
+ }
+ mu.Unlock()
+ return n
+}
+
+// appendExtensions marshals a XXX_InternalExtensions field to the end of byte slice b.
+func (u *marshalInfo) appendExtensions(b []byte, ext *XXX_InternalExtensions, deterministic bool) ([]byte, error) {
+ m, mu := ext.extensionsRead()
+ if m == nil {
+ return b, nil
+ }
+ mu.Lock()
+ defer mu.Unlock()
+
+ var err error
+ var nerr nonFatal
+
+ // Fast-path for common cases: zero or one extensions.
+ // Don't bother sorting the keys.
+ if len(m) <= 1 {
+ for _, e := range m {
+ if e.value == nil || e.desc == nil {
+ // Extension is only in its encoded form.
+ b = append(b, e.enc...)
+ continue
+ }
+
+ // We don't skip extensions that have an encoded form set,
+ // because the extension value may have been mutated after
+ // the last time this function was called.
+
+ ei := u.getExtElemInfo(e.desc)
+ v := e.value
+ p := toAddrPointer(&v, ei.isptr, ei.deref)
+ b, err = ei.marshaler(b, p, ei.wiretag, deterministic)
+ if !nerr.Merge(err) {
+ return b, err
+ }
+ }
+ return b, nerr.E
+ }
+
+ // Sort the keys to provide a deterministic encoding.
+ // Not sure this is required, but the old code does it.
+ keys := make([]int, 0, len(m))
+ for k := range m {
+ keys = append(keys, int(k))
+ }
+ sort.Ints(keys)
+
+ for _, k := range keys {
+ e := m[int32(k)]
+ if e.value == nil || e.desc == nil {
+ // Extension is only in its encoded form.
+ b = append(b, e.enc...)
+ continue
+ }
+
+ // We don't skip extensions that have an encoded form set,
+ // because the extension value may have been mutated after
+ // the last time this function was called.
+
+ ei := u.getExtElemInfo(e.desc)
+ v := e.value
+ p := toAddrPointer(&v, ei.isptr, ei.deref)
+ b, err = ei.marshaler(b, p, ei.wiretag, deterministic)
+ if !nerr.Merge(err) {
+ return b, err
+ }
+ }
+ return b, nerr.E
+}
+
+// message set format is:
+// message MessageSet {
+// repeated group Item = 1 {
+// required int32 type_id = 2;
+// required string message = 3;
+// };
+// }
+
+// sizeMessageSet computes the size of encoded data for a XXX_InternalExtensions field
+// in message set format (above).
+func (u *marshalInfo) sizeMessageSet(ext *XXX_InternalExtensions) int {
+ m, mu := ext.extensionsRead()
+ if m == nil {
+ return 0
+ }
+ mu.Lock()
+
+ n := 0
+ for id, e := range m {
+ n += 2 // start group, end group. tag = 1 (size=1)
+ n += SizeVarint(uint64(id)) + 1 // type_id, tag = 2 (size=1)
+
+ if e.value == nil || e.desc == nil {
+ // Extension is only in its encoded form.
+ msgWithLen := skipVarint(e.enc) // skip old tag, but leave the length varint
+ siz := len(msgWithLen)
+ n += siz + 1 // message, tag = 3 (size=1)
+ continue
+ }
+
+ // We don't skip extensions that have an encoded form set,
+ // because the extension value may have been mutated after
+ // the last time this function was called.
+
+ ei := u.getExtElemInfo(e.desc)
+ v := e.value
+ p := toAddrPointer(&v, ei.isptr, ei.deref)
+ n += ei.sizer(p, 1) // message, tag = 3 (size=1)
+ }
+ mu.Unlock()
+ return n
+}
+
+// appendMessageSet marshals a XXX_InternalExtensions field in message set format (above)
+// to the end of byte slice b.
+func (u *marshalInfo) appendMessageSet(b []byte, ext *XXX_InternalExtensions, deterministic bool) ([]byte, error) {
+ m, mu := ext.extensionsRead()
+ if m == nil {
+ return b, nil
+ }
+ mu.Lock()
+ defer mu.Unlock()
+
+ var err error
+ var nerr nonFatal
+
+ // Fast-path for common cases: zero or one extensions.
+ // Don't bother sorting the keys.
+ if len(m) <= 1 {
+ for id, e := range m {
+ b = append(b, 1<<3|WireStartGroup)
+ b = append(b, 2<<3|WireVarint)
+ b = appendVarint(b, uint64(id))
+
+ if e.value == nil || e.desc == nil {
+ // Extension is only in its encoded form.
+ msgWithLen := skipVarint(e.enc) // skip old tag, but leave the length varint
+ b = append(b, 3<<3|WireBytes)
+ b = append(b, msgWithLen...)
+ b = append(b, 1<<3|WireEndGroup)
+ continue
+ }
+
+ // We don't skip extensions that have an encoded form set,
+ // because the extension value may have been mutated after
+ // the last time this function was called.
+
+ ei := u.getExtElemInfo(e.desc)
+ v := e.value
+ p := toAddrPointer(&v, ei.isptr, ei.deref)
+ b, err = ei.marshaler(b, p, 3<<3|WireBytes, deterministic)
+ if !nerr.Merge(err) {
+ return b, err
+ }
+ b = append(b, 1<<3|WireEndGroup)
+ }
+ return b, nerr.E
+ }
+
+ // Sort the keys to provide a deterministic encoding.
+ keys := make([]int, 0, len(m))
+ for k := range m {
+ keys = append(keys, int(k))
+ }
+ sort.Ints(keys)
+
+ for _, id := range keys {
+ e := m[int32(id)]
+ b = append(b, 1<<3|WireStartGroup)
+ b = append(b, 2<<3|WireVarint)
+ b = appendVarint(b, uint64(id))
+
+ if e.value == nil || e.desc == nil {
+ // Extension is only in its encoded form.
+ msgWithLen := skipVarint(e.enc) // skip old tag, but leave the length varint
+ b = append(b, 3<<3|WireBytes)
+ b = append(b, msgWithLen...)
+ b = append(b, 1<<3|WireEndGroup)
+ continue
+ }
+
+ // We don't skip extensions that have an encoded form set,
+ // because the extension value may have been mutated after
+ // the last time this function was called.
+
+ ei := u.getExtElemInfo(e.desc)
+ v := e.value
+ p := toAddrPointer(&v, ei.isptr, ei.deref)
+ b, err = ei.marshaler(b, p, 3<<3|WireBytes, deterministic)
+ b = append(b, 1<<3|WireEndGroup)
+ if !nerr.Merge(err) {
+ return b, err
+ }
+ }
+ return b, nerr.E
+}
+
+// sizeV1Extensions computes the size of encoded data for a V1-API extension field.
+func (u *marshalInfo) sizeV1Extensions(m map[int32]Extension) int {
+ if m == nil {
+ return 0
+ }
+
+ n := 0
+ for _, e := range m {
+ if e.value == nil || e.desc == nil {
+ // Extension is only in its encoded form.
+ n += len(e.enc)
+ continue
+ }
+
+ // We don't skip extensions that have an encoded form set,
+ // because the extension value may have been mutated after
+ // the last time this function was called.
+
+ ei := u.getExtElemInfo(e.desc)
+ v := e.value
+ p := toAddrPointer(&v, ei.isptr, ei.deref)
+ n += ei.sizer(p, ei.tagsize)
+ }
+ return n
+}
+
+// appendV1Extensions marshals a V1-API extension field to the end of byte slice b.
+func (u *marshalInfo) appendV1Extensions(b []byte, m map[int32]Extension, deterministic bool) ([]byte, error) {
+ if m == nil {
+ return b, nil
+ }
+
+ // Sort the keys to provide a deterministic encoding.
+ keys := make([]int, 0, len(m))
+ for k := range m {
+ keys = append(keys, int(k))
+ }
+ sort.Ints(keys)
+
+ var err error
+ var nerr nonFatal
+ for _, k := range keys {
+ e := m[int32(k)]
+ if e.value == nil || e.desc == nil {
+ // Extension is only in its encoded form.
+ b = append(b, e.enc...)
+ continue
+ }
+
+ // We don't skip extensions that have an encoded form set,
+ // because the extension value may have been mutated after
+ // the last time this function was called.
+
+ ei := u.getExtElemInfo(e.desc)
+ v := e.value
+ p := toAddrPointer(&v, ei.isptr, ei.deref)
+ b, err = ei.marshaler(b, p, ei.wiretag, deterministic)
+ if !nerr.Merge(err) {
+ return b, err
+ }
+ }
+ return b, nerr.E
+}
+
+// newMarshaler is the interface representing objects that can marshal themselves.
+//
+// This exists to support protoc-gen-go generated messages.
+// The proto package will stop type-asserting to this interface in the future.
+//
+// DO NOT DEPEND ON THIS.
+type newMarshaler interface {
+ XXX_Size() int
+ XXX_Marshal(b []byte, deterministic bool) ([]byte, error)
+}
+
+// Size returns the encoded size of a protocol buffer message.
+// This is the main entry point.
+func Size(pb Message) int {
+ if m, ok := pb.(newMarshaler); ok {
+ return m.XXX_Size()
+ }
+ if m, ok := pb.(Marshaler); ok {
+ // If the message can marshal itself, let it do it, for compatibility.
+ // NOTE: This is not efficient.
+ b, _ := m.Marshal()
+ return len(b)
+ }
+ // in case somehow we didn't generate the wrapper
+ if pb == nil {
+ return 0
+ }
+ var info InternalMessageInfo
+ return info.Size(pb)
+}
+
+// Marshal takes a protocol buffer message
+// and encodes it into the wire format, returning the data.
+// This is the main entry point.
+func Marshal(pb Message) ([]byte, error) {
+ if m, ok := pb.(newMarshaler); ok {
+ siz := m.XXX_Size()
+ b := make([]byte, 0, siz)
+ return m.XXX_Marshal(b, false)
+ }
+ if m, ok := pb.(Marshaler); ok {
+ // If the message can marshal itself, let it do it, for compatibility.
+ // NOTE: This is not efficient.
+ return m.Marshal()
+ }
+ // in case somehow we didn't generate the wrapper
+ if pb == nil {
+ return nil, ErrNil
+ }
+ var info InternalMessageInfo
+ siz := info.Size(pb)
+ b := make([]byte, 0, siz)
+ return info.Marshal(b, pb, false)
+}
+
+// Marshal takes a protocol buffer message
+// and encodes it into the wire format, writing the result to the
+// Buffer.
+// This is an alternative entry point. It is not necessary to use
+// a Buffer for most applications.
+func (p *Buffer) Marshal(pb Message) error {
+ var err error
+ if m, ok := pb.(newMarshaler); ok {
+ siz := m.XXX_Size()
+ p.grow(siz) // make sure buf has enough capacity
+ p.buf, err = m.XXX_Marshal(p.buf, p.deterministic)
+ return err
+ }
+ if m, ok := pb.(Marshaler); ok {
+ // If the message can marshal itself, let it do it, for compatibility.
+ // NOTE: This is not efficient.
+ b, err := m.Marshal()
+ p.buf = append(p.buf, b...)
+ return err
+ }
+ // in case somehow we didn't generate the wrapper
+ if pb == nil {
+ return ErrNil
+ }
+ var info InternalMessageInfo
+ siz := info.Size(pb)
+ p.grow(siz) // make sure buf has enough capacity
+ p.buf, err = info.Marshal(p.buf, pb, p.deterministic)
+ return err
+}
+
+// grow grows the buffer's capacity, if necessary, to guarantee space for
+// another n bytes. After grow(n), at least n bytes can be written to the
+// buffer without another allocation.
+func (p *Buffer) grow(n int) {
+ need := len(p.buf) + n
+ if need <= cap(p.buf) {
+ return
+ }
+ newCap := len(p.buf) * 2
+ if newCap < need {
+ newCap = need
+ }
+ p.buf = append(make([]byte, 0, newCap), p.buf...)
+}
diff --git a/vendor/github.com/golang/protobuf/proto/table_merge.go b/vendor/github.com/golang/protobuf/proto/table_merge.go
new file mode 100644
index 0000000000000000000000000000000000000000..5525def6a5da89fee6a0528924cefdbc5ef987e1
--- /dev/null
+++ b/vendor/github.com/golang/protobuf/proto/table_merge.go
@@ -0,0 +1,654 @@
+// Go support for Protocol Buffers - Google's data interchange format
+//
+// Copyright 2016 The Go Authors. All rights reserved.
+// https://github.com/golang/protobuf
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package proto
+
+import (
+ "fmt"
+ "reflect"
+ "strings"
+ "sync"
+ "sync/atomic"
+)
+
+// Merge merges the src message into dst.
+// This assumes that dst and src of the same type and are non-nil.
+func (a *InternalMessageInfo) Merge(dst, src Message) {
+ mi := atomicLoadMergeInfo(&a.merge)
+ if mi == nil {
+ mi = getMergeInfo(reflect.TypeOf(dst).Elem())
+ atomicStoreMergeInfo(&a.merge, mi)
+ }
+ mi.merge(toPointer(&dst), toPointer(&src))
+}
+
+type mergeInfo struct {
+ typ reflect.Type
+
+ initialized int32 // 0: only typ is valid, 1: everything is valid
+ lock sync.Mutex
+
+ fields []mergeFieldInfo
+ unrecognized field // Offset of XXX_unrecognized
+}
+
+type mergeFieldInfo struct {
+ field field // Offset of field, guaranteed to be valid
+
+ // isPointer reports whether the value in the field is a pointer.
+ // This is true for the following situations:
+ // * Pointer to struct
+ // * Pointer to basic type (proto2 only)
+ // * Slice (first value in slice header is a pointer)
+ // * String (first value in string header is a pointer)
+ isPointer bool
+
+ // basicWidth reports the width of the field assuming that it is directly
+ // embedded in the struct (as is the case for basic types in proto3).
+ // The possible values are:
+ // 0: invalid
+ // 1: bool
+ // 4: int32, uint32, float32
+ // 8: int64, uint64, float64
+ basicWidth int
+
+ // Where dst and src are pointers to the types being merged.
+ merge func(dst, src pointer)
+}
+
+var (
+ mergeInfoMap = map[reflect.Type]*mergeInfo{}
+ mergeInfoLock sync.Mutex
+)
+
+func getMergeInfo(t reflect.Type) *mergeInfo {
+ mergeInfoLock.Lock()
+ defer mergeInfoLock.Unlock()
+ mi := mergeInfoMap[t]
+ if mi == nil {
+ mi = &mergeInfo{typ: t}
+ mergeInfoMap[t] = mi
+ }
+ return mi
+}
+
+// merge merges src into dst assuming they are both of type *mi.typ.
+func (mi *mergeInfo) merge(dst, src pointer) {
+ if dst.isNil() {
+ panic("proto: nil destination")
+ }
+ if src.isNil() {
+ return // Nothing to do.
+ }
+
+ if atomic.LoadInt32(&mi.initialized) == 0 {
+ mi.computeMergeInfo()
+ }
+
+ for _, fi := range mi.fields {
+ sfp := src.offset(fi.field)
+
+ // As an optimization, we can avoid the merge function call cost
+ // if we know for sure that the source will have no effect
+ // by checking if it is the zero value.
+ if unsafeAllowed {
+ if fi.isPointer && sfp.getPointer().isNil() { // Could be slice or string
+ continue
+ }
+ if fi.basicWidth > 0 {
+ switch {
+ case fi.basicWidth == 1 && !*sfp.toBool():
+ continue
+ case fi.basicWidth == 4 && *sfp.toUint32() == 0:
+ continue
+ case fi.basicWidth == 8 && *sfp.toUint64() == 0:
+ continue
+ }
+ }
+ }
+
+ dfp := dst.offset(fi.field)
+ fi.merge(dfp, sfp)
+ }
+
+ // TODO: Make this faster?
+ out := dst.asPointerTo(mi.typ).Elem()
+ in := src.asPointerTo(mi.typ).Elem()
+ if emIn, err := extendable(in.Addr().Interface()); err == nil {
+ emOut, _ := extendable(out.Addr().Interface())
+ mIn, muIn := emIn.extensionsRead()
+ if mIn != nil {
+ mOut := emOut.extensionsWrite()
+ muIn.Lock()
+ mergeExtension(mOut, mIn)
+ muIn.Unlock()
+ }
+ }
+
+ if mi.unrecognized.IsValid() {
+ if b := *src.offset(mi.unrecognized).toBytes(); len(b) > 0 {
+ *dst.offset(mi.unrecognized).toBytes() = append([]byte(nil), b...)
+ }
+ }
+}
+
+func (mi *mergeInfo) computeMergeInfo() {
+ mi.lock.Lock()
+ defer mi.lock.Unlock()
+ if mi.initialized != 0 {
+ return
+ }
+ t := mi.typ
+ n := t.NumField()
+
+ props := GetProperties(t)
+ for i := 0; i < n; i++ {
+ f := t.Field(i)
+ if strings.HasPrefix(f.Name, "XXX_") {
+ continue
+ }
+
+ mfi := mergeFieldInfo{field: toField(&f)}
+ tf := f.Type
+
+ // As an optimization, we can avoid the merge function call cost
+ // if we know for sure that the source will have no effect
+ // by checking if it is the zero value.
+ if unsafeAllowed {
+ switch tf.Kind() {
+ case reflect.Ptr, reflect.Slice, reflect.String:
+ // As a special case, we assume slices and strings are pointers
+ // since we know that the first field in the SliceSlice or
+ // StringHeader is a data pointer.
+ mfi.isPointer = true
+ case reflect.Bool:
+ mfi.basicWidth = 1
+ case reflect.Int32, reflect.Uint32, reflect.Float32:
+ mfi.basicWidth = 4
+ case reflect.Int64, reflect.Uint64, reflect.Float64:
+ mfi.basicWidth = 8
+ }
+ }
+
+ // Unwrap tf to get at its most basic type.
+ var isPointer, isSlice bool
+ if tf.Kind() == reflect.Slice && tf.Elem().Kind() != reflect.Uint8 {
+ isSlice = true
+ tf = tf.Elem()
+ }
+ if tf.Kind() == reflect.Ptr {
+ isPointer = true
+ tf = tf.Elem()
+ }
+ if isPointer && isSlice && tf.Kind() != reflect.Struct {
+ panic("both pointer and slice for basic type in " + tf.Name())
+ }
+
+ switch tf.Kind() {
+ case reflect.Int32:
+ switch {
+ case isSlice: // E.g., []int32
+ mfi.merge = func(dst, src pointer) {
+ // NOTE: toInt32Slice is not defined (see pointer_reflect.go).
+ /*
+ sfsp := src.toInt32Slice()
+ if *sfsp != nil {
+ dfsp := dst.toInt32Slice()
+ *dfsp = append(*dfsp, *sfsp...)
+ if *dfsp == nil {
+ *dfsp = []int64{}
+ }
+ }
+ */
+ sfs := src.getInt32Slice()
+ if sfs != nil {
+ dfs := dst.getInt32Slice()
+ dfs = append(dfs, sfs...)
+ if dfs == nil {
+ dfs = []int32{}
+ }
+ dst.setInt32Slice(dfs)
+ }
+ }
+ case isPointer: // E.g., *int32
+ mfi.merge = func(dst, src pointer) {
+ // NOTE: toInt32Ptr is not defined (see pointer_reflect.go).
+ /*
+ sfpp := src.toInt32Ptr()
+ if *sfpp != nil {
+ dfpp := dst.toInt32Ptr()
+ if *dfpp == nil {
+ *dfpp = Int32(**sfpp)
+ } else {
+ **dfpp = **sfpp
+ }
+ }
+ */
+ sfp := src.getInt32Ptr()
+ if sfp != nil {
+ dfp := dst.getInt32Ptr()
+ if dfp == nil {
+ dst.setInt32Ptr(*sfp)
+ } else {
+ *dfp = *sfp
+ }
+ }
+ }
+ default: // E.g., int32
+ mfi.merge = func(dst, src pointer) {
+ if v := *src.toInt32(); v != 0 {
+ *dst.toInt32() = v
+ }
+ }
+ }
+ case reflect.Int64:
+ switch {
+ case isSlice: // E.g., []int64
+ mfi.merge = func(dst, src pointer) {
+ sfsp := src.toInt64Slice()
+ if *sfsp != nil {
+ dfsp := dst.toInt64Slice()
+ *dfsp = append(*dfsp, *sfsp...)
+ if *dfsp == nil {
+ *dfsp = []int64{}
+ }
+ }
+ }
+ case isPointer: // E.g., *int64
+ mfi.merge = func(dst, src pointer) {
+ sfpp := src.toInt64Ptr()
+ if *sfpp != nil {
+ dfpp := dst.toInt64Ptr()
+ if *dfpp == nil {
+ *dfpp = Int64(**sfpp)
+ } else {
+ **dfpp = **sfpp
+ }
+ }
+ }
+ default: // E.g., int64
+ mfi.merge = func(dst, src pointer) {
+ if v := *src.toInt64(); v != 0 {
+ *dst.toInt64() = v
+ }
+ }
+ }
+ case reflect.Uint32:
+ switch {
+ case isSlice: // E.g., []uint32
+ mfi.merge = func(dst, src pointer) {
+ sfsp := src.toUint32Slice()
+ if *sfsp != nil {
+ dfsp := dst.toUint32Slice()
+ *dfsp = append(*dfsp, *sfsp...)
+ if *dfsp == nil {
+ *dfsp = []uint32{}
+ }
+ }
+ }
+ case isPointer: // E.g., *uint32
+ mfi.merge = func(dst, src pointer) {
+ sfpp := src.toUint32Ptr()
+ if *sfpp != nil {
+ dfpp := dst.toUint32Ptr()
+ if *dfpp == nil {
+ *dfpp = Uint32(**sfpp)
+ } else {
+ **dfpp = **sfpp
+ }
+ }
+ }
+ default: // E.g., uint32
+ mfi.merge = func(dst, src pointer) {
+ if v := *src.toUint32(); v != 0 {
+ *dst.toUint32() = v
+ }
+ }
+ }
+ case reflect.Uint64:
+ switch {
+ case isSlice: // E.g., []uint64
+ mfi.merge = func(dst, src pointer) {
+ sfsp := src.toUint64Slice()
+ if *sfsp != nil {
+ dfsp := dst.toUint64Slice()
+ *dfsp = append(*dfsp, *sfsp...)
+ if *dfsp == nil {
+ *dfsp = []uint64{}
+ }
+ }
+ }
+ case isPointer: // E.g., *uint64
+ mfi.merge = func(dst, src pointer) {
+ sfpp := src.toUint64Ptr()
+ if *sfpp != nil {
+ dfpp := dst.toUint64Ptr()
+ if *dfpp == nil {
+ *dfpp = Uint64(**sfpp)
+ } else {
+ **dfpp = **sfpp
+ }
+ }
+ }
+ default: // E.g., uint64
+ mfi.merge = func(dst, src pointer) {
+ if v := *src.toUint64(); v != 0 {
+ *dst.toUint64() = v
+ }
+ }
+ }
+ case reflect.Float32:
+ switch {
+ case isSlice: // E.g., []float32
+ mfi.merge = func(dst, src pointer) {
+ sfsp := src.toFloat32Slice()
+ if *sfsp != nil {
+ dfsp := dst.toFloat32Slice()
+ *dfsp = append(*dfsp, *sfsp...)
+ if *dfsp == nil {
+ *dfsp = []float32{}
+ }
+ }
+ }
+ case isPointer: // E.g., *float32
+ mfi.merge = func(dst, src pointer) {
+ sfpp := src.toFloat32Ptr()
+ if *sfpp != nil {
+ dfpp := dst.toFloat32Ptr()
+ if *dfpp == nil {
+ *dfpp = Float32(**sfpp)
+ } else {
+ **dfpp = **sfpp
+ }
+ }
+ }
+ default: // E.g., float32
+ mfi.merge = func(dst, src pointer) {
+ if v := *src.toFloat32(); v != 0 {
+ *dst.toFloat32() = v
+ }
+ }
+ }
+ case reflect.Float64:
+ switch {
+ case isSlice: // E.g., []float64
+ mfi.merge = func(dst, src pointer) {
+ sfsp := src.toFloat64Slice()
+ if *sfsp != nil {
+ dfsp := dst.toFloat64Slice()
+ *dfsp = append(*dfsp, *sfsp...)
+ if *dfsp == nil {
+ *dfsp = []float64{}
+ }
+ }
+ }
+ case isPointer: // E.g., *float64
+ mfi.merge = func(dst, src pointer) {
+ sfpp := src.toFloat64Ptr()
+ if *sfpp != nil {
+ dfpp := dst.toFloat64Ptr()
+ if *dfpp == nil {
+ *dfpp = Float64(**sfpp)
+ } else {
+ **dfpp = **sfpp
+ }
+ }
+ }
+ default: // E.g., float64
+ mfi.merge = func(dst, src pointer) {
+ if v := *src.toFloat64(); v != 0 {
+ *dst.toFloat64() = v
+ }
+ }
+ }
+ case reflect.Bool:
+ switch {
+ case isSlice: // E.g., []bool
+ mfi.merge = func(dst, src pointer) {
+ sfsp := src.toBoolSlice()
+ if *sfsp != nil {
+ dfsp := dst.toBoolSlice()
+ *dfsp = append(*dfsp, *sfsp...)
+ if *dfsp == nil {
+ *dfsp = []bool{}
+ }
+ }
+ }
+ case isPointer: // E.g., *bool
+ mfi.merge = func(dst, src pointer) {
+ sfpp := src.toBoolPtr()
+ if *sfpp != nil {
+ dfpp := dst.toBoolPtr()
+ if *dfpp == nil {
+ *dfpp = Bool(**sfpp)
+ } else {
+ **dfpp = **sfpp
+ }
+ }
+ }
+ default: // E.g., bool
+ mfi.merge = func(dst, src pointer) {
+ if v := *src.toBool(); v {
+ *dst.toBool() = v
+ }
+ }
+ }
+ case reflect.String:
+ switch {
+ case isSlice: // E.g., []string
+ mfi.merge = func(dst, src pointer) {
+ sfsp := src.toStringSlice()
+ if *sfsp != nil {
+ dfsp := dst.toStringSlice()
+ *dfsp = append(*dfsp, *sfsp...)
+ if *dfsp == nil {
+ *dfsp = []string{}
+ }
+ }
+ }
+ case isPointer: // E.g., *string
+ mfi.merge = func(dst, src pointer) {
+ sfpp := src.toStringPtr()
+ if *sfpp != nil {
+ dfpp := dst.toStringPtr()
+ if *dfpp == nil {
+ *dfpp = String(**sfpp)
+ } else {
+ **dfpp = **sfpp
+ }
+ }
+ }
+ default: // E.g., string
+ mfi.merge = func(dst, src pointer) {
+ if v := *src.toString(); v != "" {
+ *dst.toString() = v
+ }
+ }
+ }
+ case reflect.Slice:
+ isProto3 := props.Prop[i].proto3
+ switch {
+ case isPointer:
+ panic("bad pointer in byte slice case in " + tf.Name())
+ case tf.Elem().Kind() != reflect.Uint8:
+ panic("bad element kind in byte slice case in " + tf.Name())
+ case isSlice: // E.g., [][]byte
+ mfi.merge = func(dst, src pointer) {
+ sbsp := src.toBytesSlice()
+ if *sbsp != nil {
+ dbsp := dst.toBytesSlice()
+ for _, sb := range *sbsp {
+ if sb == nil {
+ *dbsp = append(*dbsp, nil)
+ } else {
+ *dbsp = append(*dbsp, append([]byte{}, sb...))
+ }
+ }
+ if *dbsp == nil {
+ *dbsp = [][]byte{}
+ }
+ }
+ }
+ default: // E.g., []byte
+ mfi.merge = func(dst, src pointer) {
+ sbp := src.toBytes()
+ if *sbp != nil {
+ dbp := dst.toBytes()
+ if !isProto3 || len(*sbp) > 0 {
+ *dbp = append([]byte{}, *sbp...)
+ }
+ }
+ }
+ }
+ case reflect.Struct:
+ switch {
+ case !isPointer:
+ panic(fmt.Sprintf("message field %s without pointer", tf))
+ case isSlice: // E.g., []*pb.T
+ mi := getMergeInfo(tf)
+ mfi.merge = func(dst, src pointer) {
+ sps := src.getPointerSlice()
+ if sps != nil {
+ dps := dst.getPointerSlice()
+ for _, sp := range sps {
+ var dp pointer
+ if !sp.isNil() {
+ dp = valToPointer(reflect.New(tf))
+ mi.merge(dp, sp)
+ }
+ dps = append(dps, dp)
+ }
+ if dps == nil {
+ dps = []pointer{}
+ }
+ dst.setPointerSlice(dps)
+ }
+ }
+ default: // E.g., *pb.T
+ mi := getMergeInfo(tf)
+ mfi.merge = func(dst, src pointer) {
+ sp := src.getPointer()
+ if !sp.isNil() {
+ dp := dst.getPointer()
+ if dp.isNil() {
+ dp = valToPointer(reflect.New(tf))
+ dst.setPointer(dp)
+ }
+ mi.merge(dp, sp)
+ }
+ }
+ }
+ case reflect.Map:
+ switch {
+ case isPointer || isSlice:
+ panic("bad pointer or slice in map case in " + tf.Name())
+ default: // E.g., map[K]V
+ mfi.merge = func(dst, src pointer) {
+ sm := src.asPointerTo(tf).Elem()
+ if sm.Len() == 0 {
+ return
+ }
+ dm := dst.asPointerTo(tf).Elem()
+ if dm.IsNil() {
+ dm.Set(reflect.MakeMap(tf))
+ }
+
+ switch tf.Elem().Kind() {
+ case reflect.Ptr: // Proto struct (e.g., *T)
+ for _, key := range sm.MapKeys() {
+ val := sm.MapIndex(key)
+ val = reflect.ValueOf(Clone(val.Interface().(Message)))
+ dm.SetMapIndex(key, val)
+ }
+ case reflect.Slice: // E.g. Bytes type (e.g., []byte)
+ for _, key := range sm.MapKeys() {
+ val := sm.MapIndex(key)
+ val = reflect.ValueOf(append([]byte{}, val.Bytes()...))
+ dm.SetMapIndex(key, val)
+ }
+ default: // Basic type (e.g., string)
+ for _, key := range sm.MapKeys() {
+ val := sm.MapIndex(key)
+ dm.SetMapIndex(key, val)
+ }
+ }
+ }
+ }
+ case reflect.Interface:
+ // Must be oneof field.
+ switch {
+ case isPointer || isSlice:
+ panic("bad pointer or slice in interface case in " + tf.Name())
+ default: // E.g., interface{}
+ // TODO: Make this faster?
+ mfi.merge = func(dst, src pointer) {
+ su := src.asPointerTo(tf).Elem()
+ if !su.IsNil() {
+ du := dst.asPointerTo(tf).Elem()
+ typ := su.Elem().Type()
+ if du.IsNil() || du.Elem().Type() != typ {
+ du.Set(reflect.New(typ.Elem())) // Initialize interface if empty
+ }
+ sv := su.Elem().Elem().Field(0)
+ if sv.Kind() == reflect.Ptr && sv.IsNil() {
+ return
+ }
+ dv := du.Elem().Elem().Field(0)
+ if dv.Kind() == reflect.Ptr && dv.IsNil() {
+ dv.Set(reflect.New(sv.Type().Elem())) // Initialize proto message if empty
+ }
+ switch sv.Type().Kind() {
+ case reflect.Ptr: // Proto struct (e.g., *T)
+ Merge(dv.Interface().(Message), sv.Interface().(Message))
+ case reflect.Slice: // E.g. Bytes type (e.g., []byte)
+ dv.Set(reflect.ValueOf(append([]byte{}, sv.Bytes()...)))
+ default: // Basic type (e.g., string)
+ dv.Set(sv)
+ }
+ }
+ }
+ }
+ default:
+ panic(fmt.Sprintf("merger not found for type:%s", tf))
+ }
+ mi.fields = append(mi.fields, mfi)
+ }
+
+ mi.unrecognized = invalidField
+ if f, ok := t.FieldByName("XXX_unrecognized"); ok {
+ if f.Type != reflect.TypeOf([]byte{}) {
+ panic("expected XXX_unrecognized to be of type []byte")
+ }
+ mi.unrecognized = toField(&f)
+ }
+
+ atomic.StoreInt32(&mi.initialized, 1)
+}
diff --git a/vendor/github.com/golang/protobuf/proto/table_unmarshal.go b/vendor/github.com/golang/protobuf/proto/table_unmarshal.go
new file mode 100644
index 0000000000000000000000000000000000000000..acee2fc52964081b2201a7bf7049492e82b02c46
--- /dev/null
+++ b/vendor/github.com/golang/protobuf/proto/table_unmarshal.go
@@ -0,0 +1,2053 @@
+// Go support for Protocol Buffers - Google's data interchange format
+//
+// Copyright 2016 The Go Authors. All rights reserved.
+// https://github.com/golang/protobuf
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package proto
+
+import (
+ "errors"
+ "fmt"
+ "io"
+ "math"
+ "reflect"
+ "strconv"
+ "strings"
+ "sync"
+ "sync/atomic"
+ "unicode/utf8"
+)
+
+// Unmarshal is the entry point from the generated .pb.go files.
+// This function is not intended to be used by non-generated code.
+// This function is not subject to any compatibility guarantee.
+// msg contains a pointer to a protocol buffer struct.
+// b is the data to be unmarshaled into the protocol buffer.
+// a is a pointer to a place to store cached unmarshal information.
+func (a *InternalMessageInfo) Unmarshal(msg Message, b []byte) error {
+ // Load the unmarshal information for this message type.
+ // The atomic load ensures memory consistency.
+ u := atomicLoadUnmarshalInfo(&a.unmarshal)
+ if u == nil {
+ // Slow path: find unmarshal info for msg, update a with it.
+ u = getUnmarshalInfo(reflect.TypeOf(msg).Elem())
+ atomicStoreUnmarshalInfo(&a.unmarshal, u)
+ }
+ // Then do the unmarshaling.
+ err := u.unmarshal(toPointer(&msg), b)
+ return err
+}
+
+type unmarshalInfo struct {
+ typ reflect.Type // type of the protobuf struct
+
+ // 0 = only typ field is initialized
+ // 1 = completely initialized
+ initialized int32
+ lock sync.Mutex // prevents double initialization
+ dense []unmarshalFieldInfo // fields indexed by tag #
+ sparse map[uint64]unmarshalFieldInfo // fields indexed by tag #
+ reqFields []string // names of required fields
+ reqMask uint64 // 1< 0 {
+ // Read tag and wire type.
+ // Special case 1 and 2 byte varints.
+ var x uint64
+ if b[0] < 128 {
+ x = uint64(b[0])
+ b = b[1:]
+ } else if len(b) >= 2 && b[1] < 128 {
+ x = uint64(b[0]&0x7f) + uint64(b[1])<<7
+ b = b[2:]
+ } else {
+ var n int
+ x, n = decodeVarint(b)
+ if n == 0 {
+ return io.ErrUnexpectedEOF
+ }
+ b = b[n:]
+ }
+ tag := x >> 3
+ wire := int(x) & 7
+
+ // Dispatch on the tag to one of the unmarshal* functions below.
+ var f unmarshalFieldInfo
+ if tag < uint64(len(u.dense)) {
+ f = u.dense[tag]
+ } else {
+ f = u.sparse[tag]
+ }
+ if fn := f.unmarshal; fn != nil {
+ var err error
+ b, err = fn(b, m.offset(f.field), wire)
+ if err == nil {
+ reqMask |= f.reqMask
+ continue
+ }
+ if r, ok := err.(*RequiredNotSetError); ok {
+ // Remember this error, but keep parsing. We need to produce
+ // a full parse even if a required field is missing.
+ if errLater == nil {
+ errLater = r
+ }
+ reqMask |= f.reqMask
+ continue
+ }
+ if err != errInternalBadWireType {
+ if err == errInvalidUTF8 {
+ if errLater == nil {
+ fullName := revProtoTypes[reflect.PtrTo(u.typ)] + "." + f.name
+ errLater = &invalidUTF8Error{fullName}
+ }
+ continue
+ }
+ return err
+ }
+ // Fragments with bad wire type are treated as unknown fields.
+ }
+
+ // Unknown tag.
+ if !u.unrecognized.IsValid() {
+ // Don't keep unrecognized data; just skip it.
+ var err error
+ b, err = skipField(b, wire)
+ if err != nil {
+ return err
+ }
+ continue
+ }
+ // Keep unrecognized data around.
+ // maybe in extensions, maybe in the unrecognized field.
+ z := m.offset(u.unrecognized).toBytes()
+ var emap map[int32]Extension
+ var e Extension
+ for _, r := range u.extensionRanges {
+ if uint64(r.Start) <= tag && tag <= uint64(r.End) {
+ if u.extensions.IsValid() {
+ mp := m.offset(u.extensions).toExtensions()
+ emap = mp.extensionsWrite()
+ e = emap[int32(tag)]
+ z = &e.enc
+ break
+ }
+ if u.oldExtensions.IsValid() {
+ p := m.offset(u.oldExtensions).toOldExtensions()
+ emap = *p
+ if emap == nil {
+ emap = map[int32]Extension{}
+ *p = emap
+ }
+ e = emap[int32(tag)]
+ z = &e.enc
+ break
+ }
+ panic("no extensions field available")
+ }
+ }
+
+ // Use wire type to skip data.
+ var err error
+ b0 := b
+ b, err = skipField(b, wire)
+ if err != nil {
+ return err
+ }
+ *z = encodeVarint(*z, tag<<3|uint64(wire))
+ *z = append(*z, b0[:len(b0)-len(b)]...)
+
+ if emap != nil {
+ emap[int32(tag)] = e
+ }
+ }
+ if reqMask != u.reqMask && errLater == nil {
+ // A required field of this message is missing.
+ for _, n := range u.reqFields {
+ if reqMask&1 == 0 {
+ errLater = &RequiredNotSetError{n}
+ }
+ reqMask >>= 1
+ }
+ }
+ return errLater
+}
+
+// computeUnmarshalInfo fills in u with information for use
+// in unmarshaling protocol buffers of type u.typ.
+func (u *unmarshalInfo) computeUnmarshalInfo() {
+ u.lock.Lock()
+ defer u.lock.Unlock()
+ if u.initialized != 0 {
+ return
+ }
+ t := u.typ
+ n := t.NumField()
+
+ // Set up the "not found" value for the unrecognized byte buffer.
+ // This is the default for proto3.
+ u.unrecognized = invalidField
+ u.extensions = invalidField
+ u.oldExtensions = invalidField
+
+ // List of the generated type and offset for each oneof field.
+ type oneofField struct {
+ ityp reflect.Type // interface type of oneof field
+ field field // offset in containing message
+ }
+ var oneofFields []oneofField
+
+ for i := 0; i < n; i++ {
+ f := t.Field(i)
+ if f.Name == "XXX_unrecognized" {
+ // The byte slice used to hold unrecognized input is special.
+ if f.Type != reflect.TypeOf(([]byte)(nil)) {
+ panic("bad type for XXX_unrecognized field: " + f.Type.Name())
+ }
+ u.unrecognized = toField(&f)
+ continue
+ }
+ if f.Name == "XXX_InternalExtensions" {
+ // Ditto here.
+ if f.Type != reflect.TypeOf(XXX_InternalExtensions{}) {
+ panic("bad type for XXX_InternalExtensions field: " + f.Type.Name())
+ }
+ u.extensions = toField(&f)
+ if f.Tag.Get("protobuf_messageset") == "1" {
+ u.isMessageSet = true
+ }
+ continue
+ }
+ if f.Name == "XXX_extensions" {
+ // An older form of the extensions field.
+ if f.Type != reflect.TypeOf((map[int32]Extension)(nil)) {
+ panic("bad type for XXX_extensions field: " + f.Type.Name())
+ }
+ u.oldExtensions = toField(&f)
+ continue
+ }
+ if f.Name == "XXX_NoUnkeyedLiteral" || f.Name == "XXX_sizecache" {
+ continue
+ }
+
+ oneof := f.Tag.Get("protobuf_oneof")
+ if oneof != "" {
+ oneofFields = append(oneofFields, oneofField{f.Type, toField(&f)})
+ // The rest of oneof processing happens below.
+ continue
+ }
+
+ tags := f.Tag.Get("protobuf")
+ tagArray := strings.Split(tags, ",")
+ if len(tagArray) < 2 {
+ panic("protobuf tag not enough fields in " + t.Name() + "." + f.Name + ": " + tags)
+ }
+ tag, err := strconv.Atoi(tagArray[1])
+ if err != nil {
+ panic("protobuf tag field not an integer: " + tagArray[1])
+ }
+
+ name := ""
+ for _, tag := range tagArray[3:] {
+ if strings.HasPrefix(tag, "name=") {
+ name = tag[5:]
+ }
+ }
+
+ // Extract unmarshaling function from the field (its type and tags).
+ unmarshal := fieldUnmarshaler(&f)
+
+ // Required field?
+ var reqMask uint64
+ if tagArray[2] == "req" {
+ bit := len(u.reqFields)
+ u.reqFields = append(u.reqFields, name)
+ reqMask = uint64(1) << uint(bit)
+ // TODO: if we have more than 64 required fields, we end up
+ // not verifying that all required fields are present.
+ // Fix this, perhaps using a count of required fields?
+ }
+
+ // Store the info in the correct slot in the message.
+ u.setTag(tag, toField(&f), unmarshal, reqMask, name)
+ }
+
+ // Find any types associated with oneof fields.
+ var oneofImplementers []interface{}
+ switch m := reflect.Zero(reflect.PtrTo(t)).Interface().(type) {
+ case oneofFuncsIface:
+ _, _, _, oneofImplementers = m.XXX_OneofFuncs()
+ case oneofWrappersIface:
+ oneofImplementers = m.XXX_OneofWrappers()
+ }
+ for _, v := range oneofImplementers {
+ tptr := reflect.TypeOf(v) // *Msg_X
+ typ := tptr.Elem() // Msg_X
+
+ f := typ.Field(0) // oneof implementers have one field
+ baseUnmarshal := fieldUnmarshaler(&f)
+ tags := strings.Split(f.Tag.Get("protobuf"), ",")
+ fieldNum, err := strconv.Atoi(tags[1])
+ if err != nil {
+ panic("protobuf tag field not an integer: " + tags[1])
+ }
+ var name string
+ for _, tag := range tags {
+ if strings.HasPrefix(tag, "name=") {
+ name = strings.TrimPrefix(tag, "name=")
+ break
+ }
+ }
+
+ // Find the oneof field that this struct implements.
+ // Might take O(n^2) to process all of the oneofs, but who cares.
+ for _, of := range oneofFields {
+ if tptr.Implements(of.ityp) {
+ // We have found the corresponding interface for this struct.
+ // That lets us know where this struct should be stored
+ // when we encounter it during unmarshaling.
+ unmarshal := makeUnmarshalOneof(typ, of.ityp, baseUnmarshal)
+ u.setTag(fieldNum, of.field, unmarshal, 0, name)
+ }
+ }
+
+ }
+
+ // Get extension ranges, if any.
+ fn := reflect.Zero(reflect.PtrTo(t)).MethodByName("ExtensionRangeArray")
+ if fn.IsValid() {
+ if !u.extensions.IsValid() && !u.oldExtensions.IsValid() {
+ panic("a message with extensions, but no extensions field in " + t.Name())
+ }
+ u.extensionRanges = fn.Call(nil)[0].Interface().([]ExtensionRange)
+ }
+
+ // Explicitly disallow tag 0. This will ensure we flag an error
+ // when decoding a buffer of all zeros. Without this code, we
+ // would decode and skip an all-zero buffer of even length.
+ // [0 0] is [tag=0/wiretype=varint varint-encoded-0].
+ u.setTag(0, zeroField, func(b []byte, f pointer, w int) ([]byte, error) {
+ return nil, fmt.Errorf("proto: %s: illegal tag 0 (wire type %d)", t, w)
+ }, 0, "")
+
+ // Set mask for required field check.
+ u.reqMask = uint64(1)<= 0 && (tag < 16 || tag < 2*n) { // TODO: what are the right numbers here?
+ for len(u.dense) <= tag {
+ u.dense = append(u.dense, unmarshalFieldInfo{})
+ }
+ u.dense[tag] = i
+ return
+ }
+ if u.sparse == nil {
+ u.sparse = map[uint64]unmarshalFieldInfo{}
+ }
+ u.sparse[uint64(tag)] = i
+}
+
+// fieldUnmarshaler returns an unmarshaler for the given field.
+func fieldUnmarshaler(f *reflect.StructField) unmarshaler {
+ if f.Type.Kind() == reflect.Map {
+ return makeUnmarshalMap(f)
+ }
+ return typeUnmarshaler(f.Type, f.Tag.Get("protobuf"))
+}
+
+// typeUnmarshaler returns an unmarshaler for the given field type / field tag pair.
+func typeUnmarshaler(t reflect.Type, tags string) unmarshaler {
+ tagArray := strings.Split(tags, ",")
+ encoding := tagArray[0]
+ name := "unknown"
+ proto3 := false
+ validateUTF8 := true
+ for _, tag := range tagArray[3:] {
+ if strings.HasPrefix(tag, "name=") {
+ name = tag[5:]
+ }
+ if tag == "proto3" {
+ proto3 = true
+ }
+ }
+ validateUTF8 = validateUTF8 && proto3
+
+ // Figure out packaging (pointer, slice, or both)
+ slice := false
+ pointer := false
+ if t.Kind() == reflect.Slice && t.Elem().Kind() != reflect.Uint8 {
+ slice = true
+ t = t.Elem()
+ }
+ if t.Kind() == reflect.Ptr {
+ pointer = true
+ t = t.Elem()
+ }
+
+ // We'll never have both pointer and slice for basic types.
+ if pointer && slice && t.Kind() != reflect.Struct {
+ panic("both pointer and slice for basic type in " + t.Name())
+ }
+
+ switch t.Kind() {
+ case reflect.Bool:
+ if pointer {
+ return unmarshalBoolPtr
+ }
+ if slice {
+ return unmarshalBoolSlice
+ }
+ return unmarshalBoolValue
+ case reflect.Int32:
+ switch encoding {
+ case "fixed32":
+ if pointer {
+ return unmarshalFixedS32Ptr
+ }
+ if slice {
+ return unmarshalFixedS32Slice
+ }
+ return unmarshalFixedS32Value
+ case "varint":
+ // this could be int32 or enum
+ if pointer {
+ return unmarshalInt32Ptr
+ }
+ if slice {
+ return unmarshalInt32Slice
+ }
+ return unmarshalInt32Value
+ case "zigzag32":
+ if pointer {
+ return unmarshalSint32Ptr
+ }
+ if slice {
+ return unmarshalSint32Slice
+ }
+ return unmarshalSint32Value
+ }
+ case reflect.Int64:
+ switch encoding {
+ case "fixed64":
+ if pointer {
+ return unmarshalFixedS64Ptr
+ }
+ if slice {
+ return unmarshalFixedS64Slice
+ }
+ return unmarshalFixedS64Value
+ case "varint":
+ if pointer {
+ return unmarshalInt64Ptr
+ }
+ if slice {
+ return unmarshalInt64Slice
+ }
+ return unmarshalInt64Value
+ case "zigzag64":
+ if pointer {
+ return unmarshalSint64Ptr
+ }
+ if slice {
+ return unmarshalSint64Slice
+ }
+ return unmarshalSint64Value
+ }
+ case reflect.Uint32:
+ switch encoding {
+ case "fixed32":
+ if pointer {
+ return unmarshalFixed32Ptr
+ }
+ if slice {
+ return unmarshalFixed32Slice
+ }
+ return unmarshalFixed32Value
+ case "varint":
+ if pointer {
+ return unmarshalUint32Ptr
+ }
+ if slice {
+ return unmarshalUint32Slice
+ }
+ return unmarshalUint32Value
+ }
+ case reflect.Uint64:
+ switch encoding {
+ case "fixed64":
+ if pointer {
+ return unmarshalFixed64Ptr
+ }
+ if slice {
+ return unmarshalFixed64Slice
+ }
+ return unmarshalFixed64Value
+ case "varint":
+ if pointer {
+ return unmarshalUint64Ptr
+ }
+ if slice {
+ return unmarshalUint64Slice
+ }
+ return unmarshalUint64Value
+ }
+ case reflect.Float32:
+ if pointer {
+ return unmarshalFloat32Ptr
+ }
+ if slice {
+ return unmarshalFloat32Slice
+ }
+ return unmarshalFloat32Value
+ case reflect.Float64:
+ if pointer {
+ return unmarshalFloat64Ptr
+ }
+ if slice {
+ return unmarshalFloat64Slice
+ }
+ return unmarshalFloat64Value
+ case reflect.Map:
+ panic("map type in typeUnmarshaler in " + t.Name())
+ case reflect.Slice:
+ if pointer {
+ panic("bad pointer in slice case in " + t.Name())
+ }
+ if slice {
+ return unmarshalBytesSlice
+ }
+ return unmarshalBytesValue
+ case reflect.String:
+ if validateUTF8 {
+ if pointer {
+ return unmarshalUTF8StringPtr
+ }
+ if slice {
+ return unmarshalUTF8StringSlice
+ }
+ return unmarshalUTF8StringValue
+ }
+ if pointer {
+ return unmarshalStringPtr
+ }
+ if slice {
+ return unmarshalStringSlice
+ }
+ return unmarshalStringValue
+ case reflect.Struct:
+ // message or group field
+ if !pointer {
+ panic(fmt.Sprintf("message/group field %s:%s without pointer", t, encoding))
+ }
+ switch encoding {
+ case "bytes":
+ if slice {
+ return makeUnmarshalMessageSlicePtr(getUnmarshalInfo(t), name)
+ }
+ return makeUnmarshalMessagePtr(getUnmarshalInfo(t), name)
+ case "group":
+ if slice {
+ return makeUnmarshalGroupSlicePtr(getUnmarshalInfo(t), name)
+ }
+ return makeUnmarshalGroupPtr(getUnmarshalInfo(t), name)
+ }
+ }
+ panic(fmt.Sprintf("unmarshaler not found type:%s encoding:%s", t, encoding))
+}
+
+// Below are all the unmarshalers for individual fields of various types.
+
+func unmarshalInt64Value(b []byte, f pointer, w int) ([]byte, error) {
+ if w != WireVarint {
+ return b, errInternalBadWireType
+ }
+ x, n := decodeVarint(b)
+ if n == 0 {
+ return nil, io.ErrUnexpectedEOF
+ }
+ b = b[n:]
+ v := int64(x)
+ *f.toInt64() = v
+ return b, nil
+}
+
+func unmarshalInt64Ptr(b []byte, f pointer, w int) ([]byte, error) {
+ if w != WireVarint {
+ return b, errInternalBadWireType
+ }
+ x, n := decodeVarint(b)
+ if n == 0 {
+ return nil, io.ErrUnexpectedEOF
+ }
+ b = b[n:]
+ v := int64(x)
+ *f.toInt64Ptr() = &v
+ return b, nil
+}
+
+func unmarshalInt64Slice(b []byte, f pointer, w int) ([]byte, error) {
+ if w == WireBytes { // packed
+ x, n := decodeVarint(b)
+ if n == 0 {
+ return nil, io.ErrUnexpectedEOF
+ }
+ b = b[n:]
+ if x > uint64(len(b)) {
+ return nil, io.ErrUnexpectedEOF
+ }
+ res := b[x:]
+ b = b[:x]
+ for len(b) > 0 {
+ x, n = decodeVarint(b)
+ if n == 0 {
+ return nil, io.ErrUnexpectedEOF
+ }
+ b = b[n:]
+ v := int64(x)
+ s := f.toInt64Slice()
+ *s = append(*s, v)
+ }
+ return res, nil
+ }
+ if w != WireVarint {
+ return b, errInternalBadWireType
+ }
+ x, n := decodeVarint(b)
+ if n == 0 {
+ return nil, io.ErrUnexpectedEOF
+ }
+ b = b[n:]
+ v := int64(x)
+ s := f.toInt64Slice()
+ *s = append(*s, v)
+ return b, nil
+}
+
+func unmarshalSint64Value(b []byte, f pointer, w int) ([]byte, error) {
+ if w != WireVarint {
+ return b, errInternalBadWireType
+ }
+ x, n := decodeVarint(b)
+ if n == 0 {
+ return nil, io.ErrUnexpectedEOF
+ }
+ b = b[n:]
+ v := int64(x>>1) ^ int64(x)<<63>>63
+ *f.toInt64() = v
+ return b, nil
+}
+
+func unmarshalSint64Ptr(b []byte, f pointer, w int) ([]byte, error) {
+ if w != WireVarint {
+ return b, errInternalBadWireType
+ }
+ x, n := decodeVarint(b)
+ if n == 0 {
+ return nil, io.ErrUnexpectedEOF
+ }
+ b = b[n:]
+ v := int64(x>>1) ^ int64(x)<<63>>63
+ *f.toInt64Ptr() = &v
+ return b, nil
+}
+
+func unmarshalSint64Slice(b []byte, f pointer, w int) ([]byte, error) {
+ if w == WireBytes { // packed
+ x, n := decodeVarint(b)
+ if n == 0 {
+ return nil, io.ErrUnexpectedEOF
+ }
+ b = b[n:]
+ if x > uint64(len(b)) {
+ return nil, io.ErrUnexpectedEOF
+ }
+ res := b[x:]
+ b = b[:x]
+ for len(b) > 0 {
+ x, n = decodeVarint(b)
+ if n == 0 {
+ return nil, io.ErrUnexpectedEOF
+ }
+ b = b[n:]
+ v := int64(x>>1) ^ int64(x)<<63>>63
+ s := f.toInt64Slice()
+ *s = append(*s, v)
+ }
+ return res, nil
+ }
+ if w != WireVarint {
+ return b, errInternalBadWireType
+ }
+ x, n := decodeVarint(b)
+ if n == 0 {
+ return nil, io.ErrUnexpectedEOF
+ }
+ b = b[n:]
+ v := int64(x>>1) ^ int64(x)<<63>>63
+ s := f.toInt64Slice()
+ *s = append(*s, v)
+ return b, nil
+}
+
+func unmarshalUint64Value(b []byte, f pointer, w int) ([]byte, error) {
+ if w != WireVarint {
+ return b, errInternalBadWireType
+ }
+ x, n := decodeVarint(b)
+ if n == 0 {
+ return nil, io.ErrUnexpectedEOF
+ }
+ b = b[n:]
+ v := uint64(x)
+ *f.toUint64() = v
+ return b, nil
+}
+
+func unmarshalUint64Ptr(b []byte, f pointer, w int) ([]byte, error) {
+ if w != WireVarint {
+ return b, errInternalBadWireType
+ }
+ x, n := decodeVarint(b)
+ if n == 0 {
+ return nil, io.ErrUnexpectedEOF
+ }
+ b = b[n:]
+ v := uint64(x)
+ *f.toUint64Ptr() = &v
+ return b, nil
+}
+
+func unmarshalUint64Slice(b []byte, f pointer, w int) ([]byte, error) {
+ if w == WireBytes { // packed
+ x, n := decodeVarint(b)
+ if n == 0 {
+ return nil, io.ErrUnexpectedEOF
+ }
+ b = b[n:]
+ if x > uint64(len(b)) {
+ return nil, io.ErrUnexpectedEOF
+ }
+ res := b[x:]
+ b = b[:x]
+ for len(b) > 0 {
+ x, n = decodeVarint(b)
+ if n == 0 {
+ return nil, io.ErrUnexpectedEOF
+ }
+ b = b[n:]
+ v := uint64(x)
+ s := f.toUint64Slice()
+ *s = append(*s, v)
+ }
+ return res, nil
+ }
+ if w != WireVarint {
+ return b, errInternalBadWireType
+ }
+ x, n := decodeVarint(b)
+ if n == 0 {
+ return nil, io.ErrUnexpectedEOF
+ }
+ b = b[n:]
+ v := uint64(x)
+ s := f.toUint64Slice()
+ *s = append(*s, v)
+ return b, nil
+}
+
+func unmarshalInt32Value(b []byte, f pointer, w int) ([]byte, error) {
+ if w != WireVarint {
+ return b, errInternalBadWireType
+ }
+ x, n := decodeVarint(b)
+ if n == 0 {
+ return nil, io.ErrUnexpectedEOF
+ }
+ b = b[n:]
+ v := int32(x)
+ *f.toInt32() = v
+ return b, nil
+}
+
+func unmarshalInt32Ptr(b []byte, f pointer, w int) ([]byte, error) {
+ if w != WireVarint {
+ return b, errInternalBadWireType
+ }
+ x, n := decodeVarint(b)
+ if n == 0 {
+ return nil, io.ErrUnexpectedEOF
+ }
+ b = b[n:]
+ v := int32(x)
+ f.setInt32Ptr(v)
+ return b, nil
+}
+
+func unmarshalInt32Slice(b []byte, f pointer, w int) ([]byte, error) {
+ if w == WireBytes { // packed
+ x, n := decodeVarint(b)
+ if n == 0 {
+ return nil, io.ErrUnexpectedEOF
+ }
+ b = b[n:]
+ if x > uint64(len(b)) {
+ return nil, io.ErrUnexpectedEOF
+ }
+ res := b[x:]
+ b = b[:x]
+ for len(b) > 0 {
+ x, n = decodeVarint(b)
+ if n == 0 {
+ return nil, io.ErrUnexpectedEOF
+ }
+ b = b[n:]
+ v := int32(x)
+ f.appendInt32Slice(v)
+ }
+ return res, nil
+ }
+ if w != WireVarint {
+ return b, errInternalBadWireType
+ }
+ x, n := decodeVarint(b)
+ if n == 0 {
+ return nil, io.ErrUnexpectedEOF
+ }
+ b = b[n:]
+ v := int32(x)
+ f.appendInt32Slice(v)
+ return b, nil
+}
+
+func unmarshalSint32Value(b []byte, f pointer, w int) ([]byte, error) {
+ if w != WireVarint {
+ return b, errInternalBadWireType
+ }
+ x, n := decodeVarint(b)
+ if n == 0 {
+ return nil, io.ErrUnexpectedEOF
+ }
+ b = b[n:]
+ v := int32(x>>1) ^ int32(x)<<31>>31
+ *f.toInt32() = v
+ return b, nil
+}
+
+func unmarshalSint32Ptr(b []byte, f pointer, w int) ([]byte, error) {
+ if w != WireVarint {
+ return b, errInternalBadWireType
+ }
+ x, n := decodeVarint(b)
+ if n == 0 {
+ return nil, io.ErrUnexpectedEOF
+ }
+ b = b[n:]
+ v := int32(x>>1) ^ int32(x)<<31>>31
+ f.setInt32Ptr(v)
+ return b, nil
+}
+
+func unmarshalSint32Slice(b []byte, f pointer, w int) ([]byte, error) {
+ if w == WireBytes { // packed
+ x, n := decodeVarint(b)
+ if n == 0 {
+ return nil, io.ErrUnexpectedEOF
+ }
+ b = b[n:]
+ if x > uint64(len(b)) {
+ return nil, io.ErrUnexpectedEOF
+ }
+ res := b[x:]
+ b = b[:x]
+ for len(b) > 0 {
+ x, n = decodeVarint(b)
+ if n == 0 {
+ return nil, io.ErrUnexpectedEOF
+ }
+ b = b[n:]
+ v := int32(x>>1) ^ int32(x)<<31>>31
+ f.appendInt32Slice(v)
+ }
+ return res, nil
+ }
+ if w != WireVarint {
+ return b, errInternalBadWireType
+ }
+ x, n := decodeVarint(b)
+ if n == 0 {
+ return nil, io.ErrUnexpectedEOF
+ }
+ b = b[n:]
+ v := int32(x>>1) ^ int32(x)<<31>>31
+ f.appendInt32Slice(v)
+ return b, nil
+}
+
+func unmarshalUint32Value(b []byte, f pointer, w int) ([]byte, error) {
+ if w != WireVarint {
+ return b, errInternalBadWireType
+ }
+ x, n := decodeVarint(b)
+ if n == 0 {
+ return nil, io.ErrUnexpectedEOF
+ }
+ b = b[n:]
+ v := uint32(x)
+ *f.toUint32() = v
+ return b, nil
+}
+
+func unmarshalUint32Ptr(b []byte, f pointer, w int) ([]byte, error) {
+ if w != WireVarint {
+ return b, errInternalBadWireType
+ }
+ x, n := decodeVarint(b)
+ if n == 0 {
+ return nil, io.ErrUnexpectedEOF
+ }
+ b = b[n:]
+ v := uint32(x)
+ *f.toUint32Ptr() = &v
+ return b, nil
+}
+
+func unmarshalUint32Slice(b []byte, f pointer, w int) ([]byte, error) {
+ if w == WireBytes { // packed
+ x, n := decodeVarint(b)
+ if n == 0 {
+ return nil, io.ErrUnexpectedEOF
+ }
+ b = b[n:]
+ if x > uint64(len(b)) {
+ return nil, io.ErrUnexpectedEOF
+ }
+ res := b[x:]
+ b = b[:x]
+ for len(b) > 0 {
+ x, n = decodeVarint(b)
+ if n == 0 {
+ return nil, io.ErrUnexpectedEOF
+ }
+ b = b[n:]
+ v := uint32(x)
+ s := f.toUint32Slice()
+ *s = append(*s, v)
+ }
+ return res, nil
+ }
+ if w != WireVarint {
+ return b, errInternalBadWireType
+ }
+ x, n := decodeVarint(b)
+ if n == 0 {
+ return nil, io.ErrUnexpectedEOF
+ }
+ b = b[n:]
+ v := uint32(x)
+ s := f.toUint32Slice()
+ *s = append(*s, v)
+ return b, nil
+}
+
+func unmarshalFixed64Value(b []byte, f pointer, w int) ([]byte, error) {
+ if w != WireFixed64 {
+ return b, errInternalBadWireType
+ }
+ if len(b) < 8 {
+ return nil, io.ErrUnexpectedEOF
+ }
+ v := uint64(b[0]) | uint64(b[1])<<8 | uint64(b[2])<<16 | uint64(b[3])<<24 | uint64(b[4])<<32 | uint64(b[5])<<40 | uint64(b[6])<<48 | uint64(b[7])<<56
+ *f.toUint64() = v
+ return b[8:], nil
+}
+
+func unmarshalFixed64Ptr(b []byte, f pointer, w int) ([]byte, error) {
+ if w != WireFixed64 {
+ return b, errInternalBadWireType
+ }
+ if len(b) < 8 {
+ return nil, io.ErrUnexpectedEOF
+ }
+ v := uint64(b[0]) | uint64(b[1])<<8 | uint64(b[2])<<16 | uint64(b[3])<<24 | uint64(b[4])<<32 | uint64(b[5])<<40 | uint64(b[6])<<48 | uint64(b[7])<<56
+ *f.toUint64Ptr() = &v
+ return b[8:], nil
+}
+
+func unmarshalFixed64Slice(b []byte, f pointer, w int) ([]byte, error) {
+ if w == WireBytes { // packed
+ x, n := decodeVarint(b)
+ if n == 0 {
+ return nil, io.ErrUnexpectedEOF
+ }
+ b = b[n:]
+ if x > uint64(len(b)) {
+ return nil, io.ErrUnexpectedEOF
+ }
+ res := b[x:]
+ b = b[:x]
+ for len(b) > 0 {
+ if len(b) < 8 {
+ return nil, io.ErrUnexpectedEOF
+ }
+ v := uint64(b[0]) | uint64(b[1])<<8 | uint64(b[2])<<16 | uint64(b[3])<<24 | uint64(b[4])<<32 | uint64(b[5])<<40 | uint64(b[6])<<48 | uint64(b[7])<<56
+ s := f.toUint64Slice()
+ *s = append(*s, v)
+ b = b[8:]
+ }
+ return res, nil
+ }
+ if w != WireFixed64 {
+ return b, errInternalBadWireType
+ }
+ if len(b) < 8 {
+ return nil, io.ErrUnexpectedEOF
+ }
+ v := uint64(b[0]) | uint64(b[1])<<8 | uint64(b[2])<<16 | uint64(b[3])<<24 | uint64(b[4])<<32 | uint64(b[5])<<40 | uint64(b[6])<<48 | uint64(b[7])<<56
+ s := f.toUint64Slice()
+ *s = append(*s, v)
+ return b[8:], nil
+}
+
+func unmarshalFixedS64Value(b []byte, f pointer, w int) ([]byte, error) {
+ if w != WireFixed64 {
+ return b, errInternalBadWireType
+ }
+ if len(b) < 8 {
+ return nil, io.ErrUnexpectedEOF
+ }
+ v := int64(b[0]) | int64(b[1])<<8 | int64(b[2])<<16 | int64(b[3])<<24 | int64(b[4])<<32 | int64(b[5])<<40 | int64(b[6])<<48 | int64(b[7])<<56
+ *f.toInt64() = v
+ return b[8:], nil
+}
+
+func unmarshalFixedS64Ptr(b []byte, f pointer, w int) ([]byte, error) {
+ if w != WireFixed64 {
+ return b, errInternalBadWireType
+ }
+ if len(b) < 8 {
+ return nil, io.ErrUnexpectedEOF
+ }
+ v := int64(b[0]) | int64(b[1])<<8 | int64(b[2])<<16 | int64(b[3])<<24 | int64(b[4])<<32 | int64(b[5])<<40 | int64(b[6])<<48 | int64(b[7])<<56
+ *f.toInt64Ptr() = &v
+ return b[8:], nil
+}
+
+func unmarshalFixedS64Slice(b []byte, f pointer, w int) ([]byte, error) {
+ if w == WireBytes { // packed
+ x, n := decodeVarint(b)
+ if n == 0 {
+ return nil, io.ErrUnexpectedEOF
+ }
+ b = b[n:]
+ if x > uint64(len(b)) {
+ return nil, io.ErrUnexpectedEOF
+ }
+ res := b[x:]
+ b = b[:x]
+ for len(b) > 0 {
+ if len(b) < 8 {
+ return nil, io.ErrUnexpectedEOF
+ }
+ v := int64(b[0]) | int64(b[1])<<8 | int64(b[2])<<16 | int64(b[3])<<24 | int64(b[4])<<32 | int64(b[5])<<40 | int64(b[6])<<48 | int64(b[7])<<56
+ s := f.toInt64Slice()
+ *s = append(*s, v)
+ b = b[8:]
+ }
+ return res, nil
+ }
+ if w != WireFixed64 {
+ return b, errInternalBadWireType
+ }
+ if len(b) < 8 {
+ return nil, io.ErrUnexpectedEOF
+ }
+ v := int64(b[0]) | int64(b[1])<<8 | int64(b[2])<<16 | int64(b[3])<<24 | int64(b[4])<<32 | int64(b[5])<<40 | int64(b[6])<<48 | int64(b[7])<<56
+ s := f.toInt64Slice()
+ *s = append(*s, v)
+ return b[8:], nil
+}
+
+func unmarshalFixed32Value(b []byte, f pointer, w int) ([]byte, error) {
+ if w != WireFixed32 {
+ return b, errInternalBadWireType
+ }
+ if len(b) < 4 {
+ return nil, io.ErrUnexpectedEOF
+ }
+ v := uint32(b[0]) | uint32(b[1])<<8 | uint32(b[2])<<16 | uint32(b[3])<<24
+ *f.toUint32() = v
+ return b[4:], nil
+}
+
+func unmarshalFixed32Ptr(b []byte, f pointer, w int) ([]byte, error) {
+ if w != WireFixed32 {
+ return b, errInternalBadWireType
+ }
+ if len(b) < 4 {
+ return nil, io.ErrUnexpectedEOF
+ }
+ v := uint32(b[0]) | uint32(b[1])<<8 | uint32(b[2])<<16 | uint32(b[3])<<24
+ *f.toUint32Ptr() = &v
+ return b[4:], nil
+}
+
+func unmarshalFixed32Slice(b []byte, f pointer, w int) ([]byte, error) {
+ if w == WireBytes { // packed
+ x, n := decodeVarint(b)
+ if n == 0 {
+ return nil, io.ErrUnexpectedEOF
+ }
+ b = b[n:]
+ if x > uint64(len(b)) {
+ return nil, io.ErrUnexpectedEOF
+ }
+ res := b[x:]
+ b = b[:x]
+ for len(b) > 0 {
+ if len(b) < 4 {
+ return nil, io.ErrUnexpectedEOF
+ }
+ v := uint32(b[0]) | uint32(b[1])<<8 | uint32(b[2])<<16 | uint32(b[3])<<24
+ s := f.toUint32Slice()
+ *s = append(*s, v)
+ b = b[4:]
+ }
+ return res, nil
+ }
+ if w != WireFixed32 {
+ return b, errInternalBadWireType
+ }
+ if len(b) < 4 {
+ return nil, io.ErrUnexpectedEOF
+ }
+ v := uint32(b[0]) | uint32(b[1])<<8 | uint32(b[2])<<16 | uint32(b[3])<<24
+ s := f.toUint32Slice()
+ *s = append(*s, v)
+ return b[4:], nil
+}
+
+func unmarshalFixedS32Value(b []byte, f pointer, w int) ([]byte, error) {
+ if w != WireFixed32 {
+ return b, errInternalBadWireType
+ }
+ if len(b) < 4 {
+ return nil, io.ErrUnexpectedEOF
+ }
+ v := int32(b[0]) | int32(b[1])<<8 | int32(b[2])<<16 | int32(b[3])<<24
+ *f.toInt32() = v
+ return b[4:], nil
+}
+
+func unmarshalFixedS32Ptr(b []byte, f pointer, w int) ([]byte, error) {
+ if w != WireFixed32 {
+ return b, errInternalBadWireType
+ }
+ if len(b) < 4 {
+ return nil, io.ErrUnexpectedEOF
+ }
+ v := int32(b[0]) | int32(b[1])<<8 | int32(b[2])<<16 | int32(b[3])<<24
+ f.setInt32Ptr(v)
+ return b[4:], nil
+}
+
+func unmarshalFixedS32Slice(b []byte, f pointer, w int) ([]byte, error) {
+ if w == WireBytes { // packed
+ x, n := decodeVarint(b)
+ if n == 0 {
+ return nil, io.ErrUnexpectedEOF
+ }
+ b = b[n:]
+ if x > uint64(len(b)) {
+ return nil, io.ErrUnexpectedEOF
+ }
+ res := b[x:]
+ b = b[:x]
+ for len(b) > 0 {
+ if len(b) < 4 {
+ return nil, io.ErrUnexpectedEOF
+ }
+ v := int32(b[0]) | int32(b[1])<<8 | int32(b[2])<<16 | int32(b[3])<<24
+ f.appendInt32Slice(v)
+ b = b[4:]
+ }
+ return res, nil
+ }
+ if w != WireFixed32 {
+ return b, errInternalBadWireType
+ }
+ if len(b) < 4 {
+ return nil, io.ErrUnexpectedEOF
+ }
+ v := int32(b[0]) | int32(b[1])<<8 | int32(b[2])<<16 | int32(b[3])<<24
+ f.appendInt32Slice(v)
+ return b[4:], nil
+}
+
+func unmarshalBoolValue(b []byte, f pointer, w int) ([]byte, error) {
+ if w != WireVarint {
+ return b, errInternalBadWireType
+ }
+ // Note: any length varint is allowed, even though any sane
+ // encoder will use one byte.
+ // See https://github.com/golang/protobuf/issues/76
+ x, n := decodeVarint(b)
+ if n == 0 {
+ return nil, io.ErrUnexpectedEOF
+ }
+ // TODO: check if x>1? Tests seem to indicate no.
+ v := x != 0
+ *f.toBool() = v
+ return b[n:], nil
+}
+
+func unmarshalBoolPtr(b []byte, f pointer, w int) ([]byte, error) {
+ if w != WireVarint {
+ return b, errInternalBadWireType
+ }
+ x, n := decodeVarint(b)
+ if n == 0 {
+ return nil, io.ErrUnexpectedEOF
+ }
+ v := x != 0
+ *f.toBoolPtr() = &v
+ return b[n:], nil
+}
+
+func unmarshalBoolSlice(b []byte, f pointer, w int) ([]byte, error) {
+ if w == WireBytes { // packed
+ x, n := decodeVarint(b)
+ if n == 0 {
+ return nil, io.ErrUnexpectedEOF
+ }
+ b = b[n:]
+ if x > uint64(len(b)) {
+ return nil, io.ErrUnexpectedEOF
+ }
+ res := b[x:]
+ b = b[:x]
+ for len(b) > 0 {
+ x, n = decodeVarint(b)
+ if n == 0 {
+ return nil, io.ErrUnexpectedEOF
+ }
+ v := x != 0
+ s := f.toBoolSlice()
+ *s = append(*s, v)
+ b = b[n:]
+ }
+ return res, nil
+ }
+ if w != WireVarint {
+ return b, errInternalBadWireType
+ }
+ x, n := decodeVarint(b)
+ if n == 0 {
+ return nil, io.ErrUnexpectedEOF
+ }
+ v := x != 0
+ s := f.toBoolSlice()
+ *s = append(*s, v)
+ return b[n:], nil
+}
+
+func unmarshalFloat64Value(b []byte, f pointer, w int) ([]byte, error) {
+ if w != WireFixed64 {
+ return b, errInternalBadWireType
+ }
+ if len(b) < 8 {
+ return nil, io.ErrUnexpectedEOF
+ }
+ v := math.Float64frombits(uint64(b[0]) | uint64(b[1])<<8 | uint64(b[2])<<16 | uint64(b[3])<<24 | uint64(b[4])<<32 | uint64(b[5])<<40 | uint64(b[6])<<48 | uint64(b[7])<<56)
+ *f.toFloat64() = v
+ return b[8:], nil
+}
+
+func unmarshalFloat64Ptr(b []byte, f pointer, w int) ([]byte, error) {
+ if w != WireFixed64 {
+ return b, errInternalBadWireType
+ }
+ if len(b) < 8 {
+ return nil, io.ErrUnexpectedEOF
+ }
+ v := math.Float64frombits(uint64(b[0]) | uint64(b[1])<<8 | uint64(b[2])<<16 | uint64(b[3])<<24 | uint64(b[4])<<32 | uint64(b[5])<<40 | uint64(b[6])<<48 | uint64(b[7])<<56)
+ *f.toFloat64Ptr() = &v
+ return b[8:], nil
+}
+
+func unmarshalFloat64Slice(b []byte, f pointer, w int) ([]byte, error) {
+ if w == WireBytes { // packed
+ x, n := decodeVarint(b)
+ if n == 0 {
+ return nil, io.ErrUnexpectedEOF
+ }
+ b = b[n:]
+ if x > uint64(len(b)) {
+ return nil, io.ErrUnexpectedEOF
+ }
+ res := b[x:]
+ b = b[:x]
+ for len(b) > 0 {
+ if len(b) < 8 {
+ return nil, io.ErrUnexpectedEOF
+ }
+ v := math.Float64frombits(uint64(b[0]) | uint64(b[1])<<8 | uint64(b[2])<<16 | uint64(b[3])<<24 | uint64(b[4])<<32 | uint64(b[5])<<40 | uint64(b[6])<<48 | uint64(b[7])<<56)
+ s := f.toFloat64Slice()
+ *s = append(*s, v)
+ b = b[8:]
+ }
+ return res, nil
+ }
+ if w != WireFixed64 {
+ return b, errInternalBadWireType
+ }
+ if len(b) < 8 {
+ return nil, io.ErrUnexpectedEOF
+ }
+ v := math.Float64frombits(uint64(b[0]) | uint64(b[1])<<8 | uint64(b[2])<<16 | uint64(b[3])<<24 | uint64(b[4])<<32 | uint64(b[5])<<40 | uint64(b[6])<<48 | uint64(b[7])<<56)
+ s := f.toFloat64Slice()
+ *s = append(*s, v)
+ return b[8:], nil
+}
+
+func unmarshalFloat32Value(b []byte, f pointer, w int) ([]byte, error) {
+ if w != WireFixed32 {
+ return b, errInternalBadWireType
+ }
+ if len(b) < 4 {
+ return nil, io.ErrUnexpectedEOF
+ }
+ v := math.Float32frombits(uint32(b[0]) | uint32(b[1])<<8 | uint32(b[2])<<16 | uint32(b[3])<<24)
+ *f.toFloat32() = v
+ return b[4:], nil
+}
+
+func unmarshalFloat32Ptr(b []byte, f pointer, w int) ([]byte, error) {
+ if w != WireFixed32 {
+ return b, errInternalBadWireType
+ }
+ if len(b) < 4 {
+ return nil, io.ErrUnexpectedEOF
+ }
+ v := math.Float32frombits(uint32(b[0]) | uint32(b[1])<<8 | uint32(b[2])<<16 | uint32(b[3])<<24)
+ *f.toFloat32Ptr() = &v
+ return b[4:], nil
+}
+
+func unmarshalFloat32Slice(b []byte, f pointer, w int) ([]byte, error) {
+ if w == WireBytes { // packed
+ x, n := decodeVarint(b)
+ if n == 0 {
+ return nil, io.ErrUnexpectedEOF
+ }
+ b = b[n:]
+ if x > uint64(len(b)) {
+ return nil, io.ErrUnexpectedEOF
+ }
+ res := b[x:]
+ b = b[:x]
+ for len(b) > 0 {
+ if len(b) < 4 {
+ return nil, io.ErrUnexpectedEOF
+ }
+ v := math.Float32frombits(uint32(b[0]) | uint32(b[1])<<8 | uint32(b[2])<<16 | uint32(b[3])<<24)
+ s := f.toFloat32Slice()
+ *s = append(*s, v)
+ b = b[4:]
+ }
+ return res, nil
+ }
+ if w != WireFixed32 {
+ return b, errInternalBadWireType
+ }
+ if len(b) < 4 {
+ return nil, io.ErrUnexpectedEOF
+ }
+ v := math.Float32frombits(uint32(b[0]) | uint32(b[1])<<8 | uint32(b[2])<<16 | uint32(b[3])<<24)
+ s := f.toFloat32Slice()
+ *s = append(*s, v)
+ return b[4:], nil
+}
+
+func unmarshalStringValue(b []byte, f pointer, w int) ([]byte, error) {
+ if w != WireBytes {
+ return b, errInternalBadWireType
+ }
+ x, n := decodeVarint(b)
+ if n == 0 {
+ return nil, io.ErrUnexpectedEOF
+ }
+ b = b[n:]
+ if x > uint64(len(b)) {
+ return nil, io.ErrUnexpectedEOF
+ }
+ v := string(b[:x])
+ *f.toString() = v
+ return b[x:], nil
+}
+
+func unmarshalStringPtr(b []byte, f pointer, w int) ([]byte, error) {
+ if w != WireBytes {
+ return b, errInternalBadWireType
+ }
+ x, n := decodeVarint(b)
+ if n == 0 {
+ return nil, io.ErrUnexpectedEOF
+ }
+ b = b[n:]
+ if x > uint64(len(b)) {
+ return nil, io.ErrUnexpectedEOF
+ }
+ v := string(b[:x])
+ *f.toStringPtr() = &v
+ return b[x:], nil
+}
+
+func unmarshalStringSlice(b []byte, f pointer, w int) ([]byte, error) {
+ if w != WireBytes {
+ return b, errInternalBadWireType
+ }
+ x, n := decodeVarint(b)
+ if n == 0 {
+ return nil, io.ErrUnexpectedEOF
+ }
+ b = b[n:]
+ if x > uint64(len(b)) {
+ return nil, io.ErrUnexpectedEOF
+ }
+ v := string(b[:x])
+ s := f.toStringSlice()
+ *s = append(*s, v)
+ return b[x:], nil
+}
+
+func unmarshalUTF8StringValue(b []byte, f pointer, w int) ([]byte, error) {
+ if w != WireBytes {
+ return b, errInternalBadWireType
+ }
+ x, n := decodeVarint(b)
+ if n == 0 {
+ return nil, io.ErrUnexpectedEOF
+ }
+ b = b[n:]
+ if x > uint64(len(b)) {
+ return nil, io.ErrUnexpectedEOF
+ }
+ v := string(b[:x])
+ *f.toString() = v
+ if !utf8.ValidString(v) {
+ return b[x:], errInvalidUTF8
+ }
+ return b[x:], nil
+}
+
+func unmarshalUTF8StringPtr(b []byte, f pointer, w int) ([]byte, error) {
+ if w != WireBytes {
+ return b, errInternalBadWireType
+ }
+ x, n := decodeVarint(b)
+ if n == 0 {
+ return nil, io.ErrUnexpectedEOF
+ }
+ b = b[n:]
+ if x > uint64(len(b)) {
+ return nil, io.ErrUnexpectedEOF
+ }
+ v := string(b[:x])
+ *f.toStringPtr() = &v
+ if !utf8.ValidString(v) {
+ return b[x:], errInvalidUTF8
+ }
+ return b[x:], nil
+}
+
+func unmarshalUTF8StringSlice(b []byte, f pointer, w int) ([]byte, error) {
+ if w != WireBytes {
+ return b, errInternalBadWireType
+ }
+ x, n := decodeVarint(b)
+ if n == 0 {
+ return nil, io.ErrUnexpectedEOF
+ }
+ b = b[n:]
+ if x > uint64(len(b)) {
+ return nil, io.ErrUnexpectedEOF
+ }
+ v := string(b[:x])
+ s := f.toStringSlice()
+ *s = append(*s, v)
+ if !utf8.ValidString(v) {
+ return b[x:], errInvalidUTF8
+ }
+ return b[x:], nil
+}
+
+var emptyBuf [0]byte
+
+func unmarshalBytesValue(b []byte, f pointer, w int) ([]byte, error) {
+ if w != WireBytes {
+ return b, errInternalBadWireType
+ }
+ x, n := decodeVarint(b)
+ if n == 0 {
+ return nil, io.ErrUnexpectedEOF
+ }
+ b = b[n:]
+ if x > uint64(len(b)) {
+ return nil, io.ErrUnexpectedEOF
+ }
+ // The use of append here is a trick which avoids the zeroing
+ // that would be required if we used a make/copy pair.
+ // We append to emptyBuf instead of nil because we want
+ // a non-nil result even when the length is 0.
+ v := append(emptyBuf[:], b[:x]...)
+ *f.toBytes() = v
+ return b[x:], nil
+}
+
+func unmarshalBytesSlice(b []byte, f pointer, w int) ([]byte, error) {
+ if w != WireBytes {
+ return b, errInternalBadWireType
+ }
+ x, n := decodeVarint(b)
+ if n == 0 {
+ return nil, io.ErrUnexpectedEOF
+ }
+ b = b[n:]
+ if x > uint64(len(b)) {
+ return nil, io.ErrUnexpectedEOF
+ }
+ v := append(emptyBuf[:], b[:x]...)
+ s := f.toBytesSlice()
+ *s = append(*s, v)
+ return b[x:], nil
+}
+
+func makeUnmarshalMessagePtr(sub *unmarshalInfo, name string) unmarshaler {
+ return func(b []byte, f pointer, w int) ([]byte, error) {
+ if w != WireBytes {
+ return b, errInternalBadWireType
+ }
+ x, n := decodeVarint(b)
+ if n == 0 {
+ return nil, io.ErrUnexpectedEOF
+ }
+ b = b[n:]
+ if x > uint64(len(b)) {
+ return nil, io.ErrUnexpectedEOF
+ }
+ // First read the message field to see if something is there.
+ // The semantics of multiple submessages are weird. Instead of
+ // the last one winning (as it is for all other fields), multiple
+ // submessages are merged.
+ v := f.getPointer()
+ if v.isNil() {
+ v = valToPointer(reflect.New(sub.typ))
+ f.setPointer(v)
+ }
+ err := sub.unmarshal(v, b[:x])
+ if err != nil {
+ if r, ok := err.(*RequiredNotSetError); ok {
+ r.field = name + "." + r.field
+ } else {
+ return nil, err
+ }
+ }
+ return b[x:], err
+ }
+}
+
+func makeUnmarshalMessageSlicePtr(sub *unmarshalInfo, name string) unmarshaler {
+ return func(b []byte, f pointer, w int) ([]byte, error) {
+ if w != WireBytes {
+ return b, errInternalBadWireType
+ }
+ x, n := decodeVarint(b)
+ if n == 0 {
+ return nil, io.ErrUnexpectedEOF
+ }
+ b = b[n:]
+ if x > uint64(len(b)) {
+ return nil, io.ErrUnexpectedEOF
+ }
+ v := valToPointer(reflect.New(sub.typ))
+ err := sub.unmarshal(v, b[:x])
+ if err != nil {
+ if r, ok := err.(*RequiredNotSetError); ok {
+ r.field = name + "." + r.field
+ } else {
+ return nil, err
+ }
+ }
+ f.appendPointer(v)
+ return b[x:], err
+ }
+}
+
+func makeUnmarshalGroupPtr(sub *unmarshalInfo, name string) unmarshaler {
+ return func(b []byte, f pointer, w int) ([]byte, error) {
+ if w != WireStartGroup {
+ return b, errInternalBadWireType
+ }
+ x, y := findEndGroup(b)
+ if x < 0 {
+ return nil, io.ErrUnexpectedEOF
+ }
+ v := f.getPointer()
+ if v.isNil() {
+ v = valToPointer(reflect.New(sub.typ))
+ f.setPointer(v)
+ }
+ err := sub.unmarshal(v, b[:x])
+ if err != nil {
+ if r, ok := err.(*RequiredNotSetError); ok {
+ r.field = name + "." + r.field
+ } else {
+ return nil, err
+ }
+ }
+ return b[y:], err
+ }
+}
+
+func makeUnmarshalGroupSlicePtr(sub *unmarshalInfo, name string) unmarshaler {
+ return func(b []byte, f pointer, w int) ([]byte, error) {
+ if w != WireStartGroup {
+ return b, errInternalBadWireType
+ }
+ x, y := findEndGroup(b)
+ if x < 0 {
+ return nil, io.ErrUnexpectedEOF
+ }
+ v := valToPointer(reflect.New(sub.typ))
+ err := sub.unmarshal(v, b[:x])
+ if err != nil {
+ if r, ok := err.(*RequiredNotSetError); ok {
+ r.field = name + "." + r.field
+ } else {
+ return nil, err
+ }
+ }
+ f.appendPointer(v)
+ return b[y:], err
+ }
+}
+
+func makeUnmarshalMap(f *reflect.StructField) unmarshaler {
+ t := f.Type
+ kt := t.Key()
+ vt := t.Elem()
+ unmarshalKey := typeUnmarshaler(kt, f.Tag.Get("protobuf_key"))
+ unmarshalVal := typeUnmarshaler(vt, f.Tag.Get("protobuf_val"))
+ return func(b []byte, f pointer, w int) ([]byte, error) {
+ // The map entry is a submessage. Figure out how big it is.
+ if w != WireBytes {
+ return nil, fmt.Errorf("proto: bad wiretype for map field: got %d want %d", w, WireBytes)
+ }
+ x, n := decodeVarint(b)
+ if n == 0 {
+ return nil, io.ErrUnexpectedEOF
+ }
+ b = b[n:]
+ if x > uint64(len(b)) {
+ return nil, io.ErrUnexpectedEOF
+ }
+ r := b[x:] // unused data to return
+ b = b[:x] // data for map entry
+
+ // Note: we could use #keys * #values ~= 200 functions
+ // to do map decoding without reflection. Probably not worth it.
+ // Maps will be somewhat slow. Oh well.
+
+ // Read key and value from data.
+ var nerr nonFatal
+ k := reflect.New(kt)
+ v := reflect.New(vt)
+ for len(b) > 0 {
+ x, n := decodeVarint(b)
+ if n == 0 {
+ return nil, io.ErrUnexpectedEOF
+ }
+ wire := int(x) & 7
+ b = b[n:]
+
+ var err error
+ switch x >> 3 {
+ case 1:
+ b, err = unmarshalKey(b, valToPointer(k), wire)
+ case 2:
+ b, err = unmarshalVal(b, valToPointer(v), wire)
+ default:
+ err = errInternalBadWireType // skip unknown tag
+ }
+
+ if nerr.Merge(err) {
+ continue
+ }
+ if err != errInternalBadWireType {
+ return nil, err
+ }
+
+ // Skip past unknown fields.
+ b, err = skipField(b, wire)
+ if err != nil {
+ return nil, err
+ }
+ }
+
+ // Get map, allocate if needed.
+ m := f.asPointerTo(t).Elem() // an addressable map[K]T
+ if m.IsNil() {
+ m.Set(reflect.MakeMap(t))
+ }
+
+ // Insert into map.
+ m.SetMapIndex(k.Elem(), v.Elem())
+
+ return r, nerr.E
+ }
+}
+
+// makeUnmarshalOneof makes an unmarshaler for oneof fields.
+// for:
+// message Msg {
+// oneof F {
+// int64 X = 1;
+// float64 Y = 2;
+// }
+// }
+// typ is the type of the concrete entry for a oneof case (e.g. Msg_X).
+// ityp is the interface type of the oneof field (e.g. isMsg_F).
+// unmarshal is the unmarshaler for the base type of the oneof case (e.g. int64).
+// Note that this function will be called once for each case in the oneof.
+func makeUnmarshalOneof(typ, ityp reflect.Type, unmarshal unmarshaler) unmarshaler {
+ sf := typ.Field(0)
+ field0 := toField(&sf)
+ return func(b []byte, f pointer, w int) ([]byte, error) {
+ // Allocate holder for value.
+ v := reflect.New(typ)
+
+ // Unmarshal data into holder.
+ // We unmarshal into the first field of the holder object.
+ var err error
+ var nerr nonFatal
+ b, err = unmarshal(b, valToPointer(v).offset(field0), w)
+ if !nerr.Merge(err) {
+ return nil, err
+ }
+
+ // Write pointer to holder into target field.
+ f.asPointerTo(ityp).Elem().Set(v)
+
+ return b, nerr.E
+ }
+}
+
+// Error used by decode internally.
+var errInternalBadWireType = errors.New("proto: internal error: bad wiretype")
+
+// skipField skips past a field of type wire and returns the remaining bytes.
+func skipField(b []byte, wire int) ([]byte, error) {
+ switch wire {
+ case WireVarint:
+ _, k := decodeVarint(b)
+ if k == 0 {
+ return b, io.ErrUnexpectedEOF
+ }
+ b = b[k:]
+ case WireFixed32:
+ if len(b) < 4 {
+ return b, io.ErrUnexpectedEOF
+ }
+ b = b[4:]
+ case WireFixed64:
+ if len(b) < 8 {
+ return b, io.ErrUnexpectedEOF
+ }
+ b = b[8:]
+ case WireBytes:
+ m, k := decodeVarint(b)
+ if k == 0 || uint64(len(b)-k) < m {
+ return b, io.ErrUnexpectedEOF
+ }
+ b = b[uint64(k)+m:]
+ case WireStartGroup:
+ _, i := findEndGroup(b)
+ if i == -1 {
+ return b, io.ErrUnexpectedEOF
+ }
+ b = b[i:]
+ default:
+ return b, fmt.Errorf("proto: can't skip unknown wire type %d", wire)
+ }
+ return b, nil
+}
+
+// findEndGroup finds the index of the next EndGroup tag.
+// Groups may be nested, so the "next" EndGroup tag is the first
+// unpaired EndGroup.
+// findEndGroup returns the indexes of the start and end of the EndGroup tag.
+// Returns (-1,-1) if it can't find one.
+func findEndGroup(b []byte) (int, int) {
+ depth := 1
+ i := 0
+ for {
+ x, n := decodeVarint(b[i:])
+ if n == 0 {
+ return -1, -1
+ }
+ j := i
+ i += n
+ switch x & 7 {
+ case WireVarint:
+ _, k := decodeVarint(b[i:])
+ if k == 0 {
+ return -1, -1
+ }
+ i += k
+ case WireFixed32:
+ if len(b)-4 < i {
+ return -1, -1
+ }
+ i += 4
+ case WireFixed64:
+ if len(b)-8 < i {
+ return -1, -1
+ }
+ i += 8
+ case WireBytes:
+ m, k := decodeVarint(b[i:])
+ if k == 0 {
+ return -1, -1
+ }
+ i += k
+ if uint64(len(b)-i) < m {
+ return -1, -1
+ }
+ i += int(m)
+ case WireStartGroup:
+ depth++
+ case WireEndGroup:
+ depth--
+ if depth == 0 {
+ return j, i
+ }
+ default:
+ return -1, -1
+ }
+ }
+}
+
+// encodeVarint appends a varint-encoded integer to b and returns the result.
+func encodeVarint(b []byte, x uint64) []byte {
+ for x >= 1<<7 {
+ b = append(b, byte(x&0x7f|0x80))
+ x >>= 7
+ }
+ return append(b, byte(x))
+}
+
+// decodeVarint reads a varint-encoded integer from b.
+// Returns the decoded integer and the number of bytes read.
+// If there is an error, it returns 0,0.
+func decodeVarint(b []byte) (uint64, int) {
+ var x, y uint64
+ if len(b) == 0 {
+ goto bad
+ }
+ x = uint64(b[0])
+ if x < 0x80 {
+ return x, 1
+ }
+ x -= 0x80
+
+ if len(b) <= 1 {
+ goto bad
+ }
+ y = uint64(b[1])
+ x += y << 7
+ if y < 0x80 {
+ return x, 2
+ }
+ x -= 0x80 << 7
+
+ if len(b) <= 2 {
+ goto bad
+ }
+ y = uint64(b[2])
+ x += y << 14
+ if y < 0x80 {
+ return x, 3
+ }
+ x -= 0x80 << 14
+
+ if len(b) <= 3 {
+ goto bad
+ }
+ y = uint64(b[3])
+ x += y << 21
+ if y < 0x80 {
+ return x, 4
+ }
+ x -= 0x80 << 21
+
+ if len(b) <= 4 {
+ goto bad
+ }
+ y = uint64(b[4])
+ x += y << 28
+ if y < 0x80 {
+ return x, 5
+ }
+ x -= 0x80 << 28
+
+ if len(b) <= 5 {
+ goto bad
+ }
+ y = uint64(b[5])
+ x += y << 35
+ if y < 0x80 {
+ return x, 6
+ }
+ x -= 0x80 << 35
+
+ if len(b) <= 6 {
+ goto bad
+ }
+ y = uint64(b[6])
+ x += y << 42
+ if y < 0x80 {
+ return x, 7
+ }
+ x -= 0x80 << 42
+
+ if len(b) <= 7 {
+ goto bad
+ }
+ y = uint64(b[7])
+ x += y << 49
+ if y < 0x80 {
+ return x, 8
+ }
+ x -= 0x80 << 49
+
+ if len(b) <= 8 {
+ goto bad
+ }
+ y = uint64(b[8])
+ x += y << 56
+ if y < 0x80 {
+ return x, 9
+ }
+ x -= 0x80 << 56
+
+ if len(b) <= 9 {
+ goto bad
+ }
+ y = uint64(b[9])
+ x += y << 63
+ if y < 2 {
+ return x, 10
+ }
+
+bad:
+ return 0, 0
+}
diff --git a/vendor/github.com/golang/protobuf/proto/text.go b/vendor/github.com/golang/protobuf/proto/text.go
new file mode 100644
index 0000000000000000000000000000000000000000..1aaee725b45b3e141a710273ec098ec601a71ecd
--- /dev/null
+++ b/vendor/github.com/golang/protobuf/proto/text.go
@@ -0,0 +1,843 @@
+// Go support for Protocol Buffers - Google's data interchange format
+//
+// Copyright 2010 The Go Authors. All rights reserved.
+// https://github.com/golang/protobuf
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package proto
+
+// Functions for writing the text protocol buffer format.
+
+import (
+ "bufio"
+ "bytes"
+ "encoding"
+ "errors"
+ "fmt"
+ "io"
+ "log"
+ "math"
+ "reflect"
+ "sort"
+ "strings"
+)
+
+var (
+ newline = []byte("\n")
+ spaces = []byte(" ")
+ endBraceNewline = []byte("}\n")
+ backslashN = []byte{'\\', 'n'}
+ backslashR = []byte{'\\', 'r'}
+ backslashT = []byte{'\\', 't'}
+ backslashDQ = []byte{'\\', '"'}
+ backslashBS = []byte{'\\', '\\'}
+ posInf = []byte("inf")
+ negInf = []byte("-inf")
+ nan = []byte("nan")
+)
+
+type writer interface {
+ io.Writer
+ WriteByte(byte) error
+}
+
+// textWriter is an io.Writer that tracks its indentation level.
+type textWriter struct {
+ ind int
+ complete bool // if the current position is a complete line
+ compact bool // whether to write out as a one-liner
+ w writer
+}
+
+func (w *textWriter) WriteString(s string) (n int, err error) {
+ if !strings.Contains(s, "\n") {
+ if !w.compact && w.complete {
+ w.writeIndent()
+ }
+ w.complete = false
+ return io.WriteString(w.w, s)
+ }
+ // WriteString is typically called without newlines, so this
+ // codepath and its copy are rare. We copy to avoid
+ // duplicating all of Write's logic here.
+ return w.Write([]byte(s))
+}
+
+func (w *textWriter) Write(p []byte) (n int, err error) {
+ newlines := bytes.Count(p, newline)
+ if newlines == 0 {
+ if !w.compact && w.complete {
+ w.writeIndent()
+ }
+ n, err = w.w.Write(p)
+ w.complete = false
+ return n, err
+ }
+
+ frags := bytes.SplitN(p, newline, newlines+1)
+ if w.compact {
+ for i, frag := range frags {
+ if i > 0 {
+ if err := w.w.WriteByte(' '); err != nil {
+ return n, err
+ }
+ n++
+ }
+ nn, err := w.w.Write(frag)
+ n += nn
+ if err != nil {
+ return n, err
+ }
+ }
+ return n, nil
+ }
+
+ for i, frag := range frags {
+ if w.complete {
+ w.writeIndent()
+ }
+ nn, err := w.w.Write(frag)
+ n += nn
+ if err != nil {
+ return n, err
+ }
+ if i+1 < len(frags) {
+ if err := w.w.WriteByte('\n'); err != nil {
+ return n, err
+ }
+ n++
+ }
+ }
+ w.complete = len(frags[len(frags)-1]) == 0
+ return n, nil
+}
+
+func (w *textWriter) WriteByte(c byte) error {
+ if w.compact && c == '\n' {
+ c = ' '
+ }
+ if !w.compact && w.complete {
+ w.writeIndent()
+ }
+ err := w.w.WriteByte(c)
+ w.complete = c == '\n'
+ return err
+}
+
+func (w *textWriter) indent() { w.ind++ }
+
+func (w *textWriter) unindent() {
+ if w.ind == 0 {
+ log.Print("proto: textWriter unindented too far")
+ return
+ }
+ w.ind--
+}
+
+func writeName(w *textWriter, props *Properties) error {
+ if _, err := w.WriteString(props.OrigName); err != nil {
+ return err
+ }
+ if props.Wire != "group" {
+ return w.WriteByte(':')
+ }
+ return nil
+}
+
+func requiresQuotes(u string) bool {
+ // When type URL contains any characters except [0-9A-Za-z./\-]*, it must be quoted.
+ for _, ch := range u {
+ switch {
+ case ch == '.' || ch == '/' || ch == '_':
+ continue
+ case '0' <= ch && ch <= '9':
+ continue
+ case 'A' <= ch && ch <= 'Z':
+ continue
+ case 'a' <= ch && ch <= 'z':
+ continue
+ default:
+ return true
+ }
+ }
+ return false
+}
+
+// isAny reports whether sv is a google.protobuf.Any message
+func isAny(sv reflect.Value) bool {
+ type wkt interface {
+ XXX_WellKnownType() string
+ }
+ t, ok := sv.Addr().Interface().(wkt)
+ return ok && t.XXX_WellKnownType() == "Any"
+}
+
+// writeProto3Any writes an expanded google.protobuf.Any message.
+//
+// It returns (false, nil) if sv value can't be unmarshaled (e.g. because
+// required messages are not linked in).
+//
+// It returns (true, error) when sv was written in expanded format or an error
+// was encountered.
+func (tm *TextMarshaler) writeProto3Any(w *textWriter, sv reflect.Value) (bool, error) {
+ turl := sv.FieldByName("TypeUrl")
+ val := sv.FieldByName("Value")
+ if !turl.IsValid() || !val.IsValid() {
+ return true, errors.New("proto: invalid google.protobuf.Any message")
+ }
+
+ b, ok := val.Interface().([]byte)
+ if !ok {
+ return true, errors.New("proto: invalid google.protobuf.Any message")
+ }
+
+ parts := strings.Split(turl.String(), "/")
+ mt := MessageType(parts[len(parts)-1])
+ if mt == nil {
+ return false, nil
+ }
+ m := reflect.New(mt.Elem())
+ if err := Unmarshal(b, m.Interface().(Message)); err != nil {
+ return false, nil
+ }
+ w.Write([]byte("["))
+ u := turl.String()
+ if requiresQuotes(u) {
+ writeString(w, u)
+ } else {
+ w.Write([]byte(u))
+ }
+ if w.compact {
+ w.Write([]byte("]:<"))
+ } else {
+ w.Write([]byte("]: <\n"))
+ w.ind++
+ }
+ if err := tm.writeStruct(w, m.Elem()); err != nil {
+ return true, err
+ }
+ if w.compact {
+ w.Write([]byte("> "))
+ } else {
+ w.ind--
+ w.Write([]byte(">\n"))
+ }
+ return true, nil
+}
+
+func (tm *TextMarshaler) writeStruct(w *textWriter, sv reflect.Value) error {
+ if tm.ExpandAny && isAny(sv) {
+ if canExpand, err := tm.writeProto3Any(w, sv); canExpand {
+ return err
+ }
+ }
+ st := sv.Type()
+ sprops := GetProperties(st)
+ for i := 0; i < sv.NumField(); i++ {
+ fv := sv.Field(i)
+ props := sprops.Prop[i]
+ name := st.Field(i).Name
+
+ if name == "XXX_NoUnkeyedLiteral" {
+ continue
+ }
+
+ if strings.HasPrefix(name, "XXX_") {
+ // There are two XXX_ fields:
+ // XXX_unrecognized []byte
+ // XXX_extensions map[int32]proto.Extension
+ // The first is handled here;
+ // the second is handled at the bottom of this function.
+ if name == "XXX_unrecognized" && !fv.IsNil() {
+ if err := writeUnknownStruct(w, fv.Interface().([]byte)); err != nil {
+ return err
+ }
+ }
+ continue
+ }
+ if fv.Kind() == reflect.Ptr && fv.IsNil() {
+ // Field not filled in. This could be an optional field or
+ // a required field that wasn't filled in. Either way, there
+ // isn't anything we can show for it.
+ continue
+ }
+ if fv.Kind() == reflect.Slice && fv.IsNil() {
+ // Repeated field that is empty, or a bytes field that is unused.
+ continue
+ }
+
+ if props.Repeated && fv.Kind() == reflect.Slice {
+ // Repeated field.
+ for j := 0; j < fv.Len(); j++ {
+ if err := writeName(w, props); err != nil {
+ return err
+ }
+ if !w.compact {
+ if err := w.WriteByte(' '); err != nil {
+ return err
+ }
+ }
+ v := fv.Index(j)
+ if v.Kind() == reflect.Ptr && v.IsNil() {
+ // A nil message in a repeated field is not valid,
+ // but we can handle that more gracefully than panicking.
+ if _, err := w.Write([]byte("\n")); err != nil {
+ return err
+ }
+ continue
+ }
+ if err := tm.writeAny(w, v, props); err != nil {
+ return err
+ }
+ if err := w.WriteByte('\n'); err != nil {
+ return err
+ }
+ }
+ continue
+ }
+ if fv.Kind() == reflect.Map {
+ // Map fields are rendered as a repeated struct with key/value fields.
+ keys := fv.MapKeys()
+ sort.Sort(mapKeys(keys))
+ for _, key := range keys {
+ val := fv.MapIndex(key)
+ if err := writeName(w, props); err != nil {
+ return err
+ }
+ if !w.compact {
+ if err := w.WriteByte(' '); err != nil {
+ return err
+ }
+ }
+ // open struct
+ if err := w.WriteByte('<'); err != nil {
+ return err
+ }
+ if !w.compact {
+ if err := w.WriteByte('\n'); err != nil {
+ return err
+ }
+ }
+ w.indent()
+ // key
+ if _, err := w.WriteString("key:"); err != nil {
+ return err
+ }
+ if !w.compact {
+ if err := w.WriteByte(' '); err != nil {
+ return err
+ }
+ }
+ if err := tm.writeAny(w, key, props.MapKeyProp); err != nil {
+ return err
+ }
+ if err := w.WriteByte('\n'); err != nil {
+ return err
+ }
+ // nil values aren't legal, but we can avoid panicking because of them.
+ if val.Kind() != reflect.Ptr || !val.IsNil() {
+ // value
+ if _, err := w.WriteString("value:"); err != nil {
+ return err
+ }
+ if !w.compact {
+ if err := w.WriteByte(' '); err != nil {
+ return err
+ }
+ }
+ if err := tm.writeAny(w, val, props.MapValProp); err != nil {
+ return err
+ }
+ if err := w.WriteByte('\n'); err != nil {
+ return err
+ }
+ }
+ // close struct
+ w.unindent()
+ if err := w.WriteByte('>'); err != nil {
+ return err
+ }
+ if err := w.WriteByte('\n'); err != nil {
+ return err
+ }
+ }
+ continue
+ }
+ if props.proto3 && fv.Kind() == reflect.Slice && fv.Len() == 0 {
+ // empty bytes field
+ continue
+ }
+ if fv.Kind() != reflect.Ptr && fv.Kind() != reflect.Slice {
+ // proto3 non-repeated scalar field; skip if zero value
+ if isProto3Zero(fv) {
+ continue
+ }
+ }
+
+ if fv.Kind() == reflect.Interface {
+ // Check if it is a oneof.
+ if st.Field(i).Tag.Get("protobuf_oneof") != "" {
+ // fv is nil, or holds a pointer to generated struct.
+ // That generated struct has exactly one field,
+ // which has a protobuf struct tag.
+ if fv.IsNil() {
+ continue
+ }
+ inner := fv.Elem().Elem() // interface -> *T -> T
+ tag := inner.Type().Field(0).Tag.Get("protobuf")
+ props = new(Properties) // Overwrite the outer props var, but not its pointee.
+ props.Parse(tag)
+ // Write the value in the oneof, not the oneof itself.
+ fv = inner.Field(0)
+
+ // Special case to cope with malformed messages gracefully:
+ // If the value in the oneof is a nil pointer, don't panic
+ // in writeAny.
+ if fv.Kind() == reflect.Ptr && fv.IsNil() {
+ // Use errors.New so writeAny won't render quotes.
+ msg := errors.New("/* nil */")
+ fv = reflect.ValueOf(&msg).Elem()
+ }
+ }
+ }
+
+ if err := writeName(w, props); err != nil {
+ return err
+ }
+ if !w.compact {
+ if err := w.WriteByte(' '); err != nil {
+ return err
+ }
+ }
+
+ // Enums have a String method, so writeAny will work fine.
+ if err := tm.writeAny(w, fv, props); err != nil {
+ return err
+ }
+
+ if err := w.WriteByte('\n'); err != nil {
+ return err
+ }
+ }
+
+ // Extensions (the XXX_extensions field).
+ pv := sv.Addr()
+ if _, err := extendable(pv.Interface()); err == nil {
+ if err := tm.writeExtensions(w, pv); err != nil {
+ return err
+ }
+ }
+
+ return nil
+}
+
+// writeAny writes an arbitrary field.
+func (tm *TextMarshaler) writeAny(w *textWriter, v reflect.Value, props *Properties) error {
+ v = reflect.Indirect(v)
+
+ // Floats have special cases.
+ if v.Kind() == reflect.Float32 || v.Kind() == reflect.Float64 {
+ x := v.Float()
+ var b []byte
+ switch {
+ case math.IsInf(x, 1):
+ b = posInf
+ case math.IsInf(x, -1):
+ b = negInf
+ case math.IsNaN(x):
+ b = nan
+ }
+ if b != nil {
+ _, err := w.Write(b)
+ return err
+ }
+ // Other values are handled below.
+ }
+
+ // We don't attempt to serialise every possible value type; only those
+ // that can occur in protocol buffers.
+ switch v.Kind() {
+ case reflect.Slice:
+ // Should only be a []byte; repeated fields are handled in writeStruct.
+ if err := writeString(w, string(v.Bytes())); err != nil {
+ return err
+ }
+ case reflect.String:
+ if err := writeString(w, v.String()); err != nil {
+ return err
+ }
+ case reflect.Struct:
+ // Required/optional group/message.
+ var bra, ket byte = '<', '>'
+ if props != nil && props.Wire == "group" {
+ bra, ket = '{', '}'
+ }
+ if err := w.WriteByte(bra); err != nil {
+ return err
+ }
+ if !w.compact {
+ if err := w.WriteByte('\n'); err != nil {
+ return err
+ }
+ }
+ w.indent()
+ if v.CanAddr() {
+ // Calling v.Interface on a struct causes the reflect package to
+ // copy the entire struct. This is racy with the new Marshaler
+ // since we atomically update the XXX_sizecache.
+ //
+ // Thus, we retrieve a pointer to the struct if possible to avoid
+ // a race since v.Interface on the pointer doesn't copy the struct.
+ //
+ // If v is not addressable, then we are not worried about a race
+ // since it implies that the binary Marshaler cannot possibly be
+ // mutating this value.
+ v = v.Addr()
+ }
+ if etm, ok := v.Interface().(encoding.TextMarshaler); ok {
+ text, err := etm.MarshalText()
+ if err != nil {
+ return err
+ }
+ if _, err = w.Write(text); err != nil {
+ return err
+ }
+ } else {
+ if v.Kind() == reflect.Ptr {
+ v = v.Elem()
+ }
+ if err := tm.writeStruct(w, v); err != nil {
+ return err
+ }
+ }
+ w.unindent()
+ if err := w.WriteByte(ket); err != nil {
+ return err
+ }
+ default:
+ _, err := fmt.Fprint(w, v.Interface())
+ return err
+ }
+ return nil
+}
+
+// equivalent to C's isprint.
+func isprint(c byte) bool {
+ return c >= 0x20 && c < 0x7f
+}
+
+// writeString writes a string in the protocol buffer text format.
+// It is similar to strconv.Quote except we don't use Go escape sequences,
+// we treat the string as a byte sequence, and we use octal escapes.
+// These differences are to maintain interoperability with the other
+// languages' implementations of the text format.
+func writeString(w *textWriter, s string) error {
+ // use WriteByte here to get any needed indent
+ if err := w.WriteByte('"'); err != nil {
+ return err
+ }
+ // Loop over the bytes, not the runes.
+ for i := 0; i < len(s); i++ {
+ var err error
+ // Divergence from C++: we don't escape apostrophes.
+ // There's no need to escape them, and the C++ parser
+ // copes with a naked apostrophe.
+ switch c := s[i]; c {
+ case '\n':
+ _, err = w.w.Write(backslashN)
+ case '\r':
+ _, err = w.w.Write(backslashR)
+ case '\t':
+ _, err = w.w.Write(backslashT)
+ case '"':
+ _, err = w.w.Write(backslashDQ)
+ case '\\':
+ _, err = w.w.Write(backslashBS)
+ default:
+ if isprint(c) {
+ err = w.w.WriteByte(c)
+ } else {
+ _, err = fmt.Fprintf(w.w, "\\%03o", c)
+ }
+ }
+ if err != nil {
+ return err
+ }
+ }
+ return w.WriteByte('"')
+}
+
+func writeUnknownStruct(w *textWriter, data []byte) (err error) {
+ if !w.compact {
+ if _, err := fmt.Fprintf(w, "/* %d unknown bytes */\n", len(data)); err != nil {
+ return err
+ }
+ }
+ b := NewBuffer(data)
+ for b.index < len(b.buf) {
+ x, err := b.DecodeVarint()
+ if err != nil {
+ _, err := fmt.Fprintf(w, "/* %v */\n", err)
+ return err
+ }
+ wire, tag := x&7, x>>3
+ if wire == WireEndGroup {
+ w.unindent()
+ if _, err := w.Write(endBraceNewline); err != nil {
+ return err
+ }
+ continue
+ }
+ if _, err := fmt.Fprint(w, tag); err != nil {
+ return err
+ }
+ if wire != WireStartGroup {
+ if err := w.WriteByte(':'); err != nil {
+ return err
+ }
+ }
+ if !w.compact || wire == WireStartGroup {
+ if err := w.WriteByte(' '); err != nil {
+ return err
+ }
+ }
+ switch wire {
+ case WireBytes:
+ buf, e := b.DecodeRawBytes(false)
+ if e == nil {
+ _, err = fmt.Fprintf(w, "%q", buf)
+ } else {
+ _, err = fmt.Fprintf(w, "/* %v */", e)
+ }
+ case WireFixed32:
+ x, err = b.DecodeFixed32()
+ err = writeUnknownInt(w, x, err)
+ case WireFixed64:
+ x, err = b.DecodeFixed64()
+ err = writeUnknownInt(w, x, err)
+ case WireStartGroup:
+ err = w.WriteByte('{')
+ w.indent()
+ case WireVarint:
+ x, err = b.DecodeVarint()
+ err = writeUnknownInt(w, x, err)
+ default:
+ _, err = fmt.Fprintf(w, "/* unknown wire type %d */", wire)
+ }
+ if err != nil {
+ return err
+ }
+ if err = w.WriteByte('\n'); err != nil {
+ return err
+ }
+ }
+ return nil
+}
+
+func writeUnknownInt(w *textWriter, x uint64, err error) error {
+ if err == nil {
+ _, err = fmt.Fprint(w, x)
+ } else {
+ _, err = fmt.Fprintf(w, "/* %v */", err)
+ }
+ return err
+}
+
+type int32Slice []int32
+
+func (s int32Slice) Len() int { return len(s) }
+func (s int32Slice) Less(i, j int) bool { return s[i] < s[j] }
+func (s int32Slice) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
+
+// writeExtensions writes all the extensions in pv.
+// pv is assumed to be a pointer to a protocol message struct that is extendable.
+func (tm *TextMarshaler) writeExtensions(w *textWriter, pv reflect.Value) error {
+ emap := extensionMaps[pv.Type().Elem()]
+ ep, _ := extendable(pv.Interface())
+
+ // Order the extensions by ID.
+ // This isn't strictly necessary, but it will give us
+ // canonical output, which will also make testing easier.
+ m, mu := ep.extensionsRead()
+ if m == nil {
+ return nil
+ }
+ mu.Lock()
+ ids := make([]int32, 0, len(m))
+ for id := range m {
+ ids = append(ids, id)
+ }
+ sort.Sort(int32Slice(ids))
+ mu.Unlock()
+
+ for _, extNum := range ids {
+ ext := m[extNum]
+ var desc *ExtensionDesc
+ if emap != nil {
+ desc = emap[extNum]
+ }
+ if desc == nil {
+ // Unknown extension.
+ if err := writeUnknownStruct(w, ext.enc); err != nil {
+ return err
+ }
+ continue
+ }
+
+ pb, err := GetExtension(ep, desc)
+ if err != nil {
+ return fmt.Errorf("failed getting extension: %v", err)
+ }
+
+ // Repeated extensions will appear as a slice.
+ if !desc.repeated() {
+ if err := tm.writeExtension(w, desc.Name, pb); err != nil {
+ return err
+ }
+ } else {
+ v := reflect.ValueOf(pb)
+ for i := 0; i < v.Len(); i++ {
+ if err := tm.writeExtension(w, desc.Name, v.Index(i).Interface()); err != nil {
+ return err
+ }
+ }
+ }
+ }
+ return nil
+}
+
+func (tm *TextMarshaler) writeExtension(w *textWriter, name string, pb interface{}) error {
+ if _, err := fmt.Fprintf(w, "[%s]:", name); err != nil {
+ return err
+ }
+ if !w.compact {
+ if err := w.WriteByte(' '); err != nil {
+ return err
+ }
+ }
+ if err := tm.writeAny(w, reflect.ValueOf(pb), nil); err != nil {
+ return err
+ }
+ if err := w.WriteByte('\n'); err != nil {
+ return err
+ }
+ return nil
+}
+
+func (w *textWriter) writeIndent() {
+ if !w.complete {
+ return
+ }
+ remain := w.ind * 2
+ for remain > 0 {
+ n := remain
+ if n > len(spaces) {
+ n = len(spaces)
+ }
+ w.w.Write(spaces[:n])
+ remain -= n
+ }
+ w.complete = false
+}
+
+// TextMarshaler is a configurable text format marshaler.
+type TextMarshaler struct {
+ Compact bool // use compact text format (one line).
+ ExpandAny bool // expand google.protobuf.Any messages of known types
+}
+
+// Marshal writes a given protocol buffer in text format.
+// The only errors returned are from w.
+func (tm *TextMarshaler) Marshal(w io.Writer, pb Message) error {
+ val := reflect.ValueOf(pb)
+ if pb == nil || val.IsNil() {
+ w.Write([]byte(""))
+ return nil
+ }
+ var bw *bufio.Writer
+ ww, ok := w.(writer)
+ if !ok {
+ bw = bufio.NewWriter(w)
+ ww = bw
+ }
+ aw := &textWriter{
+ w: ww,
+ complete: true,
+ compact: tm.Compact,
+ }
+
+ if etm, ok := pb.(encoding.TextMarshaler); ok {
+ text, err := etm.MarshalText()
+ if err != nil {
+ return err
+ }
+ if _, err = aw.Write(text); err != nil {
+ return err
+ }
+ if bw != nil {
+ return bw.Flush()
+ }
+ return nil
+ }
+ // Dereference the received pointer so we don't have outer < and >.
+ v := reflect.Indirect(val)
+ if err := tm.writeStruct(aw, v); err != nil {
+ return err
+ }
+ if bw != nil {
+ return bw.Flush()
+ }
+ return nil
+}
+
+// Text is the same as Marshal, but returns the string directly.
+func (tm *TextMarshaler) Text(pb Message) string {
+ var buf bytes.Buffer
+ tm.Marshal(&buf, pb)
+ return buf.String()
+}
+
+var (
+ defaultTextMarshaler = TextMarshaler{}
+ compactTextMarshaler = TextMarshaler{Compact: true}
+)
+
+// TODO: consider removing some of the Marshal functions below.
+
+// MarshalText writes a given protocol buffer in text format.
+// The only errors returned are from w.
+func MarshalText(w io.Writer, pb Message) error { return defaultTextMarshaler.Marshal(w, pb) }
+
+// MarshalTextString is the same as MarshalText, but returns the string directly.
+func MarshalTextString(pb Message) string { return defaultTextMarshaler.Text(pb) }
+
+// CompactText writes a given protocol buffer in compact text format (one line).
+func CompactText(w io.Writer, pb Message) error { return compactTextMarshaler.Marshal(w, pb) }
+
+// CompactTextString is the same as CompactText, but returns the string directly.
+func CompactTextString(pb Message) string { return compactTextMarshaler.Text(pb) }
diff --git a/vendor/github.com/golang/protobuf/proto/text_parser.go b/vendor/github.com/golang/protobuf/proto/text_parser.go
new file mode 100644
index 0000000000000000000000000000000000000000..bb55a3af276941639621b1e591ce1b8304afcd41
--- /dev/null
+++ b/vendor/github.com/golang/protobuf/proto/text_parser.go
@@ -0,0 +1,880 @@
+// Go support for Protocol Buffers - Google's data interchange format
+//
+// Copyright 2010 The Go Authors. All rights reserved.
+// https://github.com/golang/protobuf
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package proto
+
+// Functions for parsing the Text protocol buffer format.
+// TODO: message sets.
+
+import (
+ "encoding"
+ "errors"
+ "fmt"
+ "reflect"
+ "strconv"
+ "strings"
+ "unicode/utf8"
+)
+
+// Error string emitted when deserializing Any and fields are already set
+const anyRepeatedlyUnpacked = "Any message unpacked multiple times, or %q already set"
+
+type ParseError struct {
+ Message string
+ Line int // 1-based line number
+ Offset int // 0-based byte offset from start of input
+}
+
+func (p *ParseError) Error() string {
+ if p.Line == 1 {
+ // show offset only for first line
+ return fmt.Sprintf("line 1.%d: %v", p.Offset, p.Message)
+ }
+ return fmt.Sprintf("line %d: %v", p.Line, p.Message)
+}
+
+type token struct {
+ value string
+ err *ParseError
+ line int // line number
+ offset int // byte number from start of input, not start of line
+ unquoted string // the unquoted version of value, if it was a quoted string
+}
+
+func (t *token) String() string {
+ if t.err == nil {
+ return fmt.Sprintf("%q (line=%d, offset=%d)", t.value, t.line, t.offset)
+ }
+ return fmt.Sprintf("parse error: %v", t.err)
+}
+
+type textParser struct {
+ s string // remaining input
+ done bool // whether the parsing is finished (success or error)
+ backed bool // whether back() was called
+ offset, line int
+ cur token
+}
+
+func newTextParser(s string) *textParser {
+ p := new(textParser)
+ p.s = s
+ p.line = 1
+ p.cur.line = 1
+ return p
+}
+
+func (p *textParser) errorf(format string, a ...interface{}) *ParseError {
+ pe := &ParseError{fmt.Sprintf(format, a...), p.cur.line, p.cur.offset}
+ p.cur.err = pe
+ p.done = true
+ return pe
+}
+
+// Numbers and identifiers are matched by [-+._A-Za-z0-9]
+func isIdentOrNumberChar(c byte) bool {
+ switch {
+ case 'A' <= c && c <= 'Z', 'a' <= c && c <= 'z':
+ return true
+ case '0' <= c && c <= '9':
+ return true
+ }
+ switch c {
+ case '-', '+', '.', '_':
+ return true
+ }
+ return false
+}
+
+func isWhitespace(c byte) bool {
+ switch c {
+ case ' ', '\t', '\n', '\r':
+ return true
+ }
+ return false
+}
+
+func isQuote(c byte) bool {
+ switch c {
+ case '"', '\'':
+ return true
+ }
+ return false
+}
+
+func (p *textParser) skipWhitespace() {
+ i := 0
+ for i < len(p.s) && (isWhitespace(p.s[i]) || p.s[i] == '#') {
+ if p.s[i] == '#' {
+ // comment; skip to end of line or input
+ for i < len(p.s) && p.s[i] != '\n' {
+ i++
+ }
+ if i == len(p.s) {
+ break
+ }
+ }
+ if p.s[i] == '\n' {
+ p.line++
+ }
+ i++
+ }
+ p.offset += i
+ p.s = p.s[i:len(p.s)]
+ if len(p.s) == 0 {
+ p.done = true
+ }
+}
+
+func (p *textParser) advance() {
+ // Skip whitespace
+ p.skipWhitespace()
+ if p.done {
+ return
+ }
+
+ // Start of non-whitespace
+ p.cur.err = nil
+ p.cur.offset, p.cur.line = p.offset, p.line
+ p.cur.unquoted = ""
+ switch p.s[0] {
+ case '<', '>', '{', '}', ':', '[', ']', ';', ',', '/':
+ // Single symbol
+ p.cur.value, p.s = p.s[0:1], p.s[1:len(p.s)]
+ case '"', '\'':
+ // Quoted string
+ i := 1
+ for i < len(p.s) && p.s[i] != p.s[0] && p.s[i] != '\n' {
+ if p.s[i] == '\\' && i+1 < len(p.s) {
+ // skip escaped char
+ i++
+ }
+ i++
+ }
+ if i >= len(p.s) || p.s[i] != p.s[0] {
+ p.errorf("unmatched quote")
+ return
+ }
+ unq, err := unquoteC(p.s[1:i], rune(p.s[0]))
+ if err != nil {
+ p.errorf("invalid quoted string %s: %v", p.s[0:i+1], err)
+ return
+ }
+ p.cur.value, p.s = p.s[0:i+1], p.s[i+1:len(p.s)]
+ p.cur.unquoted = unq
+ default:
+ i := 0
+ for i < len(p.s) && isIdentOrNumberChar(p.s[i]) {
+ i++
+ }
+ if i == 0 {
+ p.errorf("unexpected byte %#x", p.s[0])
+ return
+ }
+ p.cur.value, p.s = p.s[0:i], p.s[i:len(p.s)]
+ }
+ p.offset += len(p.cur.value)
+}
+
+var (
+ errBadUTF8 = errors.New("proto: bad UTF-8")
+)
+
+func unquoteC(s string, quote rune) (string, error) {
+ // This is based on C++'s tokenizer.cc.
+ // Despite its name, this is *not* parsing C syntax.
+ // For instance, "\0" is an invalid quoted string.
+
+ // Avoid allocation in trivial cases.
+ simple := true
+ for _, r := range s {
+ if r == '\\' || r == quote {
+ simple = false
+ break
+ }
+ }
+ if simple {
+ return s, nil
+ }
+
+ buf := make([]byte, 0, 3*len(s)/2)
+ for len(s) > 0 {
+ r, n := utf8.DecodeRuneInString(s)
+ if r == utf8.RuneError && n == 1 {
+ return "", errBadUTF8
+ }
+ s = s[n:]
+ if r != '\\' {
+ if r < utf8.RuneSelf {
+ buf = append(buf, byte(r))
+ } else {
+ buf = append(buf, string(r)...)
+ }
+ continue
+ }
+
+ ch, tail, err := unescape(s)
+ if err != nil {
+ return "", err
+ }
+ buf = append(buf, ch...)
+ s = tail
+ }
+ return string(buf), nil
+}
+
+func unescape(s string) (ch string, tail string, err error) {
+ r, n := utf8.DecodeRuneInString(s)
+ if r == utf8.RuneError && n == 1 {
+ return "", "", errBadUTF8
+ }
+ s = s[n:]
+ switch r {
+ case 'a':
+ return "\a", s, nil
+ case 'b':
+ return "\b", s, nil
+ case 'f':
+ return "\f", s, nil
+ case 'n':
+ return "\n", s, nil
+ case 'r':
+ return "\r", s, nil
+ case 't':
+ return "\t", s, nil
+ case 'v':
+ return "\v", s, nil
+ case '?':
+ return "?", s, nil // trigraph workaround
+ case '\'', '"', '\\':
+ return string(r), s, nil
+ case '0', '1', '2', '3', '4', '5', '6', '7':
+ if len(s) < 2 {
+ return "", "", fmt.Errorf(`\%c requires 2 following digits`, r)
+ }
+ ss := string(r) + s[:2]
+ s = s[2:]
+ i, err := strconv.ParseUint(ss, 8, 8)
+ if err != nil {
+ return "", "", fmt.Errorf(`\%s contains non-octal digits`, ss)
+ }
+ return string([]byte{byte(i)}), s, nil
+ case 'x', 'X', 'u', 'U':
+ var n int
+ switch r {
+ case 'x', 'X':
+ n = 2
+ case 'u':
+ n = 4
+ case 'U':
+ n = 8
+ }
+ if len(s) < n {
+ return "", "", fmt.Errorf(`\%c requires %d following digits`, r, n)
+ }
+ ss := s[:n]
+ s = s[n:]
+ i, err := strconv.ParseUint(ss, 16, 64)
+ if err != nil {
+ return "", "", fmt.Errorf(`\%c%s contains non-hexadecimal digits`, r, ss)
+ }
+ if r == 'x' || r == 'X' {
+ return string([]byte{byte(i)}), s, nil
+ }
+ if i > utf8.MaxRune {
+ return "", "", fmt.Errorf(`\%c%s is not a valid Unicode code point`, r, ss)
+ }
+ return string(i), s, nil
+ }
+ return "", "", fmt.Errorf(`unknown escape \%c`, r)
+}
+
+// Back off the parser by one token. Can only be done between calls to next().
+// It makes the next advance() a no-op.
+func (p *textParser) back() { p.backed = true }
+
+// Advances the parser and returns the new current token.
+func (p *textParser) next() *token {
+ if p.backed || p.done {
+ p.backed = false
+ return &p.cur
+ }
+ p.advance()
+ if p.done {
+ p.cur.value = ""
+ } else if len(p.cur.value) > 0 && isQuote(p.cur.value[0]) {
+ // Look for multiple quoted strings separated by whitespace,
+ // and concatenate them.
+ cat := p.cur
+ for {
+ p.skipWhitespace()
+ if p.done || !isQuote(p.s[0]) {
+ break
+ }
+ p.advance()
+ if p.cur.err != nil {
+ return &p.cur
+ }
+ cat.value += " " + p.cur.value
+ cat.unquoted += p.cur.unquoted
+ }
+ p.done = false // parser may have seen EOF, but we want to return cat
+ p.cur = cat
+ }
+ return &p.cur
+}
+
+func (p *textParser) consumeToken(s string) error {
+ tok := p.next()
+ if tok.err != nil {
+ return tok.err
+ }
+ if tok.value != s {
+ p.back()
+ return p.errorf("expected %q, found %q", s, tok.value)
+ }
+ return nil
+}
+
+// Return a RequiredNotSetError indicating which required field was not set.
+func (p *textParser) missingRequiredFieldError(sv reflect.Value) *RequiredNotSetError {
+ st := sv.Type()
+ sprops := GetProperties(st)
+ for i := 0; i < st.NumField(); i++ {
+ if !isNil(sv.Field(i)) {
+ continue
+ }
+
+ props := sprops.Prop[i]
+ if props.Required {
+ return &RequiredNotSetError{fmt.Sprintf("%v.%v", st, props.OrigName)}
+ }
+ }
+ return &RequiredNotSetError{fmt.Sprintf("%v.", st)} // should not happen
+}
+
+// Returns the index in the struct for the named field, as well as the parsed tag properties.
+func structFieldByName(sprops *StructProperties, name string) (int, *Properties, bool) {
+ i, ok := sprops.decoderOrigNames[name]
+ if ok {
+ return i, sprops.Prop[i], true
+ }
+ return -1, nil, false
+}
+
+// Consume a ':' from the input stream (if the next token is a colon),
+// returning an error if a colon is needed but not present.
+func (p *textParser) checkForColon(props *Properties, typ reflect.Type) *ParseError {
+ tok := p.next()
+ if tok.err != nil {
+ return tok.err
+ }
+ if tok.value != ":" {
+ // Colon is optional when the field is a group or message.
+ needColon := true
+ switch props.Wire {
+ case "group":
+ needColon = false
+ case "bytes":
+ // A "bytes" field is either a message, a string, or a repeated field;
+ // those three become *T, *string and []T respectively, so we can check for
+ // this field being a pointer to a non-string.
+ if typ.Kind() == reflect.Ptr {
+ // *T or *string
+ if typ.Elem().Kind() == reflect.String {
+ break
+ }
+ } else if typ.Kind() == reflect.Slice {
+ // []T or []*T
+ if typ.Elem().Kind() != reflect.Ptr {
+ break
+ }
+ } else if typ.Kind() == reflect.String {
+ // The proto3 exception is for a string field,
+ // which requires a colon.
+ break
+ }
+ needColon = false
+ }
+ if needColon {
+ return p.errorf("expected ':', found %q", tok.value)
+ }
+ p.back()
+ }
+ return nil
+}
+
+func (p *textParser) readStruct(sv reflect.Value, terminator string) error {
+ st := sv.Type()
+ sprops := GetProperties(st)
+ reqCount := sprops.reqCount
+ var reqFieldErr error
+ fieldSet := make(map[string]bool)
+ // A struct is a sequence of "name: value", terminated by one of
+ // '>' or '}', or the end of the input. A name may also be
+ // "[extension]" or "[type/url]".
+ //
+ // The whole struct can also be an expanded Any message, like:
+ // [type/url] < ... struct contents ... >
+ for {
+ tok := p.next()
+ if tok.err != nil {
+ return tok.err
+ }
+ if tok.value == terminator {
+ break
+ }
+ if tok.value == "[" {
+ // Looks like an extension or an Any.
+ //
+ // TODO: Check whether we need to handle
+ // namespace rooted names (e.g. ".something.Foo").
+ extName, err := p.consumeExtName()
+ if err != nil {
+ return err
+ }
+
+ if s := strings.LastIndex(extName, "/"); s >= 0 {
+ // If it contains a slash, it's an Any type URL.
+ messageName := extName[s+1:]
+ mt := MessageType(messageName)
+ if mt == nil {
+ return p.errorf("unrecognized message %q in google.protobuf.Any", messageName)
+ }
+ tok = p.next()
+ if tok.err != nil {
+ return tok.err
+ }
+ // consume an optional colon
+ if tok.value == ":" {
+ tok = p.next()
+ if tok.err != nil {
+ return tok.err
+ }
+ }
+ var terminator string
+ switch tok.value {
+ case "<":
+ terminator = ">"
+ case "{":
+ terminator = "}"
+ default:
+ return p.errorf("expected '{' or '<', found %q", tok.value)
+ }
+ v := reflect.New(mt.Elem())
+ if pe := p.readStruct(v.Elem(), terminator); pe != nil {
+ return pe
+ }
+ b, err := Marshal(v.Interface().(Message))
+ if err != nil {
+ return p.errorf("failed to marshal message of type %q: %v", messageName, err)
+ }
+ if fieldSet["type_url"] {
+ return p.errorf(anyRepeatedlyUnpacked, "type_url")
+ }
+ if fieldSet["value"] {
+ return p.errorf(anyRepeatedlyUnpacked, "value")
+ }
+ sv.FieldByName("TypeUrl").SetString(extName)
+ sv.FieldByName("Value").SetBytes(b)
+ fieldSet["type_url"] = true
+ fieldSet["value"] = true
+ continue
+ }
+
+ var desc *ExtensionDesc
+ // This could be faster, but it's functional.
+ // TODO: Do something smarter than a linear scan.
+ for _, d := range RegisteredExtensions(reflect.New(st).Interface().(Message)) {
+ if d.Name == extName {
+ desc = d
+ break
+ }
+ }
+ if desc == nil {
+ return p.errorf("unrecognized extension %q", extName)
+ }
+
+ props := &Properties{}
+ props.Parse(desc.Tag)
+
+ typ := reflect.TypeOf(desc.ExtensionType)
+ if err := p.checkForColon(props, typ); err != nil {
+ return err
+ }
+
+ rep := desc.repeated()
+
+ // Read the extension structure, and set it in
+ // the value we're constructing.
+ var ext reflect.Value
+ if !rep {
+ ext = reflect.New(typ).Elem()
+ } else {
+ ext = reflect.New(typ.Elem()).Elem()
+ }
+ if err := p.readAny(ext, props); err != nil {
+ if _, ok := err.(*RequiredNotSetError); !ok {
+ return err
+ }
+ reqFieldErr = err
+ }
+ ep := sv.Addr().Interface().(Message)
+ if !rep {
+ SetExtension(ep, desc, ext.Interface())
+ } else {
+ old, err := GetExtension(ep, desc)
+ var sl reflect.Value
+ if err == nil {
+ sl = reflect.ValueOf(old) // existing slice
+ } else {
+ sl = reflect.MakeSlice(typ, 0, 1)
+ }
+ sl = reflect.Append(sl, ext)
+ SetExtension(ep, desc, sl.Interface())
+ }
+ if err := p.consumeOptionalSeparator(); err != nil {
+ return err
+ }
+ continue
+ }
+
+ // This is a normal, non-extension field.
+ name := tok.value
+ var dst reflect.Value
+ fi, props, ok := structFieldByName(sprops, name)
+ if ok {
+ dst = sv.Field(fi)
+ } else if oop, ok := sprops.OneofTypes[name]; ok {
+ // It is a oneof.
+ props = oop.Prop
+ nv := reflect.New(oop.Type.Elem())
+ dst = nv.Elem().Field(0)
+ field := sv.Field(oop.Field)
+ if !field.IsNil() {
+ return p.errorf("field '%s' would overwrite already parsed oneof '%s'", name, sv.Type().Field(oop.Field).Name)
+ }
+ field.Set(nv)
+ }
+ if !dst.IsValid() {
+ return p.errorf("unknown field name %q in %v", name, st)
+ }
+
+ if dst.Kind() == reflect.Map {
+ // Consume any colon.
+ if err := p.checkForColon(props, dst.Type()); err != nil {
+ return err
+ }
+
+ // Construct the map if it doesn't already exist.
+ if dst.IsNil() {
+ dst.Set(reflect.MakeMap(dst.Type()))
+ }
+ key := reflect.New(dst.Type().Key()).Elem()
+ val := reflect.New(dst.Type().Elem()).Elem()
+
+ // The map entry should be this sequence of tokens:
+ // < key : KEY value : VALUE >
+ // However, implementations may omit key or value, and technically
+ // we should support them in any order. See b/28924776 for a time
+ // this went wrong.
+
+ tok := p.next()
+ var terminator string
+ switch tok.value {
+ case "<":
+ terminator = ">"
+ case "{":
+ terminator = "}"
+ default:
+ return p.errorf("expected '{' or '<', found %q", tok.value)
+ }
+ for {
+ tok := p.next()
+ if tok.err != nil {
+ return tok.err
+ }
+ if tok.value == terminator {
+ break
+ }
+ switch tok.value {
+ case "key":
+ if err := p.consumeToken(":"); err != nil {
+ return err
+ }
+ if err := p.readAny(key, props.MapKeyProp); err != nil {
+ return err
+ }
+ if err := p.consumeOptionalSeparator(); err != nil {
+ return err
+ }
+ case "value":
+ if err := p.checkForColon(props.MapValProp, dst.Type().Elem()); err != nil {
+ return err
+ }
+ if err := p.readAny(val, props.MapValProp); err != nil {
+ return err
+ }
+ if err := p.consumeOptionalSeparator(); err != nil {
+ return err
+ }
+ default:
+ p.back()
+ return p.errorf(`expected "key", "value", or %q, found %q`, terminator, tok.value)
+ }
+ }
+
+ dst.SetMapIndex(key, val)
+ continue
+ }
+
+ // Check that it's not already set if it's not a repeated field.
+ if !props.Repeated && fieldSet[name] {
+ return p.errorf("non-repeated field %q was repeated", name)
+ }
+
+ if err := p.checkForColon(props, dst.Type()); err != nil {
+ return err
+ }
+
+ // Parse into the field.
+ fieldSet[name] = true
+ if err := p.readAny(dst, props); err != nil {
+ if _, ok := err.(*RequiredNotSetError); !ok {
+ return err
+ }
+ reqFieldErr = err
+ }
+ if props.Required {
+ reqCount--
+ }
+
+ if err := p.consumeOptionalSeparator(); err != nil {
+ return err
+ }
+
+ }
+
+ if reqCount > 0 {
+ return p.missingRequiredFieldError(sv)
+ }
+ return reqFieldErr
+}
+
+// consumeExtName consumes extension name or expanded Any type URL and the
+// following ']'. It returns the name or URL consumed.
+func (p *textParser) consumeExtName() (string, error) {
+ tok := p.next()
+ if tok.err != nil {
+ return "", tok.err
+ }
+
+ // If extension name or type url is quoted, it's a single token.
+ if len(tok.value) > 2 && isQuote(tok.value[0]) && tok.value[len(tok.value)-1] == tok.value[0] {
+ name, err := unquoteC(tok.value[1:len(tok.value)-1], rune(tok.value[0]))
+ if err != nil {
+ return "", err
+ }
+ return name, p.consumeToken("]")
+ }
+
+ // Consume everything up to "]"
+ var parts []string
+ for tok.value != "]" {
+ parts = append(parts, tok.value)
+ tok = p.next()
+ if tok.err != nil {
+ return "", p.errorf("unrecognized type_url or extension name: %s", tok.err)
+ }
+ if p.done && tok.value != "]" {
+ return "", p.errorf("unclosed type_url or extension name")
+ }
+ }
+ return strings.Join(parts, ""), nil
+}
+
+// consumeOptionalSeparator consumes an optional semicolon or comma.
+// It is used in readStruct to provide backward compatibility.
+func (p *textParser) consumeOptionalSeparator() error {
+ tok := p.next()
+ if tok.err != nil {
+ return tok.err
+ }
+ if tok.value != ";" && tok.value != "," {
+ p.back()
+ }
+ return nil
+}
+
+func (p *textParser) readAny(v reflect.Value, props *Properties) error {
+ tok := p.next()
+ if tok.err != nil {
+ return tok.err
+ }
+ if tok.value == "" {
+ return p.errorf("unexpected EOF")
+ }
+
+ switch fv := v; fv.Kind() {
+ case reflect.Slice:
+ at := v.Type()
+ if at.Elem().Kind() == reflect.Uint8 {
+ // Special case for []byte
+ if tok.value[0] != '"' && tok.value[0] != '\'' {
+ // Deliberately written out here, as the error after
+ // this switch statement would write "invalid []byte: ...",
+ // which is not as user-friendly.
+ return p.errorf("invalid string: %v", tok.value)
+ }
+ bytes := []byte(tok.unquoted)
+ fv.Set(reflect.ValueOf(bytes))
+ return nil
+ }
+ // Repeated field.
+ if tok.value == "[" {
+ // Repeated field with list notation, like [1,2,3].
+ for {
+ fv.Set(reflect.Append(fv, reflect.New(at.Elem()).Elem()))
+ err := p.readAny(fv.Index(fv.Len()-1), props)
+ if err != nil {
+ return err
+ }
+ tok := p.next()
+ if tok.err != nil {
+ return tok.err
+ }
+ if tok.value == "]" {
+ break
+ }
+ if tok.value != "," {
+ return p.errorf("Expected ']' or ',' found %q", tok.value)
+ }
+ }
+ return nil
+ }
+ // One value of the repeated field.
+ p.back()
+ fv.Set(reflect.Append(fv, reflect.New(at.Elem()).Elem()))
+ return p.readAny(fv.Index(fv.Len()-1), props)
+ case reflect.Bool:
+ // true/1/t/True or false/f/0/False.
+ switch tok.value {
+ case "true", "1", "t", "True":
+ fv.SetBool(true)
+ return nil
+ case "false", "0", "f", "False":
+ fv.SetBool(false)
+ return nil
+ }
+ case reflect.Float32, reflect.Float64:
+ v := tok.value
+ // Ignore 'f' for compatibility with output generated by C++, but don't
+ // remove 'f' when the value is "-inf" or "inf".
+ if strings.HasSuffix(v, "f") && tok.value != "-inf" && tok.value != "inf" {
+ v = v[:len(v)-1]
+ }
+ if f, err := strconv.ParseFloat(v, fv.Type().Bits()); err == nil {
+ fv.SetFloat(f)
+ return nil
+ }
+ case reflect.Int32:
+ if x, err := strconv.ParseInt(tok.value, 0, 32); err == nil {
+ fv.SetInt(x)
+ return nil
+ }
+
+ if len(props.Enum) == 0 {
+ break
+ }
+ m, ok := enumValueMaps[props.Enum]
+ if !ok {
+ break
+ }
+ x, ok := m[tok.value]
+ if !ok {
+ break
+ }
+ fv.SetInt(int64(x))
+ return nil
+ case reflect.Int64:
+ if x, err := strconv.ParseInt(tok.value, 0, 64); err == nil {
+ fv.SetInt(x)
+ return nil
+ }
+
+ case reflect.Ptr:
+ // A basic field (indirected through pointer), or a repeated message/group
+ p.back()
+ fv.Set(reflect.New(fv.Type().Elem()))
+ return p.readAny(fv.Elem(), props)
+ case reflect.String:
+ if tok.value[0] == '"' || tok.value[0] == '\'' {
+ fv.SetString(tok.unquoted)
+ return nil
+ }
+ case reflect.Struct:
+ var terminator string
+ switch tok.value {
+ case "{":
+ terminator = "}"
+ case "<":
+ terminator = ">"
+ default:
+ return p.errorf("expected '{' or '<', found %q", tok.value)
+ }
+ // TODO: Handle nested messages which implement encoding.TextUnmarshaler.
+ return p.readStruct(fv, terminator)
+ case reflect.Uint32:
+ if x, err := strconv.ParseUint(tok.value, 0, 32); err == nil {
+ fv.SetUint(uint64(x))
+ return nil
+ }
+ case reflect.Uint64:
+ if x, err := strconv.ParseUint(tok.value, 0, 64); err == nil {
+ fv.SetUint(x)
+ return nil
+ }
+ }
+ return p.errorf("invalid %v: %v", v.Type(), tok.value)
+}
+
+// UnmarshalText reads a protocol buffer in Text format. UnmarshalText resets pb
+// before starting to unmarshal, so any existing data in pb is always removed.
+// If a required field is not set and no other error occurs,
+// UnmarshalText returns *RequiredNotSetError.
+func UnmarshalText(s string, pb Message) error {
+ if um, ok := pb.(encoding.TextUnmarshaler); ok {
+ return um.UnmarshalText([]byte(s))
+ }
+ pb.Reset()
+ v := reflect.ValueOf(pb)
+ return newTextParser(s).readStruct(v.Elem(), "")
+}
diff --git a/vendor/github.com/jinzhu/gorm/.gitignore b/vendor/github.com/jinzhu/gorm/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..117f92f52dbf9bd22ba3a57e702e41107a3fad18
--- /dev/null
+++ b/vendor/github.com/jinzhu/gorm/.gitignore
@@ -0,0 +1,3 @@
+documents
+coverage.txt
+_book
diff --git a/vendor/github.com/jinzhu/gorm/License b/vendor/github.com/jinzhu/gorm/License
new file mode 100644
index 0000000000000000000000000000000000000000..037e1653e69a614af4884c6003750536adf99f33
--- /dev/null
+++ b/vendor/github.com/jinzhu/gorm/License
@@ -0,0 +1,21 @@
+The MIT License (MIT)
+
+Copyright (c) 2013-NOW Jinzhu
+
+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.
diff --git a/vendor/github.com/jinzhu/gorm/README.md b/vendor/github.com/jinzhu/gorm/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..6d23110370abb78b2d014824e50eba3020b52518
--- /dev/null
+++ b/vendor/github.com/jinzhu/gorm/README.md
@@ -0,0 +1,41 @@
+# GORM
+
+The fantastic ORM library for Golang, aims to be developer friendly.
+
+[](https://goreportcard.com/report/github.com/jinzhu/gorm)
+[](https://app.wercker.com/project/byKey/8596cace912c9947dd9c8542ecc8cb8b)
+[](https://codecov.io/gh/jinzhu/gorm)
+[](https://gitter.im/jinzhu/gorm?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
+[](https://opencollective.com/gorm)
+[](https://opencollective.com/gorm)
+[](https://opensource.org/licenses/MIT)
+[](https://godoc.org/github.com/jinzhu/gorm)
+
+## Overview
+
+* Full-Featured ORM (almost)
+* Associations (Has One, Has Many, Belongs To, Many To Many, Polymorphism)
+* Hooks (Before/After Create/Save/Update/Delete/Find)
+* Preloading (eager loading)
+* Transactions
+* Composite Primary Key
+* SQL Builder
+* Auto Migrations
+* Logger
+* Extendable, write Plugins based on GORM callbacks
+* Every feature comes with tests
+* Developer Friendly
+
+## Getting Started
+
+* GORM Guides [https://gorm.io](https://gorm.io)
+
+## Contributing
+
+[You can help to deliver a better GORM, check out things you can do](https://gorm.io/contribute.html)
+
+## License
+
+© Jinzhu, 2013~time.Now
+
+Released under the [MIT License](https://github.com/jinzhu/gorm/blob/master/License)
diff --git a/vendor/github.com/jinzhu/gorm/association.go b/vendor/github.com/jinzhu/gorm/association.go
new file mode 100644
index 0000000000000000000000000000000000000000..a73344fe654ae6f025e2c8a3666727e7ca254d81
--- /dev/null
+++ b/vendor/github.com/jinzhu/gorm/association.go
@@ -0,0 +1,377 @@
+package gorm
+
+import (
+ "errors"
+ "fmt"
+ "reflect"
+)
+
+// Association Mode contains some helper methods to handle relationship things easily.
+type Association struct {
+ Error error
+ scope *Scope
+ column string
+ field *Field
+}
+
+// Find find out all related associations
+func (association *Association) Find(value interface{}) *Association {
+ association.scope.related(value, association.column)
+ return association.setErr(association.scope.db.Error)
+}
+
+// Append append new associations for many2many, has_many, replace current association for has_one, belongs_to
+func (association *Association) Append(values ...interface{}) *Association {
+ if association.Error != nil {
+ return association
+ }
+
+ if relationship := association.field.Relationship; relationship.Kind == "has_one" {
+ return association.Replace(values...)
+ }
+ return association.saveAssociations(values...)
+}
+
+// Replace replace current associations with new one
+func (association *Association) Replace(values ...interface{}) *Association {
+ if association.Error != nil {
+ return association
+ }
+
+ var (
+ relationship = association.field.Relationship
+ scope = association.scope
+ field = association.field.Field
+ newDB = scope.NewDB()
+ )
+
+ // Append new values
+ association.field.Set(reflect.Zero(association.field.Field.Type()))
+ association.saveAssociations(values...)
+
+ // Belongs To
+ if relationship.Kind == "belongs_to" {
+ // Set foreign key to be null when clearing value (length equals 0)
+ if len(values) == 0 {
+ // Set foreign key to be nil
+ var foreignKeyMap = map[string]interface{}{}
+ for _, foreignKey := range relationship.ForeignDBNames {
+ foreignKeyMap[foreignKey] = nil
+ }
+ association.setErr(newDB.Model(scope.Value).UpdateColumn(foreignKeyMap).Error)
+ }
+ } else {
+ // Polymorphic Relations
+ if relationship.PolymorphicDBName != "" {
+ newDB = newDB.Where(fmt.Sprintf("%v = ?", scope.Quote(relationship.PolymorphicDBName)), relationship.PolymorphicValue)
+ }
+
+ // Delete Relations except new created
+ if len(values) > 0 {
+ var associationForeignFieldNames, associationForeignDBNames []string
+ if relationship.Kind == "many_to_many" {
+ // if many to many relations, get association fields name from association foreign keys
+ associationScope := scope.New(reflect.New(field.Type()).Interface())
+ for idx, dbName := range relationship.AssociationForeignFieldNames {
+ if field, ok := associationScope.FieldByName(dbName); ok {
+ associationForeignFieldNames = append(associationForeignFieldNames, field.Name)
+ associationForeignDBNames = append(associationForeignDBNames, relationship.AssociationForeignDBNames[idx])
+ }
+ }
+ } else {
+ // If has one/many relations, use primary keys
+ for _, field := range scope.New(reflect.New(field.Type()).Interface()).PrimaryFields() {
+ associationForeignFieldNames = append(associationForeignFieldNames, field.Name)
+ associationForeignDBNames = append(associationForeignDBNames, field.DBName)
+ }
+ }
+
+ newPrimaryKeys := scope.getColumnAsArray(associationForeignFieldNames, field.Interface())
+
+ if len(newPrimaryKeys) > 0 {
+ sql := fmt.Sprintf("%v NOT IN (%v)", toQueryCondition(scope, associationForeignDBNames), toQueryMarks(newPrimaryKeys))
+ newDB = newDB.Where(sql, toQueryValues(newPrimaryKeys)...)
+ }
+ }
+
+ if relationship.Kind == "many_to_many" {
+ // if many to many relations, delete related relations from join table
+ var sourceForeignFieldNames []string
+
+ for _, dbName := range relationship.ForeignFieldNames {
+ if field, ok := scope.FieldByName(dbName); ok {
+ sourceForeignFieldNames = append(sourceForeignFieldNames, field.Name)
+ }
+ }
+
+ if sourcePrimaryKeys := scope.getColumnAsArray(sourceForeignFieldNames, scope.Value); len(sourcePrimaryKeys) > 0 {
+ newDB = newDB.Where(fmt.Sprintf("%v IN (%v)", toQueryCondition(scope, relationship.ForeignDBNames), toQueryMarks(sourcePrimaryKeys)), toQueryValues(sourcePrimaryKeys)...)
+
+ association.setErr(relationship.JoinTableHandler.Delete(relationship.JoinTableHandler, newDB))
+ }
+ } else if relationship.Kind == "has_one" || relationship.Kind == "has_many" {
+ // has_one or has_many relations, set foreign key to be nil (TODO or delete them?)
+ var foreignKeyMap = map[string]interface{}{}
+ for idx, foreignKey := range relationship.ForeignDBNames {
+ foreignKeyMap[foreignKey] = nil
+ if field, ok := scope.FieldByName(relationship.AssociationForeignFieldNames[idx]); ok {
+ newDB = newDB.Where(fmt.Sprintf("%v = ?", scope.Quote(foreignKey)), field.Field.Interface())
+ }
+ }
+
+ fieldValue := reflect.New(association.field.Field.Type()).Interface()
+ association.setErr(newDB.Model(fieldValue).UpdateColumn(foreignKeyMap).Error)
+ }
+ }
+ return association
+}
+
+// Delete remove relationship between source & passed arguments, but won't delete those arguments
+func (association *Association) Delete(values ...interface{}) *Association {
+ if association.Error != nil {
+ return association
+ }
+
+ var (
+ relationship = association.field.Relationship
+ scope = association.scope
+ field = association.field.Field
+ newDB = scope.NewDB()
+ )
+
+ if len(values) == 0 {
+ return association
+ }
+
+ var deletingResourcePrimaryFieldNames, deletingResourcePrimaryDBNames []string
+ for _, field := range scope.New(reflect.New(field.Type()).Interface()).PrimaryFields() {
+ deletingResourcePrimaryFieldNames = append(deletingResourcePrimaryFieldNames, field.Name)
+ deletingResourcePrimaryDBNames = append(deletingResourcePrimaryDBNames, field.DBName)
+ }
+
+ deletingPrimaryKeys := scope.getColumnAsArray(deletingResourcePrimaryFieldNames, values...)
+
+ if relationship.Kind == "many_to_many" {
+ // source value's foreign keys
+ for idx, foreignKey := range relationship.ForeignDBNames {
+ if field, ok := scope.FieldByName(relationship.ForeignFieldNames[idx]); ok {
+ newDB = newDB.Where(fmt.Sprintf("%v = ?", scope.Quote(foreignKey)), field.Field.Interface())
+ }
+ }
+
+ // get association's foreign fields name
+ var associationScope = scope.New(reflect.New(field.Type()).Interface())
+ var associationForeignFieldNames []string
+ for _, associationDBName := range relationship.AssociationForeignFieldNames {
+ if field, ok := associationScope.FieldByName(associationDBName); ok {
+ associationForeignFieldNames = append(associationForeignFieldNames, field.Name)
+ }
+ }
+
+ // association value's foreign keys
+ deletingPrimaryKeys := scope.getColumnAsArray(associationForeignFieldNames, values...)
+ sql := fmt.Sprintf("%v IN (%v)", toQueryCondition(scope, relationship.AssociationForeignDBNames), toQueryMarks(deletingPrimaryKeys))
+ newDB = newDB.Where(sql, toQueryValues(deletingPrimaryKeys)...)
+
+ association.setErr(relationship.JoinTableHandler.Delete(relationship.JoinTableHandler, newDB))
+ } else {
+ var foreignKeyMap = map[string]interface{}{}
+ for _, foreignKey := range relationship.ForeignDBNames {
+ foreignKeyMap[foreignKey] = nil
+ }
+
+ if relationship.Kind == "belongs_to" {
+ // find with deleting relation's foreign keys
+ primaryKeys := scope.getColumnAsArray(relationship.AssociationForeignFieldNames, values...)
+ newDB = newDB.Where(
+ fmt.Sprintf("%v IN (%v)", toQueryCondition(scope, relationship.ForeignDBNames), toQueryMarks(primaryKeys)),
+ toQueryValues(primaryKeys)...,
+ )
+
+ // set foreign key to be null if there are some records affected
+ modelValue := reflect.New(scope.GetModelStruct().ModelType).Interface()
+ if results := newDB.Model(modelValue).UpdateColumn(foreignKeyMap); results.Error == nil {
+ if results.RowsAffected > 0 {
+ scope.updatedAttrsWithValues(foreignKeyMap)
+ }
+ } else {
+ association.setErr(results.Error)
+ }
+ } else if relationship.Kind == "has_one" || relationship.Kind == "has_many" {
+ // find all relations
+ primaryKeys := scope.getColumnAsArray(relationship.AssociationForeignFieldNames, scope.Value)
+ newDB = newDB.Where(
+ fmt.Sprintf("%v IN (%v)", toQueryCondition(scope, relationship.ForeignDBNames), toQueryMarks(primaryKeys)),
+ toQueryValues(primaryKeys)...,
+ )
+
+ // only include those deleting relations
+ newDB = newDB.Where(
+ fmt.Sprintf("%v IN (%v)", toQueryCondition(scope, deletingResourcePrimaryDBNames), toQueryMarks(deletingPrimaryKeys)),
+ toQueryValues(deletingPrimaryKeys)...,
+ )
+
+ // set matched relation's foreign key to be null
+ fieldValue := reflect.New(association.field.Field.Type()).Interface()
+ association.setErr(newDB.Model(fieldValue).UpdateColumn(foreignKeyMap).Error)
+ }
+ }
+
+ // Remove deleted records from source's field
+ if association.Error == nil {
+ if field.Kind() == reflect.Slice {
+ leftValues := reflect.Zero(field.Type())
+
+ for i := 0; i < field.Len(); i++ {
+ reflectValue := field.Index(i)
+ primaryKey := scope.getColumnAsArray(deletingResourcePrimaryFieldNames, reflectValue.Interface())[0]
+ var isDeleted = false
+ for _, pk := range deletingPrimaryKeys {
+ if equalAsString(primaryKey, pk) {
+ isDeleted = true
+ break
+ }
+ }
+ if !isDeleted {
+ leftValues = reflect.Append(leftValues, reflectValue)
+ }
+ }
+
+ association.field.Set(leftValues)
+ } else if field.Kind() == reflect.Struct {
+ primaryKey := scope.getColumnAsArray(deletingResourcePrimaryFieldNames, field.Interface())[0]
+ for _, pk := range deletingPrimaryKeys {
+ if equalAsString(primaryKey, pk) {
+ association.field.Set(reflect.Zero(field.Type()))
+ break
+ }
+ }
+ }
+ }
+
+ return association
+}
+
+// Clear remove relationship between source & current associations, won't delete those associations
+func (association *Association) Clear() *Association {
+ return association.Replace()
+}
+
+// Count return the count of current associations
+func (association *Association) Count() int {
+ var (
+ count = 0
+ relationship = association.field.Relationship
+ scope = association.scope
+ fieldValue = association.field.Field.Interface()
+ query = scope.DB()
+ )
+
+ switch relationship.Kind {
+ case "many_to_many":
+ query = relationship.JoinTableHandler.JoinWith(relationship.JoinTableHandler, query, scope.Value)
+ case "has_many", "has_one":
+ primaryKeys := scope.getColumnAsArray(relationship.AssociationForeignFieldNames, scope.Value)
+ query = query.Where(
+ fmt.Sprintf("%v IN (%v)", toQueryCondition(scope, relationship.ForeignDBNames), toQueryMarks(primaryKeys)),
+ toQueryValues(primaryKeys)...,
+ )
+ case "belongs_to":
+ primaryKeys := scope.getColumnAsArray(relationship.ForeignFieldNames, scope.Value)
+ query = query.Where(
+ fmt.Sprintf("%v IN (%v)", toQueryCondition(scope, relationship.AssociationForeignDBNames), toQueryMarks(primaryKeys)),
+ toQueryValues(primaryKeys)...,
+ )
+ }
+
+ if relationship.PolymorphicType != "" {
+ query = query.Where(
+ fmt.Sprintf("%v.%v = ?", scope.New(fieldValue).QuotedTableName(), scope.Quote(relationship.PolymorphicDBName)),
+ relationship.PolymorphicValue,
+ )
+ }
+
+ if err := query.Model(fieldValue).Count(&count).Error; err != nil {
+ association.Error = err
+ }
+ return count
+}
+
+// saveAssociations save passed values as associations
+func (association *Association) saveAssociations(values ...interface{}) *Association {
+ var (
+ scope = association.scope
+ field = association.field
+ relationship = field.Relationship
+ )
+
+ saveAssociation := func(reflectValue reflect.Value) {
+ // value has to been pointer
+ if reflectValue.Kind() != reflect.Ptr {
+ reflectPtr := reflect.New(reflectValue.Type())
+ reflectPtr.Elem().Set(reflectValue)
+ reflectValue = reflectPtr
+ }
+
+ // value has to been saved for many2many
+ if relationship.Kind == "many_to_many" {
+ if scope.New(reflectValue.Interface()).PrimaryKeyZero() {
+ association.setErr(scope.NewDB().Save(reflectValue.Interface()).Error)
+ }
+ }
+
+ // Assign Fields
+ var fieldType = field.Field.Type()
+ var setFieldBackToValue, setSliceFieldBackToValue bool
+ if reflectValue.Type().AssignableTo(fieldType) {
+ field.Set(reflectValue)
+ } else if reflectValue.Type().Elem().AssignableTo(fieldType) {
+ // if field's type is struct, then need to set value back to argument after save
+ setFieldBackToValue = true
+ field.Set(reflectValue.Elem())
+ } else if fieldType.Kind() == reflect.Slice {
+ if reflectValue.Type().AssignableTo(fieldType.Elem()) {
+ field.Set(reflect.Append(field.Field, reflectValue))
+ } else if reflectValue.Type().Elem().AssignableTo(fieldType.Elem()) {
+ // if field's type is slice of struct, then need to set value back to argument after save
+ setSliceFieldBackToValue = true
+ field.Set(reflect.Append(field.Field, reflectValue.Elem()))
+ }
+ }
+
+ if relationship.Kind == "many_to_many" {
+ association.setErr(relationship.JoinTableHandler.Add(relationship.JoinTableHandler, scope.NewDB(), scope.Value, reflectValue.Interface()))
+ } else {
+ association.setErr(scope.NewDB().Select(field.Name).Save(scope.Value).Error)
+
+ if setFieldBackToValue {
+ reflectValue.Elem().Set(field.Field)
+ } else if setSliceFieldBackToValue {
+ reflectValue.Elem().Set(field.Field.Index(field.Field.Len() - 1))
+ }
+ }
+ }
+
+ for _, value := range values {
+ reflectValue := reflect.ValueOf(value)
+ indirectReflectValue := reflect.Indirect(reflectValue)
+ if indirectReflectValue.Kind() == reflect.Struct {
+ saveAssociation(reflectValue)
+ } else if indirectReflectValue.Kind() == reflect.Slice {
+ for i := 0; i < indirectReflectValue.Len(); i++ {
+ saveAssociation(indirectReflectValue.Index(i))
+ }
+ } else {
+ association.setErr(errors.New("invalid value type"))
+ }
+ }
+ return association
+}
+
+// setErr set error when the error is not nil. And return Association.
+func (association *Association) setErr(err error) *Association {
+ if err != nil {
+ association.Error = err
+ }
+ return association
+}
diff --git a/vendor/github.com/jinzhu/gorm/callback.go b/vendor/github.com/jinzhu/gorm/callback.go
new file mode 100644
index 0000000000000000000000000000000000000000..202af06e53325c8b9b78c8a0e3e2b1479dba35c1
--- /dev/null
+++ b/vendor/github.com/jinzhu/gorm/callback.go
@@ -0,0 +1,249 @@
+package gorm
+
+import "fmt"
+
+// DefaultCallback default callbacks defined by gorm
+var DefaultCallback = &Callback{}
+
+// Callback is a struct that contains all CRUD callbacks
+// Field `creates` contains callbacks will be call when creating object
+// Field `updates` contains callbacks will be call when updating object
+// Field `deletes` contains callbacks will be call when deleting object
+// Field `queries` contains callbacks will be call when querying object with query methods like Find, First, Related, Association...
+// Field `rowQueries` contains callbacks will be call when querying object with Row, Rows...
+// Field `processors` contains all callback processors, will be used to generate above callbacks in order
+type Callback struct {
+ logger logger
+ creates []*func(scope *Scope)
+ updates []*func(scope *Scope)
+ deletes []*func(scope *Scope)
+ queries []*func(scope *Scope)
+ rowQueries []*func(scope *Scope)
+ processors []*CallbackProcessor
+}
+
+// CallbackProcessor contains callback informations
+type CallbackProcessor struct {
+ logger logger
+ name string // current callback's name
+ before string // register current callback before a callback
+ after string // register current callback after a callback
+ replace bool // replace callbacks with same name
+ remove bool // delete callbacks with same name
+ kind string // callback type: create, update, delete, query, row_query
+ processor *func(scope *Scope) // callback handler
+ parent *Callback
+}
+
+func (c *Callback) clone(logger logger) *Callback {
+ return &Callback{
+ logger: logger,
+ creates: c.creates,
+ updates: c.updates,
+ deletes: c.deletes,
+ queries: c.queries,
+ rowQueries: c.rowQueries,
+ processors: c.processors,
+ }
+}
+
+// Create could be used to register callbacks for creating object
+// db.Callback().Create().After("gorm:create").Register("plugin:run_after_create", func(*Scope) {
+// // business logic
+// ...
+//
+// // set error if some thing wrong happened, will rollback the creating
+// scope.Err(errors.New("error"))
+// })
+func (c *Callback) Create() *CallbackProcessor {
+ return &CallbackProcessor{logger: c.logger, kind: "create", parent: c}
+}
+
+// Update could be used to register callbacks for updating object, refer `Create` for usage
+func (c *Callback) Update() *CallbackProcessor {
+ return &CallbackProcessor{logger: c.logger, kind: "update", parent: c}
+}
+
+// Delete could be used to register callbacks for deleting object, refer `Create` for usage
+func (c *Callback) Delete() *CallbackProcessor {
+ return &CallbackProcessor{logger: c.logger, kind: "delete", parent: c}
+}
+
+// Query could be used to register callbacks for querying objects with query methods like `Find`, `First`, `Related`, `Association`...
+// Refer `Create` for usage
+func (c *Callback) Query() *CallbackProcessor {
+ return &CallbackProcessor{logger: c.logger, kind: "query", parent: c}
+}
+
+// RowQuery could be used to register callbacks for querying objects with `Row`, `Rows`, refer `Create` for usage
+func (c *Callback) RowQuery() *CallbackProcessor {
+ return &CallbackProcessor{logger: c.logger, kind: "row_query", parent: c}
+}
+
+// After insert a new callback after callback `callbackName`, refer `Callbacks.Create`
+func (cp *CallbackProcessor) After(callbackName string) *CallbackProcessor {
+ cp.after = callbackName
+ return cp
+}
+
+// Before insert a new callback before callback `callbackName`, refer `Callbacks.Create`
+func (cp *CallbackProcessor) Before(callbackName string) *CallbackProcessor {
+ cp.before = callbackName
+ return cp
+}
+
+// Register a new callback, refer `Callbacks.Create`
+func (cp *CallbackProcessor) Register(callbackName string, callback func(scope *Scope)) {
+ if cp.kind == "row_query" {
+ if cp.before == "" && cp.after == "" && callbackName != "gorm:row_query" {
+ cp.logger.Print(fmt.Sprintf("Registering RowQuery callback %v without specify order with Before(), After(), applying Before('gorm:row_query') by default for compatibility...\n", callbackName))
+ cp.before = "gorm:row_query"
+ }
+ }
+
+ cp.name = callbackName
+ cp.processor = &callback
+ cp.parent.processors = append(cp.parent.processors, cp)
+ cp.parent.reorder()
+}
+
+// Remove a registered callback
+// db.Callback().Create().Remove("gorm:update_time_stamp_when_create")
+func (cp *CallbackProcessor) Remove(callbackName string) {
+ cp.logger.Print(fmt.Sprintf("[info] removing callback `%v` from %v\n", callbackName, fileWithLineNum()))
+ cp.name = callbackName
+ cp.remove = true
+ cp.parent.processors = append(cp.parent.processors, cp)
+ cp.parent.reorder()
+}
+
+// Replace a registered callback with new callback
+// db.Callback().Create().Replace("gorm:update_time_stamp_when_create", func(*Scope) {
+// scope.SetColumn("Created", now)
+// scope.SetColumn("Updated", now)
+// })
+func (cp *CallbackProcessor) Replace(callbackName string, callback func(scope *Scope)) {
+ cp.logger.Print(fmt.Sprintf("[info] replacing callback `%v` from %v\n", callbackName, fileWithLineNum()))
+ cp.name = callbackName
+ cp.processor = &callback
+ cp.replace = true
+ cp.parent.processors = append(cp.parent.processors, cp)
+ cp.parent.reorder()
+}
+
+// Get registered callback
+// db.Callback().Create().Get("gorm:create")
+func (cp *CallbackProcessor) Get(callbackName string) (callback func(scope *Scope)) {
+ for _, p := range cp.parent.processors {
+ if p.name == callbackName && p.kind == cp.kind {
+ if p.remove {
+ callback = nil
+ } else {
+ callback = *p.processor
+ }
+ }
+ }
+ return
+}
+
+// getRIndex get right index from string slice
+func getRIndex(strs []string, str string) int {
+ for i := len(strs) - 1; i >= 0; i-- {
+ if strs[i] == str {
+ return i
+ }
+ }
+ return -1
+}
+
+// sortProcessors sort callback processors based on its before, after, remove, replace
+func sortProcessors(cps []*CallbackProcessor) []*func(scope *Scope) {
+ var (
+ allNames, sortedNames []string
+ sortCallbackProcessor func(c *CallbackProcessor)
+ )
+
+ for _, cp := range cps {
+ // show warning message the callback name already exists
+ if index := getRIndex(allNames, cp.name); index > -1 && !cp.replace && !cp.remove {
+ cp.logger.Print(fmt.Sprintf("[warning] duplicated callback `%v` from %v\n", cp.name, fileWithLineNum()))
+ }
+ allNames = append(allNames, cp.name)
+ }
+
+ sortCallbackProcessor = func(c *CallbackProcessor) {
+ if getRIndex(sortedNames, c.name) == -1 { // if not sorted
+ if c.before != "" { // if defined before callback
+ if index := getRIndex(sortedNames, c.before); index != -1 {
+ // if before callback already sorted, append current callback just after it
+ sortedNames = append(sortedNames[:index], append([]string{c.name}, sortedNames[index:]...)...)
+ } else if index := getRIndex(allNames, c.before); index != -1 {
+ // if before callback exists but haven't sorted, append current callback to last
+ sortedNames = append(sortedNames, c.name)
+ sortCallbackProcessor(cps[index])
+ }
+ }
+
+ if c.after != "" { // if defined after callback
+ if index := getRIndex(sortedNames, c.after); index != -1 {
+ // if after callback already sorted, append current callback just before it
+ sortedNames = append(sortedNames[:index+1], append([]string{c.name}, sortedNames[index+1:]...)...)
+ } else if index := getRIndex(allNames, c.after); index != -1 {
+ // if after callback exists but haven't sorted
+ cp := cps[index]
+ // set after callback's before callback to current callback
+ if cp.before == "" {
+ cp.before = c.name
+ }
+ sortCallbackProcessor(cp)
+ }
+ }
+
+ // if current callback haven't been sorted, append it to last
+ if getRIndex(sortedNames, c.name) == -1 {
+ sortedNames = append(sortedNames, c.name)
+ }
+ }
+ }
+
+ for _, cp := range cps {
+ sortCallbackProcessor(cp)
+ }
+
+ var sortedFuncs []*func(scope *Scope)
+ for _, name := range sortedNames {
+ if index := getRIndex(allNames, name); !cps[index].remove {
+ sortedFuncs = append(sortedFuncs, cps[index].processor)
+ }
+ }
+
+ return sortedFuncs
+}
+
+// reorder all registered processors, and reset CRUD callbacks
+func (c *Callback) reorder() {
+ var creates, updates, deletes, queries, rowQueries []*CallbackProcessor
+
+ for _, processor := range c.processors {
+ if processor.name != "" {
+ switch processor.kind {
+ case "create":
+ creates = append(creates, processor)
+ case "update":
+ updates = append(updates, processor)
+ case "delete":
+ deletes = append(deletes, processor)
+ case "query":
+ queries = append(queries, processor)
+ case "row_query":
+ rowQueries = append(rowQueries, processor)
+ }
+ }
+ }
+
+ c.creates = sortProcessors(creates)
+ c.updates = sortProcessors(updates)
+ c.deletes = sortProcessors(deletes)
+ c.queries = sortProcessors(queries)
+ c.rowQueries = sortProcessors(rowQueries)
+}
diff --git a/vendor/github.com/jinzhu/gorm/callback_create.go b/vendor/github.com/jinzhu/gorm/callback_create.go
new file mode 100644
index 0000000000000000000000000000000000000000..87aba8ee32c56cbfcc856407c7a37c66276df9cd
--- /dev/null
+++ b/vendor/github.com/jinzhu/gorm/callback_create.go
@@ -0,0 +1,173 @@
+package gorm
+
+import (
+ "fmt"
+ "strings"
+)
+
+// Define callbacks for creating
+func init() {
+ DefaultCallback.Create().Register("gorm:begin_transaction", beginTransactionCallback)
+ DefaultCallback.Create().Register("gorm:before_create", beforeCreateCallback)
+ DefaultCallback.Create().Register("gorm:save_before_associations", saveBeforeAssociationsCallback)
+ DefaultCallback.Create().Register("gorm:update_time_stamp", updateTimeStampForCreateCallback)
+ DefaultCallback.Create().Register("gorm:create", createCallback)
+ DefaultCallback.Create().Register("gorm:force_reload_after_create", forceReloadAfterCreateCallback)
+ DefaultCallback.Create().Register("gorm:save_after_associations", saveAfterAssociationsCallback)
+ DefaultCallback.Create().Register("gorm:after_create", afterCreateCallback)
+ DefaultCallback.Create().Register("gorm:commit_or_rollback_transaction", commitOrRollbackTransactionCallback)
+}
+
+// beforeCreateCallback will invoke `BeforeSave`, `BeforeCreate` method before creating
+func beforeCreateCallback(scope *Scope) {
+ if !scope.HasError() {
+ scope.CallMethod("BeforeSave")
+ }
+ if !scope.HasError() {
+ scope.CallMethod("BeforeCreate")
+ }
+}
+
+// updateTimeStampForCreateCallback will set `CreatedAt`, `UpdatedAt` when creating
+func updateTimeStampForCreateCallback(scope *Scope) {
+ if !scope.HasError() {
+ now := scope.db.nowFunc()
+
+ if createdAtField, ok := scope.FieldByName("CreatedAt"); ok {
+ if createdAtField.IsBlank {
+ createdAtField.Set(now)
+ }
+ }
+
+ if updatedAtField, ok := scope.FieldByName("UpdatedAt"); ok {
+ if updatedAtField.IsBlank {
+ updatedAtField.Set(now)
+ }
+ }
+ }
+}
+
+// createCallback the callback used to insert data into database
+func createCallback(scope *Scope) {
+ if !scope.HasError() {
+ defer scope.trace(scope.db.nowFunc())
+
+ var (
+ columns, placeholders []string
+ blankColumnsWithDefaultValue []string
+ )
+
+ for _, field := range scope.Fields() {
+ if scope.changeableField(field) {
+ if field.IsNormal && !field.IsIgnored {
+ if field.IsBlank && field.HasDefaultValue {
+ blankColumnsWithDefaultValue = append(blankColumnsWithDefaultValue, scope.Quote(field.DBName))
+ scope.InstanceSet("gorm:blank_columns_with_default_value", blankColumnsWithDefaultValue)
+ } else if !field.IsPrimaryKey || !field.IsBlank {
+ columns = append(columns, scope.Quote(field.DBName))
+ placeholders = append(placeholders, scope.AddToVars(field.Field.Interface()))
+ }
+ } else if field.Relationship != nil && field.Relationship.Kind == "belongs_to" {
+ for _, foreignKey := range field.Relationship.ForeignDBNames {
+ if foreignField, ok := scope.FieldByName(foreignKey); ok && !scope.changeableField(foreignField) {
+ columns = append(columns, scope.Quote(foreignField.DBName))
+ placeholders = append(placeholders, scope.AddToVars(foreignField.Field.Interface()))
+ }
+ }
+ }
+ }
+ }
+
+ var (
+ returningColumn = "*"
+ quotedTableName = scope.QuotedTableName()
+ primaryField = scope.PrimaryField()
+ extraOption string
+ insertModifier string
+ )
+
+ if str, ok := scope.Get("gorm:insert_option"); ok {
+ extraOption = fmt.Sprint(str)
+ }
+ if str, ok := scope.Get("gorm:insert_modifier"); ok {
+ insertModifier = strings.ToUpper(fmt.Sprint(str))
+ if insertModifier == "INTO" {
+ insertModifier = ""
+ }
+ }
+
+ if primaryField != nil {
+ returningColumn = scope.Quote(primaryField.DBName)
+ }
+
+ lastInsertIDReturningSuffix := scope.Dialect().LastInsertIDReturningSuffix(quotedTableName, returningColumn)
+
+ if len(columns) == 0 {
+ scope.Raw(fmt.Sprintf(
+ "INSERT %v INTO %v %v%v%v",
+ addExtraSpaceIfExist(insertModifier),
+ quotedTableName,
+ scope.Dialect().DefaultValueStr(),
+ addExtraSpaceIfExist(extraOption),
+ addExtraSpaceIfExist(lastInsertIDReturningSuffix),
+ ))
+ } else {
+ scope.Raw(fmt.Sprintf(
+ "INSERT %v INTO %v (%v) VALUES (%v)%v%v",
+ addExtraSpaceIfExist(insertModifier),
+ scope.QuotedTableName(),
+ strings.Join(columns, ","),
+ strings.Join(placeholders, ","),
+ addExtraSpaceIfExist(extraOption),
+ addExtraSpaceIfExist(lastInsertIDReturningSuffix),
+ ))
+ }
+
+ // execute create sql
+ if lastInsertIDReturningSuffix == "" || primaryField == nil {
+ if result, err := scope.SQLDB().Exec(scope.SQL, scope.SQLVars...); scope.Err(err) == nil {
+ // set rows affected count
+ scope.db.RowsAffected, _ = result.RowsAffected()
+
+ // set primary value to primary field
+ if primaryField != nil && primaryField.IsBlank {
+ if primaryValue, err := result.LastInsertId(); scope.Err(err) == nil {
+ scope.Err(primaryField.Set(primaryValue))
+ }
+ }
+ }
+ } else {
+ if primaryField.Field.CanAddr() {
+ if err := scope.SQLDB().QueryRow(scope.SQL, scope.SQLVars...).Scan(primaryField.Field.Addr().Interface()); scope.Err(err) == nil {
+ primaryField.IsBlank = false
+ scope.db.RowsAffected = 1
+ }
+ } else {
+ scope.Err(ErrUnaddressable)
+ }
+ }
+ }
+}
+
+// forceReloadAfterCreateCallback will reload columns that having default value, and set it back to current object
+func forceReloadAfterCreateCallback(scope *Scope) {
+ if blankColumnsWithDefaultValue, ok := scope.InstanceGet("gorm:blank_columns_with_default_value"); ok {
+ db := scope.DB().New().Table(scope.TableName()).Select(blankColumnsWithDefaultValue.([]string))
+ for _, field := range scope.Fields() {
+ if field.IsPrimaryKey && !field.IsBlank {
+ db = db.Where(fmt.Sprintf("%v = ?", field.DBName), field.Field.Interface())
+ }
+ }
+ db.Scan(scope.Value)
+ }
+}
+
+// afterCreateCallback will invoke `AfterCreate`, `AfterSave` method after creating
+func afterCreateCallback(scope *Scope) {
+ if !scope.HasError() {
+ scope.CallMethod("AfterCreate")
+ }
+ if !scope.HasError() {
+ scope.CallMethod("AfterSave")
+ }
+}
diff --git a/vendor/github.com/jinzhu/gorm/callback_delete.go b/vendor/github.com/jinzhu/gorm/callback_delete.go
new file mode 100644
index 0000000000000000000000000000000000000000..48b97acbfbfdfa00920d09ef3be31cb809837c25
--- /dev/null
+++ b/vendor/github.com/jinzhu/gorm/callback_delete.go
@@ -0,0 +1,63 @@
+package gorm
+
+import (
+ "errors"
+ "fmt"
+)
+
+// Define callbacks for deleting
+func init() {
+ DefaultCallback.Delete().Register("gorm:begin_transaction", beginTransactionCallback)
+ DefaultCallback.Delete().Register("gorm:before_delete", beforeDeleteCallback)
+ DefaultCallback.Delete().Register("gorm:delete", deleteCallback)
+ DefaultCallback.Delete().Register("gorm:after_delete", afterDeleteCallback)
+ DefaultCallback.Delete().Register("gorm:commit_or_rollback_transaction", commitOrRollbackTransactionCallback)
+}
+
+// beforeDeleteCallback will invoke `BeforeDelete` method before deleting
+func beforeDeleteCallback(scope *Scope) {
+ if scope.DB().HasBlockGlobalUpdate() && !scope.hasConditions() {
+ scope.Err(errors.New("missing WHERE clause while deleting"))
+ return
+ }
+ if !scope.HasError() {
+ scope.CallMethod("BeforeDelete")
+ }
+}
+
+// deleteCallback used to delete data from database or set deleted_at to current time (when using with soft delete)
+func deleteCallback(scope *Scope) {
+ if !scope.HasError() {
+ var extraOption string
+ if str, ok := scope.Get("gorm:delete_option"); ok {
+ extraOption = fmt.Sprint(str)
+ }
+
+ deletedAtField, hasDeletedAtField := scope.FieldByName("DeletedAt")
+
+ if !scope.Search.Unscoped && hasDeletedAtField {
+ scope.Raw(fmt.Sprintf(
+ "UPDATE %v SET %v=%v%v%v",
+ scope.QuotedTableName(),
+ scope.Quote(deletedAtField.DBName),
+ scope.AddToVars(scope.db.nowFunc()),
+ addExtraSpaceIfExist(scope.CombinedConditionSql()),
+ addExtraSpaceIfExist(extraOption),
+ )).Exec()
+ } else {
+ scope.Raw(fmt.Sprintf(
+ "DELETE FROM %v%v%v",
+ scope.QuotedTableName(),
+ addExtraSpaceIfExist(scope.CombinedConditionSql()),
+ addExtraSpaceIfExist(extraOption),
+ )).Exec()
+ }
+ }
+}
+
+// afterDeleteCallback will invoke `AfterDelete` method after deleting
+func afterDeleteCallback(scope *Scope) {
+ if !scope.HasError() {
+ scope.CallMethod("AfterDelete")
+ }
+}
diff --git a/vendor/github.com/jinzhu/gorm/callback_query.go b/vendor/github.com/jinzhu/gorm/callback_query.go
new file mode 100644
index 0000000000000000000000000000000000000000..e3b3d534666d5690c3b951982aa913d88914adc8
--- /dev/null
+++ b/vendor/github.com/jinzhu/gorm/callback_query.go
@@ -0,0 +1,104 @@
+package gorm
+
+import (
+ "errors"
+ "fmt"
+ "reflect"
+)
+
+// Define callbacks for querying
+func init() {
+ DefaultCallback.Query().Register("gorm:query", queryCallback)
+ DefaultCallback.Query().Register("gorm:preload", preloadCallback)
+ DefaultCallback.Query().Register("gorm:after_query", afterQueryCallback)
+}
+
+// queryCallback used to query data from database
+func queryCallback(scope *Scope) {
+ if _, skip := scope.InstanceGet("gorm:skip_query_callback"); skip {
+ return
+ }
+
+ //we are only preloading relations, dont touch base model
+ if _, skip := scope.InstanceGet("gorm:only_preload"); skip {
+ return
+ }
+
+ defer scope.trace(scope.db.nowFunc())
+
+ var (
+ isSlice, isPtr bool
+ resultType reflect.Type
+ results = scope.IndirectValue()
+ )
+
+ if orderBy, ok := scope.Get("gorm:order_by_primary_key"); ok {
+ if primaryField := scope.PrimaryField(); primaryField != nil {
+ scope.Search.Order(fmt.Sprintf("%v.%v %v", scope.QuotedTableName(), scope.Quote(primaryField.DBName), orderBy))
+ }
+ }
+
+ if value, ok := scope.Get("gorm:query_destination"); ok {
+ results = indirect(reflect.ValueOf(value))
+ }
+
+ if kind := results.Kind(); kind == reflect.Slice {
+ isSlice = true
+ resultType = results.Type().Elem()
+ results.Set(reflect.MakeSlice(results.Type(), 0, 0))
+
+ if resultType.Kind() == reflect.Ptr {
+ isPtr = true
+ resultType = resultType.Elem()
+ }
+ } else if kind != reflect.Struct {
+ scope.Err(errors.New("unsupported destination, should be slice or struct"))
+ return
+ }
+
+ scope.prepareQuerySQL()
+
+ if !scope.HasError() {
+ scope.db.RowsAffected = 0
+ if str, ok := scope.Get("gorm:query_option"); ok {
+ scope.SQL += addExtraSpaceIfExist(fmt.Sprint(str))
+ }
+
+ if rows, err := scope.SQLDB().Query(scope.SQL, scope.SQLVars...); scope.Err(err) == nil {
+ defer rows.Close()
+
+ columns, _ := rows.Columns()
+ for rows.Next() {
+ scope.db.RowsAffected++
+
+ elem := results
+ if isSlice {
+ elem = reflect.New(resultType).Elem()
+ }
+
+ scope.scan(rows, columns, scope.New(elem.Addr().Interface()).Fields())
+
+ if isSlice {
+ if isPtr {
+ results.Set(reflect.Append(results, elem.Addr()))
+ } else {
+ results.Set(reflect.Append(results, elem))
+ }
+ }
+ }
+
+ if err := rows.Err(); err != nil {
+ scope.Err(err)
+ } else if scope.db.RowsAffected == 0 && !isSlice {
+ scope.Err(ErrRecordNotFound)
+ }
+ }
+ }
+}
+
+// afterQueryCallback will invoke `AfterFind` method after querying
+func afterQueryCallback(scope *Scope) {
+ if !scope.HasError() {
+ scope.CallMethod("AfterFind")
+ }
+}
diff --git a/vendor/github.com/jinzhu/gorm/callback_query_preload.go b/vendor/github.com/jinzhu/gorm/callback_query_preload.go
new file mode 100644
index 0000000000000000000000000000000000000000..a936180ad76cace5dfc0a4877bf7509b21e330af
--- /dev/null
+++ b/vendor/github.com/jinzhu/gorm/callback_query_preload.go
@@ -0,0 +1,410 @@
+package gorm
+
+import (
+ "errors"
+ "fmt"
+ "reflect"
+ "strconv"
+ "strings"
+)
+
+// preloadCallback used to preload associations
+func preloadCallback(scope *Scope) {
+ if _, skip := scope.InstanceGet("gorm:skip_query_callback"); skip {
+ return
+ }
+
+ if ap, ok := scope.Get("gorm:auto_preload"); ok {
+ // If gorm:auto_preload IS NOT a bool then auto preload.
+ // Else if it IS a bool, use the value
+ if apb, ok := ap.(bool); !ok {
+ autoPreload(scope)
+ } else if apb {
+ autoPreload(scope)
+ }
+ }
+
+ if scope.Search.preload == nil || scope.HasError() {
+ return
+ }
+
+ var (
+ preloadedMap = map[string]bool{}
+ fields = scope.Fields()
+ )
+
+ for _, preload := range scope.Search.preload {
+ var (
+ preloadFields = strings.Split(preload.schema, ".")
+ currentScope = scope
+ currentFields = fields
+ )
+
+ for idx, preloadField := range preloadFields {
+ var currentPreloadConditions []interface{}
+
+ if currentScope == nil {
+ continue
+ }
+
+ // if not preloaded
+ if preloadKey := strings.Join(preloadFields[:idx+1], "."); !preloadedMap[preloadKey] {
+
+ // assign search conditions to last preload
+ if idx == len(preloadFields)-1 {
+ currentPreloadConditions = preload.conditions
+ }
+
+ for _, field := range currentFields {
+ if field.Name != preloadField || field.Relationship == nil {
+ continue
+ }
+
+ switch field.Relationship.Kind {
+ case "has_one":
+ currentScope.handleHasOnePreload(field, currentPreloadConditions)
+ case "has_many":
+ currentScope.handleHasManyPreload(field, currentPreloadConditions)
+ case "belongs_to":
+ currentScope.handleBelongsToPreload(field, currentPreloadConditions)
+ case "many_to_many":
+ currentScope.handleManyToManyPreload(field, currentPreloadConditions)
+ default:
+ scope.Err(errors.New("unsupported relation"))
+ }
+
+ preloadedMap[preloadKey] = true
+ break
+ }
+
+ if !preloadedMap[preloadKey] {
+ scope.Err(fmt.Errorf("can't preload field %s for %s", preloadField, currentScope.GetModelStruct().ModelType))
+ return
+ }
+ }
+
+ // preload next level
+ if idx < len(preloadFields)-1 {
+ currentScope = currentScope.getColumnAsScope(preloadField)
+ if currentScope != nil {
+ currentFields = currentScope.Fields()
+ }
+ }
+ }
+ }
+}
+
+func autoPreload(scope *Scope) {
+ for _, field := range scope.Fields() {
+ if field.Relationship == nil {
+ continue
+ }
+
+ if val, ok := field.TagSettingsGet("PRELOAD"); ok {
+ if preload, err := strconv.ParseBool(val); err != nil {
+ scope.Err(errors.New("invalid preload option"))
+ return
+ } else if !preload {
+ continue
+ }
+ }
+
+ scope.Search.Preload(field.Name)
+ }
+}
+
+func (scope *Scope) generatePreloadDBWithConditions(conditions []interface{}) (*DB, []interface{}) {
+ var (
+ preloadDB = scope.NewDB()
+ preloadConditions []interface{}
+ )
+
+ for _, condition := range conditions {
+ if scopes, ok := condition.(func(*DB) *DB); ok {
+ preloadDB = scopes(preloadDB)
+ } else {
+ preloadConditions = append(preloadConditions, condition)
+ }
+ }
+
+ return preloadDB, preloadConditions
+}
+
+// handleHasOnePreload used to preload has one associations
+func (scope *Scope) handleHasOnePreload(field *Field, conditions []interface{}) {
+ relation := field.Relationship
+
+ // get relations's primary keys
+ primaryKeys := scope.getColumnAsArray(relation.AssociationForeignFieldNames, scope.Value)
+ if len(primaryKeys) == 0 {
+ return
+ }
+
+ // preload conditions
+ preloadDB, preloadConditions := scope.generatePreloadDBWithConditions(conditions)
+
+ // find relations
+ query := fmt.Sprintf("%v IN (%v)", toQueryCondition(scope, relation.ForeignDBNames), toQueryMarks(primaryKeys))
+ values := toQueryValues(primaryKeys)
+ if relation.PolymorphicType != "" {
+ query += fmt.Sprintf(" AND %v = ?", scope.Quote(relation.PolymorphicDBName))
+ values = append(values, relation.PolymorphicValue)
+ }
+
+ results := makeSlice(field.Struct.Type)
+ scope.Err(preloadDB.Where(query, values...).Find(results, preloadConditions...).Error)
+
+ // assign find results
+ var (
+ resultsValue = indirect(reflect.ValueOf(results))
+ indirectScopeValue = scope.IndirectValue()
+ )
+
+ if indirectScopeValue.Kind() == reflect.Slice {
+ foreignValuesToResults := make(map[string]reflect.Value)
+ for i := 0; i < resultsValue.Len(); i++ {
+ result := resultsValue.Index(i)
+ foreignValues := toString(getValueFromFields(result, relation.ForeignFieldNames))
+ foreignValuesToResults[foreignValues] = result
+ }
+ for j := 0; j < indirectScopeValue.Len(); j++ {
+ indirectValue := indirect(indirectScopeValue.Index(j))
+ valueString := toString(getValueFromFields(indirectValue, relation.AssociationForeignFieldNames))
+ if result, found := foreignValuesToResults[valueString]; found {
+ indirectValue.FieldByName(field.Name).Set(result)
+ }
+ }
+ } else {
+ for i := 0; i < resultsValue.Len(); i++ {
+ result := resultsValue.Index(i)
+ scope.Err(field.Set(result))
+ }
+ }
+}
+
+// handleHasManyPreload used to preload has many associations
+func (scope *Scope) handleHasManyPreload(field *Field, conditions []interface{}) {
+ relation := field.Relationship
+
+ // get relations's primary keys
+ primaryKeys := scope.getColumnAsArray(relation.AssociationForeignFieldNames, scope.Value)
+ if len(primaryKeys) == 0 {
+ return
+ }
+
+ // preload conditions
+ preloadDB, preloadConditions := scope.generatePreloadDBWithConditions(conditions)
+
+ // find relations
+ query := fmt.Sprintf("%v IN (%v)", toQueryCondition(scope, relation.ForeignDBNames), toQueryMarks(primaryKeys))
+ values := toQueryValues(primaryKeys)
+ if relation.PolymorphicType != "" {
+ query += fmt.Sprintf(" AND %v = ?", scope.Quote(relation.PolymorphicDBName))
+ values = append(values, relation.PolymorphicValue)
+ }
+
+ results := makeSlice(field.Struct.Type)
+ scope.Err(preloadDB.Where(query, values...).Find(results, preloadConditions...).Error)
+
+ // assign find results
+ var (
+ resultsValue = indirect(reflect.ValueOf(results))
+ indirectScopeValue = scope.IndirectValue()
+ )
+
+ if indirectScopeValue.Kind() == reflect.Slice {
+ preloadMap := make(map[string][]reflect.Value)
+ for i := 0; i < resultsValue.Len(); i++ {
+ result := resultsValue.Index(i)
+ foreignValues := getValueFromFields(result, relation.ForeignFieldNames)
+ preloadMap[toString(foreignValues)] = append(preloadMap[toString(foreignValues)], result)
+ }
+
+ for j := 0; j < indirectScopeValue.Len(); j++ {
+ object := indirect(indirectScopeValue.Index(j))
+ objectRealValue := getValueFromFields(object, relation.AssociationForeignFieldNames)
+ f := object.FieldByName(field.Name)
+ if results, ok := preloadMap[toString(objectRealValue)]; ok {
+ f.Set(reflect.Append(f, results...))
+ } else {
+ f.Set(reflect.MakeSlice(f.Type(), 0, 0))
+ }
+ }
+ } else {
+ scope.Err(field.Set(resultsValue))
+ }
+}
+
+// handleBelongsToPreload used to preload belongs to associations
+func (scope *Scope) handleBelongsToPreload(field *Field, conditions []interface{}) {
+ relation := field.Relationship
+
+ // preload conditions
+ preloadDB, preloadConditions := scope.generatePreloadDBWithConditions(conditions)
+
+ // get relations's primary keys
+ primaryKeys := scope.getColumnAsArray(relation.ForeignFieldNames, scope.Value)
+ if len(primaryKeys) == 0 {
+ return
+ }
+
+ // find relations
+ results := makeSlice(field.Struct.Type)
+ scope.Err(preloadDB.Where(fmt.Sprintf("%v IN (%v)", toQueryCondition(scope, relation.AssociationForeignDBNames), toQueryMarks(primaryKeys)), toQueryValues(primaryKeys)...).Find(results, preloadConditions...).Error)
+
+ // assign find results
+ var (
+ resultsValue = indirect(reflect.ValueOf(results))
+ indirectScopeValue = scope.IndirectValue()
+ )
+
+ foreignFieldToObjects := make(map[string][]*reflect.Value)
+ if indirectScopeValue.Kind() == reflect.Slice {
+ for j := 0; j < indirectScopeValue.Len(); j++ {
+ object := indirect(indirectScopeValue.Index(j))
+ valueString := toString(getValueFromFields(object, relation.ForeignFieldNames))
+ foreignFieldToObjects[valueString] = append(foreignFieldToObjects[valueString], &object)
+ }
+ }
+
+ for i := 0; i < resultsValue.Len(); i++ {
+ result := resultsValue.Index(i)
+ if indirectScopeValue.Kind() == reflect.Slice {
+ valueString := toString(getValueFromFields(result, relation.AssociationForeignFieldNames))
+ if objects, found := foreignFieldToObjects[valueString]; found {
+ for _, object := range objects {
+ object.FieldByName(field.Name).Set(result)
+ }
+ }
+ } else {
+ scope.Err(field.Set(result))
+ }
+ }
+}
+
+// handleManyToManyPreload used to preload many to many associations
+func (scope *Scope) handleManyToManyPreload(field *Field, conditions []interface{}) {
+ var (
+ relation = field.Relationship
+ joinTableHandler = relation.JoinTableHandler
+ fieldType = field.Struct.Type.Elem()
+ foreignKeyValue interface{}
+ foreignKeyType = reflect.ValueOf(&foreignKeyValue).Type()
+ linkHash = map[string][]reflect.Value{}
+ isPtr bool
+ )
+
+ if fieldType.Kind() == reflect.Ptr {
+ isPtr = true
+ fieldType = fieldType.Elem()
+ }
+
+ var sourceKeys = []string{}
+ for _, key := range joinTableHandler.SourceForeignKeys() {
+ sourceKeys = append(sourceKeys, key.DBName)
+ }
+
+ // preload conditions
+ preloadDB, preloadConditions := scope.generatePreloadDBWithConditions(conditions)
+
+ // generate query with join table
+ newScope := scope.New(reflect.New(fieldType).Interface())
+ preloadDB = preloadDB.Table(newScope.TableName()).Model(newScope.Value)
+
+ if len(preloadDB.search.selects) == 0 {
+ preloadDB = preloadDB.Select("*")
+ }
+
+ preloadDB = joinTableHandler.JoinWith(joinTableHandler, preloadDB, scope.Value)
+
+ // preload inline conditions
+ if len(preloadConditions) > 0 {
+ preloadDB = preloadDB.Where(preloadConditions[0], preloadConditions[1:]...)
+ }
+
+ rows, err := preloadDB.Rows()
+
+ if scope.Err(err) != nil {
+ return
+ }
+ defer rows.Close()
+
+ columns, _ := rows.Columns()
+ for rows.Next() {
+ var (
+ elem = reflect.New(fieldType).Elem()
+ fields = scope.New(elem.Addr().Interface()).Fields()
+ )
+
+ // register foreign keys in join tables
+ var joinTableFields []*Field
+ for _, sourceKey := range sourceKeys {
+ joinTableFields = append(joinTableFields, &Field{StructField: &StructField{DBName: sourceKey, IsNormal: true}, Field: reflect.New(foreignKeyType).Elem()})
+ }
+
+ scope.scan(rows, columns, append(fields, joinTableFields...))
+
+ scope.New(elem.Addr().Interface()).
+ InstanceSet("gorm:skip_query_callback", true).
+ callCallbacks(scope.db.parent.callbacks.queries)
+
+ var foreignKeys = make([]interface{}, len(sourceKeys))
+ // generate hashed forkey keys in join table
+ for idx, joinTableField := range joinTableFields {
+ if !joinTableField.Field.IsNil() {
+ foreignKeys[idx] = joinTableField.Field.Elem().Interface()
+ }
+ }
+ hashedSourceKeys := toString(foreignKeys)
+
+ if isPtr {
+ linkHash[hashedSourceKeys] = append(linkHash[hashedSourceKeys], elem.Addr())
+ } else {
+ linkHash[hashedSourceKeys] = append(linkHash[hashedSourceKeys], elem)
+ }
+ }
+
+ if err := rows.Err(); err != nil {
+ scope.Err(err)
+ }
+
+ // assign find results
+ var (
+ indirectScopeValue = scope.IndirectValue()
+ fieldsSourceMap = map[string][]reflect.Value{}
+ foreignFieldNames = []string{}
+ )
+
+ for _, dbName := range relation.ForeignFieldNames {
+ if field, ok := scope.FieldByName(dbName); ok {
+ foreignFieldNames = append(foreignFieldNames, field.Name)
+ }
+ }
+
+ if indirectScopeValue.Kind() == reflect.Slice {
+ for j := 0; j < indirectScopeValue.Len(); j++ {
+ object := indirect(indirectScopeValue.Index(j))
+ key := toString(getValueFromFields(object, foreignFieldNames))
+ fieldsSourceMap[key] = append(fieldsSourceMap[key], object.FieldByName(field.Name))
+ }
+ } else if indirectScopeValue.IsValid() {
+ key := toString(getValueFromFields(indirectScopeValue, foreignFieldNames))
+ fieldsSourceMap[key] = append(fieldsSourceMap[key], indirectScopeValue.FieldByName(field.Name))
+ }
+
+ for source, fields := range fieldsSourceMap {
+ for _, f := range fields {
+ //If not 0 this means Value is a pointer and we already added preloaded models to it
+ if f.Len() != 0 {
+ continue
+ }
+
+ v := reflect.MakeSlice(f.Type(), 0, 0)
+ if len(linkHash[source]) > 0 {
+ v = reflect.Append(f, linkHash[source]...)
+ }
+
+ f.Set(v)
+ }
+ }
+}
diff --git a/vendor/github.com/jinzhu/gorm/callback_row_query.go b/vendor/github.com/jinzhu/gorm/callback_row_query.go
new file mode 100644
index 0000000000000000000000000000000000000000..687b0039b24d95a5da50656b38c5a216ce406df4
--- /dev/null
+++ b/vendor/github.com/jinzhu/gorm/callback_row_query.go
@@ -0,0 +1,36 @@
+package gorm
+
+import (
+ "database/sql"
+ "fmt"
+)
+
+// Define callbacks for row query
+func init() {
+ DefaultCallback.RowQuery().Register("gorm:row_query", rowQueryCallback)
+}
+
+type RowQueryResult struct {
+ Row *sql.Row
+}
+
+type RowsQueryResult struct {
+ Rows *sql.Rows
+ Error error
+}
+
+// queryCallback used to query data from database
+func rowQueryCallback(scope *Scope) {
+ if result, ok := scope.InstanceGet("row_query_result"); ok {
+ scope.prepareQuerySQL()
+ if str, ok := scope.Get("gorm:query_option"); ok {
+ scope.SQL += addExtraSpaceIfExist(fmt.Sprint(str))
+ }
+
+ if rowResult, ok := result.(*RowQueryResult); ok {
+ rowResult.Row = scope.SQLDB().QueryRow(scope.SQL, scope.SQLVars...)
+ } else if rowsResult, ok := result.(*RowsQueryResult); ok {
+ rowsResult.Rows, rowsResult.Error = scope.SQLDB().Query(scope.SQL, scope.SQLVars...)
+ }
+ }
+}
diff --git a/vendor/github.com/jinzhu/gorm/callback_save.go b/vendor/github.com/jinzhu/gorm/callback_save.go
new file mode 100644
index 0000000000000000000000000000000000000000..3b4e0589535e35a6d5c21da3e70c62fb80e68532
--- /dev/null
+++ b/vendor/github.com/jinzhu/gorm/callback_save.go
@@ -0,0 +1,170 @@
+package gorm
+
+import (
+ "reflect"
+ "strings"
+)
+
+func beginTransactionCallback(scope *Scope) {
+ scope.Begin()
+}
+
+func commitOrRollbackTransactionCallback(scope *Scope) {
+ scope.CommitOrRollback()
+}
+
+func saveAssociationCheck(scope *Scope, field *Field) (autoUpdate bool, autoCreate bool, saveReference bool, r *Relationship) {
+ checkTruth := func(value interface{}) bool {
+ if v, ok := value.(bool); ok && !v {
+ return false
+ }
+
+ if v, ok := value.(string); ok {
+ v = strings.ToLower(v)
+ return v == "true"
+ }
+
+ return true
+ }
+
+ if scope.changeableField(field) && !field.IsBlank && !field.IsIgnored {
+ if r = field.Relationship; r != nil {
+ autoUpdate, autoCreate, saveReference = true, true, true
+
+ if value, ok := scope.Get("gorm:save_associations"); ok {
+ autoUpdate = checkTruth(value)
+ autoCreate = autoUpdate
+ saveReference = autoUpdate
+ } else if value, ok := field.TagSettingsGet("SAVE_ASSOCIATIONS"); ok {
+ autoUpdate = checkTruth(value)
+ autoCreate = autoUpdate
+ saveReference = autoUpdate
+ }
+
+ if value, ok := scope.Get("gorm:association_autoupdate"); ok {
+ autoUpdate = checkTruth(value)
+ } else if value, ok := field.TagSettingsGet("ASSOCIATION_AUTOUPDATE"); ok {
+ autoUpdate = checkTruth(value)
+ }
+
+ if value, ok := scope.Get("gorm:association_autocreate"); ok {
+ autoCreate = checkTruth(value)
+ } else if value, ok := field.TagSettingsGet("ASSOCIATION_AUTOCREATE"); ok {
+ autoCreate = checkTruth(value)
+ }
+
+ if value, ok := scope.Get("gorm:association_save_reference"); ok {
+ saveReference = checkTruth(value)
+ } else if value, ok := field.TagSettingsGet("ASSOCIATION_SAVE_REFERENCE"); ok {
+ saveReference = checkTruth(value)
+ }
+ }
+ }
+
+ return
+}
+
+func saveBeforeAssociationsCallback(scope *Scope) {
+ for _, field := range scope.Fields() {
+ autoUpdate, autoCreate, saveReference, relationship := saveAssociationCheck(scope, field)
+
+ if relationship != nil && relationship.Kind == "belongs_to" {
+ fieldValue := field.Field.Addr().Interface()
+ newScope := scope.New(fieldValue)
+
+ if newScope.PrimaryKeyZero() {
+ if autoCreate {
+ scope.Err(scope.NewDB().Save(fieldValue).Error)
+ }
+ } else if autoUpdate {
+ scope.Err(scope.NewDB().Save(fieldValue).Error)
+ }
+
+ if saveReference {
+ if len(relationship.ForeignFieldNames) != 0 {
+ // set value's foreign key
+ for idx, fieldName := range relationship.ForeignFieldNames {
+ associationForeignName := relationship.AssociationForeignDBNames[idx]
+ if foreignField, ok := scope.New(fieldValue).FieldByName(associationForeignName); ok {
+ scope.Err(scope.SetColumn(fieldName, foreignField.Field.Interface()))
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+func saveAfterAssociationsCallback(scope *Scope) {
+ for _, field := range scope.Fields() {
+ autoUpdate, autoCreate, saveReference, relationship := saveAssociationCheck(scope, field)
+
+ if relationship != nil && (relationship.Kind == "has_one" || relationship.Kind == "has_many" || relationship.Kind == "many_to_many") {
+ value := field.Field
+
+ switch value.Kind() {
+ case reflect.Slice:
+ for i := 0; i < value.Len(); i++ {
+ newDB := scope.NewDB()
+ elem := value.Index(i).Addr().Interface()
+ newScope := newDB.NewScope(elem)
+
+ if saveReference {
+ if relationship.JoinTableHandler == nil && len(relationship.ForeignFieldNames) != 0 {
+ for idx, fieldName := range relationship.ForeignFieldNames {
+ associationForeignName := relationship.AssociationForeignDBNames[idx]
+ if f, ok := scope.FieldByName(associationForeignName); ok {
+ scope.Err(newScope.SetColumn(fieldName, f.Field.Interface()))
+ }
+ }
+ }
+
+ if relationship.PolymorphicType != "" {
+ scope.Err(newScope.SetColumn(relationship.PolymorphicType, relationship.PolymorphicValue))
+ }
+ }
+
+ if newScope.PrimaryKeyZero() {
+ if autoCreate {
+ scope.Err(newDB.Save(elem).Error)
+ }
+ } else if autoUpdate {
+ scope.Err(newDB.Save(elem).Error)
+ }
+
+ if !scope.New(newScope.Value).PrimaryKeyZero() && saveReference {
+ if joinTableHandler := relationship.JoinTableHandler; joinTableHandler != nil {
+ scope.Err(joinTableHandler.Add(joinTableHandler, newDB, scope.Value, newScope.Value))
+ }
+ }
+ }
+ default:
+ elem := value.Addr().Interface()
+ newScope := scope.New(elem)
+
+ if saveReference {
+ if len(relationship.ForeignFieldNames) != 0 {
+ for idx, fieldName := range relationship.ForeignFieldNames {
+ associationForeignName := relationship.AssociationForeignDBNames[idx]
+ if f, ok := scope.FieldByName(associationForeignName); ok {
+ scope.Err(newScope.SetColumn(fieldName, f.Field.Interface()))
+ }
+ }
+ }
+
+ if relationship.PolymorphicType != "" {
+ scope.Err(newScope.SetColumn(relationship.PolymorphicType, relationship.PolymorphicValue))
+ }
+ }
+
+ if newScope.PrimaryKeyZero() {
+ if autoCreate {
+ scope.Err(scope.NewDB().Save(elem).Error)
+ }
+ } else if autoUpdate {
+ scope.Err(scope.NewDB().Save(elem).Error)
+ }
+ }
+ }
+ }
+}
diff --git a/vendor/github.com/jinzhu/gorm/callback_update.go b/vendor/github.com/jinzhu/gorm/callback_update.go
new file mode 100644
index 0000000000000000000000000000000000000000..699e534b9665179f03692b10a78660537d8e37e6
--- /dev/null
+++ b/vendor/github.com/jinzhu/gorm/callback_update.go
@@ -0,0 +1,121 @@
+package gorm
+
+import (
+ "errors"
+ "fmt"
+ "sort"
+ "strings"
+)
+
+// Define callbacks for updating
+func init() {
+ DefaultCallback.Update().Register("gorm:assign_updating_attributes", assignUpdatingAttributesCallback)
+ DefaultCallback.Update().Register("gorm:begin_transaction", beginTransactionCallback)
+ DefaultCallback.Update().Register("gorm:before_update", beforeUpdateCallback)
+ DefaultCallback.Update().Register("gorm:save_before_associations", saveBeforeAssociationsCallback)
+ DefaultCallback.Update().Register("gorm:update_time_stamp", updateTimeStampForUpdateCallback)
+ DefaultCallback.Update().Register("gorm:update", updateCallback)
+ DefaultCallback.Update().Register("gorm:save_after_associations", saveAfterAssociationsCallback)
+ DefaultCallback.Update().Register("gorm:after_update", afterUpdateCallback)
+ DefaultCallback.Update().Register("gorm:commit_or_rollback_transaction", commitOrRollbackTransactionCallback)
+}
+
+// assignUpdatingAttributesCallback assign updating attributes to model
+func assignUpdatingAttributesCallback(scope *Scope) {
+ if attrs, ok := scope.InstanceGet("gorm:update_interface"); ok {
+ if updateMaps, hasUpdate := scope.updatedAttrsWithValues(attrs); hasUpdate {
+ scope.InstanceSet("gorm:update_attrs", updateMaps)
+ } else {
+ scope.SkipLeft()
+ }
+ }
+}
+
+// beforeUpdateCallback will invoke `BeforeSave`, `BeforeUpdate` method before updating
+func beforeUpdateCallback(scope *Scope) {
+ if scope.DB().HasBlockGlobalUpdate() && !scope.hasConditions() {
+ scope.Err(errors.New("missing WHERE clause while updating"))
+ return
+ }
+ if _, ok := scope.Get("gorm:update_column"); !ok {
+ if !scope.HasError() {
+ scope.CallMethod("BeforeSave")
+ }
+ if !scope.HasError() {
+ scope.CallMethod("BeforeUpdate")
+ }
+ }
+}
+
+// updateTimeStampForUpdateCallback will set `UpdatedAt` when updating
+func updateTimeStampForUpdateCallback(scope *Scope) {
+ if _, ok := scope.Get("gorm:update_column"); !ok {
+ scope.SetColumn("UpdatedAt", scope.db.nowFunc())
+ }
+}
+
+// updateCallback the callback used to update data to database
+func updateCallback(scope *Scope) {
+ if !scope.HasError() {
+ var sqls []string
+
+ if updateAttrs, ok := scope.InstanceGet("gorm:update_attrs"); ok {
+ // Sort the column names so that the generated SQL is the same every time.
+ updateMap := updateAttrs.(map[string]interface{})
+ var columns []string
+ for c := range updateMap {
+ columns = append(columns, c)
+ }
+ sort.Strings(columns)
+
+ for _, column := range columns {
+ value := updateMap[column]
+ sqls = append(sqls, fmt.Sprintf("%v = %v", scope.Quote(column), scope.AddToVars(value)))
+ }
+ } else {
+ for _, field := range scope.Fields() {
+ if scope.changeableField(field) {
+ if !field.IsPrimaryKey && field.IsNormal && (field.Name != "CreatedAt" || !field.IsBlank) {
+ if !field.IsForeignKey || !field.IsBlank || !field.HasDefaultValue {
+ sqls = append(sqls, fmt.Sprintf("%v = %v", scope.Quote(field.DBName), scope.AddToVars(field.Field.Interface())))
+ }
+ } else if relationship := field.Relationship; relationship != nil && relationship.Kind == "belongs_to" {
+ for _, foreignKey := range relationship.ForeignDBNames {
+ if foreignField, ok := scope.FieldByName(foreignKey); ok && !scope.changeableField(foreignField) {
+ sqls = append(sqls,
+ fmt.Sprintf("%v = %v", scope.Quote(foreignField.DBName), scope.AddToVars(foreignField.Field.Interface())))
+ }
+ }
+ }
+ }
+ }
+ }
+
+ var extraOption string
+ if str, ok := scope.Get("gorm:update_option"); ok {
+ extraOption = fmt.Sprint(str)
+ }
+
+ if len(sqls) > 0 {
+ scope.Raw(fmt.Sprintf(
+ "UPDATE %v SET %v%v%v",
+ scope.QuotedTableName(),
+ strings.Join(sqls, ", "),
+ addExtraSpaceIfExist(scope.CombinedConditionSql()),
+ addExtraSpaceIfExist(extraOption),
+ )).Exec()
+ }
+ }
+}
+
+// afterUpdateCallback will invoke `AfterUpdate`, `AfterSave` method after updating
+func afterUpdateCallback(scope *Scope) {
+ if _, ok := scope.Get("gorm:update_column"); !ok {
+ if !scope.HasError() {
+ scope.CallMethod("AfterUpdate")
+ }
+ if !scope.HasError() {
+ scope.CallMethod("AfterSave")
+ }
+ }
+}
diff --git a/vendor/github.com/jinzhu/gorm/dialect.go b/vendor/github.com/jinzhu/gorm/dialect.go
new file mode 100644
index 0000000000000000000000000000000000000000..831c0a8e836275b67f1554e7e93ea5f3e093a381
--- /dev/null
+++ b/vendor/github.com/jinzhu/gorm/dialect.go
@@ -0,0 +1,145 @@
+package gorm
+
+import (
+ "database/sql"
+ "fmt"
+ "reflect"
+ "strconv"
+ "strings"
+)
+
+// Dialect interface contains behaviors that differ across SQL database
+type Dialect interface {
+ // GetName get dialect's name
+ GetName() string
+
+ // SetDB set db for dialect
+ SetDB(db SQLCommon)
+
+ // BindVar return the placeholder for actual values in SQL statements, in many dbs it is "?", Postgres using $1
+ BindVar(i int) string
+ // Quote quotes field name to avoid SQL parsing exceptions by using a reserved word as a field name
+ Quote(key string) string
+ // DataTypeOf return data's sql type
+ DataTypeOf(field *StructField) string
+
+ // HasIndex check has index or not
+ HasIndex(tableName string, indexName string) bool
+ // HasForeignKey check has foreign key or not
+ HasForeignKey(tableName string, foreignKeyName string) bool
+ // RemoveIndex remove index
+ RemoveIndex(tableName string, indexName string) error
+ // HasTable check has table or not
+ HasTable(tableName string) bool
+ // HasColumn check has column or not
+ HasColumn(tableName string, columnName string) bool
+ // ModifyColumn modify column's type
+ ModifyColumn(tableName string, columnName string, typ string) error
+
+ // LimitAndOffsetSQL return generated SQL with Limit and Offset, as mssql has special case
+ LimitAndOffsetSQL(limit, offset interface{}) string
+ // SelectFromDummyTable return select values, for most dbs, `SELECT values` just works, mysql needs `SELECT value FROM DUAL`
+ SelectFromDummyTable() string
+ // LastInsertIdReturningSuffix most dbs support LastInsertId, but postgres needs to use `RETURNING`
+ LastInsertIDReturningSuffix(tableName, columnName string) string
+ // DefaultValueStr
+ DefaultValueStr() string
+
+ // BuildKeyName returns a valid key name (foreign key, index key) for the given table, field and reference
+ BuildKeyName(kind, tableName string, fields ...string) string
+
+ // NormalizeIndexAndColumn returns valid index name and column name depending on each dialect
+ NormalizeIndexAndColumn(indexName, columnName string) (string, string)
+
+ // CurrentDatabase return current database name
+ CurrentDatabase() string
+}
+
+var dialectsMap = map[string]Dialect{}
+
+func newDialect(name string, db SQLCommon) Dialect {
+ if value, ok := dialectsMap[name]; ok {
+ dialect := reflect.New(reflect.TypeOf(value).Elem()).Interface().(Dialect)
+ dialect.SetDB(db)
+ return dialect
+ }
+
+ fmt.Printf("`%v` is not officially supported, running under compatibility mode.\n", name)
+ commontDialect := &commonDialect{}
+ commontDialect.SetDB(db)
+ return commontDialect
+}
+
+// RegisterDialect register new dialect
+func RegisterDialect(name string, dialect Dialect) {
+ dialectsMap[name] = dialect
+}
+
+// GetDialect gets the dialect for the specified dialect name
+func GetDialect(name string) (dialect Dialect, ok bool) {
+ dialect, ok = dialectsMap[name]
+ return
+}
+
+// ParseFieldStructForDialect get field's sql data type
+var ParseFieldStructForDialect = func(field *StructField, dialect Dialect) (fieldValue reflect.Value, sqlType string, size int, additionalType string) {
+ // Get redirected field type
+ var (
+ reflectType = field.Struct.Type
+ dataType, _ = field.TagSettingsGet("TYPE")
+ )
+
+ for reflectType.Kind() == reflect.Ptr {
+ reflectType = reflectType.Elem()
+ }
+
+ // Get redirected field value
+ fieldValue = reflect.Indirect(reflect.New(reflectType))
+
+ if gormDataType, ok := fieldValue.Interface().(interface {
+ GormDataType(Dialect) string
+ }); ok {
+ dataType = gormDataType.GormDataType(dialect)
+ }
+
+ // Get scanner's real value
+ if dataType == "" {
+ var getScannerValue func(reflect.Value)
+ getScannerValue = func(value reflect.Value) {
+ fieldValue = value
+ if _, isScanner := reflect.New(fieldValue.Type()).Interface().(sql.Scanner); isScanner && fieldValue.Kind() == reflect.Struct {
+ getScannerValue(fieldValue.Field(0))
+ }
+ }
+ getScannerValue(fieldValue)
+ }
+
+ // Default Size
+ if num, ok := field.TagSettingsGet("SIZE"); ok {
+ size, _ = strconv.Atoi(num)
+ } else {
+ size = 255
+ }
+
+ // Default type from tag setting
+ notNull, _ := field.TagSettingsGet("NOT NULL")
+ unique, _ := field.TagSettingsGet("UNIQUE")
+ additionalType = notNull + " " + unique
+ if value, ok := field.TagSettingsGet("DEFAULT"); ok {
+ additionalType = additionalType + " DEFAULT " + value
+ }
+
+ if value, ok := field.TagSettingsGet("COMMENT"); ok {
+ additionalType = additionalType + " COMMENT " + value
+ }
+
+ return fieldValue, dataType, size, strings.TrimSpace(additionalType)
+}
+
+func currentDatabaseAndTable(dialect Dialect, tableName string) (string, string) {
+ if strings.Contains(tableName, ".") {
+ splitStrings := strings.SplitN(tableName, ".", 2)
+ return splitStrings[0], splitStrings[1]
+ }
+ return dialect.CurrentDatabase(), tableName
+}
diff --git a/vendor/github.com/jinzhu/gorm/dialect_common.go b/vendor/github.com/jinzhu/gorm/dialect_common.go
new file mode 100644
index 0000000000000000000000000000000000000000..e3a5b7022da641dbb4c6bae8a1023173a877c193
--- /dev/null
+++ b/vendor/github.com/jinzhu/gorm/dialect_common.go
@@ -0,0 +1,183 @@
+package gorm
+
+import (
+ "fmt"
+ "reflect"
+ "regexp"
+ "strconv"
+ "strings"
+ "time"
+)
+
+var keyNameRegex = regexp.MustCompile("[^a-zA-Z0-9]+")
+
+// DefaultForeignKeyNamer contains the default foreign key name generator method
+type DefaultForeignKeyNamer struct {
+}
+
+type commonDialect struct {
+ db SQLCommon
+ DefaultForeignKeyNamer
+}
+
+func init() {
+ RegisterDialect("common", &commonDialect{})
+}
+
+func (commonDialect) GetName() string {
+ return "common"
+}
+
+func (s *commonDialect) SetDB(db SQLCommon) {
+ s.db = db
+}
+
+func (commonDialect) BindVar(i int) string {
+ return "$$$" // ?
+}
+
+func (commonDialect) Quote(key string) string {
+ return fmt.Sprintf(`"%s"`, key)
+}
+
+func (s *commonDialect) fieldCanAutoIncrement(field *StructField) bool {
+ if value, ok := field.TagSettingsGet("AUTO_INCREMENT"); ok {
+ return strings.ToLower(value) != "false"
+ }
+ return field.IsPrimaryKey
+}
+
+func (s *commonDialect) DataTypeOf(field *StructField) string {
+ var dataValue, sqlType, size, additionalType = ParseFieldStructForDialect(field, s)
+
+ if sqlType == "" {
+ switch dataValue.Kind() {
+ case reflect.Bool:
+ sqlType = "BOOLEAN"
+ case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uintptr:
+ if s.fieldCanAutoIncrement(field) {
+ sqlType = "INTEGER AUTO_INCREMENT"
+ } else {
+ sqlType = "INTEGER"
+ }
+ case reflect.Int64, reflect.Uint64:
+ if s.fieldCanAutoIncrement(field) {
+ sqlType = "BIGINT AUTO_INCREMENT"
+ } else {
+ sqlType = "BIGINT"
+ }
+ case reflect.Float32, reflect.Float64:
+ sqlType = "FLOAT"
+ case reflect.String:
+ if size > 0 && size < 65532 {
+ sqlType = fmt.Sprintf("VARCHAR(%d)", size)
+ } else {
+ sqlType = "VARCHAR(65532)"
+ }
+ case reflect.Struct:
+ if _, ok := dataValue.Interface().(time.Time); ok {
+ sqlType = "TIMESTAMP"
+ }
+ default:
+ if _, ok := dataValue.Interface().([]byte); ok {
+ if size > 0 && size < 65532 {
+ sqlType = fmt.Sprintf("BINARY(%d)", size)
+ } else {
+ sqlType = "BINARY(65532)"
+ }
+ }
+ }
+ }
+
+ if sqlType == "" {
+ panic(fmt.Sprintf("invalid sql type %s (%s) for commonDialect", dataValue.Type().Name(), dataValue.Kind().String()))
+ }
+
+ if strings.TrimSpace(additionalType) == "" {
+ return sqlType
+ }
+ return fmt.Sprintf("%v %v", sqlType, additionalType)
+}
+
+func (s commonDialect) HasIndex(tableName string, indexName string) bool {
+ var count int
+ currentDatabase, tableName := currentDatabaseAndTable(&s, tableName)
+ s.db.QueryRow("SELECT count(*) FROM INFORMATION_SCHEMA.STATISTICS WHERE table_schema = ? AND table_name = ? AND index_name = ?", currentDatabase, tableName, indexName).Scan(&count)
+ return count > 0
+}
+
+func (s commonDialect) RemoveIndex(tableName string, indexName string) error {
+ _, err := s.db.Exec(fmt.Sprintf("DROP INDEX %v", indexName))
+ return err
+}
+
+func (s commonDialect) HasForeignKey(tableName string, foreignKeyName string) bool {
+ return false
+}
+
+func (s commonDialect) HasTable(tableName string) bool {
+ var count int
+ currentDatabase, tableName := currentDatabaseAndTable(&s, tableName)
+ s.db.QueryRow("SELECT count(*) FROM INFORMATION_SCHEMA.TABLES WHERE table_schema = ? AND table_name = ?", currentDatabase, tableName).Scan(&count)
+ return count > 0
+}
+
+func (s commonDialect) HasColumn(tableName string, columnName string) bool {
+ var count int
+ currentDatabase, tableName := currentDatabaseAndTable(&s, tableName)
+ s.db.QueryRow("SELECT count(*) FROM INFORMATION_SCHEMA.COLUMNS WHERE table_schema = ? AND table_name = ? AND column_name = ?", currentDatabase, tableName, columnName).Scan(&count)
+ return count > 0
+}
+
+func (s commonDialect) ModifyColumn(tableName string, columnName string, typ string) error {
+ _, err := s.db.Exec(fmt.Sprintf("ALTER TABLE %v ALTER COLUMN %v TYPE %v", tableName, columnName, typ))
+ return err
+}
+
+func (s commonDialect) CurrentDatabase() (name string) {
+ s.db.QueryRow("SELECT DATABASE()").Scan(&name)
+ return
+}
+
+func (commonDialect) LimitAndOffsetSQL(limit, offset interface{}) (sql string) {
+ if limit != nil {
+ if parsedLimit, err := strconv.ParseInt(fmt.Sprint(limit), 0, 0); err == nil && parsedLimit >= 0 {
+ sql += fmt.Sprintf(" LIMIT %d", parsedLimit)
+ }
+ }
+ if offset != nil {
+ if parsedOffset, err := strconv.ParseInt(fmt.Sprint(offset), 0, 0); err == nil && parsedOffset >= 0 {
+ sql += fmt.Sprintf(" OFFSET %d", parsedOffset)
+ }
+ }
+ return
+}
+
+func (commonDialect) SelectFromDummyTable() string {
+ return ""
+}
+
+func (commonDialect) LastInsertIDReturningSuffix(tableName, columnName string) string {
+ return ""
+}
+
+func (commonDialect) DefaultValueStr() string {
+ return "DEFAULT VALUES"
+}
+
+// BuildKeyName returns a valid key name (foreign key, index key) for the given table, field and reference
+func (DefaultForeignKeyNamer) BuildKeyName(kind, tableName string, fields ...string) string {
+ keyName := fmt.Sprintf("%s_%s_%s", kind, tableName, strings.Join(fields, "_"))
+ keyName = keyNameRegex.ReplaceAllString(keyName, "_")
+ return keyName
+}
+
+// NormalizeIndexAndColumn returns argument's index name and column name without doing anything
+func (commonDialect) NormalizeIndexAndColumn(indexName, columnName string) (string, string) {
+ return indexName, columnName
+}
+
+// IsByteArrayOrSlice returns true of the reflected value is an array or slice
+func IsByteArrayOrSlice(value reflect.Value) bool {
+ return (value.Kind() == reflect.Array || value.Kind() == reflect.Slice) && value.Type().Elem() == reflect.TypeOf(uint8(0))
+}
diff --git a/vendor/github.com/jinzhu/gorm/dialect_mysql.go b/vendor/github.com/jinzhu/gorm/dialect_mysql.go
new file mode 100644
index 0000000000000000000000000000000000000000..5a1ad708d814b16d166dde1717d4a19840f4b800
--- /dev/null
+++ b/vendor/github.com/jinzhu/gorm/dialect_mysql.go
@@ -0,0 +1,204 @@
+package gorm
+
+import (
+ "crypto/sha1"
+ "fmt"
+ "reflect"
+ "regexp"
+ "strconv"
+ "strings"
+ "time"
+ "unicode/utf8"
+)
+
+var mysqlIndexRegex = regexp.MustCompile(`^(.+)\((\d+)\)$`)
+
+type mysql struct {
+ commonDialect
+}
+
+func init() {
+ RegisterDialect("mysql", &mysql{})
+}
+
+func (mysql) GetName() string {
+ return "mysql"
+}
+
+func (mysql) Quote(key string) string {
+ return fmt.Sprintf("`%s`", key)
+}
+
+// Get Data Type for MySQL Dialect
+func (s *mysql) DataTypeOf(field *StructField) string {
+ var dataValue, sqlType, size, additionalType = ParseFieldStructForDialect(field, s)
+
+ // MySQL allows only one auto increment column per table, and it must
+ // be a KEY column.
+ if _, ok := field.TagSettingsGet("AUTO_INCREMENT"); ok {
+ if _, ok = field.TagSettingsGet("INDEX"); !ok && !field.IsPrimaryKey {
+ field.TagSettingsDelete("AUTO_INCREMENT")
+ }
+ }
+
+ if sqlType == "" {
+ switch dataValue.Kind() {
+ case reflect.Bool:
+ sqlType = "boolean"
+ case reflect.Int8:
+ if s.fieldCanAutoIncrement(field) {
+ field.TagSettingsSet("AUTO_INCREMENT", "AUTO_INCREMENT")
+ sqlType = "tinyint AUTO_INCREMENT"
+ } else {
+ sqlType = "tinyint"
+ }
+ case reflect.Int, reflect.Int16, reflect.Int32:
+ if s.fieldCanAutoIncrement(field) {
+ field.TagSettingsSet("AUTO_INCREMENT", "AUTO_INCREMENT")
+ sqlType = "int AUTO_INCREMENT"
+ } else {
+ sqlType = "int"
+ }
+ case reflect.Uint8:
+ if s.fieldCanAutoIncrement(field) {
+ field.TagSettingsSet("AUTO_INCREMENT", "AUTO_INCREMENT")
+ sqlType = "tinyint unsigned AUTO_INCREMENT"
+ } else {
+ sqlType = "tinyint unsigned"
+ }
+ case reflect.Uint, reflect.Uint16, reflect.Uint32, reflect.Uintptr:
+ if s.fieldCanAutoIncrement(field) {
+ field.TagSettingsSet("AUTO_INCREMENT", "AUTO_INCREMENT")
+ sqlType = "int unsigned AUTO_INCREMENT"
+ } else {
+ sqlType = "int unsigned"
+ }
+ case reflect.Int64:
+ if s.fieldCanAutoIncrement(field) {
+ field.TagSettingsSet("AUTO_INCREMENT", "AUTO_INCREMENT")
+ sqlType = "bigint AUTO_INCREMENT"
+ } else {
+ sqlType = "bigint"
+ }
+ case reflect.Uint64:
+ if s.fieldCanAutoIncrement(field) {
+ field.TagSettingsSet("AUTO_INCREMENT", "AUTO_INCREMENT")
+ sqlType = "bigint unsigned AUTO_INCREMENT"
+ } else {
+ sqlType = "bigint unsigned"
+ }
+ case reflect.Float32, reflect.Float64:
+ sqlType = "double"
+ case reflect.String:
+ if size > 0 && size < 65532 {
+ sqlType = fmt.Sprintf("varchar(%d)", size)
+ } else {
+ sqlType = "longtext"
+ }
+ case reflect.Struct:
+ if _, ok := dataValue.Interface().(time.Time); ok {
+ precision := ""
+ if p, ok := field.TagSettingsGet("PRECISION"); ok {
+ precision = fmt.Sprintf("(%s)", p)
+ }
+
+ if _, ok := field.TagSettingsGet("NOT NULL"); ok || field.IsPrimaryKey {
+ sqlType = fmt.Sprintf("timestamp%v", precision)
+ } else {
+ sqlType = fmt.Sprintf("timestamp%v NULL", precision)
+ }
+ }
+ default:
+ if IsByteArrayOrSlice(dataValue) {
+ if size > 0 && size < 65532 {
+ sqlType = fmt.Sprintf("varbinary(%d)", size)
+ } else {
+ sqlType = "longblob"
+ }
+ }
+ }
+ }
+
+ if sqlType == "" {
+ panic(fmt.Sprintf("invalid sql type %s (%s) for mysql", dataValue.Type().Name(), dataValue.Kind().String()))
+ }
+
+ if strings.TrimSpace(additionalType) == "" {
+ return sqlType
+ }
+ return fmt.Sprintf("%v %v", sqlType, additionalType)
+}
+
+func (s mysql) RemoveIndex(tableName string, indexName string) error {
+ _, err := s.db.Exec(fmt.Sprintf("DROP INDEX %v ON %v", indexName, s.Quote(tableName)))
+ return err
+}
+
+func (s mysql) ModifyColumn(tableName string, columnName string, typ string) error {
+ _, err := s.db.Exec(fmt.Sprintf("ALTER TABLE %v MODIFY COLUMN %v %v", tableName, columnName, typ))
+ return err
+}
+
+func (s mysql) LimitAndOffsetSQL(limit, offset interface{}) (sql string) {
+ if limit != nil {
+ if parsedLimit, err := strconv.ParseInt(fmt.Sprint(limit), 0, 0); err == nil && parsedLimit >= 0 {
+ sql += fmt.Sprintf(" LIMIT %d", parsedLimit)
+
+ if offset != nil {
+ if parsedOffset, err := strconv.ParseInt(fmt.Sprint(offset), 0, 0); err == nil && parsedOffset >= 0 {
+ sql += fmt.Sprintf(" OFFSET %d", parsedOffset)
+ }
+ }
+ }
+ }
+ return
+}
+
+func (s mysql) HasForeignKey(tableName string, foreignKeyName string) bool {
+ var count int
+ currentDatabase, tableName := currentDatabaseAndTable(&s, tableName)
+ s.db.QueryRow("SELECT count(*) FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS WHERE CONSTRAINT_SCHEMA=? AND TABLE_NAME=? AND CONSTRAINT_NAME=? AND CONSTRAINT_TYPE='FOREIGN KEY'", currentDatabase, tableName, foreignKeyName).Scan(&count)
+ return count > 0
+}
+
+func (s mysql) CurrentDatabase() (name string) {
+ s.db.QueryRow("SELECT DATABASE()").Scan(&name)
+ return
+}
+
+func (mysql) SelectFromDummyTable() string {
+ return "FROM DUAL"
+}
+
+func (s mysql) BuildKeyName(kind, tableName string, fields ...string) string {
+ keyName := s.commonDialect.BuildKeyName(kind, tableName, fields...)
+ if utf8.RuneCountInString(keyName) <= 64 {
+ return keyName
+ }
+ h := sha1.New()
+ h.Write([]byte(keyName))
+ bs := h.Sum(nil)
+
+ // sha1 is 40 characters, keep first 24 characters of destination
+ destRunes := []rune(keyNameRegex.ReplaceAllString(fields[0], "_"))
+ if len(destRunes) > 24 {
+ destRunes = destRunes[:24]
+ }
+
+ return fmt.Sprintf("%s%x", string(destRunes), bs)
+}
+
+// NormalizeIndexAndColumn returns index name and column name for specify an index prefix length if needed
+func (mysql) NormalizeIndexAndColumn(indexName, columnName string) (string, string) {
+ submatch := mysqlIndexRegex.FindStringSubmatch(indexName)
+ if len(submatch) != 3 {
+ return indexName, columnName
+ }
+ indexName = submatch[1]
+ columnName = fmt.Sprintf("%s(%s)", columnName, submatch[2])
+ return indexName, columnName
+}
+
+func (mysql) DefaultValueStr() string {
+ return "VALUES()"
+}
diff --git a/vendor/github.com/jinzhu/gorm/dialect_postgres.go b/vendor/github.com/jinzhu/gorm/dialect_postgres.go
new file mode 100644
index 0000000000000000000000000000000000000000..53d31388ef231c4c0bfb955f1a4b95d0ca58bc49
--- /dev/null
+++ b/vendor/github.com/jinzhu/gorm/dialect_postgres.go
@@ -0,0 +1,143 @@
+package gorm
+
+import (
+ "encoding/json"
+ "fmt"
+ "reflect"
+ "strings"
+ "time"
+)
+
+type postgres struct {
+ commonDialect
+}
+
+func init() {
+ RegisterDialect("postgres", &postgres{})
+ RegisterDialect("cloudsqlpostgres", &postgres{})
+}
+
+func (postgres) GetName() string {
+ return "postgres"
+}
+
+func (postgres) BindVar(i int) string {
+ return fmt.Sprintf("$%v", i)
+}
+
+func (s *postgres) DataTypeOf(field *StructField) string {
+ var dataValue, sqlType, size, additionalType = ParseFieldStructForDialect(field, s)
+
+ if sqlType == "" {
+ switch dataValue.Kind() {
+ case reflect.Bool:
+ sqlType = "boolean"
+ case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uintptr:
+ if s.fieldCanAutoIncrement(field) {
+ field.TagSettingsSet("AUTO_INCREMENT", "AUTO_INCREMENT")
+ sqlType = "serial"
+ } else {
+ sqlType = "integer"
+ }
+ case reflect.Int64, reflect.Uint32, reflect.Uint64:
+ if s.fieldCanAutoIncrement(field) {
+ field.TagSettingsSet("AUTO_INCREMENT", "AUTO_INCREMENT")
+ sqlType = "bigserial"
+ } else {
+ sqlType = "bigint"
+ }
+ case reflect.Float32, reflect.Float64:
+ sqlType = "numeric"
+ case reflect.String:
+ if _, ok := field.TagSettingsGet("SIZE"); !ok {
+ size = 0 // if SIZE haven't been set, use `text` as the default type, as there are no performance different
+ }
+
+ if size > 0 && size < 65532 {
+ sqlType = fmt.Sprintf("varchar(%d)", size)
+ } else {
+ sqlType = "text"
+ }
+ case reflect.Struct:
+ if _, ok := dataValue.Interface().(time.Time); ok {
+ sqlType = "timestamp with time zone"
+ }
+ case reflect.Map:
+ if dataValue.Type().Name() == "Hstore" {
+ sqlType = "hstore"
+ }
+ default:
+ if IsByteArrayOrSlice(dataValue) {
+ sqlType = "bytea"
+
+ if isUUID(dataValue) {
+ sqlType = "uuid"
+ }
+
+ if isJSON(dataValue) {
+ sqlType = "jsonb"
+ }
+ }
+ }
+ }
+
+ if sqlType == "" {
+ panic(fmt.Sprintf("invalid sql type %s (%s) for postgres", dataValue.Type().Name(), dataValue.Kind().String()))
+ }
+
+ if strings.TrimSpace(additionalType) == "" {
+ return sqlType
+ }
+ return fmt.Sprintf("%v %v", sqlType, additionalType)
+}
+
+func (s postgres) HasIndex(tableName string, indexName string) bool {
+ var count int
+ s.db.QueryRow("SELECT count(*) FROM pg_indexes WHERE tablename = $1 AND indexname = $2 AND schemaname = CURRENT_SCHEMA()", tableName, indexName).Scan(&count)
+ return count > 0
+}
+
+func (s postgres) HasForeignKey(tableName string, foreignKeyName string) bool {
+ var count int
+ s.db.QueryRow("SELECT count(con.conname) FROM pg_constraint con WHERE $1::regclass::oid = con.conrelid AND con.conname = $2 AND con.contype='f'", tableName, foreignKeyName).Scan(&count)
+ return count > 0
+}
+
+func (s postgres) HasTable(tableName string) bool {
+ var count int
+ s.db.QueryRow("SELECT count(*) FROM INFORMATION_SCHEMA.tables WHERE table_name = $1 AND table_type = 'BASE TABLE' AND table_schema = CURRENT_SCHEMA()", tableName).Scan(&count)
+ return count > 0
+}
+
+func (s postgres) HasColumn(tableName string, columnName string) bool {
+ var count int
+ s.db.QueryRow("SELECT count(*) FROM INFORMATION_SCHEMA.columns WHERE table_name = $1 AND column_name = $2 AND table_schema = CURRENT_SCHEMA()", tableName, columnName).Scan(&count)
+ return count > 0
+}
+
+func (s postgres) CurrentDatabase() (name string) {
+ s.db.QueryRow("SELECT CURRENT_DATABASE()").Scan(&name)
+ return
+}
+
+func (s postgres) LastInsertIDReturningSuffix(tableName, key string) string {
+ return fmt.Sprintf("RETURNING %v.%v", tableName, key)
+}
+
+func (postgres) SupportLastInsertID() bool {
+ return false
+}
+
+func isUUID(value reflect.Value) bool {
+ if value.Kind() != reflect.Array || value.Type().Len() != 16 {
+ return false
+ }
+ typename := value.Type().Name()
+ lower := strings.ToLower(typename)
+ return "uuid" == lower || "guid" == lower
+}
+
+func isJSON(value reflect.Value) bool {
+ _, ok := value.Interface().(json.RawMessage)
+ return ok
+}
diff --git a/vendor/github.com/jinzhu/gorm/dialect_sqlite3.go b/vendor/github.com/jinzhu/gorm/dialect_sqlite3.go
new file mode 100644
index 0000000000000000000000000000000000000000..5f96c363a0d5b23a19f9549fb33f5225a7d52fd5
--- /dev/null
+++ b/vendor/github.com/jinzhu/gorm/dialect_sqlite3.go
@@ -0,0 +1,107 @@
+package gorm
+
+import (
+ "fmt"
+ "reflect"
+ "strings"
+ "time"
+)
+
+type sqlite3 struct {
+ commonDialect
+}
+
+func init() {
+ RegisterDialect("sqlite3", &sqlite3{})
+}
+
+func (sqlite3) GetName() string {
+ return "sqlite3"
+}
+
+// Get Data Type for Sqlite Dialect
+func (s *sqlite3) DataTypeOf(field *StructField) string {
+ var dataValue, sqlType, size, additionalType = ParseFieldStructForDialect(field, s)
+
+ if sqlType == "" {
+ switch dataValue.Kind() {
+ case reflect.Bool:
+ sqlType = "bool"
+ case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uintptr:
+ if s.fieldCanAutoIncrement(field) {
+ field.TagSettingsSet("AUTO_INCREMENT", "AUTO_INCREMENT")
+ sqlType = "integer primary key autoincrement"
+ } else {
+ sqlType = "integer"
+ }
+ case reflect.Int64, reflect.Uint64:
+ if s.fieldCanAutoIncrement(field) {
+ field.TagSettingsSet("AUTO_INCREMENT", "AUTO_INCREMENT")
+ sqlType = "integer primary key autoincrement"
+ } else {
+ sqlType = "bigint"
+ }
+ case reflect.Float32, reflect.Float64:
+ sqlType = "real"
+ case reflect.String:
+ if size > 0 && size < 65532 {
+ sqlType = fmt.Sprintf("varchar(%d)", size)
+ } else {
+ sqlType = "text"
+ }
+ case reflect.Struct:
+ if _, ok := dataValue.Interface().(time.Time); ok {
+ sqlType = "datetime"
+ }
+ default:
+ if IsByteArrayOrSlice(dataValue) {
+ sqlType = "blob"
+ }
+ }
+ }
+
+ if sqlType == "" {
+ panic(fmt.Sprintf("invalid sql type %s (%s) for sqlite3", dataValue.Type().Name(), dataValue.Kind().String()))
+ }
+
+ if strings.TrimSpace(additionalType) == "" {
+ return sqlType
+ }
+ return fmt.Sprintf("%v %v", sqlType, additionalType)
+}
+
+func (s sqlite3) HasIndex(tableName string, indexName string) bool {
+ var count int
+ s.db.QueryRow(fmt.Sprintf("SELECT count(*) FROM sqlite_master WHERE tbl_name = ? AND sql LIKE '%%INDEX %v ON%%'", indexName), tableName).Scan(&count)
+ return count > 0
+}
+
+func (s sqlite3) HasTable(tableName string) bool {
+ var count int
+ s.db.QueryRow("SELECT count(*) FROM sqlite_master WHERE type='table' AND name=?", tableName).Scan(&count)
+ return count > 0
+}
+
+func (s sqlite3) HasColumn(tableName string, columnName string) bool {
+ var count int
+ s.db.QueryRow(fmt.Sprintf("SELECT count(*) FROM sqlite_master WHERE tbl_name = ? AND (sql LIKE '%%\"%v\" %%' OR sql LIKE '%%%v %%');\n", columnName, columnName), tableName).Scan(&count)
+ return count > 0
+}
+
+func (s sqlite3) CurrentDatabase() (name string) {
+ var (
+ ifaces = make([]interface{}, 3)
+ pointers = make([]*string, 3)
+ i int
+ )
+ for i = 0; i < 3; i++ {
+ ifaces[i] = &pointers[i]
+ }
+ if err := s.db.QueryRow("PRAGMA database_list").Scan(ifaces...); err != nil {
+ return
+ }
+ if pointers[1] != nil {
+ name = *pointers[1]
+ }
+ return
+}
diff --git a/vendor/github.com/jinzhu/gorm/dialects/mysql/mysql.go b/vendor/github.com/jinzhu/gorm/dialects/mysql/mysql.go
new file mode 100644
index 0000000000000000000000000000000000000000..9deba48aea0dc0133ddaccba782b3cc102d49c21
--- /dev/null
+++ b/vendor/github.com/jinzhu/gorm/dialects/mysql/mysql.go
@@ -0,0 +1,3 @@
+package mysql
+
+import _ "github.com/go-sql-driver/mysql"
diff --git a/vendor/github.com/jinzhu/gorm/docker-compose.yml b/vendor/github.com/jinzhu/gorm/docker-compose.yml
new file mode 100644
index 0000000000000000000000000000000000000000..79bf5fc3954b713a189929b6cbb00d284410297f
--- /dev/null
+++ b/vendor/github.com/jinzhu/gorm/docker-compose.yml
@@ -0,0 +1,30 @@
+version: '3'
+
+services:
+ mysql:
+ image: 'mysql:latest'
+ ports:
+ - 9910:3306
+ environment:
+ - MYSQL_DATABASE=gorm
+ - MYSQL_USER=gorm
+ - MYSQL_PASSWORD=gorm
+ - MYSQL_RANDOM_ROOT_PASSWORD="yes"
+ postgres:
+ image: 'postgres:latest'
+ ports:
+ - 9920:5432
+ environment:
+ - POSTGRES_USER=gorm
+ - POSTGRES_DB=gorm
+ - POSTGRES_PASSWORD=gorm
+ mssql:
+ image: 'mcmoe/mssqldocker:latest'
+ ports:
+ - 9930:1433
+ environment:
+ - ACCEPT_EULA=Y
+ - SA_PASSWORD=LoremIpsum86
+ - MSSQL_DB=gorm
+ - MSSQL_USER=gorm
+ - MSSQL_PASSWORD=LoremIpsum86
diff --git a/vendor/github.com/jinzhu/gorm/errors.go b/vendor/github.com/jinzhu/gorm/errors.go
new file mode 100644
index 0000000000000000000000000000000000000000..d5ef8d571232d52cb6dc722c225a74641d6acd5c
--- /dev/null
+++ b/vendor/github.com/jinzhu/gorm/errors.go
@@ -0,0 +1,72 @@
+package gorm
+
+import (
+ "errors"
+ "strings"
+)
+
+var (
+ // ErrRecordNotFound returns a "record not found error". Occurs only when attempting to query the database with a struct; querying with a slice won't return this error
+ ErrRecordNotFound = errors.New("record not found")
+ // ErrInvalidSQL occurs when you attempt a query with invalid SQL
+ ErrInvalidSQL = errors.New("invalid SQL")
+ // ErrInvalidTransaction occurs when you are trying to `Commit` or `Rollback`
+ ErrInvalidTransaction = errors.New("no valid transaction")
+ // ErrCantStartTransaction can't start transaction when you are trying to start one with `Begin`
+ ErrCantStartTransaction = errors.New("can't start transaction")
+ // ErrUnaddressable unaddressable value
+ ErrUnaddressable = errors.New("using unaddressable value")
+)
+
+// Errors contains all happened errors
+type Errors []error
+
+// IsRecordNotFoundError returns true if error contains a RecordNotFound error
+func IsRecordNotFoundError(err error) bool {
+ if errs, ok := err.(Errors); ok {
+ for _, err := range errs {
+ if err == ErrRecordNotFound {
+ return true
+ }
+ }
+ }
+ return err == ErrRecordNotFound
+}
+
+// GetErrors gets all errors that have occurred and returns a slice of errors (Error type)
+func (errs Errors) GetErrors() []error {
+ return errs
+}
+
+// Add adds an error to a given slice of errors
+func (errs Errors) Add(newErrors ...error) Errors {
+ for _, err := range newErrors {
+ if err == nil {
+ continue
+ }
+
+ if errors, ok := err.(Errors); ok {
+ errs = errs.Add(errors...)
+ } else {
+ ok = true
+ for _, e := range errs {
+ if err == e {
+ ok = false
+ }
+ }
+ if ok {
+ errs = append(errs, err)
+ }
+ }
+ }
+ return errs
+}
+
+// Error takes a slice of all errors that have occurred and returns it as a formatted string
+func (errs Errors) Error() string {
+ var errors = []string{}
+ for _, e := range errs {
+ errors = append(errors, e.Error())
+ }
+ return strings.Join(errors, "; ")
+}
diff --git a/vendor/github.com/jinzhu/gorm/field.go b/vendor/github.com/jinzhu/gorm/field.go
new file mode 100644
index 0000000000000000000000000000000000000000..acd06e20d7cf895523577cdbc1bce5c440d1fd91
--- /dev/null
+++ b/vendor/github.com/jinzhu/gorm/field.go
@@ -0,0 +1,66 @@
+package gorm
+
+import (
+ "database/sql"
+ "database/sql/driver"
+ "errors"
+ "fmt"
+ "reflect"
+)
+
+// Field model field definition
+type Field struct {
+ *StructField
+ IsBlank bool
+ Field reflect.Value
+}
+
+// Set set a value to the field
+func (field *Field) Set(value interface{}) (err error) {
+ if !field.Field.IsValid() {
+ return errors.New("field value not valid")
+ }
+
+ if !field.Field.CanAddr() {
+ return ErrUnaddressable
+ }
+
+ reflectValue, ok := value.(reflect.Value)
+ if !ok {
+ reflectValue = reflect.ValueOf(value)
+ }
+
+ fieldValue := field.Field
+ if reflectValue.IsValid() {
+ if reflectValue.Type().ConvertibleTo(fieldValue.Type()) {
+ fieldValue.Set(reflectValue.Convert(fieldValue.Type()))
+ } else {
+ if fieldValue.Kind() == reflect.Ptr {
+ if fieldValue.IsNil() {
+ fieldValue.Set(reflect.New(field.Struct.Type.Elem()))
+ }
+ fieldValue = fieldValue.Elem()
+ }
+
+ if reflectValue.Type().ConvertibleTo(fieldValue.Type()) {
+ fieldValue.Set(reflectValue.Convert(fieldValue.Type()))
+ } else if scanner, ok := fieldValue.Addr().Interface().(sql.Scanner); ok {
+ v := reflectValue.Interface()
+ if valuer, ok := v.(driver.Valuer); ok {
+ if v, err = valuer.Value(); err == nil {
+ err = scanner.Scan(v)
+ }
+ } else {
+ err = scanner.Scan(v)
+ }
+ } else {
+ err = fmt.Errorf("could not convert argument of field %s from %s to %s", field.Name, reflectValue.Type(), fieldValue.Type())
+ }
+ }
+ } else {
+ field.Field.Set(reflect.Zero(field.Field.Type()))
+ }
+
+ field.IsBlank = isBlank(field.Field)
+ return err
+}
diff --git a/vendor/github.com/jinzhu/gorm/go.mod b/vendor/github.com/jinzhu/gorm/go.mod
new file mode 100644
index 0000000000000000000000000000000000000000..2d2fec370fde98ba053bcf99ba2e5ebe66ec060b
--- /dev/null
+++ b/vendor/github.com/jinzhu/gorm/go.mod
@@ -0,0 +1,13 @@
+module github.com/jinzhu/gorm
+
+go 1.12
+
+require (
+ github.com/denisenkom/go-mssqldb v0.0.0-20190515213511-eb9f6a1743f3
+ github.com/erikstmartin/go-testdb v0.0.0-20160219214506-8d10e4a1bae5
+ github.com/go-sql-driver/mysql v1.4.1
+ github.com/jinzhu/inflection v1.0.0
+ github.com/jinzhu/now v1.0.1
+ github.com/lib/pq v1.1.1
+ github.com/mattn/go-sqlite3 v1.11.0
+)
diff --git a/vendor/github.com/jinzhu/gorm/go.sum b/vendor/github.com/jinzhu/gorm/go.sum
new file mode 100644
index 0000000000000000000000000000000000000000..c43559bf95917a19ea0e94929f0626bc5d84fd3a
--- /dev/null
+++ b/vendor/github.com/jinzhu/gorm/go.sum
@@ -0,0 +1,131 @@
+cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
+cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
+cloud.google.com/go v0.37.4 h1:glPeL3BQJsbF6aIIYfZizMwc5LTYz250bDMjttbBGAU=
+cloud.google.com/go v0.37.4/go.mod h1:NHPJ89PdicEuT9hdPXMROBD91xc5uRDxsMtSB16k7hw=
+github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
+github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo=
+github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI=
+github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
+github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
+github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ=
+github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
+github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
+github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/denisenkom/go-mssqldb v0.0.0-20190515213511-eb9f6a1743f3 h1:tkum0XDgfR0jcVVXuTsYv/erY2NnEDqwRojbxR1rBYA=
+github.com/denisenkom/go-mssqldb v0.0.0-20190515213511-eb9f6a1743f3/go.mod h1:zAg7JM8CkOJ43xKXIj7eRO9kmWm/TW578qo+oDO6tuM=
+github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs=
+github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU=
+github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I=
+github.com/erikstmartin/go-testdb v0.0.0-20160219214506-8d10e4a1bae5 h1:Yzb9+7DPaBjB8zlTR87/ElzFsnQfuHnVUVqpZZIcV5Y=
+github.com/erikstmartin/go-testdb v0.0.0-20160219214506-8d10e4a1bae5/go.mod h1:a2zkGnVExMxdzMo3M0Hi/3sEU+cWnZpSni0O6/Yb/P0=
+github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
+github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
+github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
+github.com/go-sql-driver/mysql v1.4.1 h1:g24URVg0OFbNUTx9qqY1IRZ9D9z3iPyi5zKhQZpNwpA=
+github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
+github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
+github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
+github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
+github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
+github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
+github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
+github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
+github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
+github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
+github.com/google/go-cmp v0.2.0 h1:+dTQ8DZQJz0Mb/HjFlkptS1FeQ4cWSnN941F8aEG4SQ=
+github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
+github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
+github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
+github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
+github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg=
+github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
+github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
+github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
+github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E=
+github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
+github.com/jinzhu/now v1.0.1 h1:HjfetcXq097iXP0uoPCdnM4Efp5/9MsM0/M+XOTeR3M=
+github.com/jinzhu/now v1.0.1/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
+github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
+github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
+github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
+github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
+github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
+github.com/lib/pq v1.1.1 h1:sJZmqHoEaY7f+NPP8pgLB/WxulyR3fewgCM2qaSlBb4=
+github.com/lib/pq v1.1.1/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
+github.com/mattn/go-sqlite3 v1.11.0 h1:LDdKkqtYlom37fkvqs8rMPFKAMe8+SgjbwZ6ex1/A/Q=
+github.com/mattn/go-sqlite3 v1.11.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
+github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
+github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
+github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
+github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
+github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
+github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw=
+github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=
+github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
+github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
+github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
+github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs=
+github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
+github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
+github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
+github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
+github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
+github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
+github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
+github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
+github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
+go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk=
+golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
+golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
+golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c h1:Vj5n4GlwjmQteupaxJ9+0FNOmBrHfq7vN4btdGoDZgI=
+golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
+golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
+golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
+golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
+golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
+golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
+golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
+golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
+golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
+golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
+golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
+golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
+golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
+golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
+golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
+google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk=
+google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
+google.golang.org/appengine v1.4.0 h1:/wp5JvzpHIxhs/dumFmF7BXTf3Z+dd4uXta4kVyO508=
+google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
+google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
+google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
+google.golang.org/genproto v0.0.0-20190404172233-64821d5d2107/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
+google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs=
+google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
+gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
+gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
+gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
+gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
+gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
+honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
+honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
+honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
diff --git a/vendor/github.com/jinzhu/gorm/interface.go b/vendor/github.com/jinzhu/gorm/interface.go
new file mode 100644
index 0000000000000000000000000000000000000000..fe649231458639fa19dcfa86ab7eea2c82fb6665
--- /dev/null
+++ b/vendor/github.com/jinzhu/gorm/interface.go
@@ -0,0 +1,24 @@
+package gorm
+
+import (
+ "context"
+ "database/sql"
+)
+
+// SQLCommon is the minimal database connection functionality gorm requires. Implemented by *sql.DB.
+type SQLCommon interface {
+ Exec(query string, args ...interface{}) (sql.Result, error)
+ Prepare(query string) (*sql.Stmt, error)
+ Query(query string, args ...interface{}) (*sql.Rows, error)
+ QueryRow(query string, args ...interface{}) *sql.Row
+}
+
+type sqlDb interface {
+ Begin() (*sql.Tx, error)
+ BeginTx(ctx context.Context, opts *sql.TxOptions) (*sql.Tx, error)
+}
+
+type sqlTx interface {
+ Commit() error
+ Rollback() error
+}
diff --git a/vendor/github.com/jinzhu/gorm/join_table_handler.go b/vendor/github.com/jinzhu/gorm/join_table_handler.go
new file mode 100644
index 0000000000000000000000000000000000000000..a036d46d25f38dec78bc74ccb0d883304d7680ed
--- /dev/null
+++ b/vendor/github.com/jinzhu/gorm/join_table_handler.go
@@ -0,0 +1,211 @@
+package gorm
+
+import (
+ "errors"
+ "fmt"
+ "reflect"
+ "strings"
+)
+
+// JoinTableHandlerInterface is an interface for how to handle many2many relations
+type JoinTableHandlerInterface interface {
+ // initialize join table handler
+ Setup(relationship *Relationship, tableName string, source reflect.Type, destination reflect.Type)
+ // Table return join table's table name
+ Table(db *DB) string
+ // Add create relationship in join table for source and destination
+ Add(handler JoinTableHandlerInterface, db *DB, source interface{}, destination interface{}) error
+ // Delete delete relationship in join table for sources
+ Delete(handler JoinTableHandlerInterface, db *DB, sources ...interface{}) error
+ // JoinWith query with `Join` conditions
+ JoinWith(handler JoinTableHandlerInterface, db *DB, source interface{}) *DB
+ // SourceForeignKeys return source foreign keys
+ SourceForeignKeys() []JoinTableForeignKey
+ // DestinationForeignKeys return destination foreign keys
+ DestinationForeignKeys() []JoinTableForeignKey
+}
+
+// JoinTableForeignKey join table foreign key struct
+type JoinTableForeignKey struct {
+ DBName string
+ AssociationDBName string
+}
+
+// JoinTableSource is a struct that contains model type and foreign keys
+type JoinTableSource struct {
+ ModelType reflect.Type
+ ForeignKeys []JoinTableForeignKey
+}
+
+// JoinTableHandler default join table handler
+type JoinTableHandler struct {
+ TableName string `sql:"-"`
+ Source JoinTableSource `sql:"-"`
+ Destination JoinTableSource `sql:"-"`
+}
+
+// SourceForeignKeys return source foreign keys
+func (s *JoinTableHandler) SourceForeignKeys() []JoinTableForeignKey {
+ return s.Source.ForeignKeys
+}
+
+// DestinationForeignKeys return destination foreign keys
+func (s *JoinTableHandler) DestinationForeignKeys() []JoinTableForeignKey {
+ return s.Destination.ForeignKeys
+}
+
+// Setup initialize a default join table handler
+func (s *JoinTableHandler) Setup(relationship *Relationship, tableName string, source reflect.Type, destination reflect.Type) {
+ s.TableName = tableName
+
+ s.Source = JoinTableSource{ModelType: source}
+ s.Source.ForeignKeys = []JoinTableForeignKey{}
+ for idx, dbName := range relationship.ForeignFieldNames {
+ s.Source.ForeignKeys = append(s.Source.ForeignKeys, JoinTableForeignKey{
+ DBName: relationship.ForeignDBNames[idx],
+ AssociationDBName: dbName,
+ })
+ }
+
+ s.Destination = JoinTableSource{ModelType: destination}
+ s.Destination.ForeignKeys = []JoinTableForeignKey{}
+ for idx, dbName := range relationship.AssociationForeignFieldNames {
+ s.Destination.ForeignKeys = append(s.Destination.ForeignKeys, JoinTableForeignKey{
+ DBName: relationship.AssociationForeignDBNames[idx],
+ AssociationDBName: dbName,
+ })
+ }
+}
+
+// Table return join table's table name
+func (s JoinTableHandler) Table(db *DB) string {
+ return DefaultTableNameHandler(db, s.TableName)
+}
+
+func (s JoinTableHandler) updateConditionMap(conditionMap map[string]interface{}, db *DB, joinTableSources []JoinTableSource, sources ...interface{}) {
+ for _, source := range sources {
+ scope := db.NewScope(source)
+ modelType := scope.GetModelStruct().ModelType
+
+ for _, joinTableSource := range joinTableSources {
+ if joinTableSource.ModelType == modelType {
+ for _, foreignKey := range joinTableSource.ForeignKeys {
+ if field, ok := scope.FieldByName(foreignKey.AssociationDBName); ok {
+ conditionMap[foreignKey.DBName] = field.Field.Interface()
+ }
+ }
+ break
+ }
+ }
+ }
+}
+
+// Add create relationship in join table for source and destination
+func (s JoinTableHandler) Add(handler JoinTableHandlerInterface, db *DB, source interface{}, destination interface{}) error {
+ var (
+ scope = db.NewScope("")
+ conditionMap = map[string]interface{}{}
+ )
+
+ // Update condition map for source
+ s.updateConditionMap(conditionMap, db, []JoinTableSource{s.Source}, source)
+
+ // Update condition map for destination
+ s.updateConditionMap(conditionMap, db, []JoinTableSource{s.Destination}, destination)
+
+ var assignColumns, binVars, conditions []string
+ var values []interface{}
+ for key, value := range conditionMap {
+ assignColumns = append(assignColumns, scope.Quote(key))
+ binVars = append(binVars, `?`)
+ conditions = append(conditions, fmt.Sprintf("%v = ?", scope.Quote(key)))
+ values = append(values, value)
+ }
+
+ for _, value := range values {
+ values = append(values, value)
+ }
+
+ quotedTable := scope.Quote(handler.Table(db))
+ sql := fmt.Sprintf(
+ "INSERT INTO %v (%v) SELECT %v %v WHERE NOT EXISTS (SELECT * FROM %v WHERE %v)",
+ quotedTable,
+ strings.Join(assignColumns, ","),
+ strings.Join(binVars, ","),
+ scope.Dialect().SelectFromDummyTable(),
+ quotedTable,
+ strings.Join(conditions, " AND "),
+ )
+
+ return db.Exec(sql, values...).Error
+}
+
+// Delete delete relationship in join table for sources
+func (s JoinTableHandler) Delete(handler JoinTableHandlerInterface, db *DB, sources ...interface{}) error {
+ var (
+ scope = db.NewScope(nil)
+ conditions []string
+ values []interface{}
+ conditionMap = map[string]interface{}{}
+ )
+
+ s.updateConditionMap(conditionMap, db, []JoinTableSource{s.Source, s.Destination}, sources...)
+
+ for key, value := range conditionMap {
+ conditions = append(conditions, fmt.Sprintf("%v = ?", scope.Quote(key)))
+ values = append(values, value)
+ }
+
+ return db.Table(handler.Table(db)).Where(strings.Join(conditions, " AND "), values...).Delete("").Error
+}
+
+// JoinWith query with `Join` conditions
+func (s JoinTableHandler) JoinWith(handler JoinTableHandlerInterface, db *DB, source interface{}) *DB {
+ var (
+ scope = db.NewScope(source)
+ tableName = handler.Table(db)
+ quotedTableName = scope.Quote(tableName)
+ joinConditions []string
+ values []interface{}
+ )
+
+ if s.Source.ModelType == scope.GetModelStruct().ModelType {
+ destinationTableName := db.NewScope(reflect.New(s.Destination.ModelType).Interface()).QuotedTableName()
+ for _, foreignKey := range s.Destination.ForeignKeys {
+ joinConditions = append(joinConditions, fmt.Sprintf("%v.%v = %v.%v", quotedTableName, scope.Quote(foreignKey.DBName), destinationTableName, scope.Quote(foreignKey.AssociationDBName)))
+ }
+
+ var foreignDBNames []string
+ var foreignFieldNames []string
+
+ for _, foreignKey := range s.Source.ForeignKeys {
+ foreignDBNames = append(foreignDBNames, foreignKey.DBName)
+ if field, ok := scope.FieldByName(foreignKey.AssociationDBName); ok {
+ foreignFieldNames = append(foreignFieldNames, field.Name)
+ }
+ }
+
+ foreignFieldValues := scope.getColumnAsArray(foreignFieldNames, scope.Value)
+
+ var condString string
+ if len(foreignFieldValues) > 0 {
+ var quotedForeignDBNames []string
+ for _, dbName := range foreignDBNames {
+ quotedForeignDBNames = append(quotedForeignDBNames, tableName+"."+dbName)
+ }
+
+ condString = fmt.Sprintf("%v IN (%v)", toQueryCondition(scope, quotedForeignDBNames), toQueryMarks(foreignFieldValues))
+
+ keys := scope.getColumnAsArray(foreignFieldNames, scope.Value)
+ values = append(values, toQueryValues(keys))
+ } else {
+ condString = fmt.Sprintf("1 <> 1")
+ }
+
+ return db.Joins(fmt.Sprintf("INNER JOIN %v ON %v", quotedTableName, strings.Join(joinConditions, " AND "))).
+ Where(condString, toQueryValues(foreignFieldValues)...)
+ }
+
+ db.Error = errors.New("wrong source type for join table handler")
+ return db
+}
diff --git a/vendor/github.com/jinzhu/gorm/logger.go b/vendor/github.com/jinzhu/gorm/logger.go
new file mode 100644
index 0000000000000000000000000000000000000000..a42f272700db2a4509ecf664193504e79eb34f83
--- /dev/null
+++ b/vendor/github.com/jinzhu/gorm/logger.go
@@ -0,0 +1,128 @@
+package gorm
+
+import (
+ "database/sql/driver"
+ "fmt"
+ "log"
+ "os"
+ "reflect"
+ "regexp"
+ "strconv"
+ "time"
+ "unicode"
+)
+
+var (
+ defaultLogger = Logger{log.New(os.Stdout, "\r\n", 0)}
+ sqlRegexp = regexp.MustCompile(`\?`)
+ numericPlaceHolderRegexp = regexp.MustCompile(`\$\d+`)
+)
+
+func isPrintable(s string) bool {
+ for _, r := range s {
+ if !unicode.IsPrint(r) {
+ return false
+ }
+ }
+ return true
+}
+
+var LogFormatter = func(values ...interface{}) (messages []interface{}) {
+ if len(values) > 1 {
+ var (
+ sql string
+ formattedValues []string
+ level = values[0]
+ currentTime = "\n\033[33m[" + NowFunc().Format("2006-01-02 15:04:05") + "]\033[0m"
+ source = fmt.Sprintf("\033[35m(%v)\033[0m", values[1])
+ )
+
+ messages = []interface{}{source, currentTime}
+
+ if level == "sql" {
+ // duration
+ messages = append(messages, fmt.Sprintf(" \033[36;1m[%.2fms]\033[0m ", float64(values[2].(time.Duration).Nanoseconds()/1e4)/100.0))
+ // sql
+
+ for _, value := range values[4].([]interface{}) {
+ indirectValue := reflect.Indirect(reflect.ValueOf(value))
+ if indirectValue.IsValid() {
+ value = indirectValue.Interface()
+ if t, ok := value.(time.Time); ok {
+ if t.IsZero() {
+ formattedValues = append(formattedValues, fmt.Sprintf("'%v'", "0000-00-00 00:00:00"))
+ } else {
+ formattedValues = append(formattedValues, fmt.Sprintf("'%v'", t.Format("2006-01-02 15:04:05")))
+ }
+ } else if b, ok := value.([]byte); ok {
+ if str := string(b); isPrintable(str) {
+ formattedValues = append(formattedValues, fmt.Sprintf("'%v'", str))
+ } else {
+ formattedValues = append(formattedValues, "''")
+ }
+ } else if r, ok := value.(driver.Valuer); ok {
+ if value, err := r.Value(); err == nil && value != nil {
+ formattedValues = append(formattedValues, fmt.Sprintf("'%v'", value))
+ } else {
+ formattedValues = append(formattedValues, "NULL")
+ }
+ } else {
+ switch value.(type) {
+ case int, int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64, float32, float64, bool:
+ formattedValues = append(formattedValues, fmt.Sprintf("%v", value))
+ default:
+ formattedValues = append(formattedValues, fmt.Sprintf("'%v'", value))
+ }
+ }
+ } else {
+ formattedValues = append(formattedValues, "NULL")
+ }
+ }
+
+ // differentiate between $n placeholders or else treat like ?
+ if numericPlaceHolderRegexp.MatchString(values[3].(string)) {
+ sql = values[3].(string)
+ for index, value := range formattedValues {
+ placeholder := fmt.Sprintf(`\$%d([^\d]|$)`, index+1)
+ sql = regexp.MustCompile(placeholder).ReplaceAllString(sql, value+"$1")
+ }
+ } else {
+ formattedValuesLength := len(formattedValues)
+ for index, value := range sqlRegexp.Split(values[3].(string), -1) {
+ sql += value
+ if index < formattedValuesLength {
+ sql += formattedValues[index]
+ }
+ }
+ }
+
+ messages = append(messages, sql)
+ messages = append(messages, fmt.Sprintf(" \n\033[36;31m[%v]\033[0m ", strconv.FormatInt(values[5].(int64), 10)+" rows affected or returned "))
+ } else {
+ messages = append(messages, "\033[31;1m")
+ messages = append(messages, values[2:]...)
+ messages = append(messages, "\033[0m")
+ }
+ }
+
+ return
+}
+
+type logger interface {
+ Print(v ...interface{})
+}
+
+// LogWriter log writer interface
+type LogWriter interface {
+ Println(v ...interface{})
+}
+
+// Logger default logger
+type Logger struct {
+ LogWriter
+}
+
+// Print format & print log
+func (logger Logger) Print(values ...interface{}) {
+ logger.Println(LogFormatter(values...)...)
+}
diff --git a/vendor/github.com/jinzhu/gorm/main.go b/vendor/github.com/jinzhu/gorm/main.go
new file mode 100644
index 0000000000000000000000000000000000000000..67e5f58e5777c72108222e7f9a9560bd3723e6fc
--- /dev/null
+++ b/vendor/github.com/jinzhu/gorm/main.go
@@ -0,0 +1,854 @@
+package gorm
+
+import (
+ "context"
+ "database/sql"
+ "errors"
+ "fmt"
+ "reflect"
+ "strings"
+ "sync"
+ "time"
+)
+
+// DB contains information for current db connection
+type DB struct {
+ sync.RWMutex
+ Value interface{}
+ Error error
+ RowsAffected int64
+
+ // single db
+ db SQLCommon
+ blockGlobalUpdate bool
+ logMode logModeValue
+ logger logger
+ search *search
+ values sync.Map
+
+ // global db
+ parent *DB
+ callbacks *Callback
+ dialect Dialect
+ singularTable bool
+
+ // function to be used to override the creating of a new timestamp
+ nowFuncOverride func() time.Time
+}
+
+type logModeValue int
+
+const (
+ defaultLogMode logModeValue = iota
+ noLogMode
+ detailedLogMode
+)
+
+// Open initialize a new db connection, need to import driver first, e.g:
+//
+// import _ "github.com/go-sql-driver/mysql"
+// func main() {
+// db, err := gorm.Open("mysql", "user:password@/dbname?charset=utf8&parseTime=True&loc=Local")
+// }
+// GORM has wrapped some drivers, for easier to remember driver's import path, so you could import the mysql driver with
+// import _ "github.com/jinzhu/gorm/dialects/mysql"
+// // import _ "github.com/jinzhu/gorm/dialects/postgres"
+// // import _ "github.com/jinzhu/gorm/dialects/sqlite"
+// // import _ "github.com/jinzhu/gorm/dialects/mssql"
+func Open(dialect string, args ...interface{}) (db *DB, err error) {
+ if len(args) == 0 {
+ err = errors.New("invalid database source")
+ return nil, err
+ }
+ var source string
+ var dbSQL SQLCommon
+ var ownDbSQL bool
+
+ switch value := args[0].(type) {
+ case string:
+ var driver = dialect
+ if len(args) == 1 {
+ source = value
+ } else if len(args) >= 2 {
+ driver = value
+ source = args[1].(string)
+ }
+ dbSQL, err = sql.Open(driver, source)
+ ownDbSQL = true
+ case SQLCommon:
+ dbSQL = value
+ ownDbSQL = false
+ default:
+ return nil, fmt.Errorf("invalid database source: %v is not a valid type", value)
+ }
+
+ db = &DB{
+ db: dbSQL,
+ logger: defaultLogger,
+ callbacks: DefaultCallback,
+ dialect: newDialect(dialect, dbSQL),
+ }
+ db.parent = db
+ if err != nil {
+ return
+ }
+ // Send a ping to make sure the database connection is alive.
+ if d, ok := dbSQL.(*sql.DB); ok {
+ if err = d.Ping(); err != nil && ownDbSQL {
+ d.Close()
+ }
+ }
+ return
+}
+
+// New clone a new db connection without search conditions
+func (s *DB) New() *DB {
+ clone := s.clone()
+ clone.search = nil
+ clone.Value = nil
+ return clone
+}
+
+type closer interface {
+ Close() error
+}
+
+// Close close current db connection. If database connection is not an io.Closer, returns an error.
+func (s *DB) Close() error {
+ if db, ok := s.parent.db.(closer); ok {
+ return db.Close()
+ }
+ return errors.New("can't close current db")
+}
+
+// DB get `*sql.DB` from current connection
+// If the underlying database connection is not a *sql.DB, returns nil
+func (s *DB) DB() *sql.DB {
+ db, _ := s.db.(*sql.DB)
+ return db
+}
+
+// CommonDB return the underlying `*sql.DB` or `*sql.Tx` instance, mainly intended to allow coexistence with legacy non-GORM code.
+func (s *DB) CommonDB() SQLCommon {
+ return s.db
+}
+
+// Dialect get dialect
+func (s *DB) Dialect() Dialect {
+ return s.dialect
+}
+
+// Callback return `Callbacks` container, you could add/change/delete callbacks with it
+// db.Callback().Create().Register("update_created_at", updateCreated)
+// Refer https://jinzhu.github.io/gorm/development.html#callbacks
+func (s *DB) Callback() *Callback {
+ s.parent.callbacks = s.parent.callbacks.clone(s.logger)
+ return s.parent.callbacks
+}
+
+// SetLogger replace default logger
+func (s *DB) SetLogger(log logger) {
+ s.logger = log
+}
+
+// LogMode set log mode, `true` for detailed logs, `false` for no log, default, will only print error logs
+func (s *DB) LogMode(enable bool) *DB {
+ if enable {
+ s.logMode = detailedLogMode
+ } else {
+ s.logMode = noLogMode
+ }
+ return s
+}
+
+// SetNowFuncOverride set the function to be used when creating a new timestamp
+func (s *DB) SetNowFuncOverride(nowFuncOverride func() time.Time) *DB {
+ s.nowFuncOverride = nowFuncOverride
+ return s
+}
+
+// Get a new timestamp, using the provided nowFuncOverride on the DB instance if set,
+// otherwise defaults to the global NowFunc()
+func (s *DB) nowFunc() time.Time {
+ if s.nowFuncOverride != nil {
+ return s.nowFuncOverride()
+ }
+
+ return NowFunc()
+}
+
+// BlockGlobalUpdate if true, generates an error on update/delete without where clause.
+// This is to prevent eventual error with empty objects updates/deletions
+func (s *DB) BlockGlobalUpdate(enable bool) *DB {
+ s.blockGlobalUpdate = enable
+ return s
+}
+
+// HasBlockGlobalUpdate return state of block
+func (s *DB) HasBlockGlobalUpdate() bool {
+ return s.blockGlobalUpdate
+}
+
+// SingularTable use singular table by default
+func (s *DB) SingularTable(enable bool) {
+ s.parent.Lock()
+ defer s.parent.Unlock()
+ s.parent.singularTable = enable
+}
+
+// NewScope create a scope for current operation
+func (s *DB) NewScope(value interface{}) *Scope {
+ dbClone := s.clone()
+ dbClone.Value = value
+ scope := &Scope{db: dbClone, Value: value}
+ if s.search != nil {
+ scope.Search = s.search.clone()
+ } else {
+ scope.Search = &search{}
+ }
+ return scope
+}
+
+// QueryExpr returns the query as expr object
+func (s *DB) QueryExpr() *expr {
+ scope := s.NewScope(s.Value)
+ scope.InstanceSet("skip_bindvar", true)
+ scope.prepareQuerySQL()
+
+ return Expr(scope.SQL, scope.SQLVars...)
+}
+
+// SubQuery returns the query as sub query
+func (s *DB) SubQuery() *expr {
+ scope := s.NewScope(s.Value)
+ scope.InstanceSet("skip_bindvar", true)
+ scope.prepareQuerySQL()
+
+ return Expr(fmt.Sprintf("(%v)", scope.SQL), scope.SQLVars...)
+}
+
+// Where return a new relation, filter records with given conditions, accepts `map`, `struct` or `string` as conditions, refer http://jinzhu.github.io/gorm/crud.html#query
+func (s *DB) Where(query interface{}, args ...interface{}) *DB {
+ return s.clone().search.Where(query, args...).db
+}
+
+// Or filter records that match before conditions or this one, similar to `Where`
+func (s *DB) Or(query interface{}, args ...interface{}) *DB {
+ return s.clone().search.Or(query, args...).db
+}
+
+// Not filter records that don't match current conditions, similar to `Where`
+func (s *DB) Not(query interface{}, args ...interface{}) *DB {
+ return s.clone().search.Not(query, args...).db
+}
+
+// Limit specify the number of records to be retrieved
+func (s *DB) Limit(limit interface{}) *DB {
+ return s.clone().search.Limit(limit).db
+}
+
+// Offset specify the number of records to skip before starting to return the records
+func (s *DB) Offset(offset interface{}) *DB {
+ return s.clone().search.Offset(offset).db
+}
+
+// Order specify order when retrieve records from database, set reorder to `true` to overwrite defined conditions
+// db.Order("name DESC")
+// db.Order("name DESC", true) // reorder
+// db.Order(gorm.Expr("name = ? DESC", "first")) // sql expression
+func (s *DB) Order(value interface{}, reorder ...bool) *DB {
+ return s.clone().search.Order(value, reorder...).db
+}
+
+// Select specify fields that you want to retrieve from database when querying, by default, will select all fields;
+// When creating/updating, specify fields that you want to save to database
+func (s *DB) Select(query interface{}, args ...interface{}) *DB {
+ return s.clone().search.Select(query, args...).db
+}
+
+// Omit specify fields that you want to ignore when saving to database for creating, updating
+func (s *DB) Omit(columns ...string) *DB {
+ return s.clone().search.Omit(columns...).db
+}
+
+// Group specify the group method on the find
+func (s *DB) Group(query string) *DB {
+ return s.clone().search.Group(query).db
+}
+
+// Having specify HAVING conditions for GROUP BY
+func (s *DB) Having(query interface{}, values ...interface{}) *DB {
+ return s.clone().search.Having(query, values...).db
+}
+
+// Joins specify Joins conditions
+// db.Joins("JOIN emails ON emails.user_id = users.id AND emails.email = ?", "jinzhu@example.org").Find(&user)
+func (s *DB) Joins(query string, args ...interface{}) *DB {
+ return s.clone().search.Joins(query, args...).db
+}
+
+// Scopes pass current database connection to arguments `func(*DB) *DB`, which could be used to add conditions dynamically
+// func AmountGreaterThan1000(db *gorm.DB) *gorm.DB {
+// return db.Where("amount > ?", 1000)
+// }
+//
+// func OrderStatus(status []string) func (db *gorm.DB) *gorm.DB {
+// return func (db *gorm.DB) *gorm.DB {
+// return db.Scopes(AmountGreaterThan1000).Where("status in (?)", status)
+// }
+// }
+//
+// db.Scopes(AmountGreaterThan1000, OrderStatus([]string{"paid", "shipped"})).Find(&orders)
+// Refer https://jinzhu.github.io/gorm/crud.html#scopes
+func (s *DB) Scopes(funcs ...func(*DB) *DB) *DB {
+ for _, f := range funcs {
+ s = f(s)
+ }
+ return s
+}
+
+// Unscoped return all record including deleted record, refer Soft Delete https://jinzhu.github.io/gorm/crud.html#soft-delete
+func (s *DB) Unscoped() *DB {
+ return s.clone().search.unscoped().db
+}
+
+// Attrs initialize struct with argument if record not found with `FirstOrInit` https://jinzhu.github.io/gorm/crud.html#firstorinit or `FirstOrCreate` https://jinzhu.github.io/gorm/crud.html#firstorcreate
+func (s *DB) Attrs(attrs ...interface{}) *DB {
+ return s.clone().search.Attrs(attrs...).db
+}
+
+// Assign assign result with argument regardless it is found or not with `FirstOrInit` https://jinzhu.github.io/gorm/crud.html#firstorinit or `FirstOrCreate` https://jinzhu.github.io/gorm/crud.html#firstorcreate
+func (s *DB) Assign(attrs ...interface{}) *DB {
+ return s.clone().search.Assign(attrs...).db
+}
+
+// First find first record that match given conditions, order by primary key
+func (s *DB) First(out interface{}, where ...interface{}) *DB {
+ newScope := s.NewScope(out)
+ newScope.Search.Limit(1)
+
+ return newScope.Set("gorm:order_by_primary_key", "ASC").
+ inlineCondition(where...).callCallbacks(s.parent.callbacks.queries).db
+}
+
+// Take return a record that match given conditions, the order will depend on the database implementation
+func (s *DB) Take(out interface{}, where ...interface{}) *DB {
+ newScope := s.NewScope(out)
+ newScope.Search.Limit(1)
+ return newScope.inlineCondition(where...).callCallbacks(s.parent.callbacks.queries).db
+}
+
+// Last find last record that match given conditions, order by primary key
+func (s *DB) Last(out interface{}, where ...interface{}) *DB {
+ newScope := s.NewScope(out)
+ newScope.Search.Limit(1)
+ return newScope.Set("gorm:order_by_primary_key", "DESC").
+ inlineCondition(where...).callCallbacks(s.parent.callbacks.queries).db
+}
+
+// Find find records that match given conditions
+func (s *DB) Find(out interface{}, where ...interface{}) *DB {
+ return s.NewScope(out).inlineCondition(where...).callCallbacks(s.parent.callbacks.queries).db
+}
+
+//Preloads preloads relations, don`t touch out
+func (s *DB) Preloads(out interface{}) *DB {
+ return s.NewScope(out).InstanceSet("gorm:only_preload", 1).callCallbacks(s.parent.callbacks.queries).db
+}
+
+// Scan scan value to a struct
+func (s *DB) Scan(dest interface{}) *DB {
+ return s.NewScope(s.Value).Set("gorm:query_destination", dest).callCallbacks(s.parent.callbacks.queries).db
+}
+
+// Row return `*sql.Row` with given conditions
+func (s *DB) Row() *sql.Row {
+ return s.NewScope(s.Value).row()
+}
+
+// Rows return `*sql.Rows` with given conditions
+func (s *DB) Rows() (*sql.Rows, error) {
+ return s.NewScope(s.Value).rows()
+}
+
+// ScanRows scan `*sql.Rows` to give struct
+func (s *DB) ScanRows(rows *sql.Rows, result interface{}) error {
+ var (
+ scope = s.NewScope(result)
+ clone = scope.db
+ columns, err = rows.Columns()
+ )
+
+ if clone.AddError(err) == nil {
+ scope.scan(rows, columns, scope.Fields())
+ }
+
+ return clone.Error
+}
+
+// Pluck used to query single column from a model as a map
+// var ages []int64
+// db.Find(&users).Pluck("age", &ages)
+func (s *DB) Pluck(column string, value interface{}) *DB {
+ return s.NewScope(s.Value).pluck(column, value).db
+}
+
+// Count get how many records for a model
+func (s *DB) Count(value interface{}) *DB {
+ return s.NewScope(s.Value).count(value).db
+}
+
+// Related get related associations
+func (s *DB) Related(value interface{}, foreignKeys ...string) *DB {
+ return s.NewScope(s.Value).related(value, foreignKeys...).db
+}
+
+// FirstOrInit find first matched record or initialize a new one with given conditions (only works with struct, map conditions)
+// https://jinzhu.github.io/gorm/crud.html#firstorinit
+func (s *DB) FirstOrInit(out interface{}, where ...interface{}) *DB {
+ c := s.clone()
+ if result := c.First(out, where...); result.Error != nil {
+ if !result.RecordNotFound() {
+ return result
+ }
+ c.NewScope(out).inlineCondition(where...).initialize()
+ } else {
+ c.NewScope(out).updatedAttrsWithValues(c.search.assignAttrs)
+ }
+ return c
+}
+
+// FirstOrCreate find first matched record or create a new one with given conditions (only works with struct, map conditions)
+// https://jinzhu.github.io/gorm/crud.html#firstorcreate
+func (s *DB) FirstOrCreate(out interface{}, where ...interface{}) *DB {
+ c := s.clone()
+ if result := s.First(out, where...); result.Error != nil {
+ if !result.RecordNotFound() {
+ return result
+ }
+ return c.NewScope(out).inlineCondition(where...).initialize().callCallbacks(c.parent.callbacks.creates).db
+ } else if len(c.search.assignAttrs) > 0 {
+ return c.NewScope(out).InstanceSet("gorm:update_interface", c.search.assignAttrs).callCallbacks(c.parent.callbacks.updates).db
+ }
+ return c
+}
+
+// Update update attributes with callbacks, refer: https://jinzhu.github.io/gorm/crud.html#update
+func (s *DB) Update(attrs ...interface{}) *DB {
+ return s.Updates(toSearchableMap(attrs...), true)
+}
+
+// Updates update attributes with callbacks, refer: https://jinzhu.github.io/gorm/crud.html#update
+func (s *DB) Updates(values interface{}, ignoreProtectedAttrs ...bool) *DB {
+ return s.NewScope(s.Value).
+ Set("gorm:ignore_protected_attrs", len(ignoreProtectedAttrs) > 0).
+ InstanceSet("gorm:update_interface", values).
+ callCallbacks(s.parent.callbacks.updates).db
+}
+
+// UpdateColumn update attributes without callbacks, refer: https://jinzhu.github.io/gorm/crud.html#update
+func (s *DB) UpdateColumn(attrs ...interface{}) *DB {
+ return s.UpdateColumns(toSearchableMap(attrs...))
+}
+
+// UpdateColumns update attributes without callbacks, refer: https://jinzhu.github.io/gorm/crud.html#update
+func (s *DB) UpdateColumns(values interface{}) *DB {
+ return s.NewScope(s.Value).
+ Set("gorm:update_column", true).
+ Set("gorm:save_associations", false).
+ InstanceSet("gorm:update_interface", values).
+ callCallbacks(s.parent.callbacks.updates).db
+}
+
+// Save update value in database, if the value doesn't have primary key, will insert it
+func (s *DB) Save(value interface{}) *DB {
+ scope := s.NewScope(value)
+ if !scope.PrimaryKeyZero() {
+ newDB := scope.callCallbacks(s.parent.callbacks.updates).db
+ if newDB.Error == nil && newDB.RowsAffected == 0 {
+ return s.New().Table(scope.TableName()).FirstOrCreate(value)
+ }
+ return newDB
+ }
+ return scope.callCallbacks(s.parent.callbacks.creates).db
+}
+
+// Create insert the value into database
+func (s *DB) Create(value interface{}) *DB {
+ scope := s.NewScope(value)
+ return scope.callCallbacks(s.parent.callbacks.creates).db
+}
+
+// Delete delete value match given conditions, if the value has primary key, then will including the primary key as condition
+func (s *DB) Delete(value interface{}, where ...interface{}) *DB {
+ return s.NewScope(value).inlineCondition(where...).callCallbacks(s.parent.callbacks.deletes).db
+}
+
+// Raw use raw sql as conditions, won't run it unless invoked by other methods
+// db.Raw("SELECT name, age FROM users WHERE name = ?", 3).Scan(&result)
+func (s *DB) Raw(sql string, values ...interface{}) *DB {
+ return s.clone().search.Raw(true).Where(sql, values...).db
+}
+
+// Exec execute raw sql
+func (s *DB) Exec(sql string, values ...interface{}) *DB {
+ scope := s.NewScope(nil)
+ generatedSQL := scope.buildCondition(map[string]interface{}{"query": sql, "args": values}, true)
+ generatedSQL = strings.TrimSuffix(strings.TrimPrefix(generatedSQL, "("), ")")
+ scope.Raw(generatedSQL)
+ return scope.Exec().db
+}
+
+// Model specify the model you would like to run db operations
+// // update all users's name to `hello`
+// db.Model(&User{}).Update("name", "hello")
+// // if user's primary key is non-blank, will use it as condition, then will only update the user's name to `hello`
+// db.Model(&user).Update("name", "hello")
+func (s *DB) Model(value interface{}) *DB {
+ c := s.clone()
+ c.Value = value
+ return c
+}
+
+// Table specify the table you would like to run db operations
+func (s *DB) Table(name string) *DB {
+ clone := s.clone()
+ clone.search.Table(name)
+ clone.Value = nil
+ return clone
+}
+
+// Debug start debug mode
+func (s *DB) Debug() *DB {
+ return s.clone().LogMode(true)
+}
+
+// Begin begins a transaction
+func (s *DB) Begin() *DB {
+ return s.BeginTx(context.Background(), &sql.TxOptions{})
+}
+
+// BeginTx begins a transaction with options
+func (s *DB) BeginTx(ctx context.Context, opts *sql.TxOptions) *DB {
+ c := s.clone()
+ if db, ok := c.db.(sqlDb); ok && db != nil {
+ tx, err := db.BeginTx(ctx, opts)
+ c.db = interface{}(tx).(SQLCommon)
+
+ c.dialect.SetDB(c.db)
+ c.AddError(err)
+ } else {
+ c.AddError(ErrCantStartTransaction)
+ }
+ return c
+}
+
+// Commit commit a transaction
+func (s *DB) Commit() *DB {
+ var emptySQLTx *sql.Tx
+ if db, ok := s.db.(sqlTx); ok && db != nil && db != emptySQLTx {
+ s.AddError(db.Commit())
+ } else {
+ s.AddError(ErrInvalidTransaction)
+ }
+ return s
+}
+
+// Rollback rollback a transaction
+func (s *DB) Rollback() *DB {
+ var emptySQLTx *sql.Tx
+ if db, ok := s.db.(sqlTx); ok && db != nil && db != emptySQLTx {
+ if err := db.Rollback(); err != nil && err != sql.ErrTxDone {
+ s.AddError(err)
+ }
+ } else {
+ s.AddError(ErrInvalidTransaction)
+ }
+ return s
+}
+
+// RollbackUnlessCommitted rollback a transaction if it has not yet been
+// committed.
+func (s *DB) RollbackUnlessCommitted() *DB {
+ var emptySQLTx *sql.Tx
+ if db, ok := s.db.(sqlTx); ok && db != nil && db != emptySQLTx {
+ err := db.Rollback()
+ // Ignore the error indicating that the transaction has already
+ // been committed.
+ if err != sql.ErrTxDone {
+ s.AddError(err)
+ }
+ } else {
+ s.AddError(ErrInvalidTransaction)
+ }
+ return s
+}
+
+// NewRecord check if value's primary key is blank
+func (s *DB) NewRecord(value interface{}) bool {
+ return s.NewScope(value).PrimaryKeyZero()
+}
+
+// RecordNotFound check if returning ErrRecordNotFound error
+func (s *DB) RecordNotFound() bool {
+ for _, err := range s.GetErrors() {
+ if err == ErrRecordNotFound {
+ return true
+ }
+ }
+ return false
+}
+
+// CreateTable create table for models
+func (s *DB) CreateTable(models ...interface{}) *DB {
+ db := s.Unscoped()
+ for _, model := range models {
+ db = db.NewScope(model).createTable().db
+ }
+ return db
+}
+
+// DropTable drop table for models
+func (s *DB) DropTable(values ...interface{}) *DB {
+ db := s.clone()
+ for _, value := range values {
+ if tableName, ok := value.(string); ok {
+ db = db.Table(tableName)
+ }
+
+ db = db.NewScope(value).dropTable().db
+ }
+ return db
+}
+
+// DropTableIfExists drop table if it is exist
+func (s *DB) DropTableIfExists(values ...interface{}) *DB {
+ db := s.clone()
+ for _, value := range values {
+ if s.HasTable(value) {
+ db.AddError(s.DropTable(value).Error)
+ }
+ }
+ return db
+}
+
+// HasTable check has table or not
+func (s *DB) HasTable(value interface{}) bool {
+ var (
+ scope = s.NewScope(value)
+ tableName string
+ )
+
+ if name, ok := value.(string); ok {
+ tableName = name
+ } else {
+ tableName = scope.TableName()
+ }
+
+ has := scope.Dialect().HasTable(tableName)
+ s.AddError(scope.db.Error)
+ return has
+}
+
+// AutoMigrate run auto migration for given models, will only add missing fields, won't delete/change current data
+func (s *DB) AutoMigrate(values ...interface{}) *DB {
+ db := s.Unscoped()
+ for _, value := range values {
+ db = db.NewScope(value).autoMigrate().db
+ }
+ return db
+}
+
+// ModifyColumn modify column to type
+func (s *DB) ModifyColumn(column string, typ string) *DB {
+ scope := s.NewScope(s.Value)
+ scope.modifyColumn(column, typ)
+ return scope.db
+}
+
+// DropColumn drop a column
+func (s *DB) DropColumn(column string) *DB {
+ scope := s.NewScope(s.Value)
+ scope.dropColumn(column)
+ return scope.db
+}
+
+// AddIndex add index for columns with given name
+func (s *DB) AddIndex(indexName string, columns ...string) *DB {
+ scope := s.Unscoped().NewScope(s.Value)
+ scope.addIndex(false, indexName, columns...)
+ return scope.db
+}
+
+// AddUniqueIndex add unique index for columns with given name
+func (s *DB) AddUniqueIndex(indexName string, columns ...string) *DB {
+ scope := s.Unscoped().NewScope(s.Value)
+ scope.addIndex(true, indexName, columns...)
+ return scope.db
+}
+
+// RemoveIndex remove index with name
+func (s *DB) RemoveIndex(indexName string) *DB {
+ scope := s.NewScope(s.Value)
+ scope.removeIndex(indexName)
+ return scope.db
+}
+
+// AddForeignKey Add foreign key to the given scope, e.g:
+// db.Model(&User{}).AddForeignKey("city_id", "cities(id)", "RESTRICT", "RESTRICT")
+func (s *DB) AddForeignKey(field string, dest string, onDelete string, onUpdate string) *DB {
+ scope := s.NewScope(s.Value)
+ scope.addForeignKey(field, dest, onDelete, onUpdate)
+ return scope.db
+}
+
+// RemoveForeignKey Remove foreign key from the given scope, e.g:
+// db.Model(&User{}).RemoveForeignKey("city_id", "cities(id)")
+func (s *DB) RemoveForeignKey(field string, dest string) *DB {
+ scope := s.clone().NewScope(s.Value)
+ scope.removeForeignKey(field, dest)
+ return scope.db
+}
+
+// Association start `Association Mode` to handler relations things easir in that mode, refer: https://jinzhu.github.io/gorm/associations.html#association-mode
+func (s *DB) Association(column string) *Association {
+ var err error
+ var scope = s.Set("gorm:association:source", s.Value).NewScope(s.Value)
+
+ if primaryField := scope.PrimaryField(); primaryField.IsBlank {
+ err = errors.New("primary key can't be nil")
+ } else {
+ if field, ok := scope.FieldByName(column); ok {
+ if field.Relationship == nil || len(field.Relationship.ForeignFieldNames) == 0 {
+ err = fmt.Errorf("invalid association %v for %v", column, scope.IndirectValue().Type())
+ } else {
+ return &Association{scope: scope, column: column, field: field}
+ }
+ } else {
+ err = fmt.Errorf("%v doesn't have column %v", scope.IndirectValue().Type(), column)
+ }
+ }
+
+ return &Association{Error: err}
+}
+
+// Preload preload associations with given conditions
+// db.Preload("Orders", "state NOT IN (?)", "cancelled").Find(&users)
+func (s *DB) Preload(column string, conditions ...interface{}) *DB {
+ return s.clone().search.Preload(column, conditions...).db
+}
+
+// Set set setting by name, which could be used in callbacks, will clone a new db, and update its setting
+func (s *DB) Set(name string, value interface{}) *DB {
+ return s.clone().InstantSet(name, value)
+}
+
+// InstantSet instant set setting, will affect current db
+func (s *DB) InstantSet(name string, value interface{}) *DB {
+ s.values.Store(name, value)
+ return s
+}
+
+// Get get setting by name
+func (s *DB) Get(name string) (value interface{}, ok bool) {
+ value, ok = s.values.Load(name)
+ return
+}
+
+// SetJoinTableHandler set a model's join table handler for a relation
+func (s *DB) SetJoinTableHandler(source interface{}, column string, handler JoinTableHandlerInterface) {
+ scope := s.NewScope(source)
+ for _, field := range scope.GetModelStruct().StructFields {
+ if field.Name == column || field.DBName == column {
+ if many2many, _ := field.TagSettingsGet("MANY2MANY"); many2many != "" {
+ source := (&Scope{Value: source}).GetModelStruct().ModelType
+ destination := (&Scope{Value: reflect.New(field.Struct.Type).Interface()}).GetModelStruct().ModelType
+ handler.Setup(field.Relationship, many2many, source, destination)
+ field.Relationship.JoinTableHandler = handler
+ if table := handler.Table(s); scope.Dialect().HasTable(table) {
+ s.Table(table).AutoMigrate(handler)
+ }
+ }
+ }
+ }
+}
+
+// AddError add error to the db
+func (s *DB) AddError(err error) error {
+ if err != nil {
+ if err != ErrRecordNotFound {
+ if s.logMode == defaultLogMode {
+ go s.print("error", fileWithLineNum(), err)
+ } else {
+ s.log(err)
+ }
+
+ errors := Errors(s.GetErrors())
+ errors = errors.Add(err)
+ if len(errors) > 1 {
+ err = errors
+ }
+ }
+
+ s.Error = err
+ }
+ return err
+}
+
+// GetErrors get happened errors from the db
+func (s *DB) GetErrors() []error {
+ if errs, ok := s.Error.(Errors); ok {
+ return errs
+ } else if s.Error != nil {
+ return []error{s.Error}
+ }
+ return []error{}
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// Private Methods For DB
+////////////////////////////////////////////////////////////////////////////////
+
+func (s *DB) clone() *DB {
+ db := &DB{
+ db: s.db,
+ parent: s.parent,
+ logger: s.logger,
+ logMode: s.logMode,
+ Value: s.Value,
+ Error: s.Error,
+ blockGlobalUpdate: s.blockGlobalUpdate,
+ dialect: newDialect(s.dialect.GetName(), s.db),
+ nowFuncOverride: s.nowFuncOverride,
+ }
+
+ s.values.Range(func(k, v interface{}) bool {
+ db.values.Store(k, v)
+ return true
+ })
+
+ if s.search == nil {
+ db.search = &search{limit: -1, offset: -1}
+ } else {
+ db.search = s.search.clone()
+ }
+
+ db.search.db = db
+ return db
+}
+
+func (s *DB) print(v ...interface{}) {
+ s.logger.Print(v...)
+}
+
+func (s *DB) log(v ...interface{}) {
+ if s != nil && s.logMode == detailedLogMode {
+ s.print(append([]interface{}{"log", fileWithLineNum()}, v...)...)
+ }
+}
+
+func (s *DB) slog(sql string, t time.Time, vars ...interface{}) {
+ if s.logMode == detailedLogMode {
+ s.print("sql", fileWithLineNum(), NowFunc().Sub(t), sql, vars, s.RowsAffected)
+ }
+}
diff --git a/vendor/github.com/jinzhu/gorm/model.go b/vendor/github.com/jinzhu/gorm/model.go
new file mode 100644
index 0000000000000000000000000000000000000000..f37ff7eaaa3988dc4e2e6468f461f4f16857ff53
--- /dev/null
+++ b/vendor/github.com/jinzhu/gorm/model.go
@@ -0,0 +1,14 @@
+package gorm
+
+import "time"
+
+// Model base model definition, including fields `ID`, `CreatedAt`, `UpdatedAt`, `DeletedAt`, which could be embedded in your models
+// type User struct {
+// gorm.Model
+// }
+type Model struct {
+ ID uint `gorm:"primary_key"`
+ CreatedAt time.Time
+ UpdatedAt time.Time
+ DeletedAt *time.Time `sql:"index"`
+}
diff --git a/vendor/github.com/jinzhu/gorm/model_struct.go b/vendor/github.com/jinzhu/gorm/model_struct.go
new file mode 100644
index 0000000000000000000000000000000000000000..5234b287087c185a60a16dd2777cf88a45337cf6
--- /dev/null
+++ b/vendor/github.com/jinzhu/gorm/model_struct.go
@@ -0,0 +1,656 @@
+package gorm
+
+import (
+ "database/sql"
+ "errors"
+ "go/ast"
+ "reflect"
+ "strings"
+ "sync"
+ "time"
+
+ "github.com/jinzhu/inflection"
+)
+
+// DefaultTableNameHandler default table name handler
+var DefaultTableNameHandler = func(db *DB, defaultTableName string) string {
+ return defaultTableName
+}
+
+var modelStructsMap sync.Map
+
+// ModelStruct model definition
+type ModelStruct struct {
+ PrimaryFields []*StructField
+ StructFields []*StructField
+ ModelType reflect.Type
+
+ defaultTableName string
+ l sync.Mutex
+}
+
+// TableName returns model's table name
+func (s *ModelStruct) TableName(db *DB) string {
+ s.l.Lock()
+ defer s.l.Unlock()
+
+ if s.defaultTableName == "" && db != nil && s.ModelType != nil {
+ // Set default table name
+ if tabler, ok := reflect.New(s.ModelType).Interface().(tabler); ok {
+ s.defaultTableName = tabler.TableName()
+ } else {
+ tableName := ToTableName(s.ModelType.Name())
+ db.parent.RLock()
+ if db == nil || (db.parent != nil && !db.parent.singularTable) {
+ tableName = inflection.Plural(tableName)
+ }
+ db.parent.RUnlock()
+ s.defaultTableName = tableName
+ }
+ }
+
+ return DefaultTableNameHandler(db, s.defaultTableName)
+}
+
+// StructField model field's struct definition
+type StructField struct {
+ DBName string
+ Name string
+ Names []string
+ IsPrimaryKey bool
+ IsNormal bool
+ IsIgnored bool
+ IsScanner bool
+ HasDefaultValue bool
+ Tag reflect.StructTag
+ TagSettings map[string]string
+ Struct reflect.StructField
+ IsForeignKey bool
+ Relationship *Relationship
+
+ tagSettingsLock sync.RWMutex
+}
+
+// TagSettingsSet Sets a tag in the tag settings map
+func (sf *StructField) TagSettingsSet(key, val string) {
+ sf.tagSettingsLock.Lock()
+ defer sf.tagSettingsLock.Unlock()
+ sf.TagSettings[key] = val
+}
+
+// TagSettingsGet returns a tag from the tag settings
+func (sf *StructField) TagSettingsGet(key string) (string, bool) {
+ sf.tagSettingsLock.RLock()
+ defer sf.tagSettingsLock.RUnlock()
+ val, ok := sf.TagSettings[key]
+ return val, ok
+}
+
+// TagSettingsDelete deletes a tag
+func (sf *StructField) TagSettingsDelete(key string) {
+ sf.tagSettingsLock.Lock()
+ defer sf.tagSettingsLock.Unlock()
+ delete(sf.TagSettings, key)
+}
+
+func (sf *StructField) clone() *StructField {
+ clone := &StructField{
+ DBName: sf.DBName,
+ Name: sf.Name,
+ Names: sf.Names,
+ IsPrimaryKey: sf.IsPrimaryKey,
+ IsNormal: sf.IsNormal,
+ IsIgnored: sf.IsIgnored,
+ IsScanner: sf.IsScanner,
+ HasDefaultValue: sf.HasDefaultValue,
+ Tag: sf.Tag,
+ TagSettings: map[string]string{},
+ Struct: sf.Struct,
+ IsForeignKey: sf.IsForeignKey,
+ }
+
+ if sf.Relationship != nil {
+ relationship := *sf.Relationship
+ clone.Relationship = &relationship
+ }
+
+ // copy the struct field tagSettings, they should be read-locked while they are copied
+ sf.tagSettingsLock.Lock()
+ defer sf.tagSettingsLock.Unlock()
+ for key, value := range sf.TagSettings {
+ clone.TagSettings[key] = value
+ }
+
+ return clone
+}
+
+// Relationship described the relationship between models
+type Relationship struct {
+ Kind string
+ PolymorphicType string
+ PolymorphicDBName string
+ PolymorphicValue string
+ ForeignFieldNames []string
+ ForeignDBNames []string
+ AssociationForeignFieldNames []string
+ AssociationForeignDBNames []string
+ JoinTableHandler JoinTableHandlerInterface
+}
+
+func getForeignField(column string, fields []*StructField) *StructField {
+ for _, field := range fields {
+ if field.Name == column || field.DBName == column || field.DBName == ToColumnName(column) {
+ return field
+ }
+ }
+ return nil
+}
+
+// GetModelStruct get value's model struct, relationships based on struct and tag definition
+func (scope *Scope) GetModelStruct() *ModelStruct {
+ var modelStruct ModelStruct
+ // Scope value can't be nil
+ if scope.Value == nil {
+ return &modelStruct
+ }
+
+ reflectType := reflect.ValueOf(scope.Value).Type()
+ for reflectType.Kind() == reflect.Slice || reflectType.Kind() == reflect.Ptr {
+ reflectType = reflectType.Elem()
+ }
+
+ // Scope value need to be a struct
+ if reflectType.Kind() != reflect.Struct {
+ return &modelStruct
+ }
+
+ // Get Cached model struct
+ isSingularTable := false
+ if scope.db != nil && scope.db.parent != nil {
+ scope.db.parent.RLock()
+ isSingularTable = scope.db.parent.singularTable
+ scope.db.parent.RUnlock()
+ }
+
+ hashKey := struct {
+ singularTable bool
+ reflectType reflect.Type
+ }{isSingularTable, reflectType}
+ if value, ok := modelStructsMap.Load(hashKey); ok && value != nil {
+ return value.(*ModelStruct)
+ }
+
+ modelStruct.ModelType = reflectType
+
+ // Get all fields
+ for i := 0; i < reflectType.NumField(); i++ {
+ if fieldStruct := reflectType.Field(i); ast.IsExported(fieldStruct.Name) {
+ field := &StructField{
+ Struct: fieldStruct,
+ Name: fieldStruct.Name,
+ Names: []string{fieldStruct.Name},
+ Tag: fieldStruct.Tag,
+ TagSettings: parseTagSetting(fieldStruct.Tag),
+ }
+
+ // is ignored field
+ if _, ok := field.TagSettingsGet("-"); ok {
+ field.IsIgnored = true
+ } else {
+ if _, ok := field.TagSettingsGet("PRIMARY_KEY"); ok {
+ field.IsPrimaryKey = true
+ modelStruct.PrimaryFields = append(modelStruct.PrimaryFields, field)
+ }
+
+ if _, ok := field.TagSettingsGet("DEFAULT"); ok && !field.IsPrimaryKey {
+ field.HasDefaultValue = true
+ }
+
+ if _, ok := field.TagSettingsGet("AUTO_INCREMENT"); ok && !field.IsPrimaryKey {
+ field.HasDefaultValue = true
+ }
+
+ indirectType := fieldStruct.Type
+ for indirectType.Kind() == reflect.Ptr {
+ indirectType = indirectType.Elem()
+ }
+
+ fieldValue := reflect.New(indirectType).Interface()
+ if _, isScanner := fieldValue.(sql.Scanner); isScanner {
+ // is scanner
+ field.IsScanner, field.IsNormal = true, true
+ if indirectType.Kind() == reflect.Struct {
+ for i := 0; i < indirectType.NumField(); i++ {
+ for key, value := range parseTagSetting(indirectType.Field(i).Tag) {
+ if _, ok := field.TagSettingsGet(key); !ok {
+ field.TagSettingsSet(key, value)
+ }
+ }
+ }
+ }
+ } else if _, isTime := fieldValue.(*time.Time); isTime {
+ // is time
+ field.IsNormal = true
+ } else if _, ok := field.TagSettingsGet("EMBEDDED"); ok || fieldStruct.Anonymous {
+ // is embedded struct
+ for _, subField := range scope.New(fieldValue).GetModelStruct().StructFields {
+ subField = subField.clone()
+ subField.Names = append([]string{fieldStruct.Name}, subField.Names...)
+ if prefix, ok := field.TagSettingsGet("EMBEDDED_PREFIX"); ok {
+ subField.DBName = prefix + subField.DBName
+ }
+
+ if subField.IsPrimaryKey {
+ if _, ok := subField.TagSettingsGet("PRIMARY_KEY"); ok {
+ modelStruct.PrimaryFields = append(modelStruct.PrimaryFields, subField)
+ } else {
+ subField.IsPrimaryKey = false
+ }
+ }
+
+ if subField.Relationship != nil && subField.Relationship.JoinTableHandler != nil {
+ if joinTableHandler, ok := subField.Relationship.JoinTableHandler.(*JoinTableHandler); ok {
+ newJoinTableHandler := &JoinTableHandler{}
+ newJoinTableHandler.Setup(subField.Relationship, joinTableHandler.TableName, reflectType, joinTableHandler.Destination.ModelType)
+ subField.Relationship.JoinTableHandler = newJoinTableHandler
+ }
+ }
+
+ modelStruct.StructFields = append(modelStruct.StructFields, subField)
+ }
+ continue
+ } else {
+ // build relationships
+ switch indirectType.Kind() {
+ case reflect.Slice:
+ defer func(field *StructField) {
+ var (
+ relationship = &Relationship{}
+ toScope = scope.New(reflect.New(field.Struct.Type).Interface())
+ foreignKeys []string
+ associationForeignKeys []string
+ elemType = field.Struct.Type
+ )
+
+ if foreignKey, _ := field.TagSettingsGet("FOREIGNKEY"); foreignKey != "" {
+ foreignKeys = strings.Split(foreignKey, ",")
+ }
+
+ if foreignKey, _ := field.TagSettingsGet("ASSOCIATION_FOREIGNKEY"); foreignKey != "" {
+ associationForeignKeys = strings.Split(foreignKey, ",")
+ } else if foreignKey, _ := field.TagSettingsGet("ASSOCIATIONFOREIGNKEY"); foreignKey != "" {
+ associationForeignKeys = strings.Split(foreignKey, ",")
+ }
+
+ for elemType.Kind() == reflect.Slice || elemType.Kind() == reflect.Ptr {
+ elemType = elemType.Elem()
+ }
+
+ if elemType.Kind() == reflect.Struct {
+ if many2many, _ := field.TagSettingsGet("MANY2MANY"); many2many != "" {
+ relationship.Kind = "many_to_many"
+
+ { // Foreign Keys for Source
+ joinTableDBNames := []string{}
+
+ if foreignKey, _ := field.TagSettingsGet("JOINTABLE_FOREIGNKEY"); foreignKey != "" {
+ joinTableDBNames = strings.Split(foreignKey, ",")
+ }
+
+ // if no foreign keys defined with tag
+ if len(foreignKeys) == 0 {
+ for _, field := range modelStruct.PrimaryFields {
+ foreignKeys = append(foreignKeys, field.DBName)
+ }
+ }
+
+ for idx, foreignKey := range foreignKeys {
+ if foreignField := getForeignField(foreignKey, modelStruct.StructFields); foreignField != nil {
+ // source foreign keys (db names)
+ relationship.ForeignFieldNames = append(relationship.ForeignFieldNames, foreignField.DBName)
+
+ // setup join table foreign keys for source
+ if len(joinTableDBNames) > idx {
+ // if defined join table's foreign key
+ relationship.ForeignDBNames = append(relationship.ForeignDBNames, joinTableDBNames[idx])
+ } else {
+ defaultJointableForeignKey := ToColumnName(reflectType.Name()) + "_" + foreignField.DBName
+ relationship.ForeignDBNames = append(relationship.ForeignDBNames, defaultJointableForeignKey)
+ }
+ }
+ }
+ }
+
+ { // Foreign Keys for Association (Destination)
+ associationJoinTableDBNames := []string{}
+
+ if foreignKey, _ := field.TagSettingsGet("ASSOCIATION_JOINTABLE_FOREIGNKEY"); foreignKey != "" {
+ associationJoinTableDBNames = strings.Split(foreignKey, ",")
+ }
+
+ // if no association foreign keys defined with tag
+ if len(associationForeignKeys) == 0 {
+ for _, field := range toScope.PrimaryFields() {
+ associationForeignKeys = append(associationForeignKeys, field.DBName)
+ }
+ }
+
+ for idx, name := range associationForeignKeys {
+ if field, ok := toScope.FieldByName(name); ok {
+ // association foreign keys (db names)
+ relationship.AssociationForeignFieldNames = append(relationship.AssociationForeignFieldNames, field.DBName)
+
+ // setup join table foreign keys for association
+ if len(associationJoinTableDBNames) > idx {
+ relationship.AssociationForeignDBNames = append(relationship.AssociationForeignDBNames, associationJoinTableDBNames[idx])
+ } else {
+ // join table foreign keys for association
+ joinTableDBName := ToColumnName(elemType.Name()) + "_" + field.DBName
+ relationship.AssociationForeignDBNames = append(relationship.AssociationForeignDBNames, joinTableDBName)
+ }
+ }
+ }
+ }
+
+ joinTableHandler := JoinTableHandler{}
+ joinTableHandler.Setup(relationship, many2many, reflectType, elemType)
+ relationship.JoinTableHandler = &joinTableHandler
+ field.Relationship = relationship
+ } else {
+ // User has many comments, associationType is User, comment use UserID as foreign key
+ var associationType = reflectType.Name()
+ var toFields = toScope.GetStructFields()
+ relationship.Kind = "has_many"
+
+ if polymorphic, _ := field.TagSettingsGet("POLYMORPHIC"); polymorphic != "" {
+ // Dog has many toys, tag polymorphic is Owner, then associationType is Owner
+ // Toy use OwnerID, OwnerType ('dogs') as foreign key
+ if polymorphicType := getForeignField(polymorphic+"Type", toFields); polymorphicType != nil {
+ associationType = polymorphic
+ relationship.PolymorphicType = polymorphicType.Name
+ relationship.PolymorphicDBName = polymorphicType.DBName
+ // if Dog has multiple set of toys set name of the set (instead of default 'dogs')
+ if value, ok := field.TagSettingsGet("POLYMORPHIC_VALUE"); ok {
+ relationship.PolymorphicValue = value
+ } else {
+ relationship.PolymorphicValue = scope.TableName()
+ }
+ polymorphicType.IsForeignKey = true
+ }
+ }
+
+ // if no foreign keys defined with tag
+ if len(foreignKeys) == 0 {
+ // if no association foreign keys defined with tag
+ if len(associationForeignKeys) == 0 {
+ for _, field := range modelStruct.PrimaryFields {
+ foreignKeys = append(foreignKeys, associationType+field.Name)
+ associationForeignKeys = append(associationForeignKeys, field.Name)
+ }
+ } else {
+ // generate foreign keys from defined association foreign keys
+ for _, scopeFieldName := range associationForeignKeys {
+ if foreignField := getForeignField(scopeFieldName, modelStruct.StructFields); foreignField != nil {
+ foreignKeys = append(foreignKeys, associationType+foreignField.Name)
+ associationForeignKeys = append(associationForeignKeys, foreignField.Name)
+ }
+ }
+ }
+ } else {
+ // generate association foreign keys from foreign keys
+ if len(associationForeignKeys) == 0 {
+ for _, foreignKey := range foreignKeys {
+ if strings.HasPrefix(foreignKey, associationType) {
+ associationForeignKey := strings.TrimPrefix(foreignKey, associationType)
+ if foreignField := getForeignField(associationForeignKey, modelStruct.StructFields); foreignField != nil {
+ associationForeignKeys = append(associationForeignKeys, associationForeignKey)
+ }
+ }
+ }
+ if len(associationForeignKeys) == 0 && len(foreignKeys) == 1 {
+ associationForeignKeys = []string{scope.PrimaryKey()}
+ }
+ } else if len(foreignKeys) != len(associationForeignKeys) {
+ scope.Err(errors.New("invalid foreign keys, should have same length"))
+ return
+ }
+ }
+
+ for idx, foreignKey := range foreignKeys {
+ if foreignField := getForeignField(foreignKey, toFields); foreignField != nil {
+ if associationField := getForeignField(associationForeignKeys[idx], modelStruct.StructFields); associationField != nil {
+ // source foreign keys
+ foreignField.IsForeignKey = true
+ relationship.AssociationForeignFieldNames = append(relationship.AssociationForeignFieldNames, associationField.Name)
+ relationship.AssociationForeignDBNames = append(relationship.AssociationForeignDBNames, associationField.DBName)
+
+ // association foreign keys
+ relationship.ForeignFieldNames = append(relationship.ForeignFieldNames, foreignField.Name)
+ relationship.ForeignDBNames = append(relationship.ForeignDBNames, foreignField.DBName)
+ }
+ }
+ }
+
+ if len(relationship.ForeignFieldNames) != 0 {
+ field.Relationship = relationship
+ }
+ }
+ } else {
+ field.IsNormal = true
+ }
+ }(field)
+ case reflect.Struct:
+ defer func(field *StructField) {
+ var (
+ // user has one profile, associationType is User, profile use UserID as foreign key
+ // user belongs to profile, associationType is Profile, user use ProfileID as foreign key
+ associationType = reflectType.Name()
+ relationship = &Relationship{}
+ toScope = scope.New(reflect.New(field.Struct.Type).Interface())
+ toFields = toScope.GetStructFields()
+ tagForeignKeys []string
+ tagAssociationForeignKeys []string
+ )
+
+ if foreignKey, _ := field.TagSettingsGet("FOREIGNKEY"); foreignKey != "" {
+ tagForeignKeys = strings.Split(foreignKey, ",")
+ }
+
+ if foreignKey, _ := field.TagSettingsGet("ASSOCIATION_FOREIGNKEY"); foreignKey != "" {
+ tagAssociationForeignKeys = strings.Split(foreignKey, ",")
+ } else if foreignKey, _ := field.TagSettingsGet("ASSOCIATIONFOREIGNKEY"); foreignKey != "" {
+ tagAssociationForeignKeys = strings.Split(foreignKey, ",")
+ }
+
+ if polymorphic, _ := field.TagSettingsGet("POLYMORPHIC"); polymorphic != "" {
+ // Cat has one toy, tag polymorphic is Owner, then associationType is Owner
+ // Toy use OwnerID, OwnerType ('cats') as foreign key
+ if polymorphicType := getForeignField(polymorphic+"Type", toFields); polymorphicType != nil {
+ associationType = polymorphic
+ relationship.PolymorphicType = polymorphicType.Name
+ relationship.PolymorphicDBName = polymorphicType.DBName
+ // if Cat has several different types of toys set name for each (instead of default 'cats')
+ if value, ok := field.TagSettingsGet("POLYMORPHIC_VALUE"); ok {
+ relationship.PolymorphicValue = value
+ } else {
+ relationship.PolymorphicValue = scope.TableName()
+ }
+ polymorphicType.IsForeignKey = true
+ }
+ }
+
+ // Has One
+ {
+ var foreignKeys = tagForeignKeys
+ var associationForeignKeys = tagAssociationForeignKeys
+ // if no foreign keys defined with tag
+ if len(foreignKeys) == 0 {
+ // if no association foreign keys defined with tag
+ if len(associationForeignKeys) == 0 {
+ for _, primaryField := range modelStruct.PrimaryFields {
+ foreignKeys = append(foreignKeys, associationType+primaryField.Name)
+ associationForeignKeys = append(associationForeignKeys, primaryField.Name)
+ }
+ } else {
+ // generate foreign keys form association foreign keys
+ for _, associationForeignKey := range tagAssociationForeignKeys {
+ if foreignField := getForeignField(associationForeignKey, modelStruct.StructFields); foreignField != nil {
+ foreignKeys = append(foreignKeys, associationType+foreignField.Name)
+ associationForeignKeys = append(associationForeignKeys, foreignField.Name)
+ }
+ }
+ }
+ } else {
+ // generate association foreign keys from foreign keys
+ if len(associationForeignKeys) == 0 {
+ for _, foreignKey := range foreignKeys {
+ if strings.HasPrefix(foreignKey, associationType) {
+ associationForeignKey := strings.TrimPrefix(foreignKey, associationType)
+ if foreignField := getForeignField(associationForeignKey, modelStruct.StructFields); foreignField != nil {
+ associationForeignKeys = append(associationForeignKeys, associationForeignKey)
+ }
+ }
+ }
+ if len(associationForeignKeys) == 0 && len(foreignKeys) == 1 {
+ associationForeignKeys = []string{scope.PrimaryKey()}
+ }
+ } else if len(foreignKeys) != len(associationForeignKeys) {
+ scope.Err(errors.New("invalid foreign keys, should have same length"))
+ return
+ }
+ }
+
+ for idx, foreignKey := range foreignKeys {
+ if foreignField := getForeignField(foreignKey, toFields); foreignField != nil {
+ if scopeField := getForeignField(associationForeignKeys[idx], modelStruct.StructFields); scopeField != nil {
+ foreignField.IsForeignKey = true
+ // source foreign keys
+ relationship.AssociationForeignFieldNames = append(relationship.AssociationForeignFieldNames, scopeField.Name)
+ relationship.AssociationForeignDBNames = append(relationship.AssociationForeignDBNames, scopeField.DBName)
+
+ // association foreign keys
+ relationship.ForeignFieldNames = append(relationship.ForeignFieldNames, foreignField.Name)
+ relationship.ForeignDBNames = append(relationship.ForeignDBNames, foreignField.DBName)
+ }
+ }
+ }
+ }
+
+ if len(relationship.ForeignFieldNames) != 0 {
+ relationship.Kind = "has_one"
+ field.Relationship = relationship
+ } else {
+ var foreignKeys = tagForeignKeys
+ var associationForeignKeys = tagAssociationForeignKeys
+
+ if len(foreignKeys) == 0 {
+ // generate foreign keys & association foreign keys
+ if len(associationForeignKeys) == 0 {
+ for _, primaryField := range toScope.PrimaryFields() {
+ foreignKeys = append(foreignKeys, field.Name+primaryField.Name)
+ associationForeignKeys = append(associationForeignKeys, primaryField.Name)
+ }
+ } else {
+ // generate foreign keys with association foreign keys
+ for _, associationForeignKey := range associationForeignKeys {
+ if foreignField := getForeignField(associationForeignKey, toFields); foreignField != nil {
+ foreignKeys = append(foreignKeys, field.Name+foreignField.Name)
+ associationForeignKeys = append(associationForeignKeys, foreignField.Name)
+ }
+ }
+ }
+ } else {
+ // generate foreign keys & association foreign keys
+ if len(associationForeignKeys) == 0 {
+ for _, foreignKey := range foreignKeys {
+ if strings.HasPrefix(foreignKey, field.Name) {
+ associationForeignKey := strings.TrimPrefix(foreignKey, field.Name)
+ if foreignField := getForeignField(associationForeignKey, toFields); foreignField != nil {
+ associationForeignKeys = append(associationForeignKeys, associationForeignKey)
+ }
+ }
+ }
+ if len(associationForeignKeys) == 0 && len(foreignKeys) == 1 {
+ associationForeignKeys = []string{toScope.PrimaryKey()}
+ }
+ } else if len(foreignKeys) != len(associationForeignKeys) {
+ scope.Err(errors.New("invalid foreign keys, should have same length"))
+ return
+ }
+ }
+
+ for idx, foreignKey := range foreignKeys {
+ if foreignField := getForeignField(foreignKey, modelStruct.StructFields); foreignField != nil {
+ if associationField := getForeignField(associationForeignKeys[idx], toFields); associationField != nil {
+ foreignField.IsForeignKey = true
+
+ // association foreign keys
+ relationship.AssociationForeignFieldNames = append(relationship.AssociationForeignFieldNames, associationField.Name)
+ relationship.AssociationForeignDBNames = append(relationship.AssociationForeignDBNames, associationField.DBName)
+
+ // source foreign keys
+ relationship.ForeignFieldNames = append(relationship.ForeignFieldNames, foreignField.Name)
+ relationship.ForeignDBNames = append(relationship.ForeignDBNames, foreignField.DBName)
+ }
+ }
+ }
+
+ if len(relationship.ForeignFieldNames) != 0 {
+ relationship.Kind = "belongs_to"
+ field.Relationship = relationship
+ }
+ }
+ }(field)
+ default:
+ field.IsNormal = true
+ }
+ }
+ }
+
+ // Even it is ignored, also possible to decode db value into the field
+ if value, ok := field.TagSettingsGet("COLUMN"); ok {
+ field.DBName = value
+ } else {
+ field.DBName = ToColumnName(fieldStruct.Name)
+ }
+
+ modelStruct.StructFields = append(modelStruct.StructFields, field)
+ }
+ }
+
+ if len(modelStruct.PrimaryFields) == 0 {
+ if field := getForeignField("id", modelStruct.StructFields); field != nil {
+ field.IsPrimaryKey = true
+ modelStruct.PrimaryFields = append(modelStruct.PrimaryFields, field)
+ }
+ }
+
+ modelStructsMap.Store(hashKey, &modelStruct)
+
+ return &modelStruct
+}
+
+// GetStructFields get model's field structs
+func (scope *Scope) GetStructFields() (fields []*StructField) {
+ return scope.GetModelStruct().StructFields
+}
+
+func parseTagSetting(tags reflect.StructTag) map[string]string {
+ setting := map[string]string{}
+ for _, str := range []string{tags.Get("sql"), tags.Get("gorm")} {
+ if str == "" {
+ continue
+ }
+ tags := strings.Split(str, ";")
+ for _, value := range tags {
+ v := strings.Split(value, ":")
+ k := strings.TrimSpace(strings.ToUpper(v[0]))
+ if len(v) >= 2 {
+ setting[k] = strings.Join(v[1:], ":")
+ } else {
+ setting[k] = k
+ }
+ }
+ }
+ return setting
+}
diff --git a/vendor/github.com/jinzhu/gorm/naming.go b/vendor/github.com/jinzhu/gorm/naming.go
new file mode 100644
index 0000000000000000000000000000000000000000..6b0a4fddbc15ee55ceadddc1adc860c13da4effb
--- /dev/null
+++ b/vendor/github.com/jinzhu/gorm/naming.go
@@ -0,0 +1,124 @@
+package gorm
+
+import (
+ "bytes"
+ "strings"
+)
+
+// Namer is a function type which is given a string and return a string
+type Namer func(string) string
+
+// NamingStrategy represents naming strategies
+type NamingStrategy struct {
+ DB Namer
+ Table Namer
+ Column Namer
+}
+
+// TheNamingStrategy is being initialized with defaultNamingStrategy
+var TheNamingStrategy = &NamingStrategy{
+ DB: defaultNamer,
+ Table: defaultNamer,
+ Column: defaultNamer,
+}
+
+// AddNamingStrategy sets the naming strategy
+func AddNamingStrategy(ns *NamingStrategy) {
+ if ns.DB == nil {
+ ns.DB = defaultNamer
+ }
+ if ns.Table == nil {
+ ns.Table = defaultNamer
+ }
+ if ns.Column == nil {
+ ns.Column = defaultNamer
+ }
+ TheNamingStrategy = ns
+}
+
+// DBName alters the given name by DB
+func (ns *NamingStrategy) DBName(name string) string {
+ return ns.DB(name)
+}
+
+// TableName alters the given name by Table
+func (ns *NamingStrategy) TableName(name string) string {
+ return ns.Table(name)
+}
+
+// ColumnName alters the given name by Column
+func (ns *NamingStrategy) ColumnName(name string) string {
+ return ns.Column(name)
+}
+
+// ToDBName convert string to db name
+func ToDBName(name string) string {
+ return TheNamingStrategy.DBName(name)
+}
+
+// ToTableName convert string to table name
+func ToTableName(name string) string {
+ return TheNamingStrategy.TableName(name)
+}
+
+// ToColumnName convert string to db name
+func ToColumnName(name string) string {
+ return TheNamingStrategy.ColumnName(name)
+}
+
+var smap = newSafeMap()
+
+func defaultNamer(name string) string {
+ const (
+ lower = false
+ upper = true
+ )
+
+ if v := smap.Get(name); v != "" {
+ return v
+ }
+
+ if name == "" {
+ return ""
+ }
+
+ var (
+ value = commonInitialismsReplacer.Replace(name)
+ buf = bytes.NewBufferString("")
+ lastCase, currCase, nextCase, nextNumber bool
+ )
+
+ for i, v := range value[:len(value)-1] {
+ nextCase = bool(value[i+1] >= 'A' && value[i+1] <= 'Z')
+ nextNumber = bool(value[i+1] >= '0' && value[i+1] <= '9')
+
+ if i > 0 {
+ if currCase == upper {
+ if lastCase == upper && (nextCase == upper || nextNumber == upper) {
+ buf.WriteRune(v)
+ } else {
+ if value[i-1] != '_' && value[i+1] != '_' {
+ buf.WriteRune('_')
+ }
+ buf.WriteRune(v)
+ }
+ } else {
+ buf.WriteRune(v)
+ if i == len(value)-2 && (nextCase == upper && nextNumber == lower) {
+ buf.WriteRune('_')
+ }
+ }
+ } else {
+ currCase = upper
+ buf.WriteRune(v)
+ }
+ lastCase = currCase
+ currCase = nextCase
+ }
+
+ buf.WriteByte(value[len(value)-1])
+
+ s := strings.ToLower(buf.String())
+ smap.Set(name, s)
+ return s
+}
diff --git a/vendor/github.com/jinzhu/gorm/scope.go b/vendor/github.com/jinzhu/gorm/scope.go
new file mode 100644
index 0000000000000000000000000000000000000000..c962c165f97dc1bb73cd0b2c48105cccb4c72107
--- /dev/null
+++ b/vendor/github.com/jinzhu/gorm/scope.go
@@ -0,0 +1,1419 @@
+package gorm
+
+import (
+ "bytes"
+ "database/sql"
+ "database/sql/driver"
+ "errors"
+ "fmt"
+ "reflect"
+ "regexp"
+ "strings"
+ "time"
+)
+
+// Scope contain current operation's information when you perform any operation on the database
+type Scope struct {
+ Search *search
+ Value interface{}
+ SQL string
+ SQLVars []interface{}
+ db *DB
+ instanceID string
+ primaryKeyField *Field
+ skipLeft bool
+ fields *[]*Field
+ selectAttrs *[]string
+}
+
+// IndirectValue return scope's reflect value's indirect value
+func (scope *Scope) IndirectValue() reflect.Value {
+ return indirect(reflect.ValueOf(scope.Value))
+}
+
+// New create a new Scope without search information
+func (scope *Scope) New(value interface{}) *Scope {
+ return &Scope{db: scope.NewDB(), Search: &search{}, Value: value}
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// Scope DB
+////////////////////////////////////////////////////////////////////////////////
+
+// DB return scope's DB connection
+func (scope *Scope) DB() *DB {
+ return scope.db
+}
+
+// NewDB create a new DB without search information
+func (scope *Scope) NewDB() *DB {
+ if scope.db != nil {
+ db := scope.db.clone()
+ db.search = nil
+ db.Value = nil
+ return db
+ }
+ return nil
+}
+
+// SQLDB return *sql.DB
+func (scope *Scope) SQLDB() SQLCommon {
+ return scope.db.db
+}
+
+// Dialect get dialect
+func (scope *Scope) Dialect() Dialect {
+ return scope.db.dialect
+}
+
+// Quote used to quote string to escape them for database
+func (scope *Scope) Quote(str string) string {
+ if strings.Contains(str, ".") {
+ newStrs := []string{}
+ for _, str := range strings.Split(str, ".") {
+ newStrs = append(newStrs, scope.Dialect().Quote(str))
+ }
+ return strings.Join(newStrs, ".")
+ }
+
+ return scope.Dialect().Quote(str)
+}
+
+// Err add error to Scope
+func (scope *Scope) Err(err error) error {
+ if err != nil {
+ scope.db.AddError(err)
+ }
+ return err
+}
+
+// HasError check if there are any error
+func (scope *Scope) HasError() bool {
+ return scope.db.Error != nil
+}
+
+// Log print log message
+func (scope *Scope) Log(v ...interface{}) {
+ scope.db.log(v...)
+}
+
+// SkipLeft skip remaining callbacks
+func (scope *Scope) SkipLeft() {
+ scope.skipLeft = true
+}
+
+// Fields get value's fields
+func (scope *Scope) Fields() []*Field {
+ if scope.fields == nil {
+ var (
+ fields []*Field
+ indirectScopeValue = scope.IndirectValue()
+ isStruct = indirectScopeValue.Kind() == reflect.Struct
+ )
+
+ for _, structField := range scope.GetModelStruct().StructFields {
+ if isStruct {
+ fieldValue := indirectScopeValue
+ for _, name := range structField.Names {
+ if fieldValue.Kind() == reflect.Ptr && fieldValue.IsNil() {
+ fieldValue.Set(reflect.New(fieldValue.Type().Elem()))
+ }
+ fieldValue = reflect.Indirect(fieldValue).FieldByName(name)
+ }
+ fields = append(fields, &Field{StructField: structField, Field: fieldValue, IsBlank: isBlank(fieldValue)})
+ } else {
+ fields = append(fields, &Field{StructField: structField, IsBlank: true})
+ }
+ }
+ scope.fields = &fields
+ }
+
+ return *scope.fields
+}
+
+// FieldByName find `gorm.Field` with field name or db name
+func (scope *Scope) FieldByName(name string) (field *Field, ok bool) {
+ var (
+ dbName = ToColumnName(name)
+ mostMatchedField *Field
+ )
+
+ for _, field := range scope.Fields() {
+ if field.Name == name || field.DBName == name {
+ return field, true
+ }
+ if field.DBName == dbName {
+ mostMatchedField = field
+ }
+ }
+ return mostMatchedField, mostMatchedField != nil
+}
+
+// PrimaryFields return scope's primary fields
+func (scope *Scope) PrimaryFields() (fields []*Field) {
+ for _, field := range scope.Fields() {
+ if field.IsPrimaryKey {
+ fields = append(fields, field)
+ }
+ }
+ return fields
+}
+
+// PrimaryField return scope's main primary field, if defined more that one primary fields, will return the one having column name `id` or the first one
+func (scope *Scope) PrimaryField() *Field {
+ if primaryFields := scope.GetModelStruct().PrimaryFields; len(primaryFields) > 0 {
+ if len(primaryFields) > 1 {
+ if field, ok := scope.FieldByName("id"); ok {
+ return field
+ }
+ }
+ return scope.PrimaryFields()[0]
+ }
+ return nil
+}
+
+// PrimaryKey get main primary field's db name
+func (scope *Scope) PrimaryKey() string {
+ if field := scope.PrimaryField(); field != nil {
+ return field.DBName
+ }
+ return ""
+}
+
+// PrimaryKeyZero check main primary field's value is blank or not
+func (scope *Scope) PrimaryKeyZero() bool {
+ field := scope.PrimaryField()
+ return field == nil || field.IsBlank
+}
+
+// PrimaryKeyValue get the primary key's value
+func (scope *Scope) PrimaryKeyValue() interface{} {
+ if field := scope.PrimaryField(); field != nil && field.Field.IsValid() {
+ return field.Field.Interface()
+ }
+ return 0
+}
+
+// HasColumn to check if has column
+func (scope *Scope) HasColumn(column string) bool {
+ for _, field := range scope.GetStructFields() {
+ if field.IsNormal && (field.Name == column || field.DBName == column) {
+ return true
+ }
+ }
+ return false
+}
+
+// SetColumn to set the column's value, column could be field or field's name/dbname
+func (scope *Scope) SetColumn(column interface{}, value interface{}) error {
+ var updateAttrs = map[string]interface{}{}
+ if attrs, ok := scope.InstanceGet("gorm:update_attrs"); ok {
+ updateAttrs = attrs.(map[string]interface{})
+ defer scope.InstanceSet("gorm:update_attrs", updateAttrs)
+ }
+
+ if field, ok := column.(*Field); ok {
+ updateAttrs[field.DBName] = value
+ return field.Set(value)
+ } else if name, ok := column.(string); ok {
+ var (
+ dbName = ToDBName(name)
+ mostMatchedField *Field
+ )
+ for _, field := range scope.Fields() {
+ if field.DBName == value {
+ updateAttrs[field.DBName] = value
+ return field.Set(value)
+ }
+ if (field.DBName == dbName) || (field.Name == name && mostMatchedField == nil) {
+ mostMatchedField = field
+ }
+ }
+
+ if mostMatchedField != nil {
+ updateAttrs[mostMatchedField.DBName] = value
+ return mostMatchedField.Set(value)
+ }
+ }
+ return errors.New("could not convert column to field")
+}
+
+// CallMethod call scope value's method, if it is a slice, will call its element's method one by one
+func (scope *Scope) CallMethod(methodName string) {
+ if scope.Value == nil {
+ return
+ }
+
+ if indirectScopeValue := scope.IndirectValue(); indirectScopeValue.Kind() == reflect.Slice {
+ for i := 0; i < indirectScopeValue.Len(); i++ {
+ scope.callMethod(methodName, indirectScopeValue.Index(i))
+ }
+ } else {
+ scope.callMethod(methodName, indirectScopeValue)
+ }
+}
+
+// AddToVars add value as sql's vars, used to prevent SQL injection
+func (scope *Scope) AddToVars(value interface{}) string {
+ _, skipBindVar := scope.InstanceGet("skip_bindvar")
+
+ if expr, ok := value.(*expr); ok {
+ exp := expr.expr
+ for _, arg := range expr.args {
+ if skipBindVar {
+ scope.AddToVars(arg)
+ } else {
+ exp = strings.Replace(exp, "?", scope.AddToVars(arg), 1)
+ }
+ }
+ return exp
+ }
+
+ scope.SQLVars = append(scope.SQLVars, value)
+
+ if skipBindVar {
+ return "?"
+ }
+ return scope.Dialect().BindVar(len(scope.SQLVars))
+}
+
+// SelectAttrs return selected attributes
+func (scope *Scope) SelectAttrs() []string {
+ if scope.selectAttrs == nil {
+ attrs := []string{}
+ for _, value := range scope.Search.selects {
+ if str, ok := value.(string); ok {
+ attrs = append(attrs, str)
+ } else if strs, ok := value.([]string); ok {
+ attrs = append(attrs, strs...)
+ } else if strs, ok := value.([]interface{}); ok {
+ for _, str := range strs {
+ attrs = append(attrs, fmt.Sprintf("%v", str))
+ }
+ }
+ }
+ scope.selectAttrs = &attrs
+ }
+ return *scope.selectAttrs
+}
+
+// OmitAttrs return omitted attributes
+func (scope *Scope) OmitAttrs() []string {
+ return scope.Search.omits
+}
+
+type tabler interface {
+ TableName() string
+}
+
+type dbTabler interface {
+ TableName(*DB) string
+}
+
+// TableName return table name
+func (scope *Scope) TableName() string {
+ if scope.Search != nil && len(scope.Search.tableName) > 0 {
+ return scope.Search.tableName
+ }
+
+ if tabler, ok := scope.Value.(tabler); ok {
+ return tabler.TableName()
+ }
+
+ if tabler, ok := scope.Value.(dbTabler); ok {
+ return tabler.TableName(scope.db)
+ }
+
+ return scope.GetModelStruct().TableName(scope.db.Model(scope.Value))
+}
+
+// QuotedTableName return quoted table name
+func (scope *Scope) QuotedTableName() (name string) {
+ if scope.Search != nil && len(scope.Search.tableName) > 0 {
+ if strings.Contains(scope.Search.tableName, " ") {
+ return scope.Search.tableName
+ }
+ return scope.Quote(scope.Search.tableName)
+ }
+
+ return scope.Quote(scope.TableName())
+}
+
+// CombinedConditionSql return combined condition sql
+func (scope *Scope) CombinedConditionSql() string {
+ joinSQL := scope.joinsSQL()
+ whereSQL := scope.whereSQL()
+ if scope.Search.raw {
+ whereSQL = strings.TrimSuffix(strings.TrimPrefix(whereSQL, "WHERE ("), ")")
+ }
+ return joinSQL + whereSQL + scope.groupSQL() +
+ scope.havingSQL() + scope.orderSQL() + scope.limitAndOffsetSQL()
+}
+
+// Raw set raw sql
+func (scope *Scope) Raw(sql string) *Scope {
+ scope.SQL = strings.Replace(sql, "$$$", "?", -1)
+ return scope
+}
+
+// Exec perform generated SQL
+func (scope *Scope) Exec() *Scope {
+ defer scope.trace(scope.db.nowFunc())
+
+ if !scope.HasError() {
+ if result, err := scope.SQLDB().Exec(scope.SQL, scope.SQLVars...); scope.Err(err) == nil {
+ if count, err := result.RowsAffected(); scope.Err(err) == nil {
+ scope.db.RowsAffected = count
+ }
+ }
+ }
+ return scope
+}
+
+// Set set value by name
+func (scope *Scope) Set(name string, value interface{}) *Scope {
+ scope.db.InstantSet(name, value)
+ return scope
+}
+
+// Get get setting by name
+func (scope *Scope) Get(name string) (interface{}, bool) {
+ return scope.db.Get(name)
+}
+
+// InstanceID get InstanceID for scope
+func (scope *Scope) InstanceID() string {
+ if scope.instanceID == "" {
+ scope.instanceID = fmt.Sprintf("%v%v", &scope, &scope.db)
+ }
+ return scope.instanceID
+}
+
+// InstanceSet set instance setting for current operation, but not for operations in callbacks, like saving associations callback
+func (scope *Scope) InstanceSet(name string, value interface{}) *Scope {
+ return scope.Set(name+scope.InstanceID(), value)
+}
+
+// InstanceGet get instance setting from current operation
+func (scope *Scope) InstanceGet(name string) (interface{}, bool) {
+ return scope.Get(name + scope.InstanceID())
+}
+
+// Begin start a transaction
+func (scope *Scope) Begin() *Scope {
+ if db, ok := scope.SQLDB().(sqlDb); ok {
+ if tx, err := db.Begin(); scope.Err(err) == nil {
+ scope.db.db = interface{}(tx).(SQLCommon)
+ scope.InstanceSet("gorm:started_transaction", true)
+ }
+ }
+ return scope
+}
+
+// CommitOrRollback commit current transaction if no error happened, otherwise will rollback it
+func (scope *Scope) CommitOrRollback() *Scope {
+ if _, ok := scope.InstanceGet("gorm:started_transaction"); ok {
+ if db, ok := scope.db.db.(sqlTx); ok {
+ if scope.HasError() {
+ db.Rollback()
+ } else {
+ scope.Err(db.Commit())
+ }
+ scope.db.db = scope.db.parent.db
+ }
+ }
+ return scope
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// Private Methods For *gorm.Scope
+////////////////////////////////////////////////////////////////////////////////
+
+func (scope *Scope) callMethod(methodName string, reflectValue reflect.Value) {
+ // Only get address from non-pointer
+ if reflectValue.CanAddr() && reflectValue.Kind() != reflect.Ptr {
+ reflectValue = reflectValue.Addr()
+ }
+
+ if methodValue := reflectValue.MethodByName(methodName); methodValue.IsValid() {
+ switch method := methodValue.Interface().(type) {
+ case func():
+ method()
+ case func(*Scope):
+ method(scope)
+ case func(*DB):
+ newDB := scope.NewDB()
+ method(newDB)
+ scope.Err(newDB.Error)
+ case func() error:
+ scope.Err(method())
+ case func(*Scope) error:
+ scope.Err(method(scope))
+ case func(*DB) error:
+ newDB := scope.NewDB()
+ scope.Err(method(newDB))
+ scope.Err(newDB.Error)
+ default:
+ scope.Err(fmt.Errorf("unsupported function %v", methodName))
+ }
+ }
+}
+
+var (
+ columnRegexp = regexp.MustCompile("^[a-zA-Z\\d]+(\\.[a-zA-Z\\d]+)*$") // only match string like `name`, `users.name`
+ isNumberRegexp = regexp.MustCompile("^\\s*\\d+\\s*$") // match if string is number
+ comparisonRegexp = regexp.MustCompile("(?i) (=|<>|(>|<)(=?)|LIKE|IS|IN) ")
+ countingQueryRegexp = regexp.MustCompile("(?i)^count(.+)$")
+)
+
+func (scope *Scope) quoteIfPossible(str string) string {
+ if columnRegexp.MatchString(str) {
+ return scope.Quote(str)
+ }
+ return str
+}
+
+func (scope *Scope) scan(rows *sql.Rows, columns []string, fields []*Field) {
+ var (
+ ignored interface{}
+ values = make([]interface{}, len(columns))
+ selectFields []*Field
+ selectedColumnsMap = map[string]int{}
+ resetFields = map[int]*Field{}
+ )
+
+ for index, column := range columns {
+ values[index] = &ignored
+
+ selectFields = fields
+ offset := 0
+ if idx, ok := selectedColumnsMap[column]; ok {
+ offset = idx + 1
+ selectFields = selectFields[offset:]
+ }
+
+ for fieldIndex, field := range selectFields {
+ if field.DBName == column {
+ if field.Field.Kind() == reflect.Ptr {
+ values[index] = field.Field.Addr().Interface()
+ } else {
+ reflectValue := reflect.New(reflect.PtrTo(field.Struct.Type))
+ reflectValue.Elem().Set(field.Field.Addr())
+ values[index] = reflectValue.Interface()
+ resetFields[index] = field
+ }
+
+ selectedColumnsMap[column] = offset + fieldIndex
+
+ if field.IsNormal {
+ break
+ }
+ }
+ }
+ }
+
+ scope.Err(rows.Scan(values...))
+
+ for index, field := range resetFields {
+ if v := reflect.ValueOf(values[index]).Elem().Elem(); v.IsValid() {
+ field.Field.Set(v)
+ }
+ }
+}
+
+func (scope *Scope) primaryCondition(value interface{}) string {
+ return fmt.Sprintf("(%v.%v = %v)", scope.QuotedTableName(), scope.Quote(scope.PrimaryKey()), value)
+}
+
+func (scope *Scope) buildCondition(clause map[string]interface{}, include bool) (str string) {
+ var (
+ quotedTableName = scope.QuotedTableName()
+ quotedPrimaryKey = scope.Quote(scope.PrimaryKey())
+ equalSQL = "="
+ inSQL = "IN"
+ )
+
+ // If building not conditions
+ if !include {
+ equalSQL = "<>"
+ inSQL = "NOT IN"
+ }
+
+ switch value := clause["query"].(type) {
+ case sql.NullInt64:
+ return fmt.Sprintf("(%v.%v %s %v)", quotedTableName, quotedPrimaryKey, equalSQL, value.Int64)
+ case int, int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64:
+ return fmt.Sprintf("(%v.%v %s %v)", quotedTableName, quotedPrimaryKey, equalSQL, value)
+ case []int, []int8, []int16, []int32, []int64, []uint, []uint8, []uint16, []uint32, []uint64, []string, []interface{}:
+ if !include && reflect.ValueOf(value).Len() == 0 {
+ return
+ }
+ str = fmt.Sprintf("(%v.%v %s (?))", quotedTableName, quotedPrimaryKey, inSQL)
+ clause["args"] = []interface{}{value}
+ case string:
+ if isNumberRegexp.MatchString(value) {
+ return fmt.Sprintf("(%v.%v %s %v)", quotedTableName, quotedPrimaryKey, equalSQL, scope.AddToVars(value))
+ }
+
+ if value != "" {
+ if !include {
+ if comparisonRegexp.MatchString(value) {
+ str = fmt.Sprintf("NOT (%v)", value)
+ } else {
+ str = fmt.Sprintf("(%v.%v NOT IN (?))", quotedTableName, scope.Quote(value))
+ }
+ } else {
+ str = fmt.Sprintf("(%v)", value)
+ }
+ }
+ case map[string]interface{}:
+ var sqls []string
+ for key, value := range value {
+ if value != nil {
+ sqls = append(sqls, fmt.Sprintf("(%v.%v %s %v)", quotedTableName, scope.Quote(key), equalSQL, scope.AddToVars(value)))
+ } else {
+ if !include {
+ sqls = append(sqls, fmt.Sprintf("(%v.%v IS NOT NULL)", quotedTableName, scope.Quote(key)))
+ } else {
+ sqls = append(sqls, fmt.Sprintf("(%v.%v IS NULL)", quotedTableName, scope.Quote(key)))
+ }
+ }
+ }
+ return strings.Join(sqls, " AND ")
+ case interface{}:
+ var sqls []string
+ newScope := scope.New(value)
+
+ if len(newScope.Fields()) == 0 {
+ scope.Err(fmt.Errorf("invalid query condition: %v", value))
+ return
+ }
+ scopeQuotedTableName := newScope.QuotedTableName()
+ for _, field := range newScope.Fields() {
+ if !field.IsIgnored && !field.IsBlank {
+ sqls = append(sqls, fmt.Sprintf("(%v.%v %s %v)", scopeQuotedTableName, scope.Quote(field.DBName), equalSQL, scope.AddToVars(field.Field.Interface())))
+ }
+ }
+ return strings.Join(sqls, " AND ")
+ default:
+ scope.Err(fmt.Errorf("invalid query condition: %v", value))
+ return
+ }
+
+ replacements := []string{}
+ args := clause["args"].([]interface{})
+ for _, arg := range args {
+ var err error
+ switch reflect.ValueOf(arg).Kind() {
+ case reflect.Slice: // For where("id in (?)", []int64{1,2})
+ if scanner, ok := interface{}(arg).(driver.Valuer); ok {
+ arg, err = scanner.Value()
+ replacements = append(replacements, scope.AddToVars(arg))
+ } else if b, ok := arg.([]byte); ok {
+ replacements = append(replacements, scope.AddToVars(b))
+ } else if as, ok := arg.([][]interface{}); ok {
+ var tempMarks []string
+ for _, a := range as {
+ var arrayMarks []string
+ for _, v := range a {
+ arrayMarks = append(arrayMarks, scope.AddToVars(v))
+ }
+
+ if len(arrayMarks) > 0 {
+ tempMarks = append(tempMarks, fmt.Sprintf("(%v)", strings.Join(arrayMarks, ",")))
+ }
+ }
+
+ if len(tempMarks) > 0 {
+ replacements = append(replacements, strings.Join(tempMarks, ","))
+ }
+ } else if values := reflect.ValueOf(arg); values.Len() > 0 {
+ var tempMarks []string
+ for i := 0; i < values.Len(); i++ {
+ tempMarks = append(tempMarks, scope.AddToVars(values.Index(i).Interface()))
+ }
+ replacements = append(replacements, strings.Join(tempMarks, ","))
+ } else {
+ replacements = append(replacements, scope.AddToVars(Expr("NULL")))
+ }
+ default:
+ if valuer, ok := interface{}(arg).(driver.Valuer); ok {
+ arg, err = valuer.Value()
+ }
+
+ replacements = append(replacements, scope.AddToVars(arg))
+ }
+
+ if err != nil {
+ scope.Err(err)
+ }
+ }
+
+ buff := bytes.NewBuffer([]byte{})
+ i := 0
+ for _, s := range str {
+ if s == '?' && len(replacements) > i {
+ buff.WriteString(replacements[i])
+ i++
+ } else {
+ buff.WriteRune(s)
+ }
+ }
+
+ str = buff.String()
+
+ return
+}
+
+func (scope *Scope) buildSelectQuery(clause map[string]interface{}) (str string) {
+ switch value := clause["query"].(type) {
+ case string:
+ str = value
+ case []string:
+ str = strings.Join(value, ", ")
+ }
+
+ args := clause["args"].([]interface{})
+ replacements := []string{}
+ for _, arg := range args {
+ switch reflect.ValueOf(arg).Kind() {
+ case reflect.Slice:
+ values := reflect.ValueOf(arg)
+ var tempMarks []string
+ for i := 0; i < values.Len(); i++ {
+ tempMarks = append(tempMarks, scope.AddToVars(values.Index(i).Interface()))
+ }
+ replacements = append(replacements, strings.Join(tempMarks, ","))
+ default:
+ if valuer, ok := interface{}(arg).(driver.Valuer); ok {
+ arg, _ = valuer.Value()
+ }
+ replacements = append(replacements, scope.AddToVars(arg))
+ }
+ }
+
+ buff := bytes.NewBuffer([]byte{})
+ i := 0
+ for pos, char := range str {
+ if str[pos] == '?' {
+ buff.WriteString(replacements[i])
+ i++
+ } else {
+ buff.WriteRune(char)
+ }
+ }
+
+ str = buff.String()
+
+ return
+}
+
+func (scope *Scope) whereSQL() (sql string) {
+ var (
+ quotedTableName = scope.QuotedTableName()
+ deletedAtField, hasDeletedAtField = scope.FieldByName("DeletedAt")
+ primaryConditions, andConditions, orConditions []string
+ )
+
+ if !scope.Search.Unscoped && hasDeletedAtField {
+ sql := fmt.Sprintf("%v.%v IS NULL", quotedTableName, scope.Quote(deletedAtField.DBName))
+ primaryConditions = append(primaryConditions, sql)
+ }
+
+ if !scope.PrimaryKeyZero() {
+ for _, field := range scope.PrimaryFields() {
+ sql := fmt.Sprintf("%v.%v = %v", quotedTableName, scope.Quote(field.DBName), scope.AddToVars(field.Field.Interface()))
+ primaryConditions = append(primaryConditions, sql)
+ }
+ }
+
+ for _, clause := range scope.Search.whereConditions {
+ if sql := scope.buildCondition(clause, true); sql != "" {
+ andConditions = append(andConditions, sql)
+ }
+ }
+
+ for _, clause := range scope.Search.orConditions {
+ if sql := scope.buildCondition(clause, true); sql != "" {
+ orConditions = append(orConditions, sql)
+ }
+ }
+
+ for _, clause := range scope.Search.notConditions {
+ if sql := scope.buildCondition(clause, false); sql != "" {
+ andConditions = append(andConditions, sql)
+ }
+ }
+
+ orSQL := strings.Join(orConditions, " OR ")
+ combinedSQL := strings.Join(andConditions, " AND ")
+ if len(combinedSQL) > 0 {
+ if len(orSQL) > 0 {
+ combinedSQL = combinedSQL + " OR " + orSQL
+ }
+ } else {
+ combinedSQL = orSQL
+ }
+
+ if len(primaryConditions) > 0 {
+ sql = "WHERE " + strings.Join(primaryConditions, " AND ")
+ if len(combinedSQL) > 0 {
+ sql = sql + " AND (" + combinedSQL + ")"
+ }
+ } else if len(combinedSQL) > 0 {
+ sql = "WHERE " + combinedSQL
+ }
+ return
+}
+
+func (scope *Scope) selectSQL() string {
+ if len(scope.Search.selects) == 0 {
+ if len(scope.Search.joinConditions) > 0 {
+ return fmt.Sprintf("%v.*", scope.QuotedTableName())
+ }
+ return "*"
+ }
+ return scope.buildSelectQuery(scope.Search.selects)
+}
+
+func (scope *Scope) orderSQL() string {
+ if len(scope.Search.orders) == 0 || scope.Search.ignoreOrderQuery {
+ return ""
+ }
+
+ var orders []string
+ for _, order := range scope.Search.orders {
+ if str, ok := order.(string); ok {
+ orders = append(orders, scope.quoteIfPossible(str))
+ } else if expr, ok := order.(*expr); ok {
+ exp := expr.expr
+ for _, arg := range expr.args {
+ exp = strings.Replace(exp, "?", scope.AddToVars(arg), 1)
+ }
+ orders = append(orders, exp)
+ }
+ }
+ return " ORDER BY " + strings.Join(orders, ",")
+}
+
+func (scope *Scope) limitAndOffsetSQL() string {
+ return scope.Dialect().LimitAndOffsetSQL(scope.Search.limit, scope.Search.offset)
+}
+
+func (scope *Scope) groupSQL() string {
+ if len(scope.Search.group) == 0 {
+ return ""
+ }
+ return " GROUP BY " + scope.Search.group
+}
+
+func (scope *Scope) havingSQL() string {
+ if len(scope.Search.havingConditions) == 0 {
+ return ""
+ }
+
+ var andConditions []string
+ for _, clause := range scope.Search.havingConditions {
+ if sql := scope.buildCondition(clause, true); sql != "" {
+ andConditions = append(andConditions, sql)
+ }
+ }
+
+ combinedSQL := strings.Join(andConditions, " AND ")
+ if len(combinedSQL) == 0 {
+ return ""
+ }
+
+ return " HAVING " + combinedSQL
+}
+
+func (scope *Scope) joinsSQL() string {
+ var joinConditions []string
+ for _, clause := range scope.Search.joinConditions {
+ if sql := scope.buildCondition(clause, true); sql != "" {
+ joinConditions = append(joinConditions, strings.TrimSuffix(strings.TrimPrefix(sql, "("), ")"))
+ }
+ }
+
+ return strings.Join(joinConditions, " ") + " "
+}
+
+func (scope *Scope) prepareQuerySQL() {
+ if scope.Search.raw {
+ scope.Raw(scope.CombinedConditionSql())
+ } else {
+ scope.Raw(fmt.Sprintf("SELECT %v FROM %v %v", scope.selectSQL(), scope.QuotedTableName(), scope.CombinedConditionSql()))
+ }
+ return
+}
+
+func (scope *Scope) inlineCondition(values ...interface{}) *Scope {
+ if len(values) > 0 {
+ scope.Search.Where(values[0], values[1:]...)
+ }
+ return scope
+}
+
+func (scope *Scope) callCallbacks(funcs []*func(s *Scope)) *Scope {
+ defer func() {
+ if err := recover(); err != nil {
+ if db, ok := scope.db.db.(sqlTx); ok {
+ db.Rollback()
+ }
+ panic(err)
+ }
+ }()
+ for _, f := range funcs {
+ (*f)(scope)
+ if scope.skipLeft {
+ break
+ }
+ }
+ return scope
+}
+
+func convertInterfaceToMap(values interface{}, withIgnoredField bool, db *DB) map[string]interface{} {
+ var attrs = map[string]interface{}{}
+
+ switch value := values.(type) {
+ case map[string]interface{}:
+ return value
+ case []interface{}:
+ for _, v := range value {
+ for key, value := range convertInterfaceToMap(v, withIgnoredField, db) {
+ attrs[key] = value
+ }
+ }
+ case interface{}:
+ reflectValue := reflect.ValueOf(values)
+
+ switch reflectValue.Kind() {
+ case reflect.Map:
+ for _, key := range reflectValue.MapKeys() {
+ attrs[ToColumnName(key.Interface().(string))] = reflectValue.MapIndex(key).Interface()
+ }
+ default:
+ for _, field := range (&Scope{Value: values, db: db}).Fields() {
+ if !field.IsBlank && (withIgnoredField || !field.IsIgnored) {
+ attrs[field.DBName] = field.Field.Interface()
+ }
+ }
+ }
+ }
+ return attrs
+}
+
+func (scope *Scope) updatedAttrsWithValues(value interface{}) (results map[string]interface{}, hasUpdate bool) {
+ if scope.IndirectValue().Kind() != reflect.Struct {
+ return convertInterfaceToMap(value, false, scope.db), true
+ }
+
+ results = map[string]interface{}{}
+
+ for key, value := range convertInterfaceToMap(value, true, scope.db) {
+ if field, ok := scope.FieldByName(key); ok && scope.changeableField(field) {
+ if _, ok := value.(*expr); ok {
+ hasUpdate = true
+ results[field.DBName] = value
+ } else {
+ err := field.Set(value)
+ if field.IsNormal && !field.IsIgnored {
+ hasUpdate = true
+ if err == ErrUnaddressable {
+ results[field.DBName] = value
+ } else {
+ results[field.DBName] = field.Field.Interface()
+ }
+ }
+ }
+ }
+ }
+ return
+}
+
+func (scope *Scope) row() *sql.Row {
+ defer scope.trace(scope.db.nowFunc())
+
+ result := &RowQueryResult{}
+ scope.InstanceSet("row_query_result", result)
+ scope.callCallbacks(scope.db.parent.callbacks.rowQueries)
+
+ return result.Row
+}
+
+func (scope *Scope) rows() (*sql.Rows, error) {
+ defer scope.trace(scope.db.nowFunc())
+
+ result := &RowsQueryResult{}
+ scope.InstanceSet("row_query_result", result)
+ scope.callCallbacks(scope.db.parent.callbacks.rowQueries)
+
+ return result.Rows, result.Error
+}
+
+func (scope *Scope) initialize() *Scope {
+ for _, clause := range scope.Search.whereConditions {
+ scope.updatedAttrsWithValues(clause["query"])
+ }
+ scope.updatedAttrsWithValues(scope.Search.initAttrs)
+ scope.updatedAttrsWithValues(scope.Search.assignAttrs)
+ return scope
+}
+
+func (scope *Scope) isQueryForColumn(query interface{}, column string) bool {
+ queryStr := strings.ToLower(fmt.Sprint(query))
+ if queryStr == column {
+ return true
+ }
+
+ if strings.HasSuffix(queryStr, "as "+column) {
+ return true
+ }
+
+ if strings.HasSuffix(queryStr, "as "+scope.Quote(column)) {
+ return true
+ }
+
+ return false
+}
+
+func (scope *Scope) pluck(column string, value interface{}) *Scope {
+ dest := reflect.Indirect(reflect.ValueOf(value))
+ if dest.Kind() != reflect.Slice {
+ scope.Err(fmt.Errorf("results should be a slice, not %s", dest.Kind()))
+ return scope
+ }
+
+ if dest.Len() > 0 {
+ dest.Set(reflect.Zero(dest.Type()))
+ }
+
+ if query, ok := scope.Search.selects["query"]; !ok || !scope.isQueryForColumn(query, column) {
+ scope.Search.Select(column)
+ }
+
+ rows, err := scope.rows()
+ if scope.Err(err) == nil {
+ defer rows.Close()
+ for rows.Next() {
+ elem := reflect.New(dest.Type().Elem()).Interface()
+ scope.Err(rows.Scan(elem))
+ dest.Set(reflect.Append(dest, reflect.ValueOf(elem).Elem()))
+ }
+
+ if err := rows.Err(); err != nil {
+ scope.Err(err)
+ }
+ }
+ return scope
+}
+
+func (scope *Scope) count(value interface{}) *Scope {
+ if query, ok := scope.Search.selects["query"]; !ok || !countingQueryRegexp.MatchString(fmt.Sprint(query)) {
+ if len(scope.Search.group) != 0 {
+ if len(scope.Search.havingConditions) != 0 {
+ scope.prepareQuerySQL()
+ scope.Search = &search{}
+ scope.Search.Select("count(*)")
+ scope.Search.Table(fmt.Sprintf("( %s ) AS count_table", scope.SQL))
+ } else {
+ scope.Search.Select("count(*) FROM ( SELECT count(*) as name ")
+ scope.Search.group += " ) AS count_table"
+ }
+ } else {
+ scope.Search.Select("count(*)")
+ }
+ }
+ scope.Search.ignoreOrderQuery = true
+ scope.Err(scope.row().Scan(value))
+ return scope
+}
+
+func (scope *Scope) typeName() string {
+ typ := scope.IndirectValue().Type()
+
+ for typ.Kind() == reflect.Slice || typ.Kind() == reflect.Ptr {
+ typ = typ.Elem()
+ }
+
+ return typ.Name()
+}
+
+// trace print sql log
+func (scope *Scope) trace(t time.Time) {
+ if len(scope.SQL) > 0 {
+ scope.db.slog(scope.SQL, t, scope.SQLVars...)
+ }
+}
+
+func (scope *Scope) changeableField(field *Field) bool {
+ if selectAttrs := scope.SelectAttrs(); len(selectAttrs) > 0 {
+ for _, attr := range selectAttrs {
+ if field.Name == attr || field.DBName == attr {
+ return true
+ }
+ }
+ return false
+ }
+
+ for _, attr := range scope.OmitAttrs() {
+ if field.Name == attr || field.DBName == attr {
+ return false
+ }
+ }
+
+ return true
+}
+
+func (scope *Scope) related(value interface{}, foreignKeys ...string) *Scope {
+ toScope := scope.db.NewScope(value)
+ tx := scope.db.Set("gorm:association:source", scope.Value)
+
+ for _, foreignKey := range append(foreignKeys, toScope.typeName()+"Id", scope.typeName()+"Id") {
+ fromField, _ := scope.FieldByName(foreignKey)
+ toField, _ := toScope.FieldByName(foreignKey)
+
+ if fromField != nil {
+ if relationship := fromField.Relationship; relationship != nil {
+ if relationship.Kind == "many_to_many" {
+ joinTableHandler := relationship.JoinTableHandler
+ scope.Err(joinTableHandler.JoinWith(joinTableHandler, tx, scope.Value).Find(value).Error)
+ } else if relationship.Kind == "belongs_to" {
+ for idx, foreignKey := range relationship.ForeignDBNames {
+ if field, ok := scope.FieldByName(foreignKey); ok {
+ tx = tx.Where(fmt.Sprintf("%v = ?", scope.Quote(relationship.AssociationForeignDBNames[idx])), field.Field.Interface())
+ }
+ }
+ scope.Err(tx.Find(value).Error)
+ } else if relationship.Kind == "has_many" || relationship.Kind == "has_one" {
+ for idx, foreignKey := range relationship.ForeignDBNames {
+ if field, ok := scope.FieldByName(relationship.AssociationForeignDBNames[idx]); ok {
+ tx = tx.Where(fmt.Sprintf("%v = ?", scope.Quote(foreignKey)), field.Field.Interface())
+ }
+ }
+
+ if relationship.PolymorphicType != "" {
+ tx = tx.Where(fmt.Sprintf("%v = ?", scope.Quote(relationship.PolymorphicDBName)), relationship.PolymorphicValue)
+ }
+ scope.Err(tx.Find(value).Error)
+ }
+ } else {
+ sql := fmt.Sprintf("%v = ?", scope.Quote(toScope.PrimaryKey()))
+ scope.Err(tx.Where(sql, fromField.Field.Interface()).Find(value).Error)
+ }
+ return scope
+ } else if toField != nil {
+ sql := fmt.Sprintf("%v = ?", scope.Quote(toField.DBName))
+ scope.Err(tx.Where(sql, scope.PrimaryKeyValue()).Find(value).Error)
+ return scope
+ }
+ }
+
+ scope.Err(fmt.Errorf("invalid association %v", foreignKeys))
+ return scope
+}
+
+// getTableOptions return the table options string or an empty string if the table options does not exist
+func (scope *Scope) getTableOptions() string {
+ tableOptions, ok := scope.Get("gorm:table_options")
+ if !ok {
+ return ""
+ }
+ return " " + tableOptions.(string)
+}
+
+func (scope *Scope) createJoinTable(field *StructField) {
+ if relationship := field.Relationship; relationship != nil && relationship.JoinTableHandler != nil {
+ joinTableHandler := relationship.JoinTableHandler
+ joinTable := joinTableHandler.Table(scope.db)
+ if !scope.Dialect().HasTable(joinTable) {
+ toScope := &Scope{Value: reflect.New(field.Struct.Type).Interface()}
+
+ var sqlTypes, primaryKeys []string
+ for idx, fieldName := range relationship.ForeignFieldNames {
+ if field, ok := scope.FieldByName(fieldName); ok {
+ foreignKeyStruct := field.clone()
+ foreignKeyStruct.IsPrimaryKey = false
+ foreignKeyStruct.TagSettingsSet("IS_JOINTABLE_FOREIGNKEY", "true")
+ foreignKeyStruct.TagSettingsDelete("AUTO_INCREMENT")
+ sqlTypes = append(sqlTypes, scope.Quote(relationship.ForeignDBNames[idx])+" "+scope.Dialect().DataTypeOf(foreignKeyStruct))
+ primaryKeys = append(primaryKeys, scope.Quote(relationship.ForeignDBNames[idx]))
+ }
+ }
+
+ for idx, fieldName := range relationship.AssociationForeignFieldNames {
+ if field, ok := toScope.FieldByName(fieldName); ok {
+ foreignKeyStruct := field.clone()
+ foreignKeyStruct.IsPrimaryKey = false
+ foreignKeyStruct.TagSettingsSet("IS_JOINTABLE_FOREIGNKEY", "true")
+ foreignKeyStruct.TagSettingsDelete("AUTO_INCREMENT")
+ sqlTypes = append(sqlTypes, scope.Quote(relationship.AssociationForeignDBNames[idx])+" "+scope.Dialect().DataTypeOf(foreignKeyStruct))
+ primaryKeys = append(primaryKeys, scope.Quote(relationship.AssociationForeignDBNames[idx]))
+ }
+ }
+
+ scope.Err(scope.NewDB().Exec(fmt.Sprintf("CREATE TABLE %v (%v, PRIMARY KEY (%v))%s", scope.Quote(joinTable), strings.Join(sqlTypes, ","), strings.Join(primaryKeys, ","), scope.getTableOptions())).Error)
+ }
+ scope.NewDB().Table(joinTable).AutoMigrate(joinTableHandler)
+ }
+}
+
+func (scope *Scope) createTable() *Scope {
+ var tags []string
+ var primaryKeys []string
+ var primaryKeyInColumnType = false
+ for _, field := range scope.GetModelStruct().StructFields {
+ if field.IsNormal {
+ sqlTag := scope.Dialect().DataTypeOf(field)
+
+ // Check if the primary key constraint was specified as
+ // part of the column type. If so, we can only support
+ // one column as the primary key.
+ if strings.Contains(strings.ToLower(sqlTag), "primary key") {
+ primaryKeyInColumnType = true
+ }
+
+ tags = append(tags, scope.Quote(field.DBName)+" "+sqlTag)
+ }
+
+ if field.IsPrimaryKey {
+ primaryKeys = append(primaryKeys, scope.Quote(field.DBName))
+ }
+ scope.createJoinTable(field)
+ }
+
+ var primaryKeyStr string
+ if len(primaryKeys) > 0 && !primaryKeyInColumnType {
+ primaryKeyStr = fmt.Sprintf(", PRIMARY KEY (%v)", strings.Join(primaryKeys, ","))
+ }
+
+ scope.Raw(fmt.Sprintf("CREATE TABLE %v (%v %v)%s", scope.QuotedTableName(), strings.Join(tags, ","), primaryKeyStr, scope.getTableOptions())).Exec()
+
+ scope.autoIndex()
+ return scope
+}
+
+func (scope *Scope) dropTable() *Scope {
+ scope.Raw(fmt.Sprintf("DROP TABLE %v", scope.QuotedTableName())).Exec()
+ return scope
+}
+
+func (scope *Scope) modifyColumn(column string, typ string) {
+ scope.db.AddError(scope.Dialect().ModifyColumn(scope.QuotedTableName(), scope.Quote(column), typ))
+}
+
+func (scope *Scope) dropColumn(column string) {
+ scope.Raw(fmt.Sprintf("ALTER TABLE %v DROP COLUMN %v", scope.QuotedTableName(), scope.Quote(column))).Exec()
+}
+
+func (scope *Scope) addIndex(unique bool, indexName string, column ...string) {
+ if scope.Dialect().HasIndex(scope.TableName(), indexName) {
+ return
+ }
+
+ var columns []string
+ for _, name := range column {
+ columns = append(columns, scope.quoteIfPossible(name))
+ }
+
+ sqlCreate := "CREATE INDEX"
+ if unique {
+ sqlCreate = "CREATE UNIQUE INDEX"
+ }
+
+ scope.Raw(fmt.Sprintf("%s %v ON %v(%v) %v", sqlCreate, indexName, scope.QuotedTableName(), strings.Join(columns, ", "), scope.whereSQL())).Exec()
+}
+
+func (scope *Scope) addForeignKey(field string, dest string, onDelete string, onUpdate string) {
+ // Compatible with old generated key
+ keyName := scope.Dialect().BuildKeyName(scope.TableName(), field, dest, "foreign")
+
+ if scope.Dialect().HasForeignKey(scope.TableName(), keyName) {
+ return
+ }
+ var query = `ALTER TABLE %s ADD CONSTRAINT %s FOREIGN KEY (%s) REFERENCES %s ON DELETE %s ON UPDATE %s;`
+ scope.Raw(fmt.Sprintf(query, scope.QuotedTableName(), scope.quoteIfPossible(keyName), scope.quoteIfPossible(field), dest, onDelete, onUpdate)).Exec()
+}
+
+func (scope *Scope) removeForeignKey(field string, dest string) {
+ keyName := scope.Dialect().BuildKeyName(scope.TableName(), field, dest, "foreign")
+ if !scope.Dialect().HasForeignKey(scope.TableName(), keyName) {
+ return
+ }
+ var mysql mysql
+ var query string
+ if scope.Dialect().GetName() == mysql.GetName() {
+ query = `ALTER TABLE %s DROP FOREIGN KEY %s;`
+ } else {
+ query = `ALTER TABLE %s DROP CONSTRAINT %s;`
+ }
+
+ scope.Raw(fmt.Sprintf(query, scope.QuotedTableName(), scope.quoteIfPossible(keyName))).Exec()
+}
+
+func (scope *Scope) removeIndex(indexName string) {
+ scope.Dialect().RemoveIndex(scope.TableName(), indexName)
+}
+
+func (scope *Scope) autoMigrate() *Scope {
+ tableName := scope.TableName()
+ quotedTableName := scope.QuotedTableName()
+
+ if !scope.Dialect().HasTable(tableName) {
+ scope.createTable()
+ } else {
+ for _, field := range scope.GetModelStruct().StructFields {
+ if !scope.Dialect().HasColumn(tableName, field.DBName) {
+ if field.IsNormal {
+ sqlTag := scope.Dialect().DataTypeOf(field)
+ scope.Raw(fmt.Sprintf("ALTER TABLE %v ADD %v %v;", quotedTableName, scope.Quote(field.DBName), sqlTag)).Exec()
+ }
+ }
+ scope.createJoinTable(field)
+ }
+ scope.autoIndex()
+ }
+ return scope
+}
+
+func (scope *Scope) autoIndex() *Scope {
+ var indexes = map[string][]string{}
+ var uniqueIndexes = map[string][]string{}
+
+ for _, field := range scope.GetStructFields() {
+ if name, ok := field.TagSettingsGet("INDEX"); ok {
+ names := strings.Split(name, ",")
+
+ for _, name := range names {
+ if name == "INDEX" || name == "" {
+ name = scope.Dialect().BuildKeyName("idx", scope.TableName(), field.DBName)
+ }
+ name, column := scope.Dialect().NormalizeIndexAndColumn(name, field.DBName)
+ indexes[name] = append(indexes[name], column)
+ }
+ }
+
+ if name, ok := field.TagSettingsGet("UNIQUE_INDEX"); ok {
+ names := strings.Split(name, ",")
+
+ for _, name := range names {
+ if name == "UNIQUE_INDEX" || name == "" {
+ name = scope.Dialect().BuildKeyName("uix", scope.TableName(), field.DBName)
+ }
+ name, column := scope.Dialect().NormalizeIndexAndColumn(name, field.DBName)
+ uniqueIndexes[name] = append(uniqueIndexes[name], column)
+ }
+ }
+ }
+
+ for name, columns := range indexes {
+ if db := scope.NewDB().Table(scope.TableName()).Model(scope.Value).AddIndex(name, columns...); db.Error != nil {
+ scope.db.AddError(db.Error)
+ }
+ }
+
+ for name, columns := range uniqueIndexes {
+ if db := scope.NewDB().Table(scope.TableName()).Model(scope.Value).AddUniqueIndex(name, columns...); db.Error != nil {
+ scope.db.AddError(db.Error)
+ }
+ }
+
+ return scope
+}
+
+func (scope *Scope) getColumnAsArray(columns []string, values ...interface{}) (results [][]interface{}) {
+ resultMap := make(map[string][]interface{})
+ for _, value := range values {
+ indirectValue := indirect(reflect.ValueOf(value))
+
+ switch indirectValue.Kind() {
+ case reflect.Slice:
+ for i := 0; i < indirectValue.Len(); i++ {
+ var result []interface{}
+ var object = indirect(indirectValue.Index(i))
+ var hasValue = false
+ for _, column := range columns {
+ field := object.FieldByName(column)
+ if hasValue || !isBlank(field) {
+ hasValue = true
+ }
+ result = append(result, field.Interface())
+ }
+
+ if hasValue {
+ h := fmt.Sprint(result...)
+ if _, exist := resultMap[h]; !exist {
+ resultMap[h] = result
+ }
+ }
+ }
+ case reflect.Struct:
+ var result []interface{}
+ var hasValue = false
+ for _, column := range columns {
+ field := indirectValue.FieldByName(column)
+ if hasValue || !isBlank(field) {
+ hasValue = true
+ }
+ result = append(result, field.Interface())
+ }
+
+ if hasValue {
+ h := fmt.Sprint(result...)
+ if _, exist := resultMap[h]; !exist {
+ resultMap[h] = result
+ }
+ }
+ }
+ }
+ for _, v := range resultMap {
+ results = append(results, v)
+ }
+ return
+}
+
+func (scope *Scope) getColumnAsScope(column string) *Scope {
+ indirectScopeValue := scope.IndirectValue()
+
+ switch indirectScopeValue.Kind() {
+ case reflect.Slice:
+ if fieldStruct, ok := scope.GetModelStruct().ModelType.FieldByName(column); ok {
+ fieldType := fieldStruct.Type
+ if fieldType.Kind() == reflect.Slice || fieldType.Kind() == reflect.Ptr {
+ fieldType = fieldType.Elem()
+ }
+
+ resultsMap := map[interface{}]bool{}
+ results := reflect.New(reflect.SliceOf(reflect.PtrTo(fieldType))).Elem()
+
+ for i := 0; i < indirectScopeValue.Len(); i++ {
+ result := indirect(indirect(indirectScopeValue.Index(i)).FieldByName(column))
+
+ if result.Kind() == reflect.Slice {
+ for j := 0; j < result.Len(); j++ {
+ if elem := result.Index(j); elem.CanAddr() && resultsMap[elem.Addr()] != true {
+ resultsMap[elem.Addr()] = true
+ results = reflect.Append(results, elem.Addr())
+ }
+ }
+ } else if result.CanAddr() && resultsMap[result.Addr()] != true {
+ resultsMap[result.Addr()] = true
+ results = reflect.Append(results, result.Addr())
+ }
+ }
+ return scope.New(results.Interface())
+ }
+ case reflect.Struct:
+ if field := indirectScopeValue.FieldByName(column); field.CanAddr() {
+ return scope.New(field.Addr().Interface())
+ }
+ }
+ return nil
+}
+
+func (scope *Scope) hasConditions() bool {
+ return !scope.PrimaryKeyZero() ||
+ len(scope.Search.whereConditions) > 0 ||
+ len(scope.Search.orConditions) > 0 ||
+ len(scope.Search.notConditions) > 0
+}
diff --git a/vendor/github.com/jinzhu/gorm/search.go b/vendor/github.com/jinzhu/gorm/search.go
new file mode 100644
index 0000000000000000000000000000000000000000..9013859562ccfa6d51bc2ff45ff58df1d740d9ee
--- /dev/null
+++ b/vendor/github.com/jinzhu/gorm/search.go
@@ -0,0 +1,153 @@
+package gorm
+
+import (
+ "fmt"
+)
+
+type search struct {
+ db *DB
+ whereConditions []map[string]interface{}
+ orConditions []map[string]interface{}
+ notConditions []map[string]interface{}
+ havingConditions []map[string]interface{}
+ joinConditions []map[string]interface{}
+ initAttrs []interface{}
+ assignAttrs []interface{}
+ selects map[string]interface{}
+ omits []string
+ orders []interface{}
+ preload []searchPreload
+ offset interface{}
+ limit interface{}
+ group string
+ tableName string
+ raw bool
+ Unscoped bool
+ ignoreOrderQuery bool
+}
+
+type searchPreload struct {
+ schema string
+ conditions []interface{}
+}
+
+func (s *search) clone() *search {
+ clone := *s
+ return &clone
+}
+
+func (s *search) Where(query interface{}, values ...interface{}) *search {
+ s.whereConditions = append(s.whereConditions, map[string]interface{}{"query": query, "args": values})
+ return s
+}
+
+func (s *search) Not(query interface{}, values ...interface{}) *search {
+ s.notConditions = append(s.notConditions, map[string]interface{}{"query": query, "args": values})
+ return s
+}
+
+func (s *search) Or(query interface{}, values ...interface{}) *search {
+ s.orConditions = append(s.orConditions, map[string]interface{}{"query": query, "args": values})
+ return s
+}
+
+func (s *search) Attrs(attrs ...interface{}) *search {
+ s.initAttrs = append(s.initAttrs, toSearchableMap(attrs...))
+ return s
+}
+
+func (s *search) Assign(attrs ...interface{}) *search {
+ s.assignAttrs = append(s.assignAttrs, toSearchableMap(attrs...))
+ return s
+}
+
+func (s *search) Order(value interface{}, reorder ...bool) *search {
+ if len(reorder) > 0 && reorder[0] {
+ s.orders = []interface{}{}
+ }
+
+ if value != nil && value != "" {
+ s.orders = append(s.orders, value)
+ }
+ return s
+}
+
+func (s *search) Select(query interface{}, args ...interface{}) *search {
+ s.selects = map[string]interface{}{"query": query, "args": args}
+ return s
+}
+
+func (s *search) Omit(columns ...string) *search {
+ s.omits = columns
+ return s
+}
+
+func (s *search) Limit(limit interface{}) *search {
+ s.limit = limit
+ return s
+}
+
+func (s *search) Offset(offset interface{}) *search {
+ s.offset = offset
+ return s
+}
+
+func (s *search) Group(query string) *search {
+ s.group = s.getInterfaceAsSQL(query)
+ return s
+}
+
+func (s *search) Having(query interface{}, values ...interface{}) *search {
+ if val, ok := query.(*expr); ok {
+ s.havingConditions = append(s.havingConditions, map[string]interface{}{"query": val.expr, "args": val.args})
+ } else {
+ s.havingConditions = append(s.havingConditions, map[string]interface{}{"query": query, "args": values})
+ }
+ return s
+}
+
+func (s *search) Joins(query string, values ...interface{}) *search {
+ s.joinConditions = append(s.joinConditions, map[string]interface{}{"query": query, "args": values})
+ return s
+}
+
+func (s *search) Preload(schema string, values ...interface{}) *search {
+ var preloads []searchPreload
+ for _, preload := range s.preload {
+ if preload.schema != schema {
+ preloads = append(preloads, preload)
+ }
+ }
+ preloads = append(preloads, searchPreload{schema, values})
+ s.preload = preloads
+ return s
+}
+
+func (s *search) Raw(b bool) *search {
+ s.raw = b
+ return s
+}
+
+func (s *search) unscoped() *search {
+ s.Unscoped = true
+ return s
+}
+
+func (s *search) Table(name string) *search {
+ s.tableName = name
+ return s
+}
+
+func (s *search) getInterfaceAsSQL(value interface{}) (str string) {
+ switch value.(type) {
+ case string, int, int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64:
+ str = fmt.Sprintf("%v", value)
+ default:
+ s.db.AddError(ErrInvalidSQL)
+ }
+
+ if str == "-1" {
+ return ""
+ }
+ return
+}
diff --git a/vendor/github.com/jinzhu/gorm/test_all.sh b/vendor/github.com/jinzhu/gorm/test_all.sh
new file mode 100644
index 0000000000000000000000000000000000000000..5cfb3321a2dd9a74f4e7d71449db87ddb1e28ba2
--- /dev/null
+++ b/vendor/github.com/jinzhu/gorm/test_all.sh
@@ -0,0 +1,5 @@
+dialects=("postgres" "mysql" "mssql" "sqlite")
+
+for dialect in "${dialects[@]}" ; do
+ DEBUG=false GORM_DIALECT=${dialect} go test
+done
diff --git a/vendor/github.com/jinzhu/gorm/utils.go b/vendor/github.com/jinzhu/gorm/utils.go
new file mode 100644
index 0000000000000000000000000000000000000000..e58e57a56abd81ae17ea5dd86f68a8b278bc7c26
--- /dev/null
+++ b/vendor/github.com/jinzhu/gorm/utils.go
@@ -0,0 +1,226 @@
+package gorm
+
+import (
+ "database/sql/driver"
+ "fmt"
+ "reflect"
+ "regexp"
+ "runtime"
+ "strings"
+ "sync"
+ "time"
+)
+
+// NowFunc returns current time, this function is exported in order to be able
+// to give the flexibility to the developer to customize it according to their
+// needs, e.g:
+// gorm.NowFunc = func() time.Time {
+// return time.Now().UTC()
+// }
+var NowFunc = func() time.Time {
+ return time.Now()
+}
+
+// Copied from golint
+var commonInitialisms = []string{"API", "ASCII", "CPU", "CSS", "DNS", "EOF", "GUID", "HTML", "HTTP", "HTTPS", "ID", "IP", "JSON", "LHS", "QPS", "RAM", "RHS", "RPC", "SLA", "SMTP", "SSH", "TLS", "TTL", "UID", "UI", "UUID", "URI", "URL", "UTF8", "VM", "XML", "XSRF", "XSS"}
+var commonInitialismsReplacer *strings.Replacer
+
+var goSrcRegexp = regexp.MustCompile(`jinzhu/gorm(@.*)?/.*.go`)
+var goTestRegexp = regexp.MustCompile(`jinzhu/gorm(@.*)?/.*test.go`)
+
+func init() {
+ var commonInitialismsForReplacer []string
+ for _, initialism := range commonInitialisms {
+ commonInitialismsForReplacer = append(commonInitialismsForReplacer, initialism, strings.Title(strings.ToLower(initialism)))
+ }
+ commonInitialismsReplacer = strings.NewReplacer(commonInitialismsForReplacer...)
+}
+
+type safeMap struct {
+ m map[string]string
+ l *sync.RWMutex
+}
+
+func (s *safeMap) Set(key string, value string) {
+ s.l.Lock()
+ defer s.l.Unlock()
+ s.m[key] = value
+}
+
+func (s *safeMap) Get(key string) string {
+ s.l.RLock()
+ defer s.l.RUnlock()
+ return s.m[key]
+}
+
+func newSafeMap() *safeMap {
+ return &safeMap{l: new(sync.RWMutex), m: make(map[string]string)}
+}
+
+// SQL expression
+type expr struct {
+ expr string
+ args []interface{}
+}
+
+// Expr generate raw SQL expression, for example:
+// DB.Model(&product).Update("price", gorm.Expr("price * ? + ?", 2, 100))
+func Expr(expression string, args ...interface{}) *expr {
+ return &expr{expr: expression, args: args}
+}
+
+func indirect(reflectValue reflect.Value) reflect.Value {
+ for reflectValue.Kind() == reflect.Ptr {
+ reflectValue = reflectValue.Elem()
+ }
+ return reflectValue
+}
+
+func toQueryMarks(primaryValues [][]interface{}) string {
+ var results []string
+
+ for _, primaryValue := range primaryValues {
+ var marks []string
+ for range primaryValue {
+ marks = append(marks, "?")
+ }
+
+ if len(marks) > 1 {
+ results = append(results, fmt.Sprintf("(%v)", strings.Join(marks, ",")))
+ } else {
+ results = append(results, strings.Join(marks, ""))
+ }
+ }
+ return strings.Join(results, ",")
+}
+
+func toQueryCondition(scope *Scope, columns []string) string {
+ var newColumns []string
+ for _, column := range columns {
+ newColumns = append(newColumns, scope.Quote(column))
+ }
+
+ if len(columns) > 1 {
+ return fmt.Sprintf("(%v)", strings.Join(newColumns, ","))
+ }
+ return strings.Join(newColumns, ",")
+}
+
+func toQueryValues(values [][]interface{}) (results []interface{}) {
+ for _, value := range values {
+ for _, v := range value {
+ results = append(results, v)
+ }
+ }
+ return
+}
+
+func fileWithLineNum() string {
+ for i := 2; i < 15; i++ {
+ _, file, line, ok := runtime.Caller(i)
+ if ok && (!goSrcRegexp.MatchString(file) || goTestRegexp.MatchString(file)) {
+ return fmt.Sprintf("%v:%v", file, line)
+ }
+ }
+ return ""
+}
+
+func isBlank(value reflect.Value) bool {
+ switch value.Kind() {
+ case reflect.String:
+ return value.Len() == 0
+ case reflect.Bool:
+ return !value.Bool()
+ case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+ return value.Int() == 0
+ case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
+ return value.Uint() == 0
+ case reflect.Float32, reflect.Float64:
+ return value.Float() == 0
+ case reflect.Interface, reflect.Ptr:
+ return value.IsNil()
+ }
+
+ return reflect.DeepEqual(value.Interface(), reflect.Zero(value.Type()).Interface())
+}
+
+func toSearchableMap(attrs ...interface{}) (result interface{}) {
+ if len(attrs) > 1 {
+ if str, ok := attrs[0].(string); ok {
+ result = map[string]interface{}{str: attrs[1]}
+ }
+ } else if len(attrs) == 1 {
+ if attr, ok := attrs[0].(map[string]interface{}); ok {
+ result = attr
+ }
+
+ if attr, ok := attrs[0].(interface{}); ok {
+ result = attr
+ }
+ }
+ return
+}
+
+func equalAsString(a interface{}, b interface{}) bool {
+ return toString(a) == toString(b)
+}
+
+func toString(str interface{}) string {
+ if values, ok := str.([]interface{}); ok {
+ var results []string
+ for _, value := range values {
+ results = append(results, toString(value))
+ }
+ return strings.Join(results, "_")
+ } else if bytes, ok := str.([]byte); ok {
+ return string(bytes)
+ } else if reflectValue := reflect.Indirect(reflect.ValueOf(str)); reflectValue.IsValid() {
+ return fmt.Sprintf("%v", reflectValue.Interface())
+ }
+ return ""
+}
+
+func makeSlice(elemType reflect.Type) interface{} {
+ if elemType.Kind() == reflect.Slice {
+ elemType = elemType.Elem()
+ }
+ sliceType := reflect.SliceOf(elemType)
+ slice := reflect.New(sliceType)
+ slice.Elem().Set(reflect.MakeSlice(sliceType, 0, 0))
+ return slice.Interface()
+}
+
+func strInSlice(a string, list []string) bool {
+ for _, b := range list {
+ if b == a {
+ return true
+ }
+ }
+ return false
+}
+
+// getValueFromFields return given fields's value
+func getValueFromFields(value reflect.Value, fieldNames []string) (results []interface{}) {
+ // If value is a nil pointer, Indirect returns a zero Value!
+ // Therefor we need to check for a zero value,
+ // as FieldByName could panic
+ if indirectValue := reflect.Indirect(value); indirectValue.IsValid() {
+ for _, fieldName := range fieldNames {
+ if fieldValue := reflect.Indirect(indirectValue.FieldByName(fieldName)); fieldValue.IsValid() {
+ result := fieldValue.Interface()
+ if r, ok := result.(driver.Valuer); ok {
+ result, _ = r.Value()
+ }
+ results = append(results, result)
+ }
+ }
+ }
+ return
+}
+
+func addExtraSpaceIfExist(str string) string {
+ if str != "" {
+ return " " + str
+ }
+ return ""
+}
diff --git a/vendor/github.com/jinzhu/gorm/wercker.yml b/vendor/github.com/jinzhu/gorm/wercker.yml
new file mode 100644
index 0000000000000000000000000000000000000000..c74fa4d4b944f3d4276e5c53cf00cc4b7457d1db
--- /dev/null
+++ b/vendor/github.com/jinzhu/gorm/wercker.yml
@@ -0,0 +1,154 @@
+# use the default golang container from Docker Hub
+box: golang
+
+services:
+ - name: mariadb
+ id: mariadb:latest
+ env:
+ MYSQL_DATABASE: gorm
+ MYSQL_USER: gorm
+ MYSQL_PASSWORD: gorm
+ MYSQL_RANDOM_ROOT_PASSWORD: "yes"
+ - name: mysql
+ id: mysql:latest
+ env:
+ MYSQL_DATABASE: gorm
+ MYSQL_USER: gorm
+ MYSQL_PASSWORD: gorm
+ MYSQL_RANDOM_ROOT_PASSWORD: "yes"
+ - name: mysql57
+ id: mysql:5.7
+ env:
+ MYSQL_DATABASE: gorm
+ MYSQL_USER: gorm
+ MYSQL_PASSWORD: gorm
+ MYSQL_RANDOM_ROOT_PASSWORD: "yes"
+ - name: mysql56
+ id: mysql:5.6
+ env:
+ MYSQL_DATABASE: gorm
+ MYSQL_USER: gorm
+ MYSQL_PASSWORD: gorm
+ MYSQL_RANDOM_ROOT_PASSWORD: "yes"
+ - name: postgres
+ id: postgres:latest
+ env:
+ POSTGRES_USER: gorm
+ POSTGRES_PASSWORD: gorm
+ POSTGRES_DB: gorm
+ - name: postgres96
+ id: postgres:9.6
+ env:
+ POSTGRES_USER: gorm
+ POSTGRES_PASSWORD: gorm
+ POSTGRES_DB: gorm
+ - name: postgres95
+ id: postgres:9.5
+ env:
+ POSTGRES_USER: gorm
+ POSTGRES_PASSWORD: gorm
+ POSTGRES_DB: gorm
+ - name: postgres94
+ id: postgres:9.4
+ env:
+ POSTGRES_USER: gorm
+ POSTGRES_PASSWORD: gorm
+ POSTGRES_DB: gorm
+ - name: postgres93
+ id: postgres:9.3
+ env:
+ POSTGRES_USER: gorm
+ POSTGRES_PASSWORD: gorm
+ POSTGRES_DB: gorm
+ - name: mssql
+ id: mcmoe/mssqldocker:latest
+ env:
+ ACCEPT_EULA: Y
+ SA_PASSWORD: LoremIpsum86
+ MSSQL_DB: gorm
+ MSSQL_USER: gorm
+ MSSQL_PASSWORD: LoremIpsum86
+
+# The steps that will be executed in the build pipeline
+build:
+ # The steps that will be executed on build
+ steps:
+ # Sets the go workspace and places you package
+ # at the right place in the workspace tree
+ - setup-go-workspace
+
+ # Gets the dependencies
+ - script:
+ name: go get
+ code: |
+ cd $WERCKER_SOURCE_DIR
+ go version
+ go get -t -v ./...
+
+ # Build the project
+ - script:
+ name: go build
+ code: |
+ go build ./...
+
+ # Test the project
+ - script:
+ name: test sqlite
+ code: |
+ go test -race -v ./...
+
+ - script:
+ name: test mariadb
+ code: |
+ GORM_DIALECT=mysql GORM_DSN="gorm:gorm@tcp(mariadb:3306)/gorm?charset=utf8&parseTime=True" go test -race ./...
+
+ - script:
+ name: test mysql
+ code: |
+ GORM_DIALECT=mysql GORM_DSN="gorm:gorm@tcp(mysql:3306)/gorm?charset=utf8&parseTime=True" go test -race ./...
+
+ - script:
+ name: test mysql5.7
+ code: |
+ GORM_DIALECT=mysql GORM_DSN="gorm:gorm@tcp(mysql57:3306)/gorm?charset=utf8&parseTime=True" go test -race ./...
+
+ - script:
+ name: test mysql5.6
+ code: |
+ GORM_DIALECT=mysql GORM_DSN="gorm:gorm@tcp(mysql56:3306)/gorm?charset=utf8&parseTime=True" go test -race ./...
+
+ - script:
+ name: test postgres
+ code: |
+ GORM_DIALECT=postgres GORM_DSN="host=postgres user=gorm password=gorm DB.name=gorm port=5432 sslmode=disable" go test -race ./...
+
+ - script:
+ name: test postgres96
+ code: |
+ GORM_DIALECT=postgres GORM_DSN="host=postgres96 user=gorm password=gorm DB.name=gorm port=5432 sslmode=disable" go test -race ./...
+
+ - script:
+ name: test postgres95
+ code: |
+ GORM_DIALECT=postgres GORM_DSN="host=postgres95 user=gorm password=gorm DB.name=gorm port=5432 sslmode=disable" go test -race ./...
+
+ - script:
+ name: test postgres94
+ code: |
+ GORM_DIALECT=postgres GORM_DSN="host=postgres94 user=gorm password=gorm DB.name=gorm port=5432 sslmode=disable" go test -race ./...
+
+ - script:
+ name: test postgres93
+ code: |
+ GORM_DIALECT=postgres GORM_DSN="host=postgres93 user=gorm password=gorm DB.name=gorm port=5432 sslmode=disable" go test -race ./...
+
+ - script:
+ name: test mssql
+ code: |
+ GORM_DIALECT=mssql GORM_DSN="sqlserver://gorm:LoremIpsum86@mssql:1433?database=gorm" go test -race ./...
+
+ - script:
+ name: codecov
+ code: |
+ go test -race -coverprofile=coverage.txt -covermode=atomic ./...
+ bash <(curl -s https://codecov.io/bash)
diff --git a/vendor/github.com/jinzhu/inflection/LICENSE b/vendor/github.com/jinzhu/inflection/LICENSE
new file mode 100644
index 0000000000000000000000000000000000000000..a1ca9a0ff9fe4a2bf4bdca7a799ae5e292fb4cd6
--- /dev/null
+++ b/vendor/github.com/jinzhu/inflection/LICENSE
@@ -0,0 +1,21 @@
+The MIT License (MIT)
+
+Copyright (c) 2015 - Jinzhu
+
+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.
diff --git a/vendor/github.com/jinzhu/inflection/README.md b/vendor/github.com/jinzhu/inflection/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..a3de33614c9dde291cd4209109a4e9dfb40e317d
--- /dev/null
+++ b/vendor/github.com/jinzhu/inflection/README.md
@@ -0,0 +1,55 @@
+# Inflection
+
+Inflection pluralizes and singularizes English nouns
+
+[](https://app.wercker.com/project/byKey/f8c7432b097d1f4ce636879670be0930)
+
+## Basic Usage
+
+```go
+inflection.Plural("person") => "people"
+inflection.Plural("Person") => "People"
+inflection.Plural("PERSON") => "PEOPLE"
+inflection.Plural("bus") => "buses"
+inflection.Plural("BUS") => "BUSES"
+inflection.Plural("Bus") => "Buses"
+
+inflection.Singular("people") => "person"
+inflection.Singular("People") => "Person"
+inflection.Singular("PEOPLE") => "PERSON"
+inflection.Singular("buses") => "bus"
+inflection.Singular("BUSES") => "BUS"
+inflection.Singular("Buses") => "Bus"
+
+inflection.Plural("FancyPerson") => "FancyPeople"
+inflection.Singular("FancyPeople") => "FancyPerson"
+```
+
+## Register Rules
+
+Standard rules are from Rails's ActiveSupport (https://github.com/rails/rails/blob/master/activesupport/lib/active_support/inflections.rb)
+
+If you want to register more rules, follow:
+
+```
+inflection.AddUncountable("fish")
+inflection.AddIrregular("person", "people")
+inflection.AddPlural("(bu)s$", "${1}ses") # "bus" => "buses" / "BUS" => "BUSES" / "Bus" => "Buses"
+inflection.AddSingular("(bus)(es)?$", "${1}") # "buses" => "bus" / "Buses" => "Bus" / "BUSES" => "BUS"
+```
+
+## Contributing
+
+You can help to make the project better, check out [http://gorm.io/contribute.html](http://gorm.io/contribute.html) for things you can do.
+
+## Author
+
+**jinzhu**
+
+*
+*
+*
+
+## License
+
+Released under the [MIT License](http://www.opensource.org/licenses/MIT).
diff --git a/vendor/github.com/jinzhu/inflection/go.mod b/vendor/github.com/jinzhu/inflection/go.mod
new file mode 100644
index 0000000000000000000000000000000000000000..2fb7690451e7f1fd9ed0d441dfc9374c5bed4e82
--- /dev/null
+++ b/vendor/github.com/jinzhu/inflection/go.mod
@@ -0,0 +1 @@
+module github.com/jinzhu/inflection
diff --git a/vendor/github.com/jinzhu/inflection/inflections.go b/vendor/github.com/jinzhu/inflection/inflections.go
new file mode 100644
index 0000000000000000000000000000000000000000..606263bb750765a2a60c9b73e65d0f28b26ec594
--- /dev/null
+++ b/vendor/github.com/jinzhu/inflection/inflections.go
@@ -0,0 +1,273 @@
+/*
+Package inflection pluralizes and singularizes English nouns.
+
+ inflection.Plural("person") => "people"
+ inflection.Plural("Person") => "People"
+ inflection.Plural("PERSON") => "PEOPLE"
+
+ inflection.Singular("people") => "person"
+ inflection.Singular("People") => "Person"
+ inflection.Singular("PEOPLE") => "PERSON"
+
+ inflection.Plural("FancyPerson") => "FancydPeople"
+ inflection.Singular("FancyPeople") => "FancydPerson"
+
+Standard rules are from Rails's ActiveSupport (https://github.com/rails/rails/blob/master/activesupport/lib/active_support/inflections.rb)
+
+If you want to register more rules, follow:
+
+ inflection.AddUncountable("fish")
+ inflection.AddIrregular("person", "people")
+ inflection.AddPlural("(bu)s$", "${1}ses") # "bus" => "buses" / "BUS" => "BUSES" / "Bus" => "Buses"
+ inflection.AddSingular("(bus)(es)?$", "${1}") # "buses" => "bus" / "Buses" => "Bus" / "BUSES" => "BUS"
+*/
+package inflection
+
+import (
+ "regexp"
+ "strings"
+)
+
+type inflection struct {
+ regexp *regexp.Regexp
+ replace string
+}
+
+// Regular is a regexp find replace inflection
+type Regular struct {
+ find string
+ replace string
+}
+
+// Irregular is a hard replace inflection,
+// containing both singular and plural forms
+type Irregular struct {
+ singular string
+ plural string
+}
+
+// RegularSlice is a slice of Regular inflections
+type RegularSlice []Regular
+
+// IrregularSlice is a slice of Irregular inflections
+type IrregularSlice []Irregular
+
+var pluralInflections = RegularSlice{
+ {"([a-z])$", "${1}s"},
+ {"s$", "s"},
+ {"^(ax|test)is$", "${1}es"},
+ {"(octop|vir)us$", "${1}i"},
+ {"(octop|vir)i$", "${1}i"},
+ {"(alias|status)$", "${1}es"},
+ {"(bu)s$", "${1}ses"},
+ {"(buffal|tomat)o$", "${1}oes"},
+ {"([ti])um$", "${1}a"},
+ {"([ti])a$", "${1}a"},
+ {"sis$", "ses"},
+ {"(?:([^f])fe|([lr])f)$", "${1}${2}ves"},
+ {"(hive)$", "${1}s"},
+ {"([^aeiouy]|qu)y$", "${1}ies"},
+ {"(x|ch|ss|sh)$", "${1}es"},
+ {"(matr|vert|ind)(?:ix|ex)$", "${1}ices"},
+ {"^(m|l)ouse$", "${1}ice"},
+ {"^(m|l)ice$", "${1}ice"},
+ {"^(ox)$", "${1}en"},
+ {"^(oxen)$", "${1}"},
+ {"(quiz)$", "${1}zes"},
+}
+
+var singularInflections = RegularSlice{
+ {"s$", ""},
+ {"(ss)$", "${1}"},
+ {"(n)ews$", "${1}ews"},
+ {"([ti])a$", "${1}um"},
+ {"((a)naly|(b)a|(d)iagno|(p)arenthe|(p)rogno|(s)ynop|(t)he)(sis|ses)$", "${1}sis"},
+ {"(^analy)(sis|ses)$", "${1}sis"},
+ {"([^f])ves$", "${1}fe"},
+ {"(hive)s$", "${1}"},
+ {"(tive)s$", "${1}"},
+ {"([lr])ves$", "${1}f"},
+ {"([^aeiouy]|qu)ies$", "${1}y"},
+ {"(s)eries$", "${1}eries"},
+ {"(m)ovies$", "${1}ovie"},
+ {"(c)ookies$", "${1}ookie"},
+ {"(x|ch|ss|sh)es$", "${1}"},
+ {"^(m|l)ice$", "${1}ouse"},
+ {"(bus)(es)?$", "${1}"},
+ {"(o)es$", "${1}"},
+ {"(shoe)s$", "${1}"},
+ {"(cris|test)(is|es)$", "${1}is"},
+ {"^(a)x[ie]s$", "${1}xis"},
+ {"(octop|vir)(us|i)$", "${1}us"},
+ {"(alias|status)(es)?$", "${1}"},
+ {"^(ox)en", "${1}"},
+ {"(vert|ind)ices$", "${1}ex"},
+ {"(matr)ices$", "${1}ix"},
+ {"(quiz)zes$", "${1}"},
+ {"(database)s$", "${1}"},
+}
+
+var irregularInflections = IrregularSlice{
+ {"person", "people"},
+ {"man", "men"},
+ {"child", "children"},
+ {"sex", "sexes"},
+ {"move", "moves"},
+ {"mombie", "mombies"},
+}
+
+var uncountableInflections = []string{"equipment", "information", "rice", "money", "species", "series", "fish", "sheep", "jeans", "police"}
+
+var compiledPluralMaps []inflection
+var compiledSingularMaps []inflection
+
+func compile() {
+ compiledPluralMaps = []inflection{}
+ compiledSingularMaps = []inflection{}
+ for _, uncountable := range uncountableInflections {
+ inf := inflection{
+ regexp: regexp.MustCompile("^(?i)(" + uncountable + ")$"),
+ replace: "${1}",
+ }
+ compiledPluralMaps = append(compiledPluralMaps, inf)
+ compiledSingularMaps = append(compiledSingularMaps, inf)
+ }
+
+ for _, value := range irregularInflections {
+ infs := []inflection{
+ inflection{regexp: regexp.MustCompile(strings.ToUpper(value.singular) + "$"), replace: strings.ToUpper(value.plural)},
+ inflection{regexp: regexp.MustCompile(strings.Title(value.singular) + "$"), replace: strings.Title(value.plural)},
+ inflection{regexp: regexp.MustCompile(value.singular + "$"), replace: value.plural},
+ }
+ compiledPluralMaps = append(compiledPluralMaps, infs...)
+ }
+
+ for _, value := range irregularInflections {
+ infs := []inflection{
+ inflection{regexp: regexp.MustCompile(strings.ToUpper(value.plural) + "$"), replace: strings.ToUpper(value.singular)},
+ inflection{regexp: regexp.MustCompile(strings.Title(value.plural) + "$"), replace: strings.Title(value.singular)},
+ inflection{regexp: regexp.MustCompile(value.plural + "$"), replace: value.singular},
+ }
+ compiledSingularMaps = append(compiledSingularMaps, infs...)
+ }
+
+ for i := len(pluralInflections) - 1; i >= 0; i-- {
+ value := pluralInflections[i]
+ infs := []inflection{
+ inflection{regexp: regexp.MustCompile(strings.ToUpper(value.find)), replace: strings.ToUpper(value.replace)},
+ inflection{regexp: regexp.MustCompile(value.find), replace: value.replace},
+ inflection{regexp: regexp.MustCompile("(?i)" + value.find), replace: value.replace},
+ }
+ compiledPluralMaps = append(compiledPluralMaps, infs...)
+ }
+
+ for i := len(singularInflections) - 1; i >= 0; i-- {
+ value := singularInflections[i]
+ infs := []inflection{
+ inflection{regexp: regexp.MustCompile(strings.ToUpper(value.find)), replace: strings.ToUpper(value.replace)},
+ inflection{regexp: regexp.MustCompile(value.find), replace: value.replace},
+ inflection{regexp: regexp.MustCompile("(?i)" + value.find), replace: value.replace},
+ }
+ compiledSingularMaps = append(compiledSingularMaps, infs...)
+ }
+}
+
+func init() {
+ compile()
+}
+
+// AddPlural adds a plural inflection
+func AddPlural(find, replace string) {
+ pluralInflections = append(pluralInflections, Regular{find, replace})
+ compile()
+}
+
+// AddSingular adds a singular inflection
+func AddSingular(find, replace string) {
+ singularInflections = append(singularInflections, Regular{find, replace})
+ compile()
+}
+
+// AddIrregular adds an irregular inflection
+func AddIrregular(singular, plural string) {
+ irregularInflections = append(irregularInflections, Irregular{singular, plural})
+ compile()
+}
+
+// AddUncountable adds an uncountable inflection
+func AddUncountable(values ...string) {
+ uncountableInflections = append(uncountableInflections, values...)
+ compile()
+}
+
+// GetPlural retrieves the plural inflection values
+func GetPlural() RegularSlice {
+ plurals := make(RegularSlice, len(pluralInflections))
+ copy(plurals, pluralInflections)
+ return plurals
+}
+
+// GetSingular retrieves the singular inflection values
+func GetSingular() RegularSlice {
+ singulars := make(RegularSlice, len(singularInflections))
+ copy(singulars, singularInflections)
+ return singulars
+}
+
+// GetIrregular retrieves the irregular inflection values
+func GetIrregular() IrregularSlice {
+ irregular := make(IrregularSlice, len(irregularInflections))
+ copy(irregular, irregularInflections)
+ return irregular
+}
+
+// GetUncountable retrieves the uncountable inflection values
+func GetUncountable() []string {
+ uncountables := make([]string, len(uncountableInflections))
+ copy(uncountables, uncountableInflections)
+ return uncountables
+}
+
+// SetPlural sets the plural inflections slice
+func SetPlural(inflections RegularSlice) {
+ pluralInflections = inflections
+ compile()
+}
+
+// SetSingular sets the singular inflections slice
+func SetSingular(inflections RegularSlice) {
+ singularInflections = inflections
+ compile()
+}
+
+// SetIrregular sets the irregular inflections slice
+func SetIrregular(inflections IrregularSlice) {
+ irregularInflections = inflections
+ compile()
+}
+
+// SetUncountable sets the uncountable inflections slice
+func SetUncountable(inflections []string) {
+ uncountableInflections = inflections
+ compile()
+}
+
+// Plural converts a word to its plural form
+func Plural(str string) string {
+ for _, inflection := range compiledPluralMaps {
+ if inflection.regexp.MatchString(str) {
+ return inflection.regexp.ReplaceAllString(str, inflection.replace)
+ }
+ }
+ return str
+}
+
+// Singular converts a word to its singular form
+func Singular(str string) string {
+ for _, inflection := range compiledSingularMaps {
+ if inflection.regexp.MatchString(str) {
+ return inflection.regexp.ReplaceAllString(str, inflection.replace)
+ }
+ }
+ return str
+}
diff --git a/vendor/github.com/jinzhu/inflection/wercker.yml b/vendor/github.com/jinzhu/inflection/wercker.yml
new file mode 100644
index 0000000000000000000000000000000000000000..5e6ce981dc3848be7645b488d74ae56c20f9b00d
--- /dev/null
+++ b/vendor/github.com/jinzhu/inflection/wercker.yml
@@ -0,0 +1,23 @@
+box: golang
+
+build:
+ steps:
+ - setup-go-workspace
+
+ # Gets the dependencies
+ - script:
+ name: go get
+ code: |
+ go get
+
+ # Build the project
+ - script:
+ name: go build
+ code: |
+ go build ./...
+
+ # Test the project
+ - script:
+ name: go test
+ code: |
+ go test ./...
diff --git a/vendor/github.com/spf13/pflag/.gitignore b/vendor/github.com/spf13/pflag/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..c3da2901346320a27a84f176e9bd3248a3e21438
--- /dev/null
+++ b/vendor/github.com/spf13/pflag/.gitignore
@@ -0,0 +1,2 @@
+.idea/*
+
diff --git a/vendor/github.com/spf13/pflag/.travis.yml b/vendor/github.com/spf13/pflag/.travis.yml
new file mode 100644
index 0000000000000000000000000000000000000000..00d04cb9b0269f0cdb33338de23a7b893c732a1e
--- /dev/null
+++ b/vendor/github.com/spf13/pflag/.travis.yml
@@ -0,0 +1,22 @@
+sudo: false
+
+language: go
+
+go:
+ - 1.9.x
+ - 1.10.x
+ - 1.11.x
+ - tip
+
+matrix:
+ allow_failures:
+ - go: tip
+
+install:
+ - go get golang.org/x/lint/golint
+ - export PATH=$GOPATH/bin:$PATH
+ - go install ./...
+
+script:
+ - verify/all.sh -v
+ - go test ./...
diff --git a/vendor/github.com/spf13/pflag/LICENSE b/vendor/github.com/spf13/pflag/LICENSE
new file mode 100644
index 0000000000000000000000000000000000000000..63ed1cfea1fb28c2051b00a3ae05a0b2cae7ce6a
--- /dev/null
+++ b/vendor/github.com/spf13/pflag/LICENSE
@@ -0,0 +1,28 @@
+Copyright (c) 2012 Alex Ogier. All rights reserved.
+Copyright (c) 2012 The Go Authors. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+ * Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above
+copyright notice, this list of conditions and the following disclaimer
+in the documentation and/or other materials provided with the
+distribution.
+ * Neither the name of Google Inc. nor the names of its
+contributors may be used to endorse or promote products derived from
+this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/vendor/github.com/spf13/pflag/README.md b/vendor/github.com/spf13/pflag/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..7eacc5bdbe5f41e155155e16b0aee6c447df7b57
--- /dev/null
+++ b/vendor/github.com/spf13/pflag/README.md
@@ -0,0 +1,296 @@
+[](https://travis-ci.org/spf13/pflag)
+[](https://goreportcard.com/report/github.com/spf13/pflag)
+[](https://godoc.org/github.com/spf13/pflag)
+
+## Description
+
+pflag is a drop-in replacement for Go's flag package, implementing
+POSIX/GNU-style --flags.
+
+pflag is compatible with the [GNU extensions to the POSIX recommendations
+for command-line options][1]. For a more precise description, see the
+"Command-line flag syntax" section below.
+
+[1]: http://www.gnu.org/software/libc/manual/html_node/Argument-Syntax.html
+
+pflag is available under the same style of BSD license as the Go language,
+which can be found in the LICENSE file.
+
+## Installation
+
+pflag is available using the standard `go get` command.
+
+Install by running:
+
+ go get github.com/spf13/pflag
+
+Run tests by running:
+
+ go test github.com/spf13/pflag
+
+## Usage
+
+pflag is a drop-in replacement of Go's native flag package. If you import
+pflag under the name "flag" then all code should continue to function
+with no changes.
+
+``` go
+import flag "github.com/spf13/pflag"
+```
+
+There is one exception to this: if you directly instantiate the Flag struct
+there is one more field "Shorthand" that you will need to set.
+Most code never instantiates this struct directly, and instead uses
+functions such as String(), BoolVar(), and Var(), and is therefore
+unaffected.
+
+Define flags using flag.String(), Bool(), Int(), etc.
+
+This declares an integer flag, -flagname, stored in the pointer ip, with type *int.
+
+``` go
+var ip *int = flag.Int("flagname", 1234, "help message for flagname")
+```
+
+If you like, you can bind the flag to a variable using the Var() functions.
+
+``` go
+var flagvar int
+func init() {
+ flag.IntVar(&flagvar, "flagname", 1234, "help message for flagname")
+}
+```
+
+Or you can create custom flags that satisfy the Value interface (with
+pointer receivers) and couple them to flag parsing by
+
+``` go
+flag.Var(&flagVal, "name", "help message for flagname")
+```
+
+For such flags, the default value is just the initial value of the variable.
+
+After all flags are defined, call
+
+``` go
+flag.Parse()
+```
+
+to parse the command line into the defined flags.
+
+Flags may then be used directly. If you're using the flags themselves,
+they are all pointers; if you bind to variables, they're values.
+
+``` go
+fmt.Println("ip has value ", *ip)
+fmt.Println("flagvar has value ", flagvar)
+```
+
+There are helper functions available to get the value stored in a Flag if you have a FlagSet but find
+it difficult to keep up with all of the pointers in your code.
+If you have a pflag.FlagSet with a flag called 'flagname' of type int you
+can use GetInt() to get the int value. But notice that 'flagname' must exist
+and it must be an int. GetString("flagname") will fail.
+
+``` go
+i, err := flagset.GetInt("flagname")
+```
+
+After parsing, the arguments after the flag are available as the
+slice flag.Args() or individually as flag.Arg(i).
+The arguments are indexed from 0 through flag.NArg()-1.
+
+The pflag package also defines some new functions that are not in flag,
+that give one-letter shorthands for flags. You can use these by appending
+'P' to the name of any function that defines a flag.
+
+``` go
+var ip = flag.IntP("flagname", "f", 1234, "help message")
+var flagvar bool
+func init() {
+ flag.BoolVarP(&flagvar, "boolname", "b", true, "help message")
+}
+flag.VarP(&flagVal, "varname", "v", "help message")
+```
+
+Shorthand letters can be used with single dashes on the command line.
+Boolean shorthand flags can be combined with other shorthand flags.
+
+The default set of command-line flags is controlled by
+top-level functions. The FlagSet type allows one to define
+independent sets of flags, such as to implement subcommands
+in a command-line interface. The methods of FlagSet are
+analogous to the top-level functions for the command-line
+flag set.
+
+## Setting no option default values for flags
+
+After you create a flag it is possible to set the pflag.NoOptDefVal for
+the given flag. Doing this changes the meaning of the flag slightly. If
+a flag has a NoOptDefVal and the flag is set on the command line without
+an option the flag will be set to the NoOptDefVal. For example given:
+
+``` go
+var ip = flag.IntP("flagname", "f", 1234, "help message")
+flag.Lookup("flagname").NoOptDefVal = "4321"
+```
+
+Would result in something like
+
+| Parsed Arguments | Resulting Value |
+| ------------- | ------------- |
+| --flagname=1357 | ip=1357 |
+| --flagname | ip=4321 |
+| [nothing] | ip=1234 |
+
+## Command line flag syntax
+
+```
+--flag // boolean flags, or flags with no option default values
+--flag x // only on flags without a default value
+--flag=x
+```
+
+Unlike the flag package, a single dash before an option means something
+different than a double dash. Single dashes signify a series of shorthand
+letters for flags. All but the last shorthand letter must be boolean flags
+or a flag with a default value
+
+```
+// boolean or flags where the 'no option default value' is set
+-f
+-f=true
+-abc
+but
+-b true is INVALID
+
+// non-boolean and flags without a 'no option default value'
+-n 1234
+-n=1234
+-n1234
+
+// mixed
+-abcs "hello"
+-absd="hello"
+-abcs1234
+```
+
+Flag parsing stops after the terminator "--". Unlike the flag package,
+flags can be interspersed with arguments anywhere on the command line
+before this terminator.
+
+Integer flags accept 1234, 0664, 0x1234 and may be negative.
+Boolean flags (in their long form) accept 1, 0, t, f, true, false,
+TRUE, FALSE, True, False.
+Duration flags accept any input valid for time.ParseDuration.
+
+## Mutating or "Normalizing" Flag names
+
+It is possible to set a custom flag name 'normalization function.' It allows flag names to be mutated both when created in the code and when used on the command line to some 'normalized' form. The 'normalized' form is used for comparison. Two examples of using the custom normalization func follow.
+
+**Example #1**: You want -, _, and . in flags to compare the same. aka --my-flag == --my_flag == --my.flag
+
+``` go
+func wordSepNormalizeFunc(f *pflag.FlagSet, name string) pflag.NormalizedName {
+ from := []string{"-", "_"}
+ to := "."
+ for _, sep := range from {
+ name = strings.Replace(name, sep, to, -1)
+ }
+ return pflag.NormalizedName(name)
+}
+
+myFlagSet.SetNormalizeFunc(wordSepNormalizeFunc)
+```
+
+**Example #2**: You want to alias two flags. aka --old-flag-name == --new-flag-name
+
+``` go
+func aliasNormalizeFunc(f *pflag.FlagSet, name string) pflag.NormalizedName {
+ switch name {
+ case "old-flag-name":
+ name = "new-flag-name"
+ break
+ }
+ return pflag.NormalizedName(name)
+}
+
+myFlagSet.SetNormalizeFunc(aliasNormalizeFunc)
+```
+
+## Deprecating a flag or its shorthand
+It is possible to deprecate a flag, or just its shorthand. Deprecating a flag/shorthand hides it from help text and prints a usage message when the deprecated flag/shorthand is used.
+
+**Example #1**: You want to deprecate a flag named "badflag" as well as inform the users what flag they should use instead.
+```go
+// deprecate a flag by specifying its name and a usage message
+flags.MarkDeprecated("badflag", "please use --good-flag instead")
+```
+This hides "badflag" from help text, and prints `Flag --badflag has been deprecated, please use --good-flag instead` when "badflag" is used.
+
+**Example #2**: You want to keep a flag name "noshorthandflag" but deprecate its shortname "n".
+```go
+// deprecate a flag shorthand by specifying its flag name and a usage message
+flags.MarkShorthandDeprecated("noshorthandflag", "please use --noshorthandflag only")
+```
+This hides the shortname "n" from help text, and prints `Flag shorthand -n has been deprecated, please use --noshorthandflag only` when the shorthand "n" is used.
+
+Note that usage message is essential here, and it should not be empty.
+
+## Hidden flags
+It is possible to mark a flag as hidden, meaning it will still function as normal, however will not show up in usage/help text.
+
+**Example**: You have a flag named "secretFlag" that you need for internal use only and don't want it showing up in help text, or for its usage text to be available.
+```go
+// hide a flag by specifying its name
+flags.MarkHidden("secretFlag")
+```
+
+## Disable sorting of flags
+`pflag` allows you to disable sorting of flags for help and usage message.
+
+**Example**:
+```go
+flags.BoolP("verbose", "v", false, "verbose output")
+flags.String("coolflag", "yeaah", "it's really cool flag")
+flags.Int("usefulflag", 777, "sometimes it's very useful")
+flags.SortFlags = false
+flags.PrintDefaults()
+```
+**Output**:
+```
+ -v, --verbose verbose output
+ --coolflag string it's really cool flag (default "yeaah")
+ --usefulflag int sometimes it's very useful (default 777)
+```
+
+
+## Supporting Go flags when using pflag
+In order to support flags defined using Go's `flag` package, they must be added to the `pflag` flagset. This is usually necessary
+to support flags defined by third-party dependencies (e.g. `golang/glog`).
+
+**Example**: You want to add the Go flags to the `CommandLine` flagset
+```go
+import (
+ goflag "flag"
+ flag "github.com/spf13/pflag"
+)
+
+var ip *int = flag.Int("flagname", 1234, "help message for flagname")
+
+func main() {
+ flag.CommandLine.AddGoFlagSet(goflag.CommandLine)
+ flag.Parse()
+}
+```
+
+## More info
+
+You can see the full reference documentation of the pflag package
+[at godoc.org][3], or through go's standard documentation system by
+running `godoc -http=:6060` and browsing to
+[http://localhost:6060/pkg/github.com/spf13/pflag][2] after
+installation.
+
+[2]: http://localhost:6060/pkg/github.com/spf13/pflag
+[3]: http://godoc.org/github.com/spf13/pflag
diff --git a/vendor/github.com/spf13/pflag/bool.go b/vendor/github.com/spf13/pflag/bool.go
new file mode 100644
index 0000000000000000000000000000000000000000..c4c5c0bfda095257e849395a0b79e7e83b2a121a
--- /dev/null
+++ b/vendor/github.com/spf13/pflag/bool.go
@@ -0,0 +1,94 @@
+package pflag
+
+import "strconv"
+
+// optional interface to indicate boolean flags that can be
+// supplied without "=value" text
+type boolFlag interface {
+ Value
+ IsBoolFlag() bool
+}
+
+// -- bool Value
+type boolValue bool
+
+func newBoolValue(val bool, p *bool) *boolValue {
+ *p = val
+ return (*boolValue)(p)
+}
+
+func (b *boolValue) Set(s string) error {
+ v, err := strconv.ParseBool(s)
+ *b = boolValue(v)
+ return err
+}
+
+func (b *boolValue) Type() string {
+ return "bool"
+}
+
+func (b *boolValue) String() string { return strconv.FormatBool(bool(*b)) }
+
+func (b *boolValue) IsBoolFlag() bool { return true }
+
+func boolConv(sval string) (interface{}, error) {
+ return strconv.ParseBool(sval)
+}
+
+// GetBool return the bool value of a flag with the given name
+func (f *FlagSet) GetBool(name string) (bool, error) {
+ val, err := f.getFlagType(name, "bool", boolConv)
+ if err != nil {
+ return false, err
+ }
+ return val.(bool), nil
+}
+
+// BoolVar defines a bool flag with specified name, default value, and usage string.
+// The argument p points to a bool variable in which to store the value of the flag.
+func (f *FlagSet) BoolVar(p *bool, name string, value bool, usage string) {
+ f.BoolVarP(p, name, "", value, usage)
+}
+
+// BoolVarP is like BoolVar, but accepts a shorthand letter that can be used after a single dash.
+func (f *FlagSet) BoolVarP(p *bool, name, shorthand string, value bool, usage string) {
+ flag := f.VarPF(newBoolValue(value, p), name, shorthand, usage)
+ flag.NoOptDefVal = "true"
+}
+
+// BoolVar defines a bool flag with specified name, default value, and usage string.
+// The argument p points to a bool variable in which to store the value of the flag.
+func BoolVar(p *bool, name string, value bool, usage string) {
+ BoolVarP(p, name, "", value, usage)
+}
+
+// BoolVarP is like BoolVar, but accepts a shorthand letter that can be used after a single dash.
+func BoolVarP(p *bool, name, shorthand string, value bool, usage string) {
+ flag := CommandLine.VarPF(newBoolValue(value, p), name, shorthand, usage)
+ flag.NoOptDefVal = "true"
+}
+
+// Bool defines a bool flag with specified name, default value, and usage string.
+// The return value is the address of a bool variable that stores the value of the flag.
+func (f *FlagSet) Bool(name string, value bool, usage string) *bool {
+ return f.BoolP(name, "", value, usage)
+}
+
+// BoolP is like Bool, but accepts a shorthand letter that can be used after a single dash.
+func (f *FlagSet) BoolP(name, shorthand string, value bool, usage string) *bool {
+ p := new(bool)
+ f.BoolVarP(p, name, shorthand, value, usage)
+ return p
+}
+
+// Bool defines a bool flag with specified name, default value, and usage string.
+// The return value is the address of a bool variable that stores the value of the flag.
+func Bool(name string, value bool, usage string) *bool {
+ return BoolP(name, "", value, usage)
+}
+
+// BoolP is like Bool, but accepts a shorthand letter that can be used after a single dash.
+func BoolP(name, shorthand string, value bool, usage string) *bool {
+ b := CommandLine.BoolP(name, shorthand, value, usage)
+ return b
+}
diff --git a/vendor/github.com/spf13/pflag/bool_slice.go b/vendor/github.com/spf13/pflag/bool_slice.go
new file mode 100644
index 0000000000000000000000000000000000000000..3731370d6a572a264f3f953fb574ef5e770bb34d
--- /dev/null
+++ b/vendor/github.com/spf13/pflag/bool_slice.go
@@ -0,0 +1,185 @@
+package pflag
+
+import (
+ "io"
+ "strconv"
+ "strings"
+)
+
+// -- boolSlice Value
+type boolSliceValue struct {
+ value *[]bool
+ changed bool
+}
+
+func newBoolSliceValue(val []bool, p *[]bool) *boolSliceValue {
+ bsv := new(boolSliceValue)
+ bsv.value = p
+ *bsv.value = val
+ return bsv
+}
+
+// Set converts, and assigns, the comma-separated boolean argument string representation as the []bool value of this flag.
+// If Set is called on a flag that already has a []bool assigned, the newly converted values will be appended.
+func (s *boolSliceValue) Set(val string) error {
+
+ // remove all quote characters
+ rmQuote := strings.NewReplacer(`"`, "", `'`, "", "`", "")
+
+ // read flag arguments with CSV parser
+ boolStrSlice, err := readAsCSV(rmQuote.Replace(val))
+ if err != nil && err != io.EOF {
+ return err
+ }
+
+ // parse boolean values into slice
+ out := make([]bool, 0, len(boolStrSlice))
+ for _, boolStr := range boolStrSlice {
+ b, err := strconv.ParseBool(strings.TrimSpace(boolStr))
+ if err != nil {
+ return err
+ }
+ out = append(out, b)
+ }
+
+ if !s.changed {
+ *s.value = out
+ } else {
+ *s.value = append(*s.value, out...)
+ }
+
+ s.changed = true
+
+ return nil
+}
+
+// Type returns a string that uniquely represents this flag's type.
+func (s *boolSliceValue) Type() string {
+ return "boolSlice"
+}
+
+// String defines a "native" format for this boolean slice flag value.
+func (s *boolSliceValue) String() string {
+
+ boolStrSlice := make([]string, len(*s.value))
+ for i, b := range *s.value {
+ boolStrSlice[i] = strconv.FormatBool(b)
+ }
+
+ out, _ := writeAsCSV(boolStrSlice)
+
+ return "[" + out + "]"
+}
+
+func (s *boolSliceValue) fromString(val string) (bool, error) {
+ return strconv.ParseBool(val)
+}
+
+func (s *boolSliceValue) toString(val bool) string {
+ return strconv.FormatBool(val)
+}
+
+func (s *boolSliceValue) Append(val string) error {
+ i, err := s.fromString(val)
+ if err != nil {
+ return err
+ }
+ *s.value = append(*s.value, i)
+ return nil
+}
+
+func (s *boolSliceValue) Replace(val []string) error {
+ out := make([]bool, len(val))
+ for i, d := range val {
+ var err error
+ out[i], err = s.fromString(d)
+ if err != nil {
+ return err
+ }
+ }
+ *s.value = out
+ return nil
+}
+
+func (s *boolSliceValue) GetSlice() []string {
+ out := make([]string, len(*s.value))
+ for i, d := range *s.value {
+ out[i] = s.toString(d)
+ }
+ return out
+}
+
+func boolSliceConv(val string) (interface{}, error) {
+ val = strings.Trim(val, "[]")
+ // Empty string would cause a slice with one (empty) entry
+ if len(val) == 0 {
+ return []bool{}, nil
+ }
+ ss := strings.Split(val, ",")
+ out := make([]bool, len(ss))
+ for i, t := range ss {
+ var err error
+ out[i], err = strconv.ParseBool(t)
+ if err != nil {
+ return nil, err
+ }
+ }
+ return out, nil
+}
+
+// GetBoolSlice returns the []bool value of a flag with the given name.
+func (f *FlagSet) GetBoolSlice(name string) ([]bool, error) {
+ val, err := f.getFlagType(name, "boolSlice", boolSliceConv)
+ if err != nil {
+ return []bool{}, err
+ }
+ return val.([]bool), nil
+}
+
+// BoolSliceVar defines a boolSlice flag with specified name, default value, and usage string.
+// The argument p points to a []bool variable in which to store the value of the flag.
+func (f *FlagSet) BoolSliceVar(p *[]bool, name string, value []bool, usage string) {
+ f.VarP(newBoolSliceValue(value, p), name, "", usage)
+}
+
+// BoolSliceVarP is like BoolSliceVar, but accepts a shorthand letter that can be used after a single dash.
+func (f *FlagSet) BoolSliceVarP(p *[]bool, name, shorthand string, value []bool, usage string) {
+ f.VarP(newBoolSliceValue(value, p), name, shorthand, usage)
+}
+
+// BoolSliceVar defines a []bool flag with specified name, default value, and usage string.
+// The argument p points to a []bool variable in which to store the value of the flag.
+func BoolSliceVar(p *[]bool, name string, value []bool, usage string) {
+ CommandLine.VarP(newBoolSliceValue(value, p), name, "", usage)
+}
+
+// BoolSliceVarP is like BoolSliceVar, but accepts a shorthand letter that can be used after a single dash.
+func BoolSliceVarP(p *[]bool, name, shorthand string, value []bool, usage string) {
+ CommandLine.VarP(newBoolSliceValue(value, p), name, shorthand, usage)
+}
+
+// BoolSlice defines a []bool flag with specified name, default value, and usage string.
+// The return value is the address of a []bool variable that stores the value of the flag.
+func (f *FlagSet) BoolSlice(name string, value []bool, usage string) *[]bool {
+ p := []bool{}
+ f.BoolSliceVarP(&p, name, "", value, usage)
+ return &p
+}
+
+// BoolSliceP is like BoolSlice, but accepts a shorthand letter that can be used after a single dash.
+func (f *FlagSet) BoolSliceP(name, shorthand string, value []bool, usage string) *[]bool {
+ p := []bool{}
+ f.BoolSliceVarP(&p, name, shorthand, value, usage)
+ return &p
+}
+
+// BoolSlice defines a []bool flag with specified name, default value, and usage string.
+// The return value is the address of a []bool variable that stores the value of the flag.
+func BoolSlice(name string, value []bool, usage string) *[]bool {
+ return CommandLine.BoolSliceP(name, "", value, usage)
+}
+
+// BoolSliceP is like BoolSlice, but accepts a shorthand letter that can be used after a single dash.
+func BoolSliceP(name, shorthand string, value []bool, usage string) *[]bool {
+ return CommandLine.BoolSliceP(name, shorthand, value, usage)
+}
diff --git a/vendor/github.com/spf13/pflag/bytes.go b/vendor/github.com/spf13/pflag/bytes.go
new file mode 100644
index 0000000000000000000000000000000000000000..67d53045708fec86213c7b79e055b52cb1c5d791
--- /dev/null
+++ b/vendor/github.com/spf13/pflag/bytes.go
@@ -0,0 +1,209 @@
+package pflag
+
+import (
+ "encoding/base64"
+ "encoding/hex"
+ "fmt"
+ "strings"
+)
+
+// BytesHex adapts []byte for use as a flag. Value of flag is HEX encoded
+type bytesHexValue []byte
+
+// String implements pflag.Value.String.
+func (bytesHex bytesHexValue) String() string {
+ return fmt.Sprintf("%X", []byte(bytesHex))
+}
+
+// Set implements pflag.Value.Set.
+func (bytesHex *bytesHexValue) Set(value string) error {
+ bin, err := hex.DecodeString(strings.TrimSpace(value))
+
+ if err != nil {
+ return err
+ }
+
+ *bytesHex = bin
+
+ return nil
+}
+
+// Type implements pflag.Value.Type.
+func (*bytesHexValue) Type() string {
+ return "bytesHex"
+}
+
+func newBytesHexValue(val []byte, p *[]byte) *bytesHexValue {
+ *p = val
+ return (*bytesHexValue)(p)
+}
+
+func bytesHexConv(sval string) (interface{}, error) {
+
+ bin, err := hex.DecodeString(sval)
+
+ if err == nil {
+ return bin, nil
+ }
+
+ return nil, fmt.Errorf("invalid string being converted to Bytes: %s %s", sval, err)
+}
+
+// GetBytesHex return the []byte value of a flag with the given name
+func (f *FlagSet) GetBytesHex(name string) ([]byte, error) {
+ val, err := f.getFlagType(name, "bytesHex", bytesHexConv)
+
+ if err != nil {
+ return []byte{}, err
+ }
+
+ return val.([]byte), nil
+}
+
+// BytesHexVar defines an []byte flag with specified name, default value, and usage string.
+// The argument p points to an []byte variable in which to store the value of the flag.
+func (f *FlagSet) BytesHexVar(p *[]byte, name string, value []byte, usage string) {
+ f.VarP(newBytesHexValue(value, p), name, "", usage)
+}
+
+// BytesHexVarP is like BytesHexVar, but accepts a shorthand letter that can be used after a single dash.
+func (f *FlagSet) BytesHexVarP(p *[]byte, name, shorthand string, value []byte, usage string) {
+ f.VarP(newBytesHexValue(value, p), name, shorthand, usage)
+}
+
+// BytesHexVar defines an []byte flag with specified name, default value, and usage string.
+// The argument p points to an []byte variable in which to store the value of the flag.
+func BytesHexVar(p *[]byte, name string, value []byte, usage string) {
+ CommandLine.VarP(newBytesHexValue(value, p), name, "", usage)
+}
+
+// BytesHexVarP is like BytesHexVar, but accepts a shorthand letter that can be used after a single dash.
+func BytesHexVarP(p *[]byte, name, shorthand string, value []byte, usage string) {
+ CommandLine.VarP(newBytesHexValue(value, p), name, shorthand, usage)
+}
+
+// BytesHex defines an []byte flag with specified name, default value, and usage string.
+// The return value is the address of an []byte variable that stores the value of the flag.
+func (f *FlagSet) BytesHex(name string, value []byte, usage string) *[]byte {
+ p := new([]byte)
+ f.BytesHexVarP(p, name, "", value, usage)
+ return p
+}
+
+// BytesHexP is like BytesHex, but accepts a shorthand letter that can be used after a single dash.
+func (f *FlagSet) BytesHexP(name, shorthand string, value []byte, usage string) *[]byte {
+ p := new([]byte)
+ f.BytesHexVarP(p, name, shorthand, value, usage)
+ return p
+}
+
+// BytesHex defines an []byte flag with specified name, default value, and usage string.
+// The return value is the address of an []byte variable that stores the value of the flag.
+func BytesHex(name string, value []byte, usage string) *[]byte {
+ return CommandLine.BytesHexP(name, "", value, usage)
+}
+
+// BytesHexP is like BytesHex, but accepts a shorthand letter that can be used after a single dash.
+func BytesHexP(name, shorthand string, value []byte, usage string) *[]byte {
+ return CommandLine.BytesHexP(name, shorthand, value, usage)
+}
+
+// BytesBase64 adapts []byte for use as a flag. Value of flag is Base64 encoded
+type bytesBase64Value []byte
+
+// String implements pflag.Value.String.
+func (bytesBase64 bytesBase64Value) String() string {
+ return base64.StdEncoding.EncodeToString([]byte(bytesBase64))
+}
+
+// Set implements pflag.Value.Set.
+func (bytesBase64 *bytesBase64Value) Set(value string) error {
+ bin, err := base64.StdEncoding.DecodeString(strings.TrimSpace(value))
+
+ if err != nil {
+ return err
+ }
+
+ *bytesBase64 = bin
+
+ return nil
+}
+
+// Type implements pflag.Value.Type.
+func (*bytesBase64Value) Type() string {
+ return "bytesBase64"
+}
+
+func newBytesBase64Value(val []byte, p *[]byte) *bytesBase64Value {
+ *p = val
+ return (*bytesBase64Value)(p)
+}
+
+func bytesBase64ValueConv(sval string) (interface{}, error) {
+
+ bin, err := base64.StdEncoding.DecodeString(sval)
+ if err == nil {
+ return bin, nil
+ }
+
+ return nil, fmt.Errorf("invalid string being converted to Bytes: %s %s", sval, err)
+}
+
+// GetBytesBase64 return the []byte value of a flag with the given name
+func (f *FlagSet) GetBytesBase64(name string) ([]byte, error) {
+ val, err := f.getFlagType(name, "bytesBase64", bytesBase64ValueConv)
+
+ if err != nil {
+ return []byte{}, err
+ }
+
+ return val.([]byte), nil
+}
+
+// BytesBase64Var defines an []byte flag with specified name, default value, and usage string.
+// The argument p points to an []byte variable in which to store the value of the flag.
+func (f *FlagSet) BytesBase64Var(p *[]byte, name string, value []byte, usage string) {
+ f.VarP(newBytesBase64Value(value, p), name, "", usage)
+}
+
+// BytesBase64VarP is like BytesBase64Var, but accepts a shorthand letter that can be used after a single dash.
+func (f *FlagSet) BytesBase64VarP(p *[]byte, name, shorthand string, value []byte, usage string) {
+ f.VarP(newBytesBase64Value(value, p), name, shorthand, usage)
+}
+
+// BytesBase64Var defines an []byte flag with specified name, default value, and usage string.
+// The argument p points to an []byte variable in which to store the value of the flag.
+func BytesBase64Var(p *[]byte, name string, value []byte, usage string) {
+ CommandLine.VarP(newBytesBase64Value(value, p), name, "", usage)
+}
+
+// BytesBase64VarP is like BytesBase64Var, but accepts a shorthand letter that can be used after a single dash.
+func BytesBase64VarP(p *[]byte, name, shorthand string, value []byte, usage string) {
+ CommandLine.VarP(newBytesBase64Value(value, p), name, shorthand, usage)
+}
+
+// BytesBase64 defines an []byte flag with specified name, default value, and usage string.
+// The return value is the address of an []byte variable that stores the value of the flag.
+func (f *FlagSet) BytesBase64(name string, value []byte, usage string) *[]byte {
+ p := new([]byte)
+ f.BytesBase64VarP(p, name, "", value, usage)
+ return p
+}
+
+// BytesBase64P is like BytesBase64, but accepts a shorthand letter that can be used after a single dash.
+func (f *FlagSet) BytesBase64P(name, shorthand string, value []byte, usage string) *[]byte {
+ p := new([]byte)
+ f.BytesBase64VarP(p, name, shorthand, value, usage)
+ return p
+}
+
+// BytesBase64 defines an []byte flag with specified name, default value, and usage string.
+// The return value is the address of an []byte variable that stores the value of the flag.
+func BytesBase64(name string, value []byte, usage string) *[]byte {
+ return CommandLine.BytesBase64P(name, "", value, usage)
+}
+
+// BytesBase64P is like BytesBase64, but accepts a shorthand letter that can be used after a single dash.
+func BytesBase64P(name, shorthand string, value []byte, usage string) *[]byte {
+ return CommandLine.BytesBase64P(name, shorthand, value, usage)
+}
diff --git a/vendor/github.com/spf13/pflag/count.go b/vendor/github.com/spf13/pflag/count.go
new file mode 100644
index 0000000000000000000000000000000000000000..a0b2679f71c7549c103f867e70f2c2b73e8c9099
--- /dev/null
+++ b/vendor/github.com/spf13/pflag/count.go
@@ -0,0 +1,96 @@
+package pflag
+
+import "strconv"
+
+// -- count Value
+type countValue int
+
+func newCountValue(val int, p *int) *countValue {
+ *p = val
+ return (*countValue)(p)
+}
+
+func (i *countValue) Set(s string) error {
+ // "+1" means that no specific value was passed, so increment
+ if s == "+1" {
+ *i = countValue(*i + 1)
+ return nil
+ }
+ v, err := strconv.ParseInt(s, 0, 0)
+ *i = countValue(v)
+ return err
+}
+
+func (i *countValue) Type() string {
+ return "count"
+}
+
+func (i *countValue) String() string { return strconv.Itoa(int(*i)) }
+
+func countConv(sval string) (interface{}, error) {
+ i, err := strconv.Atoi(sval)
+ if err != nil {
+ return nil, err
+ }
+ return i, nil
+}
+
+// GetCount return the int value of a flag with the given name
+func (f *FlagSet) GetCount(name string) (int, error) {
+ val, err := f.getFlagType(name, "count", countConv)
+ if err != nil {
+ return 0, err
+ }
+ return val.(int), nil
+}
+
+// CountVar defines a count flag with specified name, default value, and usage string.
+// The argument p points to an int variable in which to store the value of the flag.
+// A count flag will add 1 to its value every time it is found on the command line
+func (f *FlagSet) CountVar(p *int, name string, usage string) {
+ f.CountVarP(p, name, "", usage)
+}
+
+// CountVarP is like CountVar only take a shorthand for the flag name.
+func (f *FlagSet) CountVarP(p *int, name, shorthand string, usage string) {
+ flag := f.VarPF(newCountValue(0, p), name, shorthand, usage)
+ flag.NoOptDefVal = "+1"
+}
+
+// CountVar like CountVar only the flag is placed on the CommandLine instead of a given flag set
+func CountVar(p *int, name string, usage string) {
+ CommandLine.CountVar(p, name, usage)
+}
+
+// CountVarP is like CountVar only take a shorthand for the flag name.
+func CountVarP(p *int, name, shorthand string, usage string) {
+ CommandLine.CountVarP(p, name, shorthand, usage)
+}
+
+// Count defines a count flag with specified name, default value, and usage string.
+// The return value is the address of an int variable that stores the value of the flag.
+// A count flag will add 1 to its value every time it is found on the command line
+func (f *FlagSet) Count(name string, usage string) *int {
+ p := new(int)
+ f.CountVarP(p, name, "", usage)
+ return p
+}
+
+// CountP is like Count only takes a shorthand for the flag name.
+func (f *FlagSet) CountP(name, shorthand string, usage string) *int {
+ p := new(int)
+ f.CountVarP(p, name, shorthand, usage)
+ return p
+}
+
+// Count defines a count flag with specified name, default value, and usage string.
+// The return value is the address of an int variable that stores the value of the flag.
+// A count flag will add 1 to its value evey time it is found on the command line
+func Count(name string, usage string) *int {
+ return CommandLine.CountP(name, "", usage)
+}
+
+// CountP is like Count only takes a shorthand for the flag name.
+func CountP(name, shorthand string, usage string) *int {
+ return CommandLine.CountP(name, shorthand, usage)
+}
diff --git a/vendor/github.com/spf13/pflag/duration.go b/vendor/github.com/spf13/pflag/duration.go
new file mode 100644
index 0000000000000000000000000000000000000000..e9debef88ee08abab1332c5359c76b693577ded9
--- /dev/null
+++ b/vendor/github.com/spf13/pflag/duration.go
@@ -0,0 +1,86 @@
+package pflag
+
+import (
+ "time"
+)
+
+// -- time.Duration Value
+type durationValue time.Duration
+
+func newDurationValue(val time.Duration, p *time.Duration) *durationValue {
+ *p = val
+ return (*durationValue)(p)
+}
+
+func (d *durationValue) Set(s string) error {
+ v, err := time.ParseDuration(s)
+ *d = durationValue(v)
+ return err
+}
+
+func (d *durationValue) Type() string {
+ return "duration"
+}
+
+func (d *durationValue) String() string { return (*time.Duration)(d).String() }
+
+func durationConv(sval string) (interface{}, error) {
+ return time.ParseDuration(sval)
+}
+
+// GetDuration return the duration value of a flag with the given name
+func (f *FlagSet) GetDuration(name string) (time.Duration, error) {
+ val, err := f.getFlagType(name, "duration", durationConv)
+ if err != nil {
+ return 0, err
+ }
+ return val.(time.Duration), nil
+}
+
+// DurationVar defines a time.Duration flag with specified name, default value, and usage string.
+// The argument p points to a time.Duration variable in which to store the value of the flag.
+func (f *FlagSet) DurationVar(p *time.Duration, name string, value time.Duration, usage string) {
+ f.VarP(newDurationValue(value, p), name, "", usage)
+}
+
+// DurationVarP is like DurationVar, but accepts a shorthand letter that can be used after a single dash.
+func (f *FlagSet) DurationVarP(p *time.Duration, name, shorthand string, value time.Duration, usage string) {
+ f.VarP(newDurationValue(value, p), name, shorthand, usage)
+}
+
+// DurationVar defines a time.Duration flag with specified name, default value, and usage string.
+// The argument p points to a time.Duration variable in which to store the value of the flag.
+func DurationVar(p *time.Duration, name string, value time.Duration, usage string) {
+ CommandLine.VarP(newDurationValue(value, p), name, "", usage)
+}
+
+// DurationVarP is like DurationVar, but accepts a shorthand letter that can be used after a single dash.
+func DurationVarP(p *time.Duration, name, shorthand string, value time.Duration, usage string) {
+ CommandLine.VarP(newDurationValue(value, p), name, shorthand, usage)
+}
+
+// Duration defines a time.Duration flag with specified name, default value, and usage string.
+// The return value is the address of a time.Duration variable that stores the value of the flag.
+func (f *FlagSet) Duration(name string, value time.Duration, usage string) *time.Duration {
+ p := new(time.Duration)
+ f.DurationVarP(p, name, "", value, usage)
+ return p
+}
+
+// DurationP is like Duration, but accepts a shorthand letter that can be used after a single dash.
+func (f *FlagSet) DurationP(name, shorthand string, value time.Duration, usage string) *time.Duration {
+ p := new(time.Duration)
+ f.DurationVarP(p, name, shorthand, value, usage)
+ return p
+}
+
+// Duration defines a time.Duration flag with specified name, default value, and usage string.
+// The return value is the address of a time.Duration variable that stores the value of the flag.
+func Duration(name string, value time.Duration, usage string) *time.Duration {
+ return CommandLine.DurationP(name, "", value, usage)
+}
+
+// DurationP is like Duration, but accepts a shorthand letter that can be used after a single dash.
+func DurationP(name, shorthand string, value time.Duration, usage string) *time.Duration {
+ return CommandLine.DurationP(name, shorthand, value, usage)
+}
diff --git a/vendor/github.com/spf13/pflag/duration_slice.go b/vendor/github.com/spf13/pflag/duration_slice.go
new file mode 100644
index 0000000000000000000000000000000000000000..badadda53fdbc4d49ac6a874ebebdd3567cb25c6
--- /dev/null
+++ b/vendor/github.com/spf13/pflag/duration_slice.go
@@ -0,0 +1,166 @@
+package pflag
+
+import (
+ "fmt"
+ "strings"
+ "time"
+)
+
+// -- durationSlice Value
+type durationSliceValue struct {
+ value *[]time.Duration
+ changed bool
+}
+
+func newDurationSliceValue(val []time.Duration, p *[]time.Duration) *durationSliceValue {
+ dsv := new(durationSliceValue)
+ dsv.value = p
+ *dsv.value = val
+ return dsv
+}
+
+func (s *durationSliceValue) Set(val string) error {
+ ss := strings.Split(val, ",")
+ out := make([]time.Duration, len(ss))
+ for i, d := range ss {
+ var err error
+ out[i], err = time.ParseDuration(d)
+ if err != nil {
+ return err
+ }
+
+ }
+ if !s.changed {
+ *s.value = out
+ } else {
+ *s.value = append(*s.value, out...)
+ }
+ s.changed = true
+ return nil
+}
+
+func (s *durationSliceValue) Type() string {
+ return "durationSlice"
+}
+
+func (s *durationSliceValue) String() string {
+ out := make([]string, len(*s.value))
+ for i, d := range *s.value {
+ out[i] = fmt.Sprintf("%s", d)
+ }
+ return "[" + strings.Join(out, ",") + "]"
+}
+
+func (s *durationSliceValue) fromString(val string) (time.Duration, error) {
+ return time.ParseDuration(val)
+}
+
+func (s *durationSliceValue) toString(val time.Duration) string {
+ return fmt.Sprintf("%s", val)
+}
+
+func (s *durationSliceValue) Append(val string) error {
+ i, err := s.fromString(val)
+ if err != nil {
+ return err
+ }
+ *s.value = append(*s.value, i)
+ return nil
+}
+
+func (s *durationSliceValue) Replace(val []string) error {
+ out := make([]time.Duration, len(val))
+ for i, d := range val {
+ var err error
+ out[i], err = s.fromString(d)
+ if err != nil {
+ return err
+ }
+ }
+ *s.value = out
+ return nil
+}
+
+func (s *durationSliceValue) GetSlice() []string {
+ out := make([]string, len(*s.value))
+ for i, d := range *s.value {
+ out[i] = s.toString(d)
+ }
+ return out
+}
+
+func durationSliceConv(val string) (interface{}, error) {
+ val = strings.Trim(val, "[]")
+ // Empty string would cause a slice with one (empty) entry
+ if len(val) == 0 {
+ return []time.Duration{}, nil
+ }
+ ss := strings.Split(val, ",")
+ out := make([]time.Duration, len(ss))
+ for i, d := range ss {
+ var err error
+ out[i], err = time.ParseDuration(d)
+ if err != nil {
+ return nil, err
+ }
+
+ }
+ return out, nil
+}
+
+// GetDurationSlice returns the []time.Duration value of a flag with the given name
+func (f *FlagSet) GetDurationSlice(name string) ([]time.Duration, error) {
+ val, err := f.getFlagType(name, "durationSlice", durationSliceConv)
+ if err != nil {
+ return []time.Duration{}, err
+ }
+ return val.([]time.Duration), nil
+}
+
+// DurationSliceVar defines a durationSlice flag with specified name, default value, and usage string.
+// The argument p points to a []time.Duration variable in which to store the value of the flag.
+func (f *FlagSet) DurationSliceVar(p *[]time.Duration, name string, value []time.Duration, usage string) {
+ f.VarP(newDurationSliceValue(value, p), name, "", usage)
+}
+
+// DurationSliceVarP is like DurationSliceVar, but accepts a shorthand letter that can be used after a single dash.
+func (f *FlagSet) DurationSliceVarP(p *[]time.Duration, name, shorthand string, value []time.Duration, usage string) {
+ f.VarP(newDurationSliceValue(value, p), name, shorthand, usage)
+}
+
+// DurationSliceVar defines a duration[] flag with specified name, default value, and usage string.
+// The argument p points to a duration[] variable in which to store the value of the flag.
+func DurationSliceVar(p *[]time.Duration, name string, value []time.Duration, usage string) {
+ CommandLine.VarP(newDurationSliceValue(value, p), name, "", usage)
+}
+
+// DurationSliceVarP is like DurationSliceVar, but accepts a shorthand letter that can be used after a single dash.
+func DurationSliceVarP(p *[]time.Duration, name, shorthand string, value []time.Duration, usage string) {
+ CommandLine.VarP(newDurationSliceValue(value, p), name, shorthand, usage)
+}
+
+// DurationSlice defines a []time.Duration flag with specified name, default value, and usage string.
+// The return value is the address of a []time.Duration variable that stores the value of the flag.
+func (f *FlagSet) DurationSlice(name string, value []time.Duration, usage string) *[]time.Duration {
+ p := []time.Duration{}
+ f.DurationSliceVarP(&p, name, "", value, usage)
+ return &p
+}
+
+// DurationSliceP is like DurationSlice, but accepts a shorthand letter that can be used after a single dash.
+func (f *FlagSet) DurationSliceP(name, shorthand string, value []time.Duration, usage string) *[]time.Duration {
+ p := []time.Duration{}
+ f.DurationSliceVarP(&p, name, shorthand, value, usage)
+ return &p
+}
+
+// DurationSlice defines a []time.Duration flag with specified name, default value, and usage string.
+// The return value is the address of a []time.Duration variable that stores the value of the flag.
+func DurationSlice(name string, value []time.Duration, usage string) *[]time.Duration {
+ return CommandLine.DurationSliceP(name, "", value, usage)
+}
+
+// DurationSliceP is like DurationSlice, but accepts a shorthand letter that can be used after a single dash.
+func DurationSliceP(name, shorthand string, value []time.Duration, usage string) *[]time.Duration {
+ return CommandLine.DurationSliceP(name, shorthand, value, usage)
+}
diff --git a/vendor/github.com/spf13/pflag/flag.go b/vendor/github.com/spf13/pflag/flag.go
new file mode 100644
index 0000000000000000000000000000000000000000..24a5036e95b61b7dd9a66674ee897cf4768a5c06
--- /dev/null
+++ b/vendor/github.com/spf13/pflag/flag.go
@@ -0,0 +1,1239 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+/*
+Package pflag is a drop-in replacement for Go's flag package, implementing
+POSIX/GNU-style --flags.
+
+pflag is compatible with the GNU extensions to the POSIX recommendations
+for command-line options. See
+http://www.gnu.org/software/libc/manual/html_node/Argument-Syntax.html
+
+Usage:
+
+pflag is a drop-in replacement of Go's native flag package. If you import
+pflag under the name "flag" then all code should continue to function
+with no changes.
+
+ import flag "github.com/spf13/pflag"
+
+There is one exception to this: if you directly instantiate the Flag struct
+there is one more field "Shorthand" that you will need to set.
+Most code never instantiates this struct directly, and instead uses
+functions such as String(), BoolVar(), and Var(), and is therefore
+unaffected.
+
+Define flags using flag.String(), Bool(), Int(), etc.
+
+This declares an integer flag, -flagname, stored in the pointer ip, with type *int.
+ var ip = flag.Int("flagname", 1234, "help message for flagname")
+If you like, you can bind the flag to a variable using the Var() functions.
+ var flagvar int
+ func init() {
+ flag.IntVar(&flagvar, "flagname", 1234, "help message for flagname")
+ }
+Or you can create custom flags that satisfy the Value interface (with
+pointer receivers) and couple them to flag parsing by
+ flag.Var(&flagVal, "name", "help message for flagname")
+For such flags, the default value is just the initial value of the variable.
+
+After all flags are defined, call
+ flag.Parse()
+to parse the command line into the defined flags.
+
+Flags may then be used directly. If you're using the flags themselves,
+they are all pointers; if you bind to variables, they're values.
+ fmt.Println("ip has value ", *ip)
+ fmt.Println("flagvar has value ", flagvar)
+
+After parsing, the arguments after the flag are available as the
+slice flag.Args() or individually as flag.Arg(i).
+The arguments are indexed from 0 through flag.NArg()-1.
+
+The pflag package also defines some new functions that are not in flag,
+that give one-letter shorthands for flags. You can use these by appending
+'P' to the name of any function that defines a flag.
+ var ip = flag.IntP("flagname", "f", 1234, "help message")
+ var flagvar bool
+ func init() {
+ flag.BoolVarP(&flagvar, "boolname", "b", true, "help message")
+ }
+ flag.VarP(&flagval, "varname", "v", "help message")
+Shorthand letters can be used with single dashes on the command line.
+Boolean shorthand flags can be combined with other shorthand flags.
+
+Command line flag syntax:
+ --flag // boolean flags only
+ --flag=x
+
+Unlike the flag package, a single dash before an option means something
+different than a double dash. Single dashes signify a series of shorthand
+letters for flags. All but the last shorthand letter must be boolean flags.
+ // boolean flags
+ -f
+ -abc
+ // non-boolean flags
+ -n 1234
+ -Ifile
+ // mixed
+ -abcs "hello"
+ -abcn1234
+
+Flag parsing stops after the terminator "--". Unlike the flag package,
+flags can be interspersed with arguments anywhere on the command line
+before this terminator.
+
+Integer flags accept 1234, 0664, 0x1234 and may be negative.
+Boolean flags (in their long form) accept 1, 0, t, f, true, false,
+TRUE, FALSE, True, False.
+Duration flags accept any input valid for time.ParseDuration.
+
+The default set of command-line flags is controlled by
+top-level functions. The FlagSet type allows one to define
+independent sets of flags, such as to implement subcommands
+in a command-line interface. The methods of FlagSet are
+analogous to the top-level functions for the command-line
+flag set.
+*/
+package pflag
+
+import (
+ "bytes"
+ "errors"
+ goflag "flag"
+ "fmt"
+ "io"
+ "os"
+ "sort"
+ "strings"
+)
+
+// ErrHelp is the error returned if the flag -help is invoked but no such flag is defined.
+var ErrHelp = errors.New("pflag: help requested")
+
+// ErrorHandling defines how to handle flag parsing errors.
+type ErrorHandling int
+
+const (
+ // ContinueOnError will return an err from Parse() if an error is found
+ ContinueOnError ErrorHandling = iota
+ // ExitOnError will call os.Exit(2) if an error is found when parsing
+ ExitOnError
+ // PanicOnError will panic() if an error is found when parsing flags
+ PanicOnError
+)
+
+// ParseErrorsWhitelist defines the parsing errors that can be ignored
+type ParseErrorsWhitelist struct {
+ // UnknownFlags will ignore unknown flags errors and continue parsing rest of the flags
+ UnknownFlags bool
+}
+
+// NormalizedName is a flag name that has been normalized according to rules
+// for the FlagSet (e.g. making '-' and '_' equivalent).
+type NormalizedName string
+
+// A FlagSet represents a set of defined flags.
+type FlagSet struct {
+ // Usage is the function called when an error occurs while parsing flags.
+ // The field is a function (not a method) that may be changed to point to
+ // a custom error handler.
+ Usage func()
+
+ // SortFlags is used to indicate, if user wants to have sorted flags in
+ // help/usage messages.
+ SortFlags bool
+
+ // ParseErrorsWhitelist is used to configure a whitelist of errors
+ ParseErrorsWhitelist ParseErrorsWhitelist
+
+ name string
+ parsed bool
+ actual map[NormalizedName]*Flag
+ orderedActual []*Flag
+ sortedActual []*Flag
+ formal map[NormalizedName]*Flag
+ orderedFormal []*Flag
+ sortedFormal []*Flag
+ shorthands map[byte]*Flag
+ args []string // arguments after flags
+ argsLenAtDash int // len(args) when a '--' was located when parsing, or -1 if no --
+ errorHandling ErrorHandling
+ output io.Writer // nil means stderr; use out() accessor
+ interspersed bool // allow interspersed option/non-option args
+ normalizeNameFunc func(f *FlagSet, name string) NormalizedName
+
+ addedGoFlagSets []*goflag.FlagSet
+}
+
+// A Flag represents the state of a flag.
+type Flag struct {
+ Name string // name as it appears on command line
+ Shorthand string // one-letter abbreviated flag
+ Usage string // help message
+ Value Value // value as set
+ DefValue string // default value (as text); for usage message
+ Changed bool // If the user set the value (or if left to default)
+ NoOptDefVal string // default value (as text); if the flag is on the command line without any options
+ Deprecated string // If this flag is deprecated, this string is the new or now thing to use
+ Hidden bool // used by cobra.Command to allow flags to be hidden from help/usage text
+ ShorthandDeprecated string // If the shorthand of this flag is deprecated, this string is the new or now thing to use
+ Annotations map[string][]string // used by cobra.Command bash autocomple code
+}
+
+// Value is the interface to the dynamic value stored in a flag.
+// (The default value is represented as a string.)
+type Value interface {
+ String() string
+ Set(string) error
+ Type() string
+}
+
+// SliceValue is a secondary interface to all flags which hold a list
+// of values. This allows full control over the value of list flags,
+// and avoids complicated marshalling and unmarshalling to csv.
+type SliceValue interface {
+ // Append adds the specified value to the end of the flag value list.
+ Append(string) error
+ // Replace will fully overwrite any data currently in the flag value list.
+ Replace([]string) error
+ // GetSlice returns the flag value list as an array of strings.
+ GetSlice() []string
+}
+
+// sortFlags returns the flags as a slice in lexicographical sorted order.
+func sortFlags(flags map[NormalizedName]*Flag) []*Flag {
+ list := make(sort.StringSlice, len(flags))
+ i := 0
+ for k := range flags {
+ list[i] = string(k)
+ i++
+ }
+ list.Sort()
+ result := make([]*Flag, len(list))
+ for i, name := range list {
+ result[i] = flags[NormalizedName(name)]
+ }
+ return result
+}
+
+// SetNormalizeFunc allows you to add a function which can translate flag names.
+// Flags added to the FlagSet will be translated and then when anything tries to
+// look up the flag that will also be translated. So it would be possible to create
+// a flag named "getURL" and have it translated to "geturl". A user could then pass
+// "--getUrl" which may also be translated to "geturl" and everything will work.
+func (f *FlagSet) SetNormalizeFunc(n func(f *FlagSet, name string) NormalizedName) {
+ f.normalizeNameFunc = n
+ f.sortedFormal = f.sortedFormal[:0]
+ for fname, flag := range f.formal {
+ nname := f.normalizeFlagName(flag.Name)
+ if fname == nname {
+ continue
+ }
+ flag.Name = string(nname)
+ delete(f.formal, fname)
+ f.formal[nname] = flag
+ if _, set := f.actual[fname]; set {
+ delete(f.actual, fname)
+ f.actual[nname] = flag
+ }
+ }
+}
+
+// GetNormalizeFunc returns the previously set NormalizeFunc of a function which
+// does no translation, if not set previously.
+func (f *FlagSet) GetNormalizeFunc() func(f *FlagSet, name string) NormalizedName {
+ if f.normalizeNameFunc != nil {
+ return f.normalizeNameFunc
+ }
+ return func(f *FlagSet, name string) NormalizedName { return NormalizedName(name) }
+}
+
+func (f *FlagSet) normalizeFlagName(name string) NormalizedName {
+ n := f.GetNormalizeFunc()
+ return n(f, name)
+}
+
+func (f *FlagSet) out() io.Writer {
+ if f.output == nil {
+ return os.Stderr
+ }
+ return f.output
+}
+
+// SetOutput sets the destination for usage and error messages.
+// If output is nil, os.Stderr is used.
+func (f *FlagSet) SetOutput(output io.Writer) {
+ f.output = output
+}
+
+// VisitAll visits the flags in lexicographical order or
+// in primordial order if f.SortFlags is false, calling fn for each.
+// It visits all flags, even those not set.
+func (f *FlagSet) VisitAll(fn func(*Flag)) {
+ if len(f.formal) == 0 {
+ return
+ }
+
+ var flags []*Flag
+ if f.SortFlags {
+ if len(f.formal) != len(f.sortedFormal) {
+ f.sortedFormal = sortFlags(f.formal)
+ }
+ flags = f.sortedFormal
+ } else {
+ flags = f.orderedFormal
+ }
+
+ for _, flag := range flags {
+ fn(flag)
+ }
+}
+
+// HasFlags returns a bool to indicate if the FlagSet has any flags defined.
+func (f *FlagSet) HasFlags() bool {
+ return len(f.formal) > 0
+}
+
+// HasAvailableFlags returns a bool to indicate if the FlagSet has any flags
+// that are not hidden.
+func (f *FlagSet) HasAvailableFlags() bool {
+ for _, flag := range f.formal {
+ if !flag.Hidden {
+ return true
+ }
+ }
+ return false
+}
+
+// VisitAll visits the command-line flags in lexicographical order or
+// in primordial order if f.SortFlags is false, calling fn for each.
+// It visits all flags, even those not set.
+func VisitAll(fn func(*Flag)) {
+ CommandLine.VisitAll(fn)
+}
+
+// Visit visits the flags in lexicographical order or
+// in primordial order if f.SortFlags is false, calling fn for each.
+// It visits only those flags that have been set.
+func (f *FlagSet) Visit(fn func(*Flag)) {
+ if len(f.actual) == 0 {
+ return
+ }
+
+ var flags []*Flag
+ if f.SortFlags {
+ if len(f.actual) != len(f.sortedActual) {
+ f.sortedActual = sortFlags(f.actual)
+ }
+ flags = f.sortedActual
+ } else {
+ flags = f.orderedActual
+ }
+
+ for _, flag := range flags {
+ fn(flag)
+ }
+}
+
+// Visit visits the command-line flags in lexicographical order or
+// in primordial order if f.SortFlags is false, calling fn for each.
+// It visits only those flags that have been set.
+func Visit(fn func(*Flag)) {
+ CommandLine.Visit(fn)
+}
+
+// Lookup returns the Flag structure of the named flag, returning nil if none exists.
+func (f *FlagSet) Lookup(name string) *Flag {
+ return f.lookup(f.normalizeFlagName(name))
+}
+
+// ShorthandLookup returns the Flag structure of the short handed flag,
+// returning nil if none exists.
+// It panics, if len(name) > 1.
+func (f *FlagSet) ShorthandLookup(name string) *Flag {
+ if name == "" {
+ return nil
+ }
+ if len(name) > 1 {
+ msg := fmt.Sprintf("can not look up shorthand which is more than one ASCII character: %q", name)
+ fmt.Fprintf(f.out(), msg)
+ panic(msg)
+ }
+ c := name[0]
+ return f.shorthands[c]
+}
+
+// lookup returns the Flag structure of the named flag, returning nil if none exists.
+func (f *FlagSet) lookup(name NormalizedName) *Flag {
+ return f.formal[name]
+}
+
+// func to return a given type for a given flag name
+func (f *FlagSet) getFlagType(name string, ftype string, convFunc func(sval string) (interface{}, error)) (interface{}, error) {
+ flag := f.Lookup(name)
+ if flag == nil {
+ err := fmt.Errorf("flag accessed but not defined: %s", name)
+ return nil, err
+ }
+
+ if flag.Value.Type() != ftype {
+ err := fmt.Errorf("trying to get %s value of flag of type %s", ftype, flag.Value.Type())
+ return nil, err
+ }
+
+ sval := flag.Value.String()
+ result, err := convFunc(sval)
+ if err != nil {
+ return nil, err
+ }
+ return result, nil
+}
+
+// ArgsLenAtDash will return the length of f.Args at the moment when a -- was
+// found during arg parsing. This allows your program to know which args were
+// before the -- and which came after.
+func (f *FlagSet) ArgsLenAtDash() int {
+ return f.argsLenAtDash
+}
+
+// MarkDeprecated indicated that a flag is deprecated in your program. It will
+// continue to function but will not show up in help or usage messages. Using
+// this flag will also print the given usageMessage.
+func (f *FlagSet) MarkDeprecated(name string, usageMessage string) error {
+ flag := f.Lookup(name)
+ if flag == nil {
+ return fmt.Errorf("flag %q does not exist", name)
+ }
+ if usageMessage == "" {
+ return fmt.Errorf("deprecated message for flag %q must be set", name)
+ }
+ flag.Deprecated = usageMessage
+ flag.Hidden = true
+ return nil
+}
+
+// MarkShorthandDeprecated will mark the shorthand of a flag deprecated in your
+// program. It will continue to function but will not show up in help or usage
+// messages. Using this flag will also print the given usageMessage.
+func (f *FlagSet) MarkShorthandDeprecated(name string, usageMessage string) error {
+ flag := f.Lookup(name)
+ if flag == nil {
+ return fmt.Errorf("flag %q does not exist", name)
+ }
+ if usageMessage == "" {
+ return fmt.Errorf("deprecated message for flag %q must be set", name)
+ }
+ flag.ShorthandDeprecated = usageMessage
+ return nil
+}
+
+// MarkHidden sets a flag to 'hidden' in your program. It will continue to
+// function but will not show up in help or usage messages.
+func (f *FlagSet) MarkHidden(name string) error {
+ flag := f.Lookup(name)
+ if flag == nil {
+ return fmt.Errorf("flag %q does not exist", name)
+ }
+ flag.Hidden = true
+ return nil
+}
+
+// Lookup returns the Flag structure of the named command-line flag,
+// returning nil if none exists.
+func Lookup(name string) *Flag {
+ return CommandLine.Lookup(name)
+}
+
+// ShorthandLookup returns the Flag structure of the short handed flag,
+// returning nil if none exists.
+func ShorthandLookup(name string) *Flag {
+ return CommandLine.ShorthandLookup(name)
+}
+
+// Set sets the value of the named flag.
+func (f *FlagSet) Set(name, value string) error {
+ normalName := f.normalizeFlagName(name)
+ flag, ok := f.formal[normalName]
+ if !ok {
+ return fmt.Errorf("no such flag -%v", name)
+ }
+
+ err := flag.Value.Set(value)
+ if err != nil {
+ var flagName string
+ if flag.Shorthand != "" && flag.ShorthandDeprecated == "" {
+ flagName = fmt.Sprintf("-%s, --%s", flag.Shorthand, flag.Name)
+ } else {
+ flagName = fmt.Sprintf("--%s", flag.Name)
+ }
+ return fmt.Errorf("invalid argument %q for %q flag: %v", value, flagName, err)
+ }
+
+ if !flag.Changed {
+ if f.actual == nil {
+ f.actual = make(map[NormalizedName]*Flag)
+ }
+ f.actual[normalName] = flag
+ f.orderedActual = append(f.orderedActual, flag)
+
+ flag.Changed = true
+ }
+
+ if flag.Deprecated != "" {
+ fmt.Fprintf(f.out(), "Flag --%s has been deprecated, %s\n", flag.Name, flag.Deprecated)
+ }
+ return nil
+}
+
+// SetAnnotation allows one to set arbitrary annotations on a flag in the FlagSet.
+// This is sometimes used by spf13/cobra programs which want to generate additional
+// bash completion information.
+func (f *FlagSet) SetAnnotation(name, key string, values []string) error {
+ normalName := f.normalizeFlagName(name)
+ flag, ok := f.formal[normalName]
+ if !ok {
+ return fmt.Errorf("no such flag -%v", name)
+ }
+ if flag.Annotations == nil {
+ flag.Annotations = map[string][]string{}
+ }
+ flag.Annotations[key] = values
+ return nil
+}
+
+// Changed returns true if the flag was explicitly set during Parse() and false
+// otherwise
+func (f *FlagSet) Changed(name string) bool {
+ flag := f.Lookup(name)
+ // If a flag doesn't exist, it wasn't changed....
+ if flag == nil {
+ return false
+ }
+ return flag.Changed
+}
+
+// Set sets the value of the named command-line flag.
+func Set(name, value string) error {
+ return CommandLine.Set(name, value)
+}
+
+// PrintDefaults prints, to standard error unless configured
+// otherwise, the default values of all defined flags in the set.
+func (f *FlagSet) PrintDefaults() {
+ usages := f.FlagUsages()
+ fmt.Fprint(f.out(), usages)
+}
+
+// defaultIsZeroValue returns true if the default value for this flag represents
+// a zero value.
+func (f *Flag) defaultIsZeroValue() bool {
+ switch f.Value.(type) {
+ case boolFlag:
+ return f.DefValue == "false"
+ case *durationValue:
+ // Beginning in Go 1.7, duration zero values are "0s"
+ return f.DefValue == "0" || f.DefValue == "0s"
+ case *intValue, *int8Value, *int32Value, *int64Value, *uintValue, *uint8Value, *uint16Value, *uint32Value, *uint64Value, *countValue, *float32Value, *float64Value:
+ return f.DefValue == "0"
+ case *stringValue:
+ return f.DefValue == ""
+ case *ipValue, *ipMaskValue, *ipNetValue:
+ return f.DefValue == ""
+ case *intSliceValue, *stringSliceValue, *stringArrayValue:
+ return f.DefValue == "[]"
+ default:
+ switch f.Value.String() {
+ case "false":
+ return true
+ case "":
+ return true
+ case "":
+ return true
+ case "0":
+ return true
+ }
+ return false
+ }
+}
+
+// UnquoteUsage extracts a back-quoted name from the usage
+// string for a flag and returns it and the un-quoted usage.
+// Given "a `name` to show" it returns ("name", "a name to show").
+// If there are no back quotes, the name is an educated guess of the
+// type of the flag's value, or the empty string if the flag is boolean.
+func UnquoteUsage(flag *Flag) (name string, usage string) {
+ // Look for a back-quoted name, but avoid the strings package.
+ usage = flag.Usage
+ for i := 0; i < len(usage); i++ {
+ if usage[i] == '`' {
+ for j := i + 1; j < len(usage); j++ {
+ if usage[j] == '`' {
+ name = usage[i+1 : j]
+ usage = usage[:i] + name + usage[j+1:]
+ return name, usage
+ }
+ }
+ break // Only one back quote; use type name.
+ }
+ }
+
+ name = flag.Value.Type()
+ switch name {
+ case "bool":
+ name = ""
+ case "float64":
+ name = "float"
+ case "int64":
+ name = "int"
+ case "uint64":
+ name = "uint"
+ case "stringSlice":
+ name = "strings"
+ case "intSlice":
+ name = "ints"
+ case "uintSlice":
+ name = "uints"
+ case "boolSlice":
+ name = "bools"
+ }
+
+ return
+}
+
+// Splits the string `s` on whitespace into an initial substring up to
+// `i` runes in length and the remainder. Will go `slop` over `i` if
+// that encompasses the entire string (which allows the caller to
+// avoid short orphan words on the final line).
+func wrapN(i, slop int, s string) (string, string) {
+ if i+slop > len(s) {
+ return s, ""
+ }
+
+ w := strings.LastIndexAny(s[:i], " \t\n")
+ if w <= 0 {
+ return s, ""
+ }
+ nlPos := strings.LastIndex(s[:i], "\n")
+ if nlPos > 0 && nlPos < w {
+ return s[:nlPos], s[nlPos+1:]
+ }
+ return s[:w], s[w+1:]
+}
+
+// Wraps the string `s` to a maximum width `w` with leading indent
+// `i`. The first line is not indented (this is assumed to be done by
+// caller). Pass `w` == 0 to do no wrapping
+func wrap(i, w int, s string) string {
+ if w == 0 {
+ return strings.Replace(s, "\n", "\n"+strings.Repeat(" ", i), -1)
+ }
+
+ // space between indent i and end of line width w into which
+ // we should wrap the text.
+ wrap := w - i
+
+ var r, l string
+
+ // Not enough space for sensible wrapping. Wrap as a block on
+ // the next line instead.
+ if wrap < 24 {
+ i = 16
+ wrap = w - i
+ r += "\n" + strings.Repeat(" ", i)
+ }
+ // If still not enough space then don't even try to wrap.
+ if wrap < 24 {
+ return strings.Replace(s, "\n", r, -1)
+ }
+
+ // Try to avoid short orphan words on the final line, by
+ // allowing wrapN to go a bit over if that would fit in the
+ // remainder of the line.
+ slop := 5
+ wrap = wrap - slop
+
+ // Handle first line, which is indented by the caller (or the
+ // special case above)
+ l, s = wrapN(wrap, slop, s)
+ r = r + strings.Replace(l, "\n", "\n"+strings.Repeat(" ", i), -1)
+
+ // Now wrap the rest
+ for s != "" {
+ var t string
+
+ t, s = wrapN(wrap, slop, s)
+ r = r + "\n" + strings.Repeat(" ", i) + strings.Replace(t, "\n", "\n"+strings.Repeat(" ", i), -1)
+ }
+
+ return r
+
+}
+
+// FlagUsagesWrapped returns a string containing the usage information
+// for all flags in the FlagSet. Wrapped to `cols` columns (0 for no
+// wrapping)
+func (f *FlagSet) FlagUsagesWrapped(cols int) string {
+ buf := new(bytes.Buffer)
+
+ lines := make([]string, 0, len(f.formal))
+
+ maxlen := 0
+ f.VisitAll(func(flag *Flag) {
+ if flag.Hidden {
+ return
+ }
+
+ line := ""
+ if flag.Shorthand != "" && flag.ShorthandDeprecated == "" {
+ line = fmt.Sprintf(" -%s, --%s", flag.Shorthand, flag.Name)
+ } else {
+ line = fmt.Sprintf(" --%s", flag.Name)
+ }
+
+ varname, usage := UnquoteUsage(flag)
+ if varname != "" {
+ line += " " + varname
+ }
+ if flag.NoOptDefVal != "" {
+ switch flag.Value.Type() {
+ case "string":
+ line += fmt.Sprintf("[=\"%s\"]", flag.NoOptDefVal)
+ case "bool":
+ if flag.NoOptDefVal != "true" {
+ line += fmt.Sprintf("[=%s]", flag.NoOptDefVal)
+ }
+ case "count":
+ if flag.NoOptDefVal != "+1" {
+ line += fmt.Sprintf("[=%s]", flag.NoOptDefVal)
+ }
+ default:
+ line += fmt.Sprintf("[=%s]", flag.NoOptDefVal)
+ }
+ }
+
+ // This special character will be replaced with spacing once the
+ // correct alignment is calculated
+ line += "\x00"
+ if len(line) > maxlen {
+ maxlen = len(line)
+ }
+
+ line += usage
+ if !flag.defaultIsZeroValue() {
+ if flag.Value.Type() == "string" {
+ line += fmt.Sprintf(" (default %q)", flag.DefValue)
+ } else {
+ line += fmt.Sprintf(" (default %s)", flag.DefValue)
+ }
+ }
+ if len(flag.Deprecated) != 0 {
+ line += fmt.Sprintf(" (DEPRECATED: %s)", flag.Deprecated)
+ }
+
+ lines = append(lines, line)
+ })
+
+ for _, line := range lines {
+ sidx := strings.Index(line, "\x00")
+ spacing := strings.Repeat(" ", maxlen-sidx)
+ // maxlen + 2 comes from + 1 for the \x00 and + 1 for the (deliberate) off-by-one in maxlen-sidx
+ fmt.Fprintln(buf, line[:sidx], spacing, wrap(maxlen+2, cols, line[sidx+1:]))
+ }
+
+ return buf.String()
+}
+
+// FlagUsages returns a string containing the usage information for all flags in
+// the FlagSet
+func (f *FlagSet) FlagUsages() string {
+ return f.FlagUsagesWrapped(0)
+}
+
+// PrintDefaults prints to standard error the default values of all defined command-line flags.
+func PrintDefaults() {
+ CommandLine.PrintDefaults()
+}
+
+// defaultUsage is the default function to print a usage message.
+func defaultUsage(f *FlagSet) {
+ fmt.Fprintf(f.out(), "Usage of %s:\n", f.name)
+ f.PrintDefaults()
+}
+
+// NOTE: Usage is not just defaultUsage(CommandLine)
+// because it serves (via godoc flag Usage) as the example
+// for how to write your own usage function.
+
+// Usage prints to standard error a usage message documenting all defined command-line flags.
+// The function is a variable that may be changed to point to a custom function.
+// By default it prints a simple header and calls PrintDefaults; for details about the
+// format of the output and how to control it, see the documentation for PrintDefaults.
+var Usage = func() {
+ fmt.Fprintf(os.Stderr, "Usage of %s:\n", os.Args[0])
+ PrintDefaults()
+}
+
+// NFlag returns the number of flags that have been set.
+func (f *FlagSet) NFlag() int { return len(f.actual) }
+
+// NFlag returns the number of command-line flags that have been set.
+func NFlag() int { return len(CommandLine.actual) }
+
+// Arg returns the i'th argument. Arg(0) is the first remaining argument
+// after flags have been processed.
+func (f *FlagSet) Arg(i int) string {
+ if i < 0 || i >= len(f.args) {
+ return ""
+ }
+ return f.args[i]
+}
+
+// Arg returns the i'th command-line argument. Arg(0) is the first remaining argument
+// after flags have been processed.
+func Arg(i int) string {
+ return CommandLine.Arg(i)
+}
+
+// NArg is the number of arguments remaining after flags have been processed.
+func (f *FlagSet) NArg() int { return len(f.args) }
+
+// NArg is the number of arguments remaining after flags have been processed.
+func NArg() int { return len(CommandLine.args) }
+
+// Args returns the non-flag arguments.
+func (f *FlagSet) Args() []string { return f.args }
+
+// Args returns the non-flag command-line arguments.
+func Args() []string { return CommandLine.args }
+
+// Var defines a flag with the specified name and usage string. The type and
+// value of the flag are represented by the first argument, of type Value, which
+// typically holds a user-defined implementation of Value. For instance, the
+// caller could create a flag that turns a comma-separated string into a slice
+// of strings by giving the slice the methods of Value; in particular, Set would
+// decompose the comma-separated string into the slice.
+func (f *FlagSet) Var(value Value, name string, usage string) {
+ f.VarP(value, name, "", usage)
+}
+
+// VarPF is like VarP, but returns the flag created
+func (f *FlagSet) VarPF(value Value, name, shorthand, usage string) *Flag {
+ // Remember the default value as a string; it won't change.
+ flag := &Flag{
+ Name: name,
+ Shorthand: shorthand,
+ Usage: usage,
+ Value: value,
+ DefValue: value.String(),
+ }
+ f.AddFlag(flag)
+ return flag
+}
+
+// VarP is like Var, but accepts a shorthand letter that can be used after a single dash.
+func (f *FlagSet) VarP(value Value, name, shorthand, usage string) {
+ f.VarPF(value, name, shorthand, usage)
+}
+
+// AddFlag will add the flag to the FlagSet
+func (f *FlagSet) AddFlag(flag *Flag) {
+ normalizedFlagName := f.normalizeFlagName(flag.Name)
+
+ _, alreadyThere := f.formal[normalizedFlagName]
+ if alreadyThere {
+ msg := fmt.Sprintf("%s flag redefined: %s", f.name, flag.Name)
+ fmt.Fprintln(f.out(), msg)
+ panic(msg) // Happens only if flags are declared with identical names
+ }
+ if f.formal == nil {
+ f.formal = make(map[NormalizedName]*Flag)
+ }
+
+ flag.Name = string(normalizedFlagName)
+ f.formal[normalizedFlagName] = flag
+ f.orderedFormal = append(f.orderedFormal, flag)
+
+ if flag.Shorthand == "" {
+ return
+ }
+ if len(flag.Shorthand) > 1 {
+ msg := fmt.Sprintf("%q shorthand is more than one ASCII character", flag.Shorthand)
+ fmt.Fprintf(f.out(), msg)
+ panic(msg)
+ }
+ if f.shorthands == nil {
+ f.shorthands = make(map[byte]*Flag)
+ }
+ c := flag.Shorthand[0]
+ used, alreadyThere := f.shorthands[c]
+ if alreadyThere {
+ msg := fmt.Sprintf("unable to redefine %q shorthand in %q flagset: it's already used for %q flag", c, f.name, used.Name)
+ fmt.Fprintf(f.out(), msg)
+ panic(msg)
+ }
+ f.shorthands[c] = flag
+}
+
+// AddFlagSet adds one FlagSet to another. If a flag is already present in f
+// the flag from newSet will be ignored.
+func (f *FlagSet) AddFlagSet(newSet *FlagSet) {
+ if newSet == nil {
+ return
+ }
+ newSet.VisitAll(func(flag *Flag) {
+ if f.Lookup(flag.Name) == nil {
+ f.AddFlag(flag)
+ }
+ })
+}
+
+// Var defines a flag with the specified name and usage string. The type and
+// value of the flag are represented by the first argument, of type Value, which
+// typically holds a user-defined implementation of Value. For instance, the
+// caller could create a flag that turns a comma-separated string into a slice
+// of strings by giving the slice the methods of Value; in particular, Set would
+// decompose the comma-separated string into the slice.
+func Var(value Value, name string, usage string) {
+ CommandLine.VarP(value, name, "", usage)
+}
+
+// VarP is like Var, but accepts a shorthand letter that can be used after a single dash.
+func VarP(value Value, name, shorthand, usage string) {
+ CommandLine.VarP(value, name, shorthand, usage)
+}
+
+// failf prints to standard error a formatted error and usage message and
+// returns the error.
+func (f *FlagSet) failf(format string, a ...interface{}) error {
+ err := fmt.Errorf(format, a...)
+ if f.errorHandling != ContinueOnError {
+ fmt.Fprintln(f.out(), err)
+ f.usage()
+ }
+ return err
+}
+
+// usage calls the Usage method for the flag set, or the usage function if
+// the flag set is CommandLine.
+func (f *FlagSet) usage() {
+ if f == CommandLine {
+ Usage()
+ } else if f.Usage == nil {
+ defaultUsage(f)
+ } else {
+ f.Usage()
+ }
+}
+
+//--unknown (args will be empty)
+//--unknown --next-flag ... (args will be --next-flag ...)
+//--unknown arg ... (args will be arg ...)
+func stripUnknownFlagValue(args []string) []string {
+ if len(args) == 0 {
+ //--unknown
+ return args
+ }
+
+ first := args[0]
+ if len(first) > 0 && first[0] == '-' {
+ //--unknown --next-flag ...
+ return args
+ }
+
+ //--unknown arg ... (args will be arg ...)
+ if len(args) > 1 {
+ return args[1:]
+ }
+ return nil
+}
+
+func (f *FlagSet) parseLongArg(s string, args []string, fn parseFunc) (a []string, err error) {
+ a = args
+ name := s[2:]
+ if len(name) == 0 || name[0] == '-' || name[0] == '=' {
+ err = f.failf("bad flag syntax: %s", s)
+ return
+ }
+
+ split := strings.SplitN(name, "=", 2)
+ name = split[0]
+ flag, exists := f.formal[f.normalizeFlagName(name)]
+
+ if !exists {
+ switch {
+ case name == "help":
+ f.usage()
+ return a, ErrHelp
+ case f.ParseErrorsWhitelist.UnknownFlags:
+ // --unknown=unknownval arg ...
+ // we do not want to lose arg in this case
+ if len(split) >= 2 {
+ return a, nil
+ }
+
+ return stripUnknownFlagValue(a), nil
+ default:
+ err = f.failf("unknown flag: --%s", name)
+ return
+ }
+ }
+
+ var value string
+ if len(split) == 2 {
+ // '--flag=arg'
+ value = split[1]
+ } else if flag.NoOptDefVal != "" {
+ // '--flag' (arg was optional)
+ value = flag.NoOptDefVal
+ } else if len(a) > 0 {
+ // '--flag arg'
+ value = a[0]
+ a = a[1:]
+ } else {
+ // '--flag' (arg was required)
+ err = f.failf("flag needs an argument: %s", s)
+ return
+ }
+
+ err = fn(flag, value)
+ if err != nil {
+ f.failf(err.Error())
+ }
+ return
+}
+
+func (f *FlagSet) parseSingleShortArg(shorthands string, args []string, fn parseFunc) (outShorts string, outArgs []string, err error) {
+ outArgs = args
+
+ if strings.HasPrefix(shorthands, "test.") {
+ return
+ }
+
+ outShorts = shorthands[1:]
+ c := shorthands[0]
+
+ flag, exists := f.shorthands[c]
+ if !exists {
+ switch {
+ case c == 'h':
+ f.usage()
+ err = ErrHelp
+ return
+ case f.ParseErrorsWhitelist.UnknownFlags:
+ // '-f=arg arg ...'
+ // we do not want to lose arg in this case
+ if len(shorthands) > 2 && shorthands[1] == '=' {
+ outShorts = ""
+ return
+ }
+
+ outArgs = stripUnknownFlagValue(outArgs)
+ return
+ default:
+ err = f.failf("unknown shorthand flag: %q in -%s", c, shorthands)
+ return
+ }
+ }
+
+ var value string
+ if len(shorthands) > 2 && shorthands[1] == '=' {
+ // '-f=arg'
+ value = shorthands[2:]
+ outShorts = ""
+ } else if flag.NoOptDefVal != "" {
+ // '-f' (arg was optional)
+ value = flag.NoOptDefVal
+ } else if len(shorthands) > 1 {
+ // '-farg'
+ value = shorthands[1:]
+ outShorts = ""
+ } else if len(args) > 0 {
+ // '-f arg'
+ value = args[0]
+ outArgs = args[1:]
+ } else {
+ // '-f' (arg was required)
+ err = f.failf("flag needs an argument: %q in -%s", c, shorthands)
+ return
+ }
+
+ if flag.ShorthandDeprecated != "" {
+ fmt.Fprintf(f.out(), "Flag shorthand -%s has been deprecated, %s\n", flag.Shorthand, flag.ShorthandDeprecated)
+ }
+
+ err = fn(flag, value)
+ if err != nil {
+ f.failf(err.Error())
+ }
+ return
+}
+
+func (f *FlagSet) parseShortArg(s string, args []string, fn parseFunc) (a []string, err error) {
+ a = args
+ shorthands := s[1:]
+
+ // "shorthands" can be a series of shorthand letters of flags (e.g. "-vvv").
+ for len(shorthands) > 0 {
+ shorthands, a, err = f.parseSingleShortArg(shorthands, args, fn)
+ if err != nil {
+ return
+ }
+ }
+
+ return
+}
+
+func (f *FlagSet) parseArgs(args []string, fn parseFunc) (err error) {
+ for len(args) > 0 {
+ s := args[0]
+ args = args[1:]
+ if len(s) == 0 || s[0] != '-' || len(s) == 1 {
+ if !f.interspersed {
+ f.args = append(f.args, s)
+ f.args = append(f.args, args...)
+ return nil
+ }
+ f.args = append(f.args, s)
+ continue
+ }
+
+ if s[1] == '-' {
+ if len(s) == 2 { // "--" terminates the flags
+ f.argsLenAtDash = len(f.args)
+ f.args = append(f.args, args...)
+ break
+ }
+ args, err = f.parseLongArg(s, args, fn)
+ } else {
+ args, err = f.parseShortArg(s, args, fn)
+ }
+ if err != nil {
+ return
+ }
+ }
+ return
+}
+
+// Parse parses flag definitions from the argument list, which should not
+// include the command name. Must be called after all flags in the FlagSet
+// are defined and before flags are accessed by the program.
+// The return value will be ErrHelp if -help was set but not defined.
+func (f *FlagSet) Parse(arguments []string) error {
+ if f.addedGoFlagSets != nil {
+ for _, goFlagSet := range f.addedGoFlagSets {
+ goFlagSet.Parse(nil)
+ }
+ }
+ f.parsed = true
+
+ if len(arguments) < 0 {
+ return nil
+ }
+
+ f.args = make([]string, 0, len(arguments))
+
+ set := func(flag *Flag, value string) error {
+ return f.Set(flag.Name, value)
+ }
+
+ err := f.parseArgs(arguments, set)
+ if err != nil {
+ switch f.errorHandling {
+ case ContinueOnError:
+ return err
+ case ExitOnError:
+ fmt.Println(err)
+ os.Exit(2)
+ case PanicOnError:
+ panic(err)
+ }
+ }
+ return nil
+}
+
+type parseFunc func(flag *Flag, value string) error
+
+// ParseAll parses flag definitions from the argument list, which should not
+// include the command name. The arguments for fn are flag and value. Must be
+// called after all flags in the FlagSet are defined and before flags are
+// accessed by the program. The return value will be ErrHelp if -help was set
+// but not defined.
+func (f *FlagSet) ParseAll(arguments []string, fn func(flag *Flag, value string) error) error {
+ f.parsed = true
+ f.args = make([]string, 0, len(arguments))
+
+ err := f.parseArgs(arguments, fn)
+ if err != nil {
+ switch f.errorHandling {
+ case ContinueOnError:
+ return err
+ case ExitOnError:
+ os.Exit(2)
+ case PanicOnError:
+ panic(err)
+ }
+ }
+ return nil
+}
+
+// Parsed reports whether f.Parse has been called.
+func (f *FlagSet) Parsed() bool {
+ return f.parsed
+}
+
+// Parse parses the command-line flags from os.Args[1:]. Must be called
+// after all flags are defined and before flags are accessed by the program.
+func Parse() {
+ // Ignore errors; CommandLine is set for ExitOnError.
+ CommandLine.Parse(os.Args[1:])
+}
+
+// ParseAll parses the command-line flags from os.Args[1:] and called fn for each.
+// The arguments for fn are flag and value. Must be called after all flags are
+// defined and before flags are accessed by the program.
+func ParseAll(fn func(flag *Flag, value string) error) {
+ // Ignore errors; CommandLine is set for ExitOnError.
+ CommandLine.ParseAll(os.Args[1:], fn)
+}
+
+// SetInterspersed sets whether to support interspersed option/non-option arguments.
+func SetInterspersed(interspersed bool) {
+ CommandLine.SetInterspersed(interspersed)
+}
+
+// Parsed returns true if the command-line flags have been parsed.
+func Parsed() bool {
+ return CommandLine.Parsed()
+}
+
+// CommandLine is the default set of command-line flags, parsed from os.Args.
+var CommandLine = NewFlagSet(os.Args[0], ExitOnError)
+
+// NewFlagSet returns a new, empty flag set with the specified name,
+// error handling property and SortFlags set to true.
+func NewFlagSet(name string, errorHandling ErrorHandling) *FlagSet {
+ f := &FlagSet{
+ name: name,
+ errorHandling: errorHandling,
+ argsLenAtDash: -1,
+ interspersed: true,
+ SortFlags: true,
+ }
+ return f
+}
+
+// SetInterspersed sets whether to support interspersed option/non-option arguments.
+func (f *FlagSet) SetInterspersed(interspersed bool) {
+ f.interspersed = interspersed
+}
+
+// Init sets the name and error handling property for a flag set.
+// By default, the zero FlagSet uses an empty name and the
+// ContinueOnError error handling policy.
+func (f *FlagSet) Init(name string, errorHandling ErrorHandling) {
+ f.name = name
+ f.errorHandling = errorHandling
+ f.argsLenAtDash = -1
+}
diff --git a/vendor/github.com/spf13/pflag/float32.go b/vendor/github.com/spf13/pflag/float32.go
new file mode 100644
index 0000000000000000000000000000000000000000..a243f81f7fbb900c5f69b3a13b040bfe26b8cecf
--- /dev/null
+++ b/vendor/github.com/spf13/pflag/float32.go
@@ -0,0 +1,88 @@
+package pflag
+
+import "strconv"
+
+// -- float32 Value
+type float32Value float32
+
+func newFloat32Value(val float32, p *float32) *float32Value {
+ *p = val
+ return (*float32Value)(p)
+}
+
+func (f *float32Value) Set(s string) error {
+ v, err := strconv.ParseFloat(s, 32)
+ *f = float32Value(v)
+ return err
+}
+
+func (f *float32Value) Type() string {
+ return "float32"
+}
+
+func (f *float32Value) String() string { return strconv.FormatFloat(float64(*f), 'g', -1, 32) }
+
+func float32Conv(sval string) (interface{}, error) {
+ v, err := strconv.ParseFloat(sval, 32)
+ if err != nil {
+ return 0, err
+ }
+ return float32(v), nil
+}
+
+// GetFloat32 return the float32 value of a flag with the given name
+func (f *FlagSet) GetFloat32(name string) (float32, error) {
+ val, err := f.getFlagType(name, "float32", float32Conv)
+ if err != nil {
+ return 0, err
+ }
+ return val.(float32), nil
+}
+
+// Float32Var defines a float32 flag with specified name, default value, and usage string.
+// The argument p points to a float32 variable in which to store the value of the flag.
+func (f *FlagSet) Float32Var(p *float32, name string, value float32, usage string) {
+ f.VarP(newFloat32Value(value, p), name, "", usage)
+}
+
+// Float32VarP is like Float32Var, but accepts a shorthand letter that can be used after a single dash.
+func (f *FlagSet) Float32VarP(p *float32, name, shorthand string, value float32, usage string) {
+ f.VarP(newFloat32Value(value, p), name, shorthand, usage)
+}
+
+// Float32Var defines a float32 flag with specified name, default value, and usage string.
+// The argument p points to a float32 variable in which to store the value of the flag.
+func Float32Var(p *float32, name string, value float32, usage string) {
+ CommandLine.VarP(newFloat32Value(value, p), name, "", usage)
+}
+
+// Float32VarP is like Float32Var, but accepts a shorthand letter that can be used after a single dash.
+func Float32VarP(p *float32, name, shorthand string, value float32, usage string) {
+ CommandLine.VarP(newFloat32Value(value, p), name, shorthand, usage)
+}
+
+// Float32 defines a float32 flag with specified name, default value, and usage string.
+// The return value is the address of a float32 variable that stores the value of the flag.
+func (f *FlagSet) Float32(name string, value float32, usage string) *float32 {
+ p := new(float32)
+ f.Float32VarP(p, name, "", value, usage)
+ return p
+}
+
+// Float32P is like Float32, but accepts a shorthand letter that can be used after a single dash.
+func (f *FlagSet) Float32P(name, shorthand string, value float32, usage string) *float32 {
+ p := new(float32)
+ f.Float32VarP(p, name, shorthand, value, usage)
+ return p
+}
+
+// Float32 defines a float32 flag with specified name, default value, and usage string.
+// The return value is the address of a float32 variable that stores the value of the flag.
+func Float32(name string, value float32, usage string) *float32 {
+ return CommandLine.Float32P(name, "", value, usage)
+}
+
+// Float32P is like Float32, but accepts a shorthand letter that can be used after a single dash.
+func Float32P(name, shorthand string, value float32, usage string) *float32 {
+ return CommandLine.Float32P(name, shorthand, value, usage)
+}
diff --git a/vendor/github.com/spf13/pflag/float32_slice.go b/vendor/github.com/spf13/pflag/float32_slice.go
new file mode 100644
index 0000000000000000000000000000000000000000..caa352741a603952255ce4c5c532f1c505e14c83
--- /dev/null
+++ b/vendor/github.com/spf13/pflag/float32_slice.go
@@ -0,0 +1,174 @@
+package pflag
+
+import (
+ "fmt"
+ "strconv"
+ "strings"
+)
+
+// -- float32Slice Value
+type float32SliceValue struct {
+ value *[]float32
+ changed bool
+}
+
+func newFloat32SliceValue(val []float32, p *[]float32) *float32SliceValue {
+ isv := new(float32SliceValue)
+ isv.value = p
+ *isv.value = val
+ return isv
+}
+
+func (s *float32SliceValue) Set(val string) error {
+ ss := strings.Split(val, ",")
+ out := make([]float32, len(ss))
+ for i, d := range ss {
+ var err error
+ var temp64 float64
+ temp64, err = strconv.ParseFloat(d, 32)
+ if err != nil {
+ return err
+ }
+ out[i] = float32(temp64)
+
+ }
+ if !s.changed {
+ *s.value = out
+ } else {
+ *s.value = append(*s.value, out...)
+ }
+ s.changed = true
+ return nil
+}
+
+func (s *float32SliceValue) Type() string {
+ return "float32Slice"
+}
+
+func (s *float32SliceValue) String() string {
+ out := make([]string, len(*s.value))
+ for i, d := range *s.value {
+ out[i] = fmt.Sprintf("%f", d)
+ }
+ return "[" + strings.Join(out, ",") + "]"
+}
+
+func (s *float32SliceValue) fromString(val string) (float32, error) {
+ t64, err := strconv.ParseFloat(val, 32)
+ if err != nil {
+ return 0, err
+ }
+ return float32(t64), nil
+}
+
+func (s *float32SliceValue) toString(val float32) string {
+ return fmt.Sprintf("%f", val)
+}
+
+func (s *float32SliceValue) Append(val string) error {
+ i, err := s.fromString(val)
+ if err != nil {
+ return err
+ }
+ *s.value = append(*s.value, i)
+ return nil
+}
+
+func (s *float32SliceValue) Replace(val []string) error {
+ out := make([]float32, len(val))
+ for i, d := range val {
+ var err error
+ out[i], err = s.fromString(d)
+ if err != nil {
+ return err
+ }
+ }
+ *s.value = out
+ return nil
+}
+
+func (s *float32SliceValue) GetSlice() []string {
+ out := make([]string, len(*s.value))
+ for i, d := range *s.value {
+ out[i] = s.toString(d)
+ }
+ return out
+}
+
+func float32SliceConv(val string) (interface{}, error) {
+ val = strings.Trim(val, "[]")
+ // Empty string would cause a slice with one (empty) entry
+ if len(val) == 0 {
+ return []float32{}, nil
+ }
+ ss := strings.Split(val, ",")
+ out := make([]float32, len(ss))
+ for i, d := range ss {
+ var err error
+ var temp64 float64
+ temp64, err = strconv.ParseFloat(d, 32)
+ if err != nil {
+ return nil, err
+ }
+ out[i] = float32(temp64)
+
+ }
+ return out, nil
+}
+
+// GetFloat32Slice return the []float32 value of a flag with the given name
+func (f *FlagSet) GetFloat32Slice(name string) ([]float32, error) {
+ val, err := f.getFlagType(name, "float32Slice", float32SliceConv)
+ if err != nil {
+ return []float32{}, err
+ }
+ return val.([]float32), nil
+}
+
+// Float32SliceVar defines a float32Slice flag with specified name, default value, and usage string.
+// The argument p points to a []float32 variable in which to store the value of the flag.
+func (f *FlagSet) Float32SliceVar(p *[]float32, name string, value []float32, usage string) {
+ f.VarP(newFloat32SliceValue(value, p), name, "", usage)
+}
+
+// Float32SliceVarP is like Float32SliceVar, but accepts a shorthand letter that can be used after a single dash.
+func (f *FlagSet) Float32SliceVarP(p *[]float32, name, shorthand string, value []float32, usage string) {
+ f.VarP(newFloat32SliceValue(value, p), name, shorthand, usage)
+}
+
+// Float32SliceVar defines a float32[] flag with specified name, default value, and usage string.
+// The argument p points to a float32[] variable in which to store the value of the flag.
+func Float32SliceVar(p *[]float32, name string, value []float32, usage string) {
+ CommandLine.VarP(newFloat32SliceValue(value, p), name, "", usage)
+}
+
+// Float32SliceVarP is like Float32SliceVar, but accepts a shorthand letter that can be used after a single dash.
+func Float32SliceVarP(p *[]float32, name, shorthand string, value []float32, usage string) {
+ CommandLine.VarP(newFloat32SliceValue(value, p), name, shorthand, usage)
+}
+
+// Float32Slice defines a []float32 flag with specified name, default value, and usage string.
+// The return value is the address of a []float32 variable that stores the value of the flag.
+func (f *FlagSet) Float32Slice(name string, value []float32, usage string) *[]float32 {
+ p := []float32{}
+ f.Float32SliceVarP(&p, name, "", value, usage)
+ return &p
+}
+
+// Float32SliceP is like Float32Slice, but accepts a shorthand letter that can be used after a single dash.
+func (f *FlagSet) Float32SliceP(name, shorthand string, value []float32, usage string) *[]float32 {
+ p := []float32{}
+ f.Float32SliceVarP(&p, name, shorthand, value, usage)
+ return &p
+}
+
+// Float32Slice defines a []float32 flag with specified name, default value, and usage string.
+// The return value is the address of a []float32 variable that stores the value of the flag.
+func Float32Slice(name string, value []float32, usage string) *[]float32 {
+ return CommandLine.Float32SliceP(name, "", value, usage)
+}
+
+// Float32SliceP is like Float32Slice, but accepts a shorthand letter that can be used after a single dash.
+func Float32SliceP(name, shorthand string, value []float32, usage string) *[]float32 {
+ return CommandLine.Float32SliceP(name, shorthand, value, usage)
+}
diff --git a/vendor/github.com/spf13/pflag/float64.go b/vendor/github.com/spf13/pflag/float64.go
new file mode 100644
index 0000000000000000000000000000000000000000..04b5492a7d365cbfb9e979055151ec13698b3cb1
--- /dev/null
+++ b/vendor/github.com/spf13/pflag/float64.go
@@ -0,0 +1,84 @@
+package pflag
+
+import "strconv"
+
+// -- float64 Value
+type float64Value float64
+
+func newFloat64Value(val float64, p *float64) *float64Value {
+ *p = val
+ return (*float64Value)(p)
+}
+
+func (f *float64Value) Set(s string) error {
+ v, err := strconv.ParseFloat(s, 64)
+ *f = float64Value(v)
+ return err
+}
+
+func (f *float64Value) Type() string {
+ return "float64"
+}
+
+func (f *float64Value) String() string { return strconv.FormatFloat(float64(*f), 'g', -1, 64) }
+
+func float64Conv(sval string) (interface{}, error) {
+ return strconv.ParseFloat(sval, 64)
+}
+
+// GetFloat64 return the float64 value of a flag with the given name
+func (f *FlagSet) GetFloat64(name string) (float64, error) {
+ val, err := f.getFlagType(name, "float64", float64Conv)
+ if err != nil {
+ return 0, err
+ }
+ return val.(float64), nil
+}
+
+// Float64Var defines a float64 flag with specified name, default value, and usage string.
+// The argument p points to a float64 variable in which to store the value of the flag.
+func (f *FlagSet) Float64Var(p *float64, name string, value float64, usage string) {
+ f.VarP(newFloat64Value(value, p), name, "", usage)
+}
+
+// Float64VarP is like Float64Var, but accepts a shorthand letter that can be used after a single dash.
+func (f *FlagSet) Float64VarP(p *float64, name, shorthand string, value float64, usage string) {
+ f.VarP(newFloat64Value(value, p), name, shorthand, usage)
+}
+
+// Float64Var defines a float64 flag with specified name, default value, and usage string.
+// The argument p points to a float64 variable in which to store the value of the flag.
+func Float64Var(p *float64, name string, value float64, usage string) {
+ CommandLine.VarP(newFloat64Value(value, p), name, "", usage)
+}
+
+// Float64VarP is like Float64Var, but accepts a shorthand letter that can be used after a single dash.
+func Float64VarP(p *float64, name, shorthand string, value float64, usage string) {
+ CommandLine.VarP(newFloat64Value(value, p), name, shorthand, usage)
+}
+
+// Float64 defines a float64 flag with specified name, default value, and usage string.
+// The return value is the address of a float64 variable that stores the value of the flag.
+func (f *FlagSet) Float64(name string, value float64, usage string) *float64 {
+ p := new(float64)
+ f.Float64VarP(p, name, "", value, usage)
+ return p
+}
+
+// Float64P is like Float64, but accepts a shorthand letter that can be used after a single dash.
+func (f *FlagSet) Float64P(name, shorthand string, value float64, usage string) *float64 {
+ p := new(float64)
+ f.Float64VarP(p, name, shorthand, value, usage)
+ return p
+}
+
+// Float64 defines a float64 flag with specified name, default value, and usage string.
+// The return value is the address of a float64 variable that stores the value of the flag.
+func Float64(name string, value float64, usage string) *float64 {
+ return CommandLine.Float64P(name, "", value, usage)
+}
+
+// Float64P is like Float64, but accepts a shorthand letter that can be used after a single dash.
+func Float64P(name, shorthand string, value float64, usage string) *float64 {
+ return CommandLine.Float64P(name, shorthand, value, usage)
+}
diff --git a/vendor/github.com/spf13/pflag/float64_slice.go b/vendor/github.com/spf13/pflag/float64_slice.go
new file mode 100644
index 0000000000000000000000000000000000000000..85bf3073d5064d7539c9153fb7acf085d43a3f80
--- /dev/null
+++ b/vendor/github.com/spf13/pflag/float64_slice.go
@@ -0,0 +1,166 @@
+package pflag
+
+import (
+ "fmt"
+ "strconv"
+ "strings"
+)
+
+// -- float64Slice Value
+type float64SliceValue struct {
+ value *[]float64
+ changed bool
+}
+
+func newFloat64SliceValue(val []float64, p *[]float64) *float64SliceValue {
+ isv := new(float64SliceValue)
+ isv.value = p
+ *isv.value = val
+ return isv
+}
+
+func (s *float64SliceValue) Set(val string) error {
+ ss := strings.Split(val, ",")
+ out := make([]float64, len(ss))
+ for i, d := range ss {
+ var err error
+ out[i], err = strconv.ParseFloat(d, 64)
+ if err != nil {
+ return err
+ }
+
+ }
+ if !s.changed {
+ *s.value = out
+ } else {
+ *s.value = append(*s.value, out...)
+ }
+ s.changed = true
+ return nil
+}
+
+func (s *float64SliceValue) Type() string {
+ return "float64Slice"
+}
+
+func (s *float64SliceValue) String() string {
+ out := make([]string, len(*s.value))
+ for i, d := range *s.value {
+ out[i] = fmt.Sprintf("%f", d)
+ }
+ return "[" + strings.Join(out, ",") + "]"
+}
+
+func (s *float64SliceValue) fromString(val string) (float64, error) {
+ return strconv.ParseFloat(val, 64)
+}
+
+func (s *float64SliceValue) toString(val float64) string {
+ return fmt.Sprintf("%f", val)
+}
+
+func (s *float64SliceValue) Append(val string) error {
+ i, err := s.fromString(val)
+ if err != nil {
+ return err
+ }
+ *s.value = append(*s.value, i)
+ return nil
+}
+
+func (s *float64SliceValue) Replace(val []string) error {
+ out := make([]float64, len(val))
+ for i, d := range val {
+ var err error
+ out[i], err = s.fromString(d)
+ if err != nil {
+ return err
+ }
+ }
+ *s.value = out
+ return nil
+}
+
+func (s *float64SliceValue) GetSlice() []string {
+ out := make([]string, len(*s.value))
+ for i, d := range *s.value {
+ out[i] = s.toString(d)
+ }
+ return out
+}
+
+func float64SliceConv(val string) (interface{}, error) {
+ val = strings.Trim(val, "[]")
+ // Empty string would cause a slice with one (empty) entry
+ if len(val) == 0 {
+ return []float64{}, nil
+ }
+ ss := strings.Split(val, ",")
+ out := make([]float64, len(ss))
+ for i, d := range ss {
+ var err error
+ out[i], err = strconv.ParseFloat(d, 64)
+ if err != nil {
+ return nil, err
+ }
+
+ }
+ return out, nil
+}
+
+// GetFloat64Slice return the []float64 value of a flag with the given name
+func (f *FlagSet) GetFloat64Slice(name string) ([]float64, error) {
+ val, err := f.getFlagType(name, "float64Slice", float64SliceConv)
+ if err != nil {
+ return []float64{}, err
+ }
+ return val.([]float64), nil
+}
+
+// Float64SliceVar defines a float64Slice flag with specified name, default value, and usage string.
+// The argument p points to a []float64 variable in which to store the value of the flag.
+func (f *FlagSet) Float64SliceVar(p *[]float64, name string, value []float64, usage string) {
+ f.VarP(newFloat64SliceValue(value, p), name, "", usage)
+}
+
+// Float64SliceVarP is like Float64SliceVar, but accepts a shorthand letter that can be used after a single dash.
+func (f *FlagSet) Float64SliceVarP(p *[]float64, name, shorthand string, value []float64, usage string) {
+ f.VarP(newFloat64SliceValue(value, p), name, shorthand, usage)
+}
+
+// Float64SliceVar defines a float64[] flag with specified name, default value, and usage string.
+// The argument p points to a float64[] variable in which to store the value of the flag.
+func Float64SliceVar(p *[]float64, name string, value []float64, usage string) {
+ CommandLine.VarP(newFloat64SliceValue(value, p), name, "", usage)
+}
+
+// Float64SliceVarP is like Float64SliceVar, but accepts a shorthand letter that can be used after a single dash.
+func Float64SliceVarP(p *[]float64, name, shorthand string, value []float64, usage string) {
+ CommandLine.VarP(newFloat64SliceValue(value, p), name, shorthand, usage)
+}
+
+// Float64Slice defines a []float64 flag with specified name, default value, and usage string.
+// The return value is the address of a []float64 variable that stores the value of the flag.
+func (f *FlagSet) Float64Slice(name string, value []float64, usage string) *[]float64 {
+ p := []float64{}
+ f.Float64SliceVarP(&p, name, "", value, usage)
+ return &p
+}
+
+// Float64SliceP is like Float64Slice, but accepts a shorthand letter that can be used after a single dash.
+func (f *FlagSet) Float64SliceP(name, shorthand string, value []float64, usage string) *[]float64 {
+ p := []float64{}
+ f.Float64SliceVarP(&p, name, shorthand, value, usage)
+ return &p
+}
+
+// Float64Slice defines a []float64 flag with specified name, default value, and usage string.
+// The return value is the address of a []float64 variable that stores the value of the flag.
+func Float64Slice(name string, value []float64, usage string) *[]float64 {
+ return CommandLine.Float64SliceP(name, "", value, usage)
+}
+
+// Float64SliceP is like Float64Slice, but accepts a shorthand letter that can be used after a single dash.
+func Float64SliceP(name, shorthand string, value []float64, usage string) *[]float64 {
+ return CommandLine.Float64SliceP(name, shorthand, value, usage)
+}
diff --git a/vendor/github.com/spf13/pflag/go.mod b/vendor/github.com/spf13/pflag/go.mod
new file mode 100644
index 0000000000000000000000000000000000000000..b2287eec13482801cae47dacc0f1f9005562d889
--- /dev/null
+++ b/vendor/github.com/spf13/pflag/go.mod
@@ -0,0 +1,3 @@
+module github.com/spf13/pflag
+
+go 1.12
diff --git a/vendor/github.com/spf13/pflag/go.sum b/vendor/github.com/spf13/pflag/go.sum
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/vendor/github.com/spf13/pflag/golangflag.go b/vendor/github.com/spf13/pflag/golangflag.go
new file mode 100644
index 0000000000000000000000000000000000000000..d3dd72b7feed6744b897518f6a468ff7bacab69f
--- /dev/null
+++ b/vendor/github.com/spf13/pflag/golangflag.go
@@ -0,0 +1,105 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package pflag
+
+import (
+ goflag "flag"
+ "reflect"
+ "strings"
+)
+
+// flagValueWrapper implements pflag.Value around a flag.Value. The main
+// difference here is the addition of the Type method that returns a string
+// name of the type. As this is generally unknown, we approximate that with
+// reflection.
+type flagValueWrapper struct {
+ inner goflag.Value
+ flagType string
+}
+
+// We are just copying the boolFlag interface out of goflag as that is what
+// they use to decide if a flag should get "true" when no arg is given.
+type goBoolFlag interface {
+ goflag.Value
+ IsBoolFlag() bool
+}
+
+func wrapFlagValue(v goflag.Value) Value {
+ // If the flag.Value happens to also be a pflag.Value, just use it directly.
+ if pv, ok := v.(Value); ok {
+ return pv
+ }
+
+ pv := &flagValueWrapper{
+ inner: v,
+ }
+
+ t := reflect.TypeOf(v)
+ if t.Kind() == reflect.Interface || t.Kind() == reflect.Ptr {
+ t = t.Elem()
+ }
+
+ pv.flagType = strings.TrimSuffix(t.Name(), "Value")
+ return pv
+}
+
+func (v *flagValueWrapper) String() string {
+ return v.inner.String()
+}
+
+func (v *flagValueWrapper) Set(s string) error {
+ return v.inner.Set(s)
+}
+
+func (v *flagValueWrapper) Type() string {
+ return v.flagType
+}
+
+// PFlagFromGoFlag will return a *pflag.Flag given a *flag.Flag
+// If the *flag.Flag.Name was a single character (ex: `v`) it will be accessiblei
+// with both `-v` and `--v` in flags. If the golang flag was more than a single
+// character (ex: `verbose`) it will only be accessible via `--verbose`
+func PFlagFromGoFlag(goflag *goflag.Flag) *Flag {
+ // Remember the default value as a string; it won't change.
+ flag := &Flag{
+ Name: goflag.Name,
+ Usage: goflag.Usage,
+ Value: wrapFlagValue(goflag.Value),
+ // Looks like golang flags don't set DefValue correctly :-(
+ //DefValue: goflag.DefValue,
+ DefValue: goflag.Value.String(),
+ }
+ // Ex: if the golang flag was -v, allow both -v and --v to work
+ if len(flag.Name) == 1 {
+ flag.Shorthand = flag.Name
+ }
+ if fv, ok := goflag.Value.(goBoolFlag); ok && fv.IsBoolFlag() {
+ flag.NoOptDefVal = "true"
+ }
+ return flag
+}
+
+// AddGoFlag will add the given *flag.Flag to the pflag.FlagSet
+func (f *FlagSet) AddGoFlag(goflag *goflag.Flag) {
+ if f.Lookup(goflag.Name) != nil {
+ return
+ }
+ newflag := PFlagFromGoFlag(goflag)
+ f.AddFlag(newflag)
+}
+
+// AddGoFlagSet will add the given *flag.FlagSet to the pflag.FlagSet
+func (f *FlagSet) AddGoFlagSet(newSet *goflag.FlagSet) {
+ if newSet == nil {
+ return
+ }
+ newSet.VisitAll(func(goflag *goflag.Flag) {
+ f.AddGoFlag(goflag)
+ })
+ if f.addedGoFlagSets == nil {
+ f.addedGoFlagSets = make([]*goflag.FlagSet, 0)
+ }
+ f.addedGoFlagSets = append(f.addedGoFlagSets, newSet)
+}
diff --git a/vendor/github.com/spf13/pflag/int.go b/vendor/github.com/spf13/pflag/int.go
new file mode 100644
index 0000000000000000000000000000000000000000..1474b89df6654b1ddcc9d3107f54966aa67e72a2
--- /dev/null
+++ b/vendor/github.com/spf13/pflag/int.go
@@ -0,0 +1,84 @@
+package pflag
+
+import "strconv"
+
+// -- int Value
+type intValue int
+
+func newIntValue(val int, p *int) *intValue {
+ *p = val
+ return (*intValue)(p)
+}
+
+func (i *intValue) Set(s string) error {
+ v, err := strconv.ParseInt(s, 0, 64)
+ *i = intValue(v)
+ return err
+}
+
+func (i *intValue) Type() string {
+ return "int"
+}
+
+func (i *intValue) String() string { return strconv.Itoa(int(*i)) }
+
+func intConv(sval string) (interface{}, error) {
+ return strconv.Atoi(sval)
+}
+
+// GetInt return the int value of a flag with the given name
+func (f *FlagSet) GetInt(name string) (int, error) {
+ val, err := f.getFlagType(name, "int", intConv)
+ if err != nil {
+ return 0, err
+ }
+ return val.(int), nil
+}
+
+// IntVar defines an int flag with specified name, default value, and usage string.
+// The argument p points to an int variable in which to store the value of the flag.
+func (f *FlagSet) IntVar(p *int, name string, value int, usage string) {
+ f.VarP(newIntValue(value, p), name, "", usage)
+}
+
+// IntVarP is like IntVar, but accepts a shorthand letter that can be used after a single dash.
+func (f *FlagSet) IntVarP(p *int, name, shorthand string, value int, usage string) {
+ f.VarP(newIntValue(value, p), name, shorthand, usage)
+}
+
+// IntVar defines an int flag with specified name, default value, and usage string.
+// The argument p points to an int variable in which to store the value of the flag.
+func IntVar(p *int, name string, value int, usage string) {
+ CommandLine.VarP(newIntValue(value, p), name, "", usage)
+}
+
+// IntVarP is like IntVar, but accepts a shorthand letter that can be used after a single dash.
+func IntVarP(p *int, name, shorthand string, value int, usage string) {
+ CommandLine.VarP(newIntValue(value, p), name, shorthand, usage)
+}
+
+// Int defines an int flag with specified name, default value, and usage string.
+// The return value is the address of an int variable that stores the value of the flag.
+func (f *FlagSet) Int(name string, value int, usage string) *int {
+ p := new(int)
+ f.IntVarP(p, name, "", value, usage)
+ return p
+}
+
+// IntP is like Int, but accepts a shorthand letter that can be used after a single dash.
+func (f *FlagSet) IntP(name, shorthand string, value int, usage string) *int {
+ p := new(int)
+ f.IntVarP(p, name, shorthand, value, usage)
+ return p
+}
+
+// Int defines an int flag with specified name, default value, and usage string.
+// The return value is the address of an int variable that stores the value of the flag.
+func Int(name string, value int, usage string) *int {
+ return CommandLine.IntP(name, "", value, usage)
+}
+
+// IntP is like Int, but accepts a shorthand letter that can be used after a single dash.
+func IntP(name, shorthand string, value int, usage string) *int {
+ return CommandLine.IntP(name, shorthand, value, usage)
+}
diff --git a/vendor/github.com/spf13/pflag/int16.go b/vendor/github.com/spf13/pflag/int16.go
new file mode 100644
index 0000000000000000000000000000000000000000..f1a01d05e6946c68062903ebb0081741e65ff5c2
--- /dev/null
+++ b/vendor/github.com/spf13/pflag/int16.go
@@ -0,0 +1,88 @@
+package pflag
+
+import "strconv"
+
+// -- int16 Value
+type int16Value int16
+
+func newInt16Value(val int16, p *int16) *int16Value {
+ *p = val
+ return (*int16Value)(p)
+}
+
+func (i *int16Value) Set(s string) error {
+ v, err := strconv.ParseInt(s, 0, 16)
+ *i = int16Value(v)
+ return err
+}
+
+func (i *int16Value) Type() string {
+ return "int16"
+}
+
+func (i *int16Value) String() string { return strconv.FormatInt(int64(*i), 10) }
+
+func int16Conv(sval string) (interface{}, error) {
+ v, err := strconv.ParseInt(sval, 0, 16)
+ if err != nil {
+ return 0, err
+ }
+ return int16(v), nil
+}
+
+// GetInt16 returns the int16 value of a flag with the given name
+func (f *FlagSet) GetInt16(name string) (int16, error) {
+ val, err := f.getFlagType(name, "int16", int16Conv)
+ if err != nil {
+ return 0, err
+ }
+ return val.(int16), nil
+}
+
+// Int16Var defines an int16 flag with specified name, default value, and usage string.
+// The argument p points to an int16 variable in which to store the value of the flag.
+func (f *FlagSet) Int16Var(p *int16, name string, value int16, usage string) {
+ f.VarP(newInt16Value(value, p), name, "", usage)
+}
+
+// Int16VarP is like Int16Var, but accepts a shorthand letter that can be used after a single dash.
+func (f *FlagSet) Int16VarP(p *int16, name, shorthand string, value int16, usage string) {
+ f.VarP(newInt16Value(value, p), name, shorthand, usage)
+}
+
+// Int16Var defines an int16 flag with specified name, default value, and usage string.
+// The argument p points to an int16 variable in which to store the value of the flag.
+func Int16Var(p *int16, name string, value int16, usage string) {
+ CommandLine.VarP(newInt16Value(value, p), name, "", usage)
+}
+
+// Int16VarP is like Int16Var, but accepts a shorthand letter that can be used after a single dash.
+func Int16VarP(p *int16, name, shorthand string, value int16, usage string) {
+ CommandLine.VarP(newInt16Value(value, p), name, shorthand, usage)
+}
+
+// Int16 defines an int16 flag with specified name, default value, and usage string.
+// The return value is the address of an int16 variable that stores the value of the flag.
+func (f *FlagSet) Int16(name string, value int16, usage string) *int16 {
+ p := new(int16)
+ f.Int16VarP(p, name, "", value, usage)
+ return p
+}
+
+// Int16P is like Int16, but accepts a shorthand letter that can be used after a single dash.
+func (f *FlagSet) Int16P(name, shorthand string, value int16, usage string) *int16 {
+ p := new(int16)
+ f.Int16VarP(p, name, shorthand, value, usage)
+ return p
+}
+
+// Int16 defines an int16 flag with specified name, default value, and usage string.
+// The return value is the address of an int16 variable that stores the value of the flag.
+func Int16(name string, value int16, usage string) *int16 {
+ return CommandLine.Int16P(name, "", value, usage)
+}
+
+// Int16P is like Int16, but accepts a shorthand letter that can be used after a single dash.
+func Int16P(name, shorthand string, value int16, usage string) *int16 {
+ return CommandLine.Int16P(name, shorthand, value, usage)
+}
diff --git a/vendor/github.com/spf13/pflag/int32.go b/vendor/github.com/spf13/pflag/int32.go
new file mode 100644
index 0000000000000000000000000000000000000000..9b95944f0fe3c897d503c4a94a19c2271cbcc26c
--- /dev/null
+++ b/vendor/github.com/spf13/pflag/int32.go
@@ -0,0 +1,88 @@
+package pflag
+
+import "strconv"
+
+// -- int32 Value
+type int32Value int32
+
+func newInt32Value(val int32, p *int32) *int32Value {
+ *p = val
+ return (*int32Value)(p)
+}
+
+func (i *int32Value) Set(s string) error {
+ v, err := strconv.ParseInt(s, 0, 32)
+ *i = int32Value(v)
+ return err
+}
+
+func (i *int32Value) Type() string {
+ return "int32"
+}
+
+func (i *int32Value) String() string { return strconv.FormatInt(int64(*i), 10) }
+
+func int32Conv(sval string) (interface{}, error) {
+ v, err := strconv.ParseInt(sval, 0, 32)
+ if err != nil {
+ return 0, err
+ }
+ return int32(v), nil
+}
+
+// GetInt32 return the int32 value of a flag with the given name
+func (f *FlagSet) GetInt32(name string) (int32, error) {
+ val, err := f.getFlagType(name, "int32", int32Conv)
+ if err != nil {
+ return 0, err
+ }
+ return val.(int32), nil
+}
+
+// Int32Var defines an int32 flag with specified name, default value, and usage string.
+// The argument p points to an int32 variable in which to store the value of the flag.
+func (f *FlagSet) Int32Var(p *int32, name string, value int32, usage string) {
+ f.VarP(newInt32Value(value, p), name, "", usage)
+}
+
+// Int32VarP is like Int32Var, but accepts a shorthand letter that can be used after a single dash.
+func (f *FlagSet) Int32VarP(p *int32, name, shorthand string, value int32, usage string) {
+ f.VarP(newInt32Value(value, p), name, shorthand, usage)
+}
+
+// Int32Var defines an int32 flag with specified name, default value, and usage string.
+// The argument p points to an int32 variable in which to store the value of the flag.
+func Int32Var(p *int32, name string, value int32, usage string) {
+ CommandLine.VarP(newInt32Value(value, p), name, "", usage)
+}
+
+// Int32VarP is like Int32Var, but accepts a shorthand letter that can be used after a single dash.
+func Int32VarP(p *int32, name, shorthand string, value int32, usage string) {
+ CommandLine.VarP(newInt32Value(value, p), name, shorthand, usage)
+}
+
+// Int32 defines an int32 flag with specified name, default value, and usage string.
+// The return value is the address of an int32 variable that stores the value of the flag.
+func (f *FlagSet) Int32(name string, value int32, usage string) *int32 {
+ p := new(int32)
+ f.Int32VarP(p, name, "", value, usage)
+ return p
+}
+
+// Int32P is like Int32, but accepts a shorthand letter that can be used after a single dash.
+func (f *FlagSet) Int32P(name, shorthand string, value int32, usage string) *int32 {
+ p := new(int32)
+ f.Int32VarP(p, name, shorthand, value, usage)
+ return p
+}
+
+// Int32 defines an int32 flag with specified name, default value, and usage string.
+// The return value is the address of an int32 variable that stores the value of the flag.
+func Int32(name string, value int32, usage string) *int32 {
+ return CommandLine.Int32P(name, "", value, usage)
+}
+
+// Int32P is like Int32, but accepts a shorthand letter that can be used after a single dash.
+func Int32P(name, shorthand string, value int32, usage string) *int32 {
+ return CommandLine.Int32P(name, shorthand, value, usage)
+}
diff --git a/vendor/github.com/spf13/pflag/int32_slice.go b/vendor/github.com/spf13/pflag/int32_slice.go
new file mode 100644
index 0000000000000000000000000000000000000000..ff128ff06d869653f3cc3ed8b50204f7a7a0503e
--- /dev/null
+++ b/vendor/github.com/spf13/pflag/int32_slice.go
@@ -0,0 +1,174 @@
+package pflag
+
+import (
+ "fmt"
+ "strconv"
+ "strings"
+)
+
+// -- int32Slice Value
+type int32SliceValue struct {
+ value *[]int32
+ changed bool
+}
+
+func newInt32SliceValue(val []int32, p *[]int32) *int32SliceValue {
+ isv := new(int32SliceValue)
+ isv.value = p
+ *isv.value = val
+ return isv
+}
+
+func (s *int32SliceValue) Set(val string) error {
+ ss := strings.Split(val, ",")
+ out := make([]int32, len(ss))
+ for i, d := range ss {
+ var err error
+ var temp64 int64
+ temp64, err = strconv.ParseInt(d, 0, 32)
+ if err != nil {
+ return err
+ }
+ out[i] = int32(temp64)
+
+ }
+ if !s.changed {
+ *s.value = out
+ } else {
+ *s.value = append(*s.value, out...)
+ }
+ s.changed = true
+ return nil
+}
+
+func (s *int32SliceValue) Type() string {
+ return "int32Slice"
+}
+
+func (s *int32SliceValue) String() string {
+ out := make([]string, len(*s.value))
+ for i, d := range *s.value {
+ out[i] = fmt.Sprintf("%d", d)
+ }
+ return "[" + strings.Join(out, ",") + "]"
+}
+
+func (s *int32SliceValue) fromString(val string) (int32, error) {
+ t64, err := strconv.ParseInt(val, 0, 32)
+ if err != nil {
+ return 0, err
+ }
+ return int32(t64), nil
+}
+
+func (s *int32SliceValue) toString(val int32) string {
+ return fmt.Sprintf("%d", val)
+}
+
+func (s *int32SliceValue) Append(val string) error {
+ i, err := s.fromString(val)
+ if err != nil {
+ return err
+ }
+ *s.value = append(*s.value, i)
+ return nil
+}
+
+func (s *int32SliceValue) Replace(val []string) error {
+ out := make([]int32, len(val))
+ for i, d := range val {
+ var err error
+ out[i], err = s.fromString(d)
+ if err != nil {
+ return err
+ }
+ }
+ *s.value = out
+ return nil
+}
+
+func (s *int32SliceValue) GetSlice() []string {
+ out := make([]string, len(*s.value))
+ for i, d := range *s.value {
+ out[i] = s.toString(d)
+ }
+ return out
+}
+
+func int32SliceConv(val string) (interface{}, error) {
+ val = strings.Trim(val, "[]")
+ // Empty string would cause a slice with one (empty) entry
+ if len(val) == 0 {
+ return []int32{}, nil
+ }
+ ss := strings.Split(val, ",")
+ out := make([]int32, len(ss))
+ for i, d := range ss {
+ var err error
+ var temp64 int64
+ temp64, err = strconv.ParseInt(d, 0, 32)
+ if err != nil {
+ return nil, err
+ }
+ out[i] = int32(temp64)
+
+ }
+ return out, nil
+}
+
+// GetInt32Slice return the []int32 value of a flag with the given name
+func (f *FlagSet) GetInt32Slice(name string) ([]int32, error) {
+ val, err := f.getFlagType(name, "int32Slice", int32SliceConv)
+ if err != nil {
+ return []int32{}, err
+ }
+ return val.([]int32), nil
+}
+
+// Int32SliceVar defines a int32Slice flag with specified name, default value, and usage string.
+// The argument p points to a []int32 variable in which to store the value of the flag.
+func (f *FlagSet) Int32SliceVar(p *[]int32, name string, value []int32, usage string) {
+ f.VarP(newInt32SliceValue(value, p), name, "", usage)
+}
+
+// Int32SliceVarP is like Int32SliceVar, but accepts a shorthand letter that can be used after a single dash.
+func (f *FlagSet) Int32SliceVarP(p *[]int32, name, shorthand string, value []int32, usage string) {
+ f.VarP(newInt32SliceValue(value, p), name, shorthand, usage)
+}
+
+// Int32SliceVar defines a int32[] flag with specified name, default value, and usage string.
+// The argument p points to a int32[] variable in which to store the value of the flag.
+func Int32SliceVar(p *[]int32, name string, value []int32, usage string) {
+ CommandLine.VarP(newInt32SliceValue(value, p), name, "", usage)
+}
+
+// Int32SliceVarP is like Int32SliceVar, but accepts a shorthand letter that can be used after a single dash.
+func Int32SliceVarP(p *[]int32, name, shorthand string, value []int32, usage string) {
+ CommandLine.VarP(newInt32SliceValue(value, p), name, shorthand, usage)
+}
+
+// Int32Slice defines a []int32 flag with specified name, default value, and usage string.
+// The return value is the address of a []int32 variable that stores the value of the flag.
+func (f *FlagSet) Int32Slice(name string, value []int32, usage string) *[]int32 {
+ p := []int32{}
+ f.Int32SliceVarP(&p, name, "", value, usage)
+ return &p
+}
+
+// Int32SliceP is like Int32Slice, but accepts a shorthand letter that can be used after a single dash.
+func (f *FlagSet) Int32SliceP(name, shorthand string, value []int32, usage string) *[]int32 {
+ p := []int32{}
+ f.Int32SliceVarP(&p, name, shorthand, value, usage)
+ return &p
+}
+
+// Int32Slice defines a []int32 flag with specified name, default value, and usage string.
+// The return value is the address of a []int32 variable that stores the value of the flag.
+func Int32Slice(name string, value []int32, usage string) *[]int32 {
+ return CommandLine.Int32SliceP(name, "", value, usage)
+}
+
+// Int32SliceP is like Int32Slice, but accepts a shorthand letter that can be used after a single dash.
+func Int32SliceP(name, shorthand string, value []int32, usage string) *[]int32 {
+ return CommandLine.Int32SliceP(name, shorthand, value, usage)
+}
diff --git a/vendor/github.com/spf13/pflag/int64.go b/vendor/github.com/spf13/pflag/int64.go
new file mode 100644
index 0000000000000000000000000000000000000000..0026d781d9fb8ee93031d279223f46793fa98eb8
--- /dev/null
+++ b/vendor/github.com/spf13/pflag/int64.go
@@ -0,0 +1,84 @@
+package pflag
+
+import "strconv"
+
+// -- int64 Value
+type int64Value int64
+
+func newInt64Value(val int64, p *int64) *int64Value {
+ *p = val
+ return (*int64Value)(p)
+}
+
+func (i *int64Value) Set(s string) error {
+ v, err := strconv.ParseInt(s, 0, 64)
+ *i = int64Value(v)
+ return err
+}
+
+func (i *int64Value) Type() string {
+ return "int64"
+}
+
+func (i *int64Value) String() string { return strconv.FormatInt(int64(*i), 10) }
+
+func int64Conv(sval string) (interface{}, error) {
+ return strconv.ParseInt(sval, 0, 64)
+}
+
+// GetInt64 return the int64 value of a flag with the given name
+func (f *FlagSet) GetInt64(name string) (int64, error) {
+ val, err := f.getFlagType(name, "int64", int64Conv)
+ if err != nil {
+ return 0, err
+ }
+ return val.(int64), nil
+}
+
+// Int64Var defines an int64 flag with specified name, default value, and usage string.
+// The argument p points to an int64 variable in which to store the value of the flag.
+func (f *FlagSet) Int64Var(p *int64, name string, value int64, usage string) {
+ f.VarP(newInt64Value(value, p), name, "", usage)
+}
+
+// Int64VarP is like Int64Var, but accepts a shorthand letter that can be used after a single dash.
+func (f *FlagSet) Int64VarP(p *int64, name, shorthand string, value int64, usage string) {
+ f.VarP(newInt64Value(value, p), name, shorthand, usage)
+}
+
+// Int64Var defines an int64 flag with specified name, default value, and usage string.
+// The argument p points to an int64 variable in which to store the value of the flag.
+func Int64Var(p *int64, name string, value int64, usage string) {
+ CommandLine.VarP(newInt64Value(value, p), name, "", usage)
+}
+
+// Int64VarP is like Int64Var, but accepts a shorthand letter that can be used after a single dash.
+func Int64VarP(p *int64, name, shorthand string, value int64, usage string) {
+ CommandLine.VarP(newInt64Value(value, p), name, shorthand, usage)
+}
+
+// Int64 defines an int64 flag with specified name, default value, and usage string.
+// The return value is the address of an int64 variable that stores the value of the flag.
+func (f *FlagSet) Int64(name string, value int64, usage string) *int64 {
+ p := new(int64)
+ f.Int64VarP(p, name, "", value, usage)
+ return p
+}
+
+// Int64P is like Int64, but accepts a shorthand letter that can be used after a single dash.
+func (f *FlagSet) Int64P(name, shorthand string, value int64, usage string) *int64 {
+ p := new(int64)
+ f.Int64VarP(p, name, shorthand, value, usage)
+ return p
+}
+
+// Int64 defines an int64 flag with specified name, default value, and usage string.
+// The return value is the address of an int64 variable that stores the value of the flag.
+func Int64(name string, value int64, usage string) *int64 {
+ return CommandLine.Int64P(name, "", value, usage)
+}
+
+// Int64P is like Int64, but accepts a shorthand letter that can be used after a single dash.
+func Int64P(name, shorthand string, value int64, usage string) *int64 {
+ return CommandLine.Int64P(name, shorthand, value, usage)
+}
diff --git a/vendor/github.com/spf13/pflag/int64_slice.go b/vendor/github.com/spf13/pflag/int64_slice.go
new file mode 100644
index 0000000000000000000000000000000000000000..25464638f3ab60c17e73617abe428c55f6cf8c6e
--- /dev/null
+++ b/vendor/github.com/spf13/pflag/int64_slice.go
@@ -0,0 +1,166 @@
+package pflag
+
+import (
+ "fmt"
+ "strconv"
+ "strings"
+)
+
+// -- int64Slice Value
+type int64SliceValue struct {
+ value *[]int64
+ changed bool
+}
+
+func newInt64SliceValue(val []int64, p *[]int64) *int64SliceValue {
+ isv := new(int64SliceValue)
+ isv.value = p
+ *isv.value = val
+ return isv
+}
+
+func (s *int64SliceValue) Set(val string) error {
+ ss := strings.Split(val, ",")
+ out := make([]int64, len(ss))
+ for i, d := range ss {
+ var err error
+ out[i], err = strconv.ParseInt(d, 0, 64)
+ if err != nil {
+ return err
+ }
+
+ }
+ if !s.changed {
+ *s.value = out
+ } else {
+ *s.value = append(*s.value, out...)
+ }
+ s.changed = true
+ return nil
+}
+
+func (s *int64SliceValue) Type() string {
+ return "int64Slice"
+}
+
+func (s *int64SliceValue) String() string {
+ out := make([]string, len(*s.value))
+ for i, d := range *s.value {
+ out[i] = fmt.Sprintf("%d", d)
+ }
+ return "[" + strings.Join(out, ",") + "]"
+}
+
+func (s *int64SliceValue) fromString(val string) (int64, error) {
+ return strconv.ParseInt(val, 0, 64)
+}
+
+func (s *int64SliceValue) toString(val int64) string {
+ return fmt.Sprintf("%d", val)
+}
+
+func (s *int64SliceValue) Append(val string) error {
+ i, err := s.fromString(val)
+ if err != nil {
+ return err
+ }
+ *s.value = append(*s.value, i)
+ return nil
+}
+
+func (s *int64SliceValue) Replace(val []string) error {
+ out := make([]int64, len(val))
+ for i, d := range val {
+ var err error
+ out[i], err = s.fromString(d)
+ if err != nil {
+ return err
+ }
+ }
+ *s.value = out
+ return nil
+}
+
+func (s *int64SliceValue) GetSlice() []string {
+ out := make([]string, len(*s.value))
+ for i, d := range *s.value {
+ out[i] = s.toString(d)
+ }
+ return out
+}
+
+func int64SliceConv(val string) (interface{}, error) {
+ val = strings.Trim(val, "[]")
+ // Empty string would cause a slice with one (empty) entry
+ if len(val) == 0 {
+ return []int64{}, nil
+ }
+ ss := strings.Split(val, ",")
+ out := make([]int64, len(ss))
+ for i, d := range ss {
+ var err error
+ out[i], err = strconv.ParseInt(d, 0, 64)
+ if err != nil {
+ return nil, err
+ }
+
+ }
+ return out, nil
+}
+
+// GetInt64Slice return the []int64 value of a flag with the given name
+func (f *FlagSet) GetInt64Slice(name string) ([]int64, error) {
+ val, err := f.getFlagType(name, "int64Slice", int64SliceConv)
+ if err != nil {
+ return []int64{}, err
+ }
+ return val.([]int64), nil
+}
+
+// Int64SliceVar defines a int64Slice flag with specified name, default value, and usage string.
+// The argument p points to a []int64 variable in which to store the value of the flag.
+func (f *FlagSet) Int64SliceVar(p *[]int64, name string, value []int64, usage string) {
+ f.VarP(newInt64SliceValue(value, p), name, "", usage)
+}
+
+// Int64SliceVarP is like Int64SliceVar, but accepts a shorthand letter that can be used after a single dash.
+func (f *FlagSet) Int64SliceVarP(p *[]int64, name, shorthand string, value []int64, usage string) {
+ f.VarP(newInt64SliceValue(value, p), name, shorthand, usage)
+}
+
+// Int64SliceVar defines a int64[] flag with specified name, default value, and usage string.
+// The argument p points to a int64[] variable in which to store the value of the flag.
+func Int64SliceVar(p *[]int64, name string, value []int64, usage string) {
+ CommandLine.VarP(newInt64SliceValue(value, p), name, "", usage)
+}
+
+// Int64SliceVarP is like Int64SliceVar, but accepts a shorthand letter that can be used after a single dash.
+func Int64SliceVarP(p *[]int64, name, shorthand string, value []int64, usage string) {
+ CommandLine.VarP(newInt64SliceValue(value, p), name, shorthand, usage)
+}
+
+// Int64Slice defines a []int64 flag with specified name, default value, and usage string.
+// The return value is the address of a []int64 variable that stores the value of the flag.
+func (f *FlagSet) Int64Slice(name string, value []int64, usage string) *[]int64 {
+ p := []int64{}
+ f.Int64SliceVarP(&p, name, "", value, usage)
+ return &p
+}
+
+// Int64SliceP is like Int64Slice, but accepts a shorthand letter that can be used after a single dash.
+func (f *FlagSet) Int64SliceP(name, shorthand string, value []int64, usage string) *[]int64 {
+ p := []int64{}
+ f.Int64SliceVarP(&p, name, shorthand, value, usage)
+ return &p
+}
+
+// Int64Slice defines a []int64 flag with specified name, default value, and usage string.
+// The return value is the address of a []int64 variable that stores the value of the flag.
+func Int64Slice(name string, value []int64, usage string) *[]int64 {
+ return CommandLine.Int64SliceP(name, "", value, usage)
+}
+
+// Int64SliceP is like Int64Slice, but accepts a shorthand letter that can be used after a single dash.
+func Int64SliceP(name, shorthand string, value []int64, usage string) *[]int64 {
+ return CommandLine.Int64SliceP(name, shorthand, value, usage)
+}
diff --git a/vendor/github.com/spf13/pflag/int8.go b/vendor/github.com/spf13/pflag/int8.go
new file mode 100644
index 0000000000000000000000000000000000000000..4da92228e63e24f3c3ecfcc98493ca222fa797c0
--- /dev/null
+++ b/vendor/github.com/spf13/pflag/int8.go
@@ -0,0 +1,88 @@
+package pflag
+
+import "strconv"
+
+// -- int8 Value
+type int8Value int8
+
+func newInt8Value(val int8, p *int8) *int8Value {
+ *p = val
+ return (*int8Value)(p)
+}
+
+func (i *int8Value) Set(s string) error {
+ v, err := strconv.ParseInt(s, 0, 8)
+ *i = int8Value(v)
+ return err
+}
+
+func (i *int8Value) Type() string {
+ return "int8"
+}
+
+func (i *int8Value) String() string { return strconv.FormatInt(int64(*i), 10) }
+
+func int8Conv(sval string) (interface{}, error) {
+ v, err := strconv.ParseInt(sval, 0, 8)
+ if err != nil {
+ return 0, err
+ }
+ return int8(v), nil
+}
+
+// GetInt8 return the int8 value of a flag with the given name
+func (f *FlagSet) GetInt8(name string) (int8, error) {
+ val, err := f.getFlagType(name, "int8", int8Conv)
+ if err != nil {
+ return 0, err
+ }
+ return val.(int8), nil
+}
+
+// Int8Var defines an int8 flag with specified name, default value, and usage string.
+// The argument p points to an int8 variable in which to store the value of the flag.
+func (f *FlagSet) Int8Var(p *int8, name string, value int8, usage string) {
+ f.VarP(newInt8Value(value, p), name, "", usage)
+}
+
+// Int8VarP is like Int8Var, but accepts a shorthand letter that can be used after a single dash.
+func (f *FlagSet) Int8VarP(p *int8, name, shorthand string, value int8, usage string) {
+ f.VarP(newInt8Value(value, p), name, shorthand, usage)
+}
+
+// Int8Var defines an int8 flag with specified name, default value, and usage string.
+// The argument p points to an int8 variable in which to store the value of the flag.
+func Int8Var(p *int8, name string, value int8, usage string) {
+ CommandLine.VarP(newInt8Value(value, p), name, "", usage)
+}
+
+// Int8VarP is like Int8Var, but accepts a shorthand letter that can be used after a single dash.
+func Int8VarP(p *int8, name, shorthand string, value int8, usage string) {
+ CommandLine.VarP(newInt8Value(value, p), name, shorthand, usage)
+}
+
+// Int8 defines an int8 flag with specified name, default value, and usage string.
+// The return value is the address of an int8 variable that stores the value of the flag.
+func (f *FlagSet) Int8(name string, value int8, usage string) *int8 {
+ p := new(int8)
+ f.Int8VarP(p, name, "", value, usage)
+ return p
+}
+
+// Int8P is like Int8, but accepts a shorthand letter that can be used after a single dash.
+func (f *FlagSet) Int8P(name, shorthand string, value int8, usage string) *int8 {
+ p := new(int8)
+ f.Int8VarP(p, name, shorthand, value, usage)
+ return p
+}
+
+// Int8 defines an int8 flag with specified name, default value, and usage string.
+// The return value is the address of an int8 variable that stores the value of the flag.
+func Int8(name string, value int8, usage string) *int8 {
+ return CommandLine.Int8P(name, "", value, usage)
+}
+
+// Int8P is like Int8, but accepts a shorthand letter that can be used after a single dash.
+func Int8P(name, shorthand string, value int8, usage string) *int8 {
+ return CommandLine.Int8P(name, shorthand, value, usage)
+}
diff --git a/vendor/github.com/spf13/pflag/int_slice.go b/vendor/github.com/spf13/pflag/int_slice.go
new file mode 100644
index 0000000000000000000000000000000000000000..e71c39d91aa710719e1ab9d1ba101015e2545d04
--- /dev/null
+++ b/vendor/github.com/spf13/pflag/int_slice.go
@@ -0,0 +1,158 @@
+package pflag
+
+import (
+ "fmt"
+ "strconv"
+ "strings"
+)
+
+// -- intSlice Value
+type intSliceValue struct {
+ value *[]int
+ changed bool
+}
+
+func newIntSliceValue(val []int, p *[]int) *intSliceValue {
+ isv := new(intSliceValue)
+ isv.value = p
+ *isv.value = val
+ return isv
+}
+
+func (s *intSliceValue) Set(val string) error {
+ ss := strings.Split(val, ",")
+ out := make([]int, len(ss))
+ for i, d := range ss {
+ var err error
+ out[i], err = strconv.Atoi(d)
+ if err != nil {
+ return err
+ }
+
+ }
+ if !s.changed {
+ *s.value = out
+ } else {
+ *s.value = append(*s.value, out...)
+ }
+ s.changed = true
+ return nil
+}
+
+func (s *intSliceValue) Type() string {
+ return "intSlice"
+}
+
+func (s *intSliceValue) String() string {
+ out := make([]string, len(*s.value))
+ for i, d := range *s.value {
+ out[i] = fmt.Sprintf("%d", d)
+ }
+ return "[" + strings.Join(out, ",") + "]"
+}
+
+func (s *intSliceValue) Append(val string) error {
+ i, err := strconv.Atoi(val)
+ if err != nil {
+ return err
+ }
+ *s.value = append(*s.value, i)
+ return nil
+}
+
+func (s *intSliceValue) Replace(val []string) error {
+ out := make([]int, len(val))
+ for i, d := range val {
+ var err error
+ out[i], err = strconv.Atoi(d)
+ if err != nil {
+ return err
+ }
+ }
+ *s.value = out
+ return nil
+}
+
+func (s *intSliceValue) GetSlice() []string {
+ out := make([]string, len(*s.value))
+ for i, d := range *s.value {
+ out[i] = strconv.Itoa(d)
+ }
+ return out
+}
+
+func intSliceConv(val string) (interface{}, error) {
+ val = strings.Trim(val, "[]")
+ // Empty string would cause a slice with one (empty) entry
+ if len(val) == 0 {
+ return []int{}, nil
+ }
+ ss := strings.Split(val, ",")
+ out := make([]int, len(ss))
+ for i, d := range ss {
+ var err error
+ out[i], err = strconv.Atoi(d)
+ if err != nil {
+ return nil, err
+ }
+
+ }
+ return out, nil
+}
+
+// GetIntSlice return the []int value of a flag with the given name
+func (f *FlagSet) GetIntSlice(name string) ([]int, error) {
+ val, err := f.getFlagType(name, "intSlice", intSliceConv)
+ if err != nil {
+ return []int{}, err
+ }
+ return val.([]int), nil
+}
+
+// IntSliceVar defines a intSlice flag with specified name, default value, and usage string.
+// The argument p points to a []int variable in which to store the value of the flag.
+func (f *FlagSet) IntSliceVar(p *[]int, name string, value []int, usage string) {
+ f.VarP(newIntSliceValue(value, p), name, "", usage)
+}
+
+// IntSliceVarP is like IntSliceVar, but accepts a shorthand letter that can be used after a single dash.
+func (f *FlagSet) IntSliceVarP(p *[]int, name, shorthand string, value []int, usage string) {
+ f.VarP(newIntSliceValue(value, p), name, shorthand, usage)
+}
+
+// IntSliceVar defines a int[] flag with specified name, default value, and usage string.
+// The argument p points to a int[] variable in which to store the value of the flag.
+func IntSliceVar(p *[]int, name string, value []int, usage string) {
+ CommandLine.VarP(newIntSliceValue(value, p), name, "", usage)
+}
+
+// IntSliceVarP is like IntSliceVar, but accepts a shorthand letter that can be used after a single dash.
+func IntSliceVarP(p *[]int, name, shorthand string, value []int, usage string) {
+ CommandLine.VarP(newIntSliceValue(value, p), name, shorthand, usage)
+}
+
+// IntSlice defines a []int flag with specified name, default value, and usage string.
+// The return value is the address of a []int variable that stores the value of the flag.
+func (f *FlagSet) IntSlice(name string, value []int, usage string) *[]int {
+ p := []int{}
+ f.IntSliceVarP(&p, name, "", value, usage)
+ return &p
+}
+
+// IntSliceP is like IntSlice, but accepts a shorthand letter that can be used after a single dash.
+func (f *FlagSet) IntSliceP(name, shorthand string, value []int, usage string) *[]int {
+ p := []int{}
+ f.IntSliceVarP(&p, name, shorthand, value, usage)
+ return &p
+}
+
+// IntSlice defines a []int flag with specified name, default value, and usage string.
+// The return value is the address of a []int variable that stores the value of the flag.
+func IntSlice(name string, value []int, usage string) *[]int {
+ return CommandLine.IntSliceP(name, "", value, usage)
+}
+
+// IntSliceP is like IntSlice, but accepts a shorthand letter that can be used after a single dash.
+func IntSliceP(name, shorthand string, value []int, usage string) *[]int {
+ return CommandLine.IntSliceP(name, shorthand, value, usage)
+}
diff --git a/vendor/github.com/spf13/pflag/ip.go b/vendor/github.com/spf13/pflag/ip.go
new file mode 100644
index 0000000000000000000000000000000000000000..3d414ba69fe1d3881c1551a5cdf2850b3886d35a
--- /dev/null
+++ b/vendor/github.com/spf13/pflag/ip.go
@@ -0,0 +1,94 @@
+package pflag
+
+import (
+ "fmt"
+ "net"
+ "strings"
+)
+
+// -- net.IP value
+type ipValue net.IP
+
+func newIPValue(val net.IP, p *net.IP) *ipValue {
+ *p = val
+ return (*ipValue)(p)
+}
+
+func (i *ipValue) String() string { return net.IP(*i).String() }
+func (i *ipValue) Set(s string) error {
+ ip := net.ParseIP(strings.TrimSpace(s))
+ if ip == nil {
+ return fmt.Errorf("failed to parse IP: %q", s)
+ }
+ *i = ipValue(ip)
+ return nil
+}
+
+func (i *ipValue) Type() string {
+ return "ip"
+}
+
+func ipConv(sval string) (interface{}, error) {
+ ip := net.ParseIP(sval)
+ if ip != nil {
+ return ip, nil
+ }
+ return nil, fmt.Errorf("invalid string being converted to IP address: %s", sval)
+}
+
+// GetIP return the net.IP value of a flag with the given name
+func (f *FlagSet) GetIP(name string) (net.IP, error) {
+ val, err := f.getFlagType(name, "ip", ipConv)
+ if err != nil {
+ return nil, err
+ }
+ return val.(net.IP), nil
+}
+
+// IPVar defines an net.IP flag with specified name, default value, and usage string.
+// The argument p points to an net.IP variable in which to store the value of the flag.
+func (f *FlagSet) IPVar(p *net.IP, name string, value net.IP, usage string) {
+ f.VarP(newIPValue(value, p), name, "", usage)
+}
+
+// IPVarP is like IPVar, but accepts a shorthand letter that can be used after a single dash.
+func (f *FlagSet) IPVarP(p *net.IP, name, shorthand string, value net.IP, usage string) {
+ f.VarP(newIPValue(value, p), name, shorthand, usage)
+}
+
+// IPVar defines an net.IP flag with specified name, default value, and usage string.
+// The argument p points to an net.IP variable in which to store the value of the flag.
+func IPVar(p *net.IP, name string, value net.IP, usage string) {
+ CommandLine.VarP(newIPValue(value, p), name, "", usage)
+}
+
+// IPVarP is like IPVar, but accepts a shorthand letter that can be used after a single dash.
+func IPVarP(p *net.IP, name, shorthand string, value net.IP, usage string) {
+ CommandLine.VarP(newIPValue(value, p), name, shorthand, usage)
+}
+
+// IP defines an net.IP flag with specified name, default value, and usage string.
+// The return value is the address of an net.IP variable that stores the value of the flag.
+func (f *FlagSet) IP(name string, value net.IP, usage string) *net.IP {
+ p := new(net.IP)
+ f.IPVarP(p, name, "", value, usage)
+ return p
+}
+
+// IPP is like IP, but accepts a shorthand letter that can be used after a single dash.
+func (f *FlagSet) IPP(name, shorthand string, value net.IP, usage string) *net.IP {
+ p := new(net.IP)
+ f.IPVarP(p, name, shorthand, value, usage)
+ return p
+}
+
+// IP defines an net.IP flag with specified name, default value, and usage string.
+// The return value is the address of an net.IP variable that stores the value of the flag.
+func IP(name string, value net.IP, usage string) *net.IP {
+ return CommandLine.IPP(name, "", value, usage)
+}
+
+// IPP is like IP, but accepts a shorthand letter that can be used after a single dash.
+func IPP(name, shorthand string, value net.IP, usage string) *net.IP {
+ return CommandLine.IPP(name, shorthand, value, usage)
+}
diff --git a/vendor/github.com/spf13/pflag/ip_slice.go b/vendor/github.com/spf13/pflag/ip_slice.go
new file mode 100644
index 0000000000000000000000000000000000000000..775faae4fd8d2bb79954058dedc0ff950535e9d6
--- /dev/null
+++ b/vendor/github.com/spf13/pflag/ip_slice.go
@@ -0,0 +1,186 @@
+package pflag
+
+import (
+ "fmt"
+ "io"
+ "net"
+ "strings"
+)
+
+// -- ipSlice Value
+type ipSliceValue struct {
+ value *[]net.IP
+ changed bool
+}
+
+func newIPSliceValue(val []net.IP, p *[]net.IP) *ipSliceValue {
+ ipsv := new(ipSliceValue)
+ ipsv.value = p
+ *ipsv.value = val
+ return ipsv
+}
+
+// Set converts, and assigns, the comma-separated IP argument string representation as the []net.IP value of this flag.
+// If Set is called on a flag that already has a []net.IP assigned, the newly converted values will be appended.
+func (s *ipSliceValue) Set(val string) error {
+
+ // remove all quote characters
+ rmQuote := strings.NewReplacer(`"`, "", `'`, "", "`", "")
+
+ // read flag arguments with CSV parser
+ ipStrSlice, err := readAsCSV(rmQuote.Replace(val))
+ if err != nil && err != io.EOF {
+ return err
+ }
+
+ // parse ip values into slice
+ out := make([]net.IP, 0, len(ipStrSlice))
+ for _, ipStr := range ipStrSlice {
+ ip := net.ParseIP(strings.TrimSpace(ipStr))
+ if ip == nil {
+ return fmt.Errorf("invalid string being converted to IP address: %s", ipStr)
+ }
+ out = append(out, ip)
+ }
+
+ if !s.changed {
+ *s.value = out
+ } else {
+ *s.value = append(*s.value, out...)
+ }
+
+ s.changed = true
+
+ return nil
+}
+
+// Type returns a string that uniquely represents this flag's type.
+func (s *ipSliceValue) Type() string {
+ return "ipSlice"
+}
+
+// String defines a "native" format for this net.IP slice flag value.
+func (s *ipSliceValue) String() string {
+
+ ipStrSlice := make([]string, len(*s.value))
+ for i, ip := range *s.value {
+ ipStrSlice[i] = ip.String()
+ }
+
+ out, _ := writeAsCSV(ipStrSlice)
+
+ return "[" + out + "]"
+}
+
+func (s *ipSliceValue) fromString(val string) (net.IP, error) {
+ return net.ParseIP(strings.TrimSpace(val)), nil
+}
+
+func (s *ipSliceValue) toString(val net.IP) string {
+ return val.String()
+}
+
+func (s *ipSliceValue) Append(val string) error {
+ i, err := s.fromString(val)
+ if err != nil {
+ return err
+ }
+ *s.value = append(*s.value, i)
+ return nil
+}
+
+func (s *ipSliceValue) Replace(val []string) error {
+ out := make([]net.IP, len(val))
+ for i, d := range val {
+ var err error
+ out[i], err = s.fromString(d)
+ if err != nil {
+ return err
+ }
+ }
+ *s.value = out
+ return nil
+}
+
+func (s *ipSliceValue) GetSlice() []string {
+ out := make([]string, len(*s.value))
+ for i, d := range *s.value {
+ out[i] = s.toString(d)
+ }
+ return out
+}
+
+func ipSliceConv(val string) (interface{}, error) {
+ val = strings.Trim(val, "[]")
+ // Empty string would cause a slice with one (empty) entry
+ if len(val) == 0 {
+ return []net.IP{}, nil
+ }
+ ss := strings.Split(val, ",")
+ out := make([]net.IP, len(ss))
+ for i, sval := range ss {
+ ip := net.ParseIP(strings.TrimSpace(sval))
+ if ip == nil {
+ return nil, fmt.Errorf("invalid string being converted to IP address: %s", sval)
+ }
+ out[i] = ip
+ }
+ return out, nil
+}
+
+// GetIPSlice returns the []net.IP value of a flag with the given name
+func (f *FlagSet) GetIPSlice(name string) ([]net.IP, error) {
+ val, err := f.getFlagType(name, "ipSlice", ipSliceConv)
+ if err != nil {
+ return []net.IP{}, err
+ }
+ return val.([]net.IP), nil
+}
+
+// IPSliceVar defines a ipSlice flag with specified name, default value, and usage string.
+// The argument p points to a []net.IP variable in which to store the value of the flag.
+func (f *FlagSet) IPSliceVar(p *[]net.IP, name string, value []net.IP, usage string) {
+ f.VarP(newIPSliceValue(value, p), name, "", usage)
+}
+
+// IPSliceVarP is like IPSliceVar, but accepts a shorthand letter that can be used after a single dash.
+func (f *FlagSet) IPSliceVarP(p *[]net.IP, name, shorthand string, value []net.IP, usage string) {
+ f.VarP(newIPSliceValue(value, p), name, shorthand, usage)
+}
+
+// IPSliceVar defines a []net.IP flag with specified name, default value, and usage string.
+// The argument p points to a []net.IP variable in which to store the value of the flag.
+func IPSliceVar(p *[]net.IP, name string, value []net.IP, usage string) {
+ CommandLine.VarP(newIPSliceValue(value, p), name, "", usage)
+}
+
+// IPSliceVarP is like IPSliceVar, but accepts a shorthand letter that can be used after a single dash.
+func IPSliceVarP(p *[]net.IP, name, shorthand string, value []net.IP, usage string) {
+ CommandLine.VarP(newIPSliceValue(value, p), name, shorthand, usage)
+}
+
+// IPSlice defines a []net.IP flag with specified name, default value, and usage string.
+// The return value is the address of a []net.IP variable that stores the value of that flag.
+func (f *FlagSet) IPSlice(name string, value []net.IP, usage string) *[]net.IP {
+ p := []net.IP{}
+ f.IPSliceVarP(&p, name, "", value, usage)
+ return &p
+}
+
+// IPSliceP is like IPSlice, but accepts a shorthand letter that can be used after a single dash.
+func (f *FlagSet) IPSliceP(name, shorthand string, value []net.IP, usage string) *[]net.IP {
+ p := []net.IP{}
+ f.IPSliceVarP(&p, name, shorthand, value, usage)
+ return &p
+}
+
+// IPSlice defines a []net.IP flag with specified name, default value, and usage string.
+// The return value is the address of a []net.IP variable that stores the value of the flag.
+func IPSlice(name string, value []net.IP, usage string) *[]net.IP {
+ return CommandLine.IPSliceP(name, "", value, usage)
+}
+
+// IPSliceP is like IPSlice, but accepts a shorthand letter that can be used after a single dash.
+func IPSliceP(name, shorthand string, value []net.IP, usage string) *[]net.IP {
+ return CommandLine.IPSliceP(name, shorthand, value, usage)
+}
diff --git a/vendor/github.com/spf13/pflag/ipmask.go b/vendor/github.com/spf13/pflag/ipmask.go
new file mode 100644
index 0000000000000000000000000000000000000000..5bd44bd21d27ee553e2828f80190673c8ad2c6e8
--- /dev/null
+++ b/vendor/github.com/spf13/pflag/ipmask.go
@@ -0,0 +1,122 @@
+package pflag
+
+import (
+ "fmt"
+ "net"
+ "strconv"
+)
+
+// -- net.IPMask value
+type ipMaskValue net.IPMask
+
+func newIPMaskValue(val net.IPMask, p *net.IPMask) *ipMaskValue {
+ *p = val
+ return (*ipMaskValue)(p)
+}
+
+func (i *ipMaskValue) String() string { return net.IPMask(*i).String() }
+func (i *ipMaskValue) Set(s string) error {
+ ip := ParseIPv4Mask(s)
+ if ip == nil {
+ return fmt.Errorf("failed to parse IP mask: %q", s)
+ }
+ *i = ipMaskValue(ip)
+ return nil
+}
+
+func (i *ipMaskValue) Type() string {
+ return "ipMask"
+}
+
+// ParseIPv4Mask written in IP form (e.g. 255.255.255.0).
+// This function should really belong to the net package.
+func ParseIPv4Mask(s string) net.IPMask {
+ mask := net.ParseIP(s)
+ if mask == nil {
+ if len(s) != 8 {
+ return nil
+ }
+ // net.IPMask.String() actually outputs things like ffffff00
+ // so write a horrible parser for that as well :-(
+ m := []int{}
+ for i := 0; i < 4; i++ {
+ b := "0x" + s[2*i:2*i+2]
+ d, err := strconv.ParseInt(b, 0, 0)
+ if err != nil {
+ return nil
+ }
+ m = append(m, int(d))
+ }
+ s := fmt.Sprintf("%d.%d.%d.%d", m[0], m[1], m[2], m[3])
+ mask = net.ParseIP(s)
+ if mask == nil {
+ return nil
+ }
+ }
+ return net.IPv4Mask(mask[12], mask[13], mask[14], mask[15])
+}
+
+func parseIPv4Mask(sval string) (interface{}, error) {
+ mask := ParseIPv4Mask(sval)
+ if mask == nil {
+ return nil, fmt.Errorf("unable to parse %s as net.IPMask", sval)
+ }
+ return mask, nil
+}
+
+// GetIPv4Mask return the net.IPv4Mask value of a flag with the given name
+func (f *FlagSet) GetIPv4Mask(name string) (net.IPMask, error) {
+ val, err := f.getFlagType(name, "ipMask", parseIPv4Mask)
+ if err != nil {
+ return nil, err
+ }
+ return val.(net.IPMask), nil
+}
+
+// IPMaskVar defines an net.IPMask flag with specified name, default value, and usage string.
+// The argument p points to an net.IPMask variable in which to store the value of the flag.
+func (f *FlagSet) IPMaskVar(p *net.IPMask, name string, value net.IPMask, usage string) {
+ f.VarP(newIPMaskValue(value, p), name, "", usage)
+}
+
+// IPMaskVarP is like IPMaskVar, but accepts a shorthand letter that can be used after a single dash.
+func (f *FlagSet) IPMaskVarP(p *net.IPMask, name, shorthand string, value net.IPMask, usage string) {
+ f.VarP(newIPMaskValue(value, p), name, shorthand, usage)
+}
+
+// IPMaskVar defines an net.IPMask flag with specified name, default value, and usage string.
+// The argument p points to an net.IPMask variable in which to store the value of the flag.
+func IPMaskVar(p *net.IPMask, name string, value net.IPMask, usage string) {
+ CommandLine.VarP(newIPMaskValue(value, p), name, "", usage)
+}
+
+// IPMaskVarP is like IPMaskVar, but accepts a shorthand letter that can be used after a single dash.
+func IPMaskVarP(p *net.IPMask, name, shorthand string, value net.IPMask, usage string) {
+ CommandLine.VarP(newIPMaskValue(value, p), name, shorthand, usage)
+}
+
+// IPMask defines an net.IPMask flag with specified name, default value, and usage string.
+// The return value is the address of an net.IPMask variable that stores the value of the flag.
+func (f *FlagSet) IPMask(name string, value net.IPMask, usage string) *net.IPMask {
+ p := new(net.IPMask)
+ f.IPMaskVarP(p, name, "", value, usage)
+ return p
+}
+
+// IPMaskP is like IPMask, but accepts a shorthand letter that can be used after a single dash.
+func (f *FlagSet) IPMaskP(name, shorthand string, value net.IPMask, usage string) *net.IPMask {
+ p := new(net.IPMask)
+ f.IPMaskVarP(p, name, shorthand, value, usage)
+ return p
+}
+
+// IPMask defines an net.IPMask flag with specified name, default value, and usage string.
+// The return value is the address of an net.IPMask variable that stores the value of the flag.
+func IPMask(name string, value net.IPMask, usage string) *net.IPMask {
+ return CommandLine.IPMaskP(name, "", value, usage)
+}
+
+// IPMaskP is like IP, but accepts a shorthand letter that can be used after a single dash.
+func IPMaskP(name, shorthand string, value net.IPMask, usage string) *net.IPMask {
+ return CommandLine.IPMaskP(name, shorthand, value, usage)
+}
diff --git a/vendor/github.com/spf13/pflag/ipnet.go b/vendor/github.com/spf13/pflag/ipnet.go
new file mode 100644
index 0000000000000000000000000000000000000000..e2c1b8bcd53a53f9134a6e33741d32b9a31cdfba
--- /dev/null
+++ b/vendor/github.com/spf13/pflag/ipnet.go
@@ -0,0 +1,98 @@
+package pflag
+
+import (
+ "fmt"
+ "net"
+ "strings"
+)
+
+// IPNet adapts net.IPNet for use as a flag.
+type ipNetValue net.IPNet
+
+func (ipnet ipNetValue) String() string {
+ n := net.IPNet(ipnet)
+ return n.String()
+}
+
+func (ipnet *ipNetValue) Set(value string) error {
+ _, n, err := net.ParseCIDR(strings.TrimSpace(value))
+ if err != nil {
+ return err
+ }
+ *ipnet = ipNetValue(*n)
+ return nil
+}
+
+func (*ipNetValue) Type() string {
+ return "ipNet"
+}
+
+func newIPNetValue(val net.IPNet, p *net.IPNet) *ipNetValue {
+ *p = val
+ return (*ipNetValue)(p)
+}
+
+func ipNetConv(sval string) (interface{}, error) {
+ _, n, err := net.ParseCIDR(strings.TrimSpace(sval))
+ if err == nil {
+ return *n, nil
+ }
+ return nil, fmt.Errorf("invalid string being converted to IPNet: %s", sval)
+}
+
+// GetIPNet return the net.IPNet value of a flag with the given name
+func (f *FlagSet) GetIPNet(name string) (net.IPNet, error) {
+ val, err := f.getFlagType(name, "ipNet", ipNetConv)
+ if err != nil {
+ return net.IPNet{}, err
+ }
+ return val.(net.IPNet), nil
+}
+
+// IPNetVar defines an net.IPNet flag with specified name, default value, and usage string.
+// The argument p points to an net.IPNet variable in which to store the value of the flag.
+func (f *FlagSet) IPNetVar(p *net.IPNet, name string, value net.IPNet, usage string) {
+ f.VarP(newIPNetValue(value, p), name, "", usage)
+}
+
+// IPNetVarP is like IPNetVar, but accepts a shorthand letter that can be used after a single dash.
+func (f *FlagSet) IPNetVarP(p *net.IPNet, name, shorthand string, value net.IPNet, usage string) {
+ f.VarP(newIPNetValue(value, p), name, shorthand, usage)
+}
+
+// IPNetVar defines an net.IPNet flag with specified name, default value, and usage string.
+// The argument p points to an net.IPNet variable in which to store the value of the flag.
+func IPNetVar(p *net.IPNet, name string, value net.IPNet, usage string) {
+ CommandLine.VarP(newIPNetValue(value, p), name, "", usage)
+}
+
+// IPNetVarP is like IPNetVar, but accepts a shorthand letter that can be used after a single dash.
+func IPNetVarP(p *net.IPNet, name, shorthand string, value net.IPNet, usage string) {
+ CommandLine.VarP(newIPNetValue(value, p), name, shorthand, usage)
+}
+
+// IPNet defines an net.IPNet flag with specified name, default value, and usage string.
+// The return value is the address of an net.IPNet variable that stores the value of the flag.
+func (f *FlagSet) IPNet(name string, value net.IPNet, usage string) *net.IPNet {
+ p := new(net.IPNet)
+ f.IPNetVarP(p, name, "", value, usage)
+ return p
+}
+
+// IPNetP is like IPNet, but accepts a shorthand letter that can be used after a single dash.
+func (f *FlagSet) IPNetP(name, shorthand string, value net.IPNet, usage string) *net.IPNet {
+ p := new(net.IPNet)
+ f.IPNetVarP(p, name, shorthand, value, usage)
+ return p
+}
+
+// IPNet defines an net.IPNet flag with specified name, default value, and usage string.
+// The return value is the address of an net.IPNet variable that stores the value of the flag.
+func IPNet(name string, value net.IPNet, usage string) *net.IPNet {
+ return CommandLine.IPNetP(name, "", value, usage)
+}
+
+// IPNetP is like IPNet, but accepts a shorthand letter that can be used after a single dash.
+func IPNetP(name, shorthand string, value net.IPNet, usage string) *net.IPNet {
+ return CommandLine.IPNetP(name, shorthand, value, usage)
+}
diff --git a/vendor/github.com/spf13/pflag/string.go b/vendor/github.com/spf13/pflag/string.go
new file mode 100644
index 0000000000000000000000000000000000000000..04e0a26ff7f2653b7c569dabe8cb91296d76e288
--- /dev/null
+++ b/vendor/github.com/spf13/pflag/string.go
@@ -0,0 +1,80 @@
+package pflag
+
+// -- string Value
+type stringValue string
+
+func newStringValue(val string, p *string) *stringValue {
+ *p = val
+ return (*stringValue)(p)
+}
+
+func (s *stringValue) Set(val string) error {
+ *s = stringValue(val)
+ return nil
+}
+func (s *stringValue) Type() string {
+ return "string"
+}
+
+func (s *stringValue) String() string { return string(*s) }
+
+func stringConv(sval string) (interface{}, error) {
+ return sval, nil
+}
+
+// GetString return the string value of a flag with the given name
+func (f *FlagSet) GetString(name string) (string, error) {
+ val, err := f.getFlagType(name, "string", stringConv)
+ if err != nil {
+ return "", err
+ }
+ return val.(string), nil
+}
+
+// StringVar defines a string flag with specified name, default value, and usage string.
+// The argument p points to a string variable in which to store the value of the flag.
+func (f *FlagSet) StringVar(p *string, name string, value string, usage string) {
+ f.VarP(newStringValue(value, p), name, "", usage)
+}
+
+// StringVarP is like StringVar, but accepts a shorthand letter that can be used after a single dash.
+func (f *FlagSet) StringVarP(p *string, name, shorthand string, value string, usage string) {
+ f.VarP(newStringValue(value, p), name, shorthand, usage)
+}
+
+// StringVar defines a string flag with specified name, default value, and usage string.
+// The argument p points to a string variable in which to store the value of the flag.
+func StringVar(p *string, name string, value string, usage string) {
+ CommandLine.VarP(newStringValue(value, p), name, "", usage)
+}
+
+// StringVarP is like StringVar, but accepts a shorthand letter that can be used after a single dash.
+func StringVarP(p *string, name, shorthand string, value string, usage string) {
+ CommandLine.VarP(newStringValue(value, p), name, shorthand, usage)
+}
+
+// String defines a string flag with specified name, default value, and usage string.
+// The return value is the address of a string variable that stores the value of the flag.
+func (f *FlagSet) String(name string, value string, usage string) *string {
+ p := new(string)
+ f.StringVarP(p, name, "", value, usage)
+ return p
+}
+
+// StringP is like String, but accepts a shorthand letter that can be used after a single dash.
+func (f *FlagSet) StringP(name, shorthand string, value string, usage string) *string {
+ p := new(string)
+ f.StringVarP(p, name, shorthand, value, usage)
+ return p
+}
+
+// String defines a string flag with specified name, default value, and usage string.
+// The return value is the address of a string variable that stores the value of the flag.
+func String(name string, value string, usage string) *string {
+ return CommandLine.StringP(name, "", value, usage)
+}
+
+// StringP is like String, but accepts a shorthand letter that can be used after a single dash.
+func StringP(name, shorthand string, value string, usage string) *string {
+ return CommandLine.StringP(name, shorthand, value, usage)
+}
diff --git a/vendor/github.com/spf13/pflag/string_array.go b/vendor/github.com/spf13/pflag/string_array.go
new file mode 100644
index 0000000000000000000000000000000000000000..4894af818023bf132665556333e84426f80d7cc8
--- /dev/null
+++ b/vendor/github.com/spf13/pflag/string_array.go
@@ -0,0 +1,129 @@
+package pflag
+
+// -- stringArray Value
+type stringArrayValue struct {
+ value *[]string
+ changed bool
+}
+
+func newStringArrayValue(val []string, p *[]string) *stringArrayValue {
+ ssv := new(stringArrayValue)
+ ssv.value = p
+ *ssv.value = val
+ return ssv
+}
+
+func (s *stringArrayValue) Set(val string) error {
+ if !s.changed {
+ *s.value = []string{val}
+ s.changed = true
+ } else {
+ *s.value = append(*s.value, val)
+ }
+ return nil
+}
+
+func (s *stringArrayValue) Append(val string) error {
+ *s.value = append(*s.value, val)
+ return nil
+}
+
+func (s *stringArrayValue) Replace(val []string) error {
+ out := make([]string, len(val))
+ for i, d := range val {
+ var err error
+ out[i] = d
+ if err != nil {
+ return err
+ }
+ }
+ *s.value = out
+ return nil
+}
+
+func (s *stringArrayValue) GetSlice() []string {
+ out := make([]string, len(*s.value))
+ for i, d := range *s.value {
+ out[i] = d
+ }
+ return out
+}
+
+func (s *stringArrayValue) Type() string {
+ return "stringArray"
+}
+
+func (s *stringArrayValue) String() string {
+ str, _ := writeAsCSV(*s.value)
+ return "[" + str + "]"
+}
+
+func stringArrayConv(sval string) (interface{}, error) {
+ sval = sval[1 : len(sval)-1]
+ // An empty string would cause a array with one (empty) string
+ if len(sval) == 0 {
+ return []string{}, nil
+ }
+ return readAsCSV(sval)
+}
+
+// GetStringArray return the []string value of a flag with the given name
+func (f *FlagSet) GetStringArray(name string) ([]string, error) {
+ val, err := f.getFlagType(name, "stringArray", stringArrayConv)
+ if err != nil {
+ return []string{}, err
+ }
+ return val.([]string), nil
+}
+
+// StringArrayVar defines a string flag with specified name, default value, and usage string.
+// The argument p points to a []string variable in which to store the values of the multiple flags.
+// The value of each argument will not try to be separated by comma. Use a StringSlice for that.
+func (f *FlagSet) StringArrayVar(p *[]string, name string, value []string, usage string) {
+ f.VarP(newStringArrayValue(value, p), name, "", usage)
+}
+
+// StringArrayVarP is like StringArrayVar, but accepts a shorthand letter that can be used after a single dash.
+func (f *FlagSet) StringArrayVarP(p *[]string, name, shorthand string, value []string, usage string) {
+ f.VarP(newStringArrayValue(value, p), name, shorthand, usage)
+}
+
+// StringArrayVar defines a string flag with specified name, default value, and usage string.
+// The argument p points to a []string variable in which to store the value of the flag.
+// The value of each argument will not try to be separated by comma. Use a StringSlice for that.
+func StringArrayVar(p *[]string, name string, value []string, usage string) {
+ CommandLine.VarP(newStringArrayValue(value, p), name, "", usage)
+}
+
+// StringArrayVarP is like StringArrayVar, but accepts a shorthand letter that can be used after a single dash.
+func StringArrayVarP(p *[]string, name, shorthand string, value []string, usage string) {
+ CommandLine.VarP(newStringArrayValue(value, p), name, shorthand, usage)
+}
+
+// StringArray defines a string flag with specified name, default value, and usage string.
+// The return value is the address of a []string variable that stores the value of the flag.
+// The value of each argument will not try to be separated by comma. Use a StringSlice for that.
+func (f *FlagSet) StringArray(name string, value []string, usage string) *[]string {
+ p := []string{}
+ f.StringArrayVarP(&p, name, "", value, usage)
+ return &p
+}
+
+// StringArrayP is like StringArray, but accepts a shorthand letter that can be used after a single dash.
+func (f *FlagSet) StringArrayP(name, shorthand string, value []string, usage string) *[]string {
+ p := []string{}
+ f.StringArrayVarP(&p, name, shorthand, value, usage)
+ return &p
+}
+
+// StringArray defines a string flag with specified name, default value, and usage string.
+// The return value is the address of a []string variable that stores the value of the flag.
+// The value of each argument will not try to be separated by comma. Use a StringSlice for that.
+func StringArray(name string, value []string, usage string) *[]string {
+ return CommandLine.StringArrayP(name, "", value, usage)
+}
+
+// StringArrayP is like StringArray, but accepts a shorthand letter that can be used after a single dash.
+func StringArrayP(name, shorthand string, value []string, usage string) *[]string {
+ return CommandLine.StringArrayP(name, shorthand, value, usage)
+}
diff --git a/vendor/github.com/spf13/pflag/string_slice.go b/vendor/github.com/spf13/pflag/string_slice.go
new file mode 100644
index 0000000000000000000000000000000000000000..3cb2e69dba026d8a451f67f71e21fdff780ea58c
--- /dev/null
+++ b/vendor/github.com/spf13/pflag/string_slice.go
@@ -0,0 +1,163 @@
+package pflag
+
+import (
+ "bytes"
+ "encoding/csv"
+ "strings"
+)
+
+// -- stringSlice Value
+type stringSliceValue struct {
+ value *[]string
+ changed bool
+}
+
+func newStringSliceValue(val []string, p *[]string) *stringSliceValue {
+ ssv := new(stringSliceValue)
+ ssv.value = p
+ *ssv.value = val
+ return ssv
+}
+
+func readAsCSV(val string) ([]string, error) {
+ if val == "" {
+ return []string{}, nil
+ }
+ stringReader := strings.NewReader(val)
+ csvReader := csv.NewReader(stringReader)
+ return csvReader.Read()
+}
+
+func writeAsCSV(vals []string) (string, error) {
+ b := &bytes.Buffer{}
+ w := csv.NewWriter(b)
+ err := w.Write(vals)
+ if err != nil {
+ return "", err
+ }
+ w.Flush()
+ return strings.TrimSuffix(b.String(), "\n"), nil
+}
+
+func (s *stringSliceValue) Set(val string) error {
+ v, err := readAsCSV(val)
+ if err != nil {
+ return err
+ }
+ if !s.changed {
+ *s.value = v
+ } else {
+ *s.value = append(*s.value, v...)
+ }
+ s.changed = true
+ return nil
+}
+
+func (s *stringSliceValue) Type() string {
+ return "stringSlice"
+}
+
+func (s *stringSliceValue) String() string {
+ str, _ := writeAsCSV(*s.value)
+ return "[" + str + "]"
+}
+
+func (s *stringSliceValue) Append(val string) error {
+ *s.value = append(*s.value, val)
+ return nil
+}
+
+func (s *stringSliceValue) Replace(val []string) error {
+ *s.value = val
+ return nil
+}
+
+func (s *stringSliceValue) GetSlice() []string {
+ return *s.value
+}
+
+func stringSliceConv(sval string) (interface{}, error) {
+ sval = sval[1 : len(sval)-1]
+ // An empty string would cause a slice with one (empty) string
+ if len(sval) == 0 {
+ return []string{}, nil
+ }
+ return readAsCSV(sval)
+}
+
+// GetStringSlice return the []string value of a flag with the given name
+func (f *FlagSet) GetStringSlice(name string) ([]string, error) {
+ val, err := f.getFlagType(name, "stringSlice", stringSliceConv)
+ if err != nil {
+ return []string{}, err
+ }
+ return val.([]string), nil
+}
+
+// StringSliceVar defines a string flag with specified name, default value, and usage string.
+// The argument p points to a []string variable in which to store the value of the flag.
+// Compared to StringArray flags, StringSlice flags take comma-separated value as arguments and split them accordingly.
+// For example:
+// --ss="v1,v2" --ss="v3"
+// will result in
+// []string{"v1", "v2", "v3"}
+func (f *FlagSet) StringSliceVar(p *[]string, name string, value []string, usage string) {
+ f.VarP(newStringSliceValue(value, p), name, "", usage)
+}
+
+// StringSliceVarP is like StringSliceVar, but accepts a shorthand letter that can be used after a single dash.
+func (f *FlagSet) StringSliceVarP(p *[]string, name, shorthand string, value []string, usage string) {
+ f.VarP(newStringSliceValue(value, p), name, shorthand, usage)
+}
+
+// StringSliceVar defines a string flag with specified name, default value, and usage string.
+// The argument p points to a []string variable in which to store the value of the flag.
+// Compared to StringArray flags, StringSlice flags take comma-separated value as arguments and split them accordingly.
+// For example:
+// --ss="v1,v2" --ss="v3"
+// will result in
+// []string{"v1", "v2", "v3"}
+func StringSliceVar(p *[]string, name string, value []string, usage string) {
+ CommandLine.VarP(newStringSliceValue(value, p), name, "", usage)
+}
+
+// StringSliceVarP is like StringSliceVar, but accepts a shorthand letter that can be used after a single dash.
+func StringSliceVarP(p *[]string, name, shorthand string, value []string, usage string) {
+ CommandLine.VarP(newStringSliceValue(value, p), name, shorthand, usage)
+}
+
+// StringSlice defines a string flag with specified name, default value, and usage string.
+// The return value is the address of a []string variable that stores the value of the flag.
+// Compared to StringArray flags, StringSlice flags take comma-separated value as arguments and split them accordingly.
+// For example:
+// --ss="v1,v2" --ss="v3"
+// will result in
+// []string{"v1", "v2", "v3"}
+func (f *FlagSet) StringSlice(name string, value []string, usage string) *[]string {
+ p := []string{}
+ f.StringSliceVarP(&p, name, "", value, usage)
+ return &p
+}
+
+// StringSliceP is like StringSlice, but accepts a shorthand letter that can be used after a single dash.
+func (f *FlagSet) StringSliceP(name, shorthand string, value []string, usage string) *[]string {
+ p := []string{}
+ f.StringSliceVarP(&p, name, shorthand, value, usage)
+ return &p
+}
+
+// StringSlice defines a string flag with specified name, default value, and usage string.
+// The return value is the address of a []string variable that stores the value of the flag.
+// Compared to StringArray flags, StringSlice flags take comma-separated value as arguments and split them accordingly.
+// For example:
+// --ss="v1,v2" --ss="v3"
+// will result in
+// []string{"v1", "v2", "v3"}
+func StringSlice(name string, value []string, usage string) *[]string {
+ return CommandLine.StringSliceP(name, "", value, usage)
+}
+
+// StringSliceP is like StringSlice, but accepts a shorthand letter that can be used after a single dash.
+func StringSliceP(name, shorthand string, value []string, usage string) *[]string {
+ return CommandLine.StringSliceP(name, shorthand, value, usage)
+}
diff --git a/vendor/github.com/spf13/pflag/string_to_int.go b/vendor/github.com/spf13/pflag/string_to_int.go
new file mode 100644
index 0000000000000000000000000000000000000000..5ceda3965dfeb3080e613f08a79343a72d702231
--- /dev/null
+++ b/vendor/github.com/spf13/pflag/string_to_int.go
@@ -0,0 +1,149 @@
+package pflag
+
+import (
+ "bytes"
+ "fmt"
+ "strconv"
+ "strings"
+)
+
+// -- stringToInt Value
+type stringToIntValue struct {
+ value *map[string]int
+ changed bool
+}
+
+func newStringToIntValue(val map[string]int, p *map[string]int) *stringToIntValue {
+ ssv := new(stringToIntValue)
+ ssv.value = p
+ *ssv.value = val
+ return ssv
+}
+
+// Format: a=1,b=2
+func (s *stringToIntValue) Set(val string) error {
+ ss := strings.Split(val, ",")
+ out := make(map[string]int, len(ss))
+ for _, pair := range ss {
+ kv := strings.SplitN(pair, "=", 2)
+ if len(kv) != 2 {
+ return fmt.Errorf("%s must be formatted as key=value", pair)
+ }
+ var err error
+ out[kv[0]], err = strconv.Atoi(kv[1])
+ if err != nil {
+ return err
+ }
+ }
+ if !s.changed {
+ *s.value = out
+ } else {
+ for k, v := range out {
+ (*s.value)[k] = v
+ }
+ }
+ s.changed = true
+ return nil
+}
+
+func (s *stringToIntValue) Type() string {
+ return "stringToInt"
+}
+
+func (s *stringToIntValue) String() string {
+ var buf bytes.Buffer
+ i := 0
+ for k, v := range *s.value {
+ if i > 0 {
+ buf.WriteRune(',')
+ }
+ buf.WriteString(k)
+ buf.WriteRune('=')
+ buf.WriteString(strconv.Itoa(v))
+ i++
+ }
+ return "[" + buf.String() + "]"
+}
+
+func stringToIntConv(val string) (interface{}, error) {
+ val = strings.Trim(val, "[]")
+ // An empty string would cause an empty map
+ if len(val) == 0 {
+ return map[string]int{}, nil
+ }
+ ss := strings.Split(val, ",")
+ out := make(map[string]int, len(ss))
+ for _, pair := range ss {
+ kv := strings.SplitN(pair, "=", 2)
+ if len(kv) != 2 {
+ return nil, fmt.Errorf("%s must be formatted as key=value", pair)
+ }
+ var err error
+ out[kv[0]], err = strconv.Atoi(kv[1])
+ if err != nil {
+ return nil, err
+ }
+ }
+ return out, nil
+}
+
+// GetStringToInt return the map[string]int value of a flag with the given name
+func (f *FlagSet) GetStringToInt(name string) (map[string]int, error) {
+ val, err := f.getFlagType(name, "stringToInt", stringToIntConv)
+ if err != nil {
+ return map[string]int{}, err
+ }
+ return val.(map[string]int), nil
+}
+
+// StringToIntVar defines a string flag with specified name, default value, and usage string.
+// The argument p points to a map[string]int variable in which to store the values of the multiple flags.
+// The value of each argument will not try to be separated by comma
+func (f *FlagSet) StringToIntVar(p *map[string]int, name string, value map[string]int, usage string) {
+ f.VarP(newStringToIntValue(value, p), name, "", usage)
+}
+
+// StringToIntVarP is like StringToIntVar, but accepts a shorthand letter that can be used after a single dash.
+func (f *FlagSet) StringToIntVarP(p *map[string]int, name, shorthand string, value map[string]int, usage string) {
+ f.VarP(newStringToIntValue(value, p), name, shorthand, usage)
+}
+
+// StringToIntVar defines a string flag with specified name, default value, and usage string.
+// The argument p points to a map[string]int variable in which to store the value of the flag.
+// The value of each argument will not try to be separated by comma
+func StringToIntVar(p *map[string]int, name string, value map[string]int, usage string) {
+ CommandLine.VarP(newStringToIntValue(value, p), name, "", usage)
+}
+
+// StringToIntVarP is like StringToIntVar, but accepts a shorthand letter that can be used after a single dash.
+func StringToIntVarP(p *map[string]int, name, shorthand string, value map[string]int, usage string) {
+ CommandLine.VarP(newStringToIntValue(value, p), name, shorthand, usage)
+}
+
+// StringToInt defines a string flag with specified name, default value, and usage string.
+// The return value is the address of a map[string]int variable that stores the value of the flag.
+// The value of each argument will not try to be separated by comma
+func (f *FlagSet) StringToInt(name string, value map[string]int, usage string) *map[string]int {
+ p := map[string]int{}
+ f.StringToIntVarP(&p, name, "", value, usage)
+ return &p
+}
+
+// StringToIntP is like StringToInt, but accepts a shorthand letter that can be used after a single dash.
+func (f *FlagSet) StringToIntP(name, shorthand string, value map[string]int, usage string) *map[string]int {
+ p := map[string]int{}
+ f.StringToIntVarP(&p, name, shorthand, value, usage)
+ return &p
+}
+
+// StringToInt defines a string flag with specified name, default value, and usage string.
+// The return value is the address of a map[string]int variable that stores the value of the flag.
+// The value of each argument will not try to be separated by comma
+func StringToInt(name string, value map[string]int, usage string) *map[string]int {
+ return CommandLine.StringToIntP(name, "", value, usage)
+}
+
+// StringToIntP is like StringToInt, but accepts a shorthand letter that can be used after a single dash.
+func StringToIntP(name, shorthand string, value map[string]int, usage string) *map[string]int {
+ return CommandLine.StringToIntP(name, shorthand, value, usage)
+}
diff --git a/vendor/github.com/spf13/pflag/string_to_int64.go b/vendor/github.com/spf13/pflag/string_to_int64.go
new file mode 100644
index 0000000000000000000000000000000000000000..a807a04a0bad8348fc3f2ab720e723e512c8dfb5
--- /dev/null
+++ b/vendor/github.com/spf13/pflag/string_to_int64.go
@@ -0,0 +1,149 @@
+package pflag
+
+import (
+ "bytes"
+ "fmt"
+ "strconv"
+ "strings"
+)
+
+// -- stringToInt64 Value
+type stringToInt64Value struct {
+ value *map[string]int64
+ changed bool
+}
+
+func newStringToInt64Value(val map[string]int64, p *map[string]int64) *stringToInt64Value {
+ ssv := new(stringToInt64Value)
+ ssv.value = p
+ *ssv.value = val
+ return ssv
+}
+
+// Format: a=1,b=2
+func (s *stringToInt64Value) Set(val string) error {
+ ss := strings.Split(val, ",")
+ out := make(map[string]int64, len(ss))
+ for _, pair := range ss {
+ kv := strings.SplitN(pair, "=", 2)
+ if len(kv) != 2 {
+ return fmt.Errorf("%s must be formatted as key=value", pair)
+ }
+ var err error
+ out[kv[0]], err = strconv.ParseInt(kv[1], 10, 64)
+ if err != nil {
+ return err
+ }
+ }
+ if !s.changed {
+ *s.value = out
+ } else {
+ for k, v := range out {
+ (*s.value)[k] = v
+ }
+ }
+ s.changed = true
+ return nil
+}
+
+func (s *stringToInt64Value) Type() string {
+ return "stringToInt64"
+}
+
+func (s *stringToInt64Value) String() string {
+ var buf bytes.Buffer
+ i := 0
+ for k, v := range *s.value {
+ if i > 0 {
+ buf.WriteRune(',')
+ }
+ buf.WriteString(k)
+ buf.WriteRune('=')
+ buf.WriteString(strconv.FormatInt(v, 10))
+ i++
+ }
+ return "[" + buf.String() + "]"
+}
+
+func stringToInt64Conv(val string) (interface{}, error) {
+ val = strings.Trim(val, "[]")
+ // An empty string would cause an empty map
+ if len(val) == 0 {
+ return map[string]int64{}, nil
+ }
+ ss := strings.Split(val, ",")
+ out := make(map[string]int64, len(ss))
+ for _, pair := range ss {
+ kv := strings.SplitN(pair, "=", 2)
+ if len(kv) != 2 {
+ return nil, fmt.Errorf("%s must be formatted as key=value", pair)
+ }
+ var err error
+ out[kv[0]], err = strconv.ParseInt(kv[1], 10, 64)
+ if err != nil {
+ return nil, err
+ }
+ }
+ return out, nil
+}
+
+// GetStringToInt64 return the map[string]int64 value of a flag with the given name
+func (f *FlagSet) GetStringToInt64(name string) (map[string]int64, error) {
+ val, err := f.getFlagType(name, "stringToInt64", stringToInt64Conv)
+ if err != nil {
+ return map[string]int64{}, err
+ }
+ return val.(map[string]int64), nil
+}
+
+// StringToInt64Var defines a string flag with specified name, default value, and usage string.
+// The argument p point64s to a map[string]int64 variable in which to store the values of the multiple flags.
+// The value of each argument will not try to be separated by comma
+func (f *FlagSet) StringToInt64Var(p *map[string]int64, name string, value map[string]int64, usage string) {
+ f.VarP(newStringToInt64Value(value, p), name, "", usage)
+}
+
+// StringToInt64VarP is like StringToInt64Var, but accepts a shorthand letter that can be used after a single dash.
+func (f *FlagSet) StringToInt64VarP(p *map[string]int64, name, shorthand string, value map[string]int64, usage string) {
+ f.VarP(newStringToInt64Value(value, p), name, shorthand, usage)
+}
+
+// StringToInt64Var defines a string flag with specified name, default value, and usage string.
+// The argument p point64s to a map[string]int64 variable in which to store the value of the flag.
+// The value of each argument will not try to be separated by comma
+func StringToInt64Var(p *map[string]int64, name string, value map[string]int64, usage string) {
+ CommandLine.VarP(newStringToInt64Value(value, p), name, "", usage)
+}
+
+// StringToInt64VarP is like StringToInt64Var, but accepts a shorthand letter that can be used after a single dash.
+func StringToInt64VarP(p *map[string]int64, name, shorthand string, value map[string]int64, usage string) {
+ CommandLine.VarP(newStringToInt64Value(value, p), name, shorthand, usage)
+}
+
+// StringToInt64 defines a string flag with specified name, default value, and usage string.
+// The return value is the address of a map[string]int64 variable that stores the value of the flag.
+// The value of each argument will not try to be separated by comma
+func (f *FlagSet) StringToInt64(name string, value map[string]int64, usage string) *map[string]int64 {
+ p := map[string]int64{}
+ f.StringToInt64VarP(&p, name, "", value, usage)
+ return &p
+}
+
+// StringToInt64P is like StringToInt64, but accepts a shorthand letter that can be used after a single dash.
+func (f *FlagSet) StringToInt64P(name, shorthand string, value map[string]int64, usage string) *map[string]int64 {
+ p := map[string]int64{}
+ f.StringToInt64VarP(&p, name, shorthand, value, usage)
+ return &p
+}
+
+// StringToInt64 defines a string flag with specified name, default value, and usage string.
+// The return value is the address of a map[string]int64 variable that stores the value of the flag.
+// The value of each argument will not try to be separated by comma
+func StringToInt64(name string, value map[string]int64, usage string) *map[string]int64 {
+ return CommandLine.StringToInt64P(name, "", value, usage)
+}
+
+// StringToInt64P is like StringToInt64, but accepts a shorthand letter that can be used after a single dash.
+func StringToInt64P(name, shorthand string, value map[string]int64, usage string) *map[string]int64 {
+ return CommandLine.StringToInt64P(name, shorthand, value, usage)
+}
diff --git a/vendor/github.com/spf13/pflag/string_to_string.go b/vendor/github.com/spf13/pflag/string_to_string.go
new file mode 100644
index 0000000000000000000000000000000000000000..890a01afc030044c028766cc5d988255db86eacb
--- /dev/null
+++ b/vendor/github.com/spf13/pflag/string_to_string.go
@@ -0,0 +1,160 @@
+package pflag
+
+import (
+ "bytes"
+ "encoding/csv"
+ "fmt"
+ "strings"
+)
+
+// -- stringToString Value
+type stringToStringValue struct {
+ value *map[string]string
+ changed bool
+}
+
+func newStringToStringValue(val map[string]string, p *map[string]string) *stringToStringValue {
+ ssv := new(stringToStringValue)
+ ssv.value = p
+ *ssv.value = val
+ return ssv
+}
+
+// Format: a=1,b=2
+func (s *stringToStringValue) Set(val string) error {
+ var ss []string
+ n := strings.Count(val, "=")
+ switch n {
+ case 0:
+ return fmt.Errorf("%s must be formatted as key=value", val)
+ case 1:
+ ss = append(ss, strings.Trim(val, `"`))
+ default:
+ r := csv.NewReader(strings.NewReader(val))
+ var err error
+ ss, err = r.Read()
+ if err != nil {
+ return err
+ }
+ }
+
+ out := make(map[string]string, len(ss))
+ for _, pair := range ss {
+ kv := strings.SplitN(pair, "=", 2)
+ if len(kv) != 2 {
+ return fmt.Errorf("%s must be formatted as key=value", pair)
+ }
+ out[kv[0]] = kv[1]
+ }
+ if !s.changed {
+ *s.value = out
+ } else {
+ for k, v := range out {
+ (*s.value)[k] = v
+ }
+ }
+ s.changed = true
+ return nil
+}
+
+func (s *stringToStringValue) Type() string {
+ return "stringToString"
+}
+
+func (s *stringToStringValue) String() string {
+ records := make([]string, 0, len(*s.value)>>1)
+ for k, v := range *s.value {
+ records = append(records, k+"="+v)
+ }
+
+ var buf bytes.Buffer
+ w := csv.NewWriter(&buf)
+ if err := w.Write(records); err != nil {
+ panic(err)
+ }
+ w.Flush()
+ return "[" + strings.TrimSpace(buf.String()) + "]"
+}
+
+func stringToStringConv(val string) (interface{}, error) {
+ val = strings.Trim(val, "[]")
+ // An empty string would cause an empty map
+ if len(val) == 0 {
+ return map[string]string{}, nil
+ }
+ r := csv.NewReader(strings.NewReader(val))
+ ss, err := r.Read()
+ if err != nil {
+ return nil, err
+ }
+ out := make(map[string]string, len(ss))
+ for _, pair := range ss {
+ kv := strings.SplitN(pair, "=", 2)
+ if len(kv) != 2 {
+ return nil, fmt.Errorf("%s must be formatted as key=value", pair)
+ }
+ out[kv[0]] = kv[1]
+ }
+ return out, nil
+}
+
+// GetStringToString return the map[string]string value of a flag with the given name
+func (f *FlagSet) GetStringToString(name string) (map[string]string, error) {
+ val, err := f.getFlagType(name, "stringToString", stringToStringConv)
+ if err != nil {
+ return map[string]string{}, err
+ }
+ return val.(map[string]string), nil
+}
+
+// StringToStringVar defines a string flag with specified name, default value, and usage string.
+// The argument p points to a map[string]string variable in which to store the values of the multiple flags.
+// The value of each argument will not try to be separated by comma
+func (f *FlagSet) StringToStringVar(p *map[string]string, name string, value map[string]string, usage string) {
+ f.VarP(newStringToStringValue(value, p), name, "", usage)
+}
+
+// StringToStringVarP is like StringToStringVar, but accepts a shorthand letter that can be used after a single dash.
+func (f *FlagSet) StringToStringVarP(p *map[string]string, name, shorthand string, value map[string]string, usage string) {
+ f.VarP(newStringToStringValue(value, p), name, shorthand, usage)
+}
+
+// StringToStringVar defines a string flag with specified name, default value, and usage string.
+// The argument p points to a map[string]string variable in which to store the value of the flag.
+// The value of each argument will not try to be separated by comma
+func StringToStringVar(p *map[string]string, name string, value map[string]string, usage string) {
+ CommandLine.VarP(newStringToStringValue(value, p), name, "", usage)
+}
+
+// StringToStringVarP is like StringToStringVar, but accepts a shorthand letter that can be used after a single dash.
+func StringToStringVarP(p *map[string]string, name, shorthand string, value map[string]string, usage string) {
+ CommandLine.VarP(newStringToStringValue(value, p), name, shorthand, usage)
+}
+
+// StringToString defines a string flag with specified name, default value, and usage string.
+// The return value is the address of a map[string]string variable that stores the value of the flag.
+// The value of each argument will not try to be separated by comma
+func (f *FlagSet) StringToString(name string, value map[string]string, usage string) *map[string]string {
+ p := map[string]string{}
+ f.StringToStringVarP(&p, name, "", value, usage)
+ return &p
+}
+
+// StringToStringP is like StringToString, but accepts a shorthand letter that can be used after a single dash.
+func (f *FlagSet) StringToStringP(name, shorthand string, value map[string]string, usage string) *map[string]string {
+ p := map[string]string{}
+ f.StringToStringVarP(&p, name, shorthand, value, usage)
+ return &p
+}
+
+// StringToString defines a string flag with specified name, default value, and usage string.
+// The return value is the address of a map[string]string variable that stores the value of the flag.
+// The value of each argument will not try to be separated by comma
+func StringToString(name string, value map[string]string, usage string) *map[string]string {
+ return CommandLine.StringToStringP(name, "", value, usage)
+}
+
+// StringToStringP is like StringToString, but accepts a shorthand letter that can be used after a single dash.
+func StringToStringP(name, shorthand string, value map[string]string, usage string) *map[string]string {
+ return CommandLine.StringToStringP(name, shorthand, value, usage)
+}
diff --git a/vendor/github.com/spf13/pflag/uint.go b/vendor/github.com/spf13/pflag/uint.go
new file mode 100644
index 0000000000000000000000000000000000000000..dcbc2b758c3e54aa0c87467680ceed3896b7f429
--- /dev/null
+++ b/vendor/github.com/spf13/pflag/uint.go
@@ -0,0 +1,88 @@
+package pflag
+
+import "strconv"
+
+// -- uint Value
+type uintValue uint
+
+func newUintValue(val uint, p *uint) *uintValue {
+ *p = val
+ return (*uintValue)(p)
+}
+
+func (i *uintValue) Set(s string) error {
+ v, err := strconv.ParseUint(s, 0, 64)
+ *i = uintValue(v)
+ return err
+}
+
+func (i *uintValue) Type() string {
+ return "uint"
+}
+
+func (i *uintValue) String() string { return strconv.FormatUint(uint64(*i), 10) }
+
+func uintConv(sval string) (interface{}, error) {
+ v, err := strconv.ParseUint(sval, 0, 0)
+ if err != nil {
+ return 0, err
+ }
+ return uint(v), nil
+}
+
+// GetUint return the uint value of a flag with the given name
+func (f *FlagSet) GetUint(name string) (uint, error) {
+ val, err := f.getFlagType(name, "uint", uintConv)
+ if err != nil {
+ return 0, err
+ }
+ return val.(uint), nil
+}
+
+// UintVar defines a uint flag with specified name, default value, and usage string.
+// The argument p points to a uint variable in which to store the value of the flag.
+func (f *FlagSet) UintVar(p *uint, name string, value uint, usage string) {
+ f.VarP(newUintValue(value, p), name, "", usage)
+}
+
+// UintVarP is like UintVar, but accepts a shorthand letter that can be used after a single dash.
+func (f *FlagSet) UintVarP(p *uint, name, shorthand string, value uint, usage string) {
+ f.VarP(newUintValue(value, p), name, shorthand, usage)
+}
+
+// UintVar defines a uint flag with specified name, default value, and usage string.
+// The argument p points to a uint variable in which to store the value of the flag.
+func UintVar(p *uint, name string, value uint, usage string) {
+ CommandLine.VarP(newUintValue(value, p), name, "", usage)
+}
+
+// UintVarP is like UintVar, but accepts a shorthand letter that can be used after a single dash.
+func UintVarP(p *uint, name, shorthand string, value uint, usage string) {
+ CommandLine.VarP(newUintValue(value, p), name, shorthand, usage)
+}
+
+// Uint defines a uint flag with specified name, default value, and usage string.
+// The return value is the address of a uint variable that stores the value of the flag.
+func (f *FlagSet) Uint(name string, value uint, usage string) *uint {
+ p := new(uint)
+ f.UintVarP(p, name, "", value, usage)
+ return p
+}
+
+// UintP is like Uint, but accepts a shorthand letter that can be used after a single dash.
+func (f *FlagSet) UintP(name, shorthand string, value uint, usage string) *uint {
+ p := new(uint)
+ f.UintVarP(p, name, shorthand, value, usage)
+ return p
+}
+
+// Uint defines a uint flag with specified name, default value, and usage string.
+// The return value is the address of a uint variable that stores the value of the flag.
+func Uint(name string, value uint, usage string) *uint {
+ return CommandLine.UintP(name, "", value, usage)
+}
+
+// UintP is like Uint, but accepts a shorthand letter that can be used after a single dash.
+func UintP(name, shorthand string, value uint, usage string) *uint {
+ return CommandLine.UintP(name, shorthand, value, usage)
+}
diff --git a/vendor/github.com/spf13/pflag/uint16.go b/vendor/github.com/spf13/pflag/uint16.go
new file mode 100644
index 0000000000000000000000000000000000000000..7e9914eddded70662356d132d2b16623c9bd807c
--- /dev/null
+++ b/vendor/github.com/spf13/pflag/uint16.go
@@ -0,0 +1,88 @@
+package pflag
+
+import "strconv"
+
+// -- uint16 value
+type uint16Value uint16
+
+func newUint16Value(val uint16, p *uint16) *uint16Value {
+ *p = val
+ return (*uint16Value)(p)
+}
+
+func (i *uint16Value) Set(s string) error {
+ v, err := strconv.ParseUint(s, 0, 16)
+ *i = uint16Value(v)
+ return err
+}
+
+func (i *uint16Value) Type() string {
+ return "uint16"
+}
+
+func (i *uint16Value) String() string { return strconv.FormatUint(uint64(*i), 10) }
+
+func uint16Conv(sval string) (interface{}, error) {
+ v, err := strconv.ParseUint(sval, 0, 16)
+ if err != nil {
+ return 0, err
+ }
+ return uint16(v), nil
+}
+
+// GetUint16 return the uint16 value of a flag with the given name
+func (f *FlagSet) GetUint16(name string) (uint16, error) {
+ val, err := f.getFlagType(name, "uint16", uint16Conv)
+ if err != nil {
+ return 0, err
+ }
+ return val.(uint16), nil
+}
+
+// Uint16Var defines a uint flag with specified name, default value, and usage string.
+// The argument p points to a uint variable in which to store the value of the flag.
+func (f *FlagSet) Uint16Var(p *uint16, name string, value uint16, usage string) {
+ f.VarP(newUint16Value(value, p), name, "", usage)
+}
+
+// Uint16VarP is like Uint16Var, but accepts a shorthand letter that can be used after a single dash.
+func (f *FlagSet) Uint16VarP(p *uint16, name, shorthand string, value uint16, usage string) {
+ f.VarP(newUint16Value(value, p), name, shorthand, usage)
+}
+
+// Uint16Var defines a uint flag with specified name, default value, and usage string.
+// The argument p points to a uint variable in which to store the value of the flag.
+func Uint16Var(p *uint16, name string, value uint16, usage string) {
+ CommandLine.VarP(newUint16Value(value, p), name, "", usage)
+}
+
+// Uint16VarP is like Uint16Var, but accepts a shorthand letter that can be used after a single dash.
+func Uint16VarP(p *uint16, name, shorthand string, value uint16, usage string) {
+ CommandLine.VarP(newUint16Value(value, p), name, shorthand, usage)
+}
+
+// Uint16 defines a uint flag with specified name, default value, and usage string.
+// The return value is the address of a uint variable that stores the value of the flag.
+func (f *FlagSet) Uint16(name string, value uint16, usage string) *uint16 {
+ p := new(uint16)
+ f.Uint16VarP(p, name, "", value, usage)
+ return p
+}
+
+// Uint16P is like Uint16, but accepts a shorthand letter that can be used after a single dash.
+func (f *FlagSet) Uint16P(name, shorthand string, value uint16, usage string) *uint16 {
+ p := new(uint16)
+ f.Uint16VarP(p, name, shorthand, value, usage)
+ return p
+}
+
+// Uint16 defines a uint flag with specified name, default value, and usage string.
+// The return value is the address of a uint variable that stores the value of the flag.
+func Uint16(name string, value uint16, usage string) *uint16 {
+ return CommandLine.Uint16P(name, "", value, usage)
+}
+
+// Uint16P is like Uint16, but accepts a shorthand letter that can be used after a single dash.
+func Uint16P(name, shorthand string, value uint16, usage string) *uint16 {
+ return CommandLine.Uint16P(name, shorthand, value, usage)
+}
diff --git a/vendor/github.com/spf13/pflag/uint32.go b/vendor/github.com/spf13/pflag/uint32.go
new file mode 100644
index 0000000000000000000000000000000000000000..d8024539bf6510282ced06b7f27fcdec6e0e5cb9
--- /dev/null
+++ b/vendor/github.com/spf13/pflag/uint32.go
@@ -0,0 +1,88 @@
+package pflag
+
+import "strconv"
+
+// -- uint32 value
+type uint32Value uint32
+
+func newUint32Value(val uint32, p *uint32) *uint32Value {
+ *p = val
+ return (*uint32Value)(p)
+}
+
+func (i *uint32Value) Set(s string) error {
+ v, err := strconv.ParseUint(s, 0, 32)
+ *i = uint32Value(v)
+ return err
+}
+
+func (i *uint32Value) Type() string {
+ return "uint32"
+}
+
+func (i *uint32Value) String() string { return strconv.FormatUint(uint64(*i), 10) }
+
+func uint32Conv(sval string) (interface{}, error) {
+ v, err := strconv.ParseUint(sval, 0, 32)
+ if err != nil {
+ return 0, err
+ }
+ return uint32(v), nil
+}
+
+// GetUint32 return the uint32 value of a flag with the given name
+func (f *FlagSet) GetUint32(name string) (uint32, error) {
+ val, err := f.getFlagType(name, "uint32", uint32Conv)
+ if err != nil {
+ return 0, err
+ }
+ return val.(uint32), nil
+}
+
+// Uint32Var defines a uint32 flag with specified name, default value, and usage string.
+// The argument p points to a uint32 variable in which to store the value of the flag.
+func (f *FlagSet) Uint32Var(p *uint32, name string, value uint32, usage string) {
+ f.VarP(newUint32Value(value, p), name, "", usage)
+}
+
+// Uint32VarP is like Uint32Var, but accepts a shorthand letter that can be used after a single dash.
+func (f *FlagSet) Uint32VarP(p *uint32, name, shorthand string, value uint32, usage string) {
+ f.VarP(newUint32Value(value, p), name, shorthand, usage)
+}
+
+// Uint32Var defines a uint32 flag with specified name, default value, and usage string.
+// The argument p points to a uint32 variable in which to store the value of the flag.
+func Uint32Var(p *uint32, name string, value uint32, usage string) {
+ CommandLine.VarP(newUint32Value(value, p), name, "", usage)
+}
+
+// Uint32VarP is like Uint32Var, but accepts a shorthand letter that can be used after a single dash.
+func Uint32VarP(p *uint32, name, shorthand string, value uint32, usage string) {
+ CommandLine.VarP(newUint32Value(value, p), name, shorthand, usage)
+}
+
+// Uint32 defines a uint32 flag with specified name, default value, and usage string.
+// The return value is the address of a uint32 variable that stores the value of the flag.
+func (f *FlagSet) Uint32(name string, value uint32, usage string) *uint32 {
+ p := new(uint32)
+ f.Uint32VarP(p, name, "", value, usage)
+ return p
+}
+
+// Uint32P is like Uint32, but accepts a shorthand letter that can be used after a single dash.
+func (f *FlagSet) Uint32P(name, shorthand string, value uint32, usage string) *uint32 {
+ p := new(uint32)
+ f.Uint32VarP(p, name, shorthand, value, usage)
+ return p
+}
+
+// Uint32 defines a uint32 flag with specified name, default value, and usage string.
+// The return value is the address of a uint32 variable that stores the value of the flag.
+func Uint32(name string, value uint32, usage string) *uint32 {
+ return CommandLine.Uint32P(name, "", value, usage)
+}
+
+// Uint32P is like Uint32, but accepts a shorthand letter that can be used after a single dash.
+func Uint32P(name, shorthand string, value uint32, usage string) *uint32 {
+ return CommandLine.Uint32P(name, shorthand, value, usage)
+}
diff --git a/vendor/github.com/spf13/pflag/uint64.go b/vendor/github.com/spf13/pflag/uint64.go
new file mode 100644
index 0000000000000000000000000000000000000000..f62240f2ceab10a28d1ff206a8071ad2f2afa1cd
--- /dev/null
+++ b/vendor/github.com/spf13/pflag/uint64.go
@@ -0,0 +1,88 @@
+package pflag
+
+import "strconv"
+
+// -- uint64 Value
+type uint64Value uint64
+
+func newUint64Value(val uint64, p *uint64) *uint64Value {
+ *p = val
+ return (*uint64Value)(p)
+}
+
+func (i *uint64Value) Set(s string) error {
+ v, err := strconv.ParseUint(s, 0, 64)
+ *i = uint64Value(v)
+ return err
+}
+
+func (i *uint64Value) Type() string {
+ return "uint64"
+}
+
+func (i *uint64Value) String() string { return strconv.FormatUint(uint64(*i), 10) }
+
+func uint64Conv(sval string) (interface{}, error) {
+ v, err := strconv.ParseUint(sval, 0, 64)
+ if err != nil {
+ return 0, err
+ }
+ return uint64(v), nil
+}
+
+// GetUint64 return the uint64 value of a flag with the given name
+func (f *FlagSet) GetUint64(name string) (uint64, error) {
+ val, err := f.getFlagType(name, "uint64", uint64Conv)
+ if err != nil {
+ return 0, err
+ }
+ return val.(uint64), nil
+}
+
+// Uint64Var defines a uint64 flag with specified name, default value, and usage string.
+// The argument p points to a uint64 variable in which to store the value of the flag.
+func (f *FlagSet) Uint64Var(p *uint64, name string, value uint64, usage string) {
+ f.VarP(newUint64Value(value, p), name, "", usage)
+}
+
+// Uint64VarP is like Uint64Var, but accepts a shorthand letter that can be used after a single dash.
+func (f *FlagSet) Uint64VarP(p *uint64, name, shorthand string, value uint64, usage string) {
+ f.VarP(newUint64Value(value, p), name, shorthand, usage)
+}
+
+// Uint64Var defines a uint64 flag with specified name, default value, and usage string.
+// The argument p points to a uint64 variable in which to store the value of the flag.
+func Uint64Var(p *uint64, name string, value uint64, usage string) {
+ CommandLine.VarP(newUint64Value(value, p), name, "", usage)
+}
+
+// Uint64VarP is like Uint64Var, but accepts a shorthand letter that can be used after a single dash.
+func Uint64VarP(p *uint64, name, shorthand string, value uint64, usage string) {
+ CommandLine.VarP(newUint64Value(value, p), name, shorthand, usage)
+}
+
+// Uint64 defines a uint64 flag with specified name, default value, and usage string.
+// The return value is the address of a uint64 variable that stores the value of the flag.
+func (f *FlagSet) Uint64(name string, value uint64, usage string) *uint64 {
+ p := new(uint64)
+ f.Uint64VarP(p, name, "", value, usage)
+ return p
+}
+
+// Uint64P is like Uint64, but accepts a shorthand letter that can be used after a single dash.
+func (f *FlagSet) Uint64P(name, shorthand string, value uint64, usage string) *uint64 {
+ p := new(uint64)
+ f.Uint64VarP(p, name, shorthand, value, usage)
+ return p
+}
+
+// Uint64 defines a uint64 flag with specified name, default value, and usage string.
+// The return value is the address of a uint64 variable that stores the value of the flag.
+func Uint64(name string, value uint64, usage string) *uint64 {
+ return CommandLine.Uint64P(name, "", value, usage)
+}
+
+// Uint64P is like Uint64, but accepts a shorthand letter that can be used after a single dash.
+func Uint64P(name, shorthand string, value uint64, usage string) *uint64 {
+ return CommandLine.Uint64P(name, shorthand, value, usage)
+}
diff --git a/vendor/github.com/spf13/pflag/uint8.go b/vendor/github.com/spf13/pflag/uint8.go
new file mode 100644
index 0000000000000000000000000000000000000000..bb0e83c1f6d7d2a540f74a0652639eccdb8c5cf2
--- /dev/null
+++ b/vendor/github.com/spf13/pflag/uint8.go
@@ -0,0 +1,88 @@
+package pflag
+
+import "strconv"
+
+// -- uint8 Value
+type uint8Value uint8
+
+func newUint8Value(val uint8, p *uint8) *uint8Value {
+ *p = val
+ return (*uint8Value)(p)
+}
+
+func (i *uint8Value) Set(s string) error {
+ v, err := strconv.ParseUint(s, 0, 8)
+ *i = uint8Value(v)
+ return err
+}
+
+func (i *uint8Value) Type() string {
+ return "uint8"
+}
+
+func (i *uint8Value) String() string { return strconv.FormatUint(uint64(*i), 10) }
+
+func uint8Conv(sval string) (interface{}, error) {
+ v, err := strconv.ParseUint(sval, 0, 8)
+ if err != nil {
+ return 0, err
+ }
+ return uint8(v), nil
+}
+
+// GetUint8 return the uint8 value of a flag with the given name
+func (f *FlagSet) GetUint8(name string) (uint8, error) {
+ val, err := f.getFlagType(name, "uint8", uint8Conv)
+ if err != nil {
+ return 0, err
+ }
+ return val.(uint8), nil
+}
+
+// Uint8Var defines a uint8 flag with specified name, default value, and usage string.
+// The argument p points to a uint8 variable in which to store the value of the flag.
+func (f *FlagSet) Uint8Var(p *uint8, name string, value uint8, usage string) {
+ f.VarP(newUint8Value(value, p), name, "", usage)
+}
+
+// Uint8VarP is like Uint8Var, but accepts a shorthand letter that can be used after a single dash.
+func (f *FlagSet) Uint8VarP(p *uint8, name, shorthand string, value uint8, usage string) {
+ f.VarP(newUint8Value(value, p), name, shorthand, usage)
+}
+
+// Uint8Var defines a uint8 flag with specified name, default value, and usage string.
+// The argument p points to a uint8 variable in which to store the value of the flag.
+func Uint8Var(p *uint8, name string, value uint8, usage string) {
+ CommandLine.VarP(newUint8Value(value, p), name, "", usage)
+}
+
+// Uint8VarP is like Uint8Var, but accepts a shorthand letter that can be used after a single dash.
+func Uint8VarP(p *uint8, name, shorthand string, value uint8, usage string) {
+ CommandLine.VarP(newUint8Value(value, p), name, shorthand, usage)
+}
+
+// Uint8 defines a uint8 flag with specified name, default value, and usage string.
+// The return value is the address of a uint8 variable that stores the value of the flag.
+func (f *FlagSet) Uint8(name string, value uint8, usage string) *uint8 {
+ p := new(uint8)
+ f.Uint8VarP(p, name, "", value, usage)
+ return p
+}
+
+// Uint8P is like Uint8, but accepts a shorthand letter that can be used after a single dash.
+func (f *FlagSet) Uint8P(name, shorthand string, value uint8, usage string) *uint8 {
+ p := new(uint8)
+ f.Uint8VarP(p, name, shorthand, value, usage)
+ return p
+}
+
+// Uint8 defines a uint8 flag with specified name, default value, and usage string.
+// The return value is the address of a uint8 variable that stores the value of the flag.
+func Uint8(name string, value uint8, usage string) *uint8 {
+ return CommandLine.Uint8P(name, "", value, usage)
+}
+
+// Uint8P is like Uint8, but accepts a shorthand letter that can be used after a single dash.
+func Uint8P(name, shorthand string, value uint8, usage string) *uint8 {
+ return CommandLine.Uint8P(name, shorthand, value, usage)
+}
diff --git a/vendor/github.com/spf13/pflag/uint_slice.go b/vendor/github.com/spf13/pflag/uint_slice.go
new file mode 100644
index 0000000000000000000000000000000000000000..5fa924835ed3f52841cc50a58aa5a4fcb9ed68c2
--- /dev/null
+++ b/vendor/github.com/spf13/pflag/uint_slice.go
@@ -0,0 +1,168 @@
+package pflag
+
+import (
+ "fmt"
+ "strconv"
+ "strings"
+)
+
+// -- uintSlice Value
+type uintSliceValue struct {
+ value *[]uint
+ changed bool
+}
+
+func newUintSliceValue(val []uint, p *[]uint) *uintSliceValue {
+ uisv := new(uintSliceValue)
+ uisv.value = p
+ *uisv.value = val
+ return uisv
+}
+
+func (s *uintSliceValue) Set(val string) error {
+ ss := strings.Split(val, ",")
+ out := make([]uint, len(ss))
+ for i, d := range ss {
+ u, err := strconv.ParseUint(d, 10, 0)
+ if err != nil {
+ return err
+ }
+ out[i] = uint(u)
+ }
+ if !s.changed {
+ *s.value = out
+ } else {
+ *s.value = append(*s.value, out...)
+ }
+ s.changed = true
+ return nil
+}
+
+func (s *uintSliceValue) Type() string {
+ return "uintSlice"
+}
+
+func (s *uintSliceValue) String() string {
+ out := make([]string, len(*s.value))
+ for i, d := range *s.value {
+ out[i] = fmt.Sprintf("%d", d)
+ }
+ return "[" + strings.Join(out, ",") + "]"
+}
+
+func (s *uintSliceValue) fromString(val string) (uint, error) {
+ t, err := strconv.ParseUint(val, 10, 0)
+ if err != nil {
+ return 0, err
+ }
+ return uint(t), nil
+}
+
+func (s *uintSliceValue) toString(val uint) string {
+ return fmt.Sprintf("%d", val)
+}
+
+func (s *uintSliceValue) Append(val string) error {
+ i, err := s.fromString(val)
+ if err != nil {
+ return err
+ }
+ *s.value = append(*s.value, i)
+ return nil
+}
+
+func (s *uintSliceValue) Replace(val []string) error {
+ out := make([]uint, len(val))
+ for i, d := range val {
+ var err error
+ out[i], err = s.fromString(d)
+ if err != nil {
+ return err
+ }
+ }
+ *s.value = out
+ return nil
+}
+
+func (s *uintSliceValue) GetSlice() []string {
+ out := make([]string, len(*s.value))
+ for i, d := range *s.value {
+ out[i] = s.toString(d)
+ }
+ return out
+}
+
+func uintSliceConv(val string) (interface{}, error) {
+ val = strings.Trim(val, "[]")
+ // Empty string would cause a slice with one (empty) entry
+ if len(val) == 0 {
+ return []uint{}, nil
+ }
+ ss := strings.Split(val, ",")
+ out := make([]uint, len(ss))
+ for i, d := range ss {
+ u, err := strconv.ParseUint(d, 10, 0)
+ if err != nil {
+ return nil, err
+ }
+ out[i] = uint(u)
+ }
+ return out, nil
+}
+
+// GetUintSlice returns the []uint value of a flag with the given name.
+func (f *FlagSet) GetUintSlice(name string) ([]uint, error) {
+ val, err := f.getFlagType(name, "uintSlice", uintSliceConv)
+ if err != nil {
+ return []uint{}, err
+ }
+ return val.([]uint), nil
+}
+
+// UintSliceVar defines a uintSlice flag with specified name, default value, and usage string.
+// The argument p points to a []uint variable in which to store the value of the flag.
+func (f *FlagSet) UintSliceVar(p *[]uint, name string, value []uint, usage string) {
+ f.VarP(newUintSliceValue(value, p), name, "", usage)
+}
+
+// UintSliceVarP is like UintSliceVar, but accepts a shorthand letter that can be used after a single dash.
+func (f *FlagSet) UintSliceVarP(p *[]uint, name, shorthand string, value []uint, usage string) {
+ f.VarP(newUintSliceValue(value, p), name, shorthand, usage)
+}
+
+// UintSliceVar defines a uint[] flag with specified name, default value, and usage string.
+// The argument p points to a uint[] variable in which to store the value of the flag.
+func UintSliceVar(p *[]uint, name string, value []uint, usage string) {
+ CommandLine.VarP(newUintSliceValue(value, p), name, "", usage)
+}
+
+// UintSliceVarP is like the UintSliceVar, but accepts a shorthand letter that can be used after a single dash.
+func UintSliceVarP(p *[]uint, name, shorthand string, value []uint, usage string) {
+ CommandLine.VarP(newUintSliceValue(value, p), name, shorthand, usage)
+}
+
+// UintSlice defines a []uint flag with specified name, default value, and usage string.
+// The return value is the address of a []uint variable that stores the value of the flag.
+func (f *FlagSet) UintSlice(name string, value []uint, usage string) *[]uint {
+ p := []uint{}
+ f.UintSliceVarP(&p, name, "", value, usage)
+ return &p
+}
+
+// UintSliceP is like UintSlice, but accepts a shorthand letter that can be used after a single dash.
+func (f *FlagSet) UintSliceP(name, shorthand string, value []uint, usage string) *[]uint {
+ p := []uint{}
+ f.UintSliceVarP(&p, name, shorthand, value, usage)
+ return &p
+}
+
+// UintSlice defines a []uint flag with specified name, default value, and usage string.
+// The return value is the address of a []uint variable that stores the value of the flag.
+func UintSlice(name string, value []uint, usage string) *[]uint {
+ return CommandLine.UintSliceP(name, "", value, usage)
+}
+
+// UintSliceP is like UintSlice, but accepts a shorthand letter that can be used after a single dash.
+func UintSliceP(name, shorthand string, value []uint, usage string) *[]uint {
+ return CommandLine.UintSliceP(name, shorthand, value, usage)
+}
diff --git a/vendor/golang.org/x/net/AUTHORS b/vendor/golang.org/x/net/AUTHORS
new file mode 100644
index 0000000000000000000000000000000000000000..15167cd746c560e5b3d3b233a169aa64d3e9101e
--- /dev/null
+++ b/vendor/golang.org/x/net/AUTHORS
@@ -0,0 +1,3 @@
+# This source code refers to The Go Authors for copyright purposes.
+# The master list of authors is in the main Go distribution,
+# visible at http://tip.golang.org/AUTHORS.
diff --git a/vendor/golang.org/x/net/CONTRIBUTORS b/vendor/golang.org/x/net/CONTRIBUTORS
new file mode 100644
index 0000000000000000000000000000000000000000..1c4577e9680611383f46044d17fa343a96997c3c
--- /dev/null
+++ b/vendor/golang.org/x/net/CONTRIBUTORS
@@ -0,0 +1,3 @@
+# This source code was written by the Go contributors.
+# The master list of contributors is in the main Go distribution,
+# visible at http://tip.golang.org/CONTRIBUTORS.
diff --git a/vendor/golang.org/x/net/LICENSE b/vendor/golang.org/x/net/LICENSE
new file mode 100644
index 0000000000000000000000000000000000000000..6a66aea5eafe0ca6a688840c47219556c552488e
--- /dev/null
+++ b/vendor/golang.org/x/net/LICENSE
@@ -0,0 +1,27 @@
+Copyright (c) 2009 The Go Authors. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+ * Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above
+copyright notice, this list of conditions and the following disclaimer
+in the documentation and/or other materials provided with the
+distribution.
+ * Neither the name of Google Inc. nor the names of its
+contributors may be used to endorse or promote products derived from
+this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/vendor/golang.org/x/net/PATENTS b/vendor/golang.org/x/net/PATENTS
new file mode 100644
index 0000000000000000000000000000000000000000..733099041f84fa1e58611ab2e11af51c1f26d1d2
--- /dev/null
+++ b/vendor/golang.org/x/net/PATENTS
@@ -0,0 +1,22 @@
+Additional IP Rights Grant (Patents)
+
+"This implementation" means the copyrightable works distributed by
+Google as part of the Go project.
+
+Google 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,
+transfer and otherwise run, modify and propagate the contents of this
+implementation of Go, where such license applies only to those patent
+claims, both currently owned or controlled by Google and acquired in
+the future, licensable by Google that are necessarily infringed by this
+implementation of Go. This grant does not include claims that would be
+infringed only as a consequence of further modification of this
+implementation. If you or your agent or exclusive licensee institute or
+order or agree to the institution of patent litigation against any
+entity (including a cross-claim or counterclaim in a lawsuit) alleging
+that this implementation of Go or any code incorporated within this
+implementation of Go constitutes direct or contributory patent
+infringement, or inducement of patent infringement, then any patent
+rights granted to you under this License for this implementation of Go
+shall terminate as of the date such litigation is filed.
diff --git a/vendor/golang.org/x/net/context/context.go b/vendor/golang.org/x/net/context/context.go
new file mode 100644
index 0000000000000000000000000000000000000000..a3c021d3f88e98457163fd084ac9b49e1ddf5931
--- /dev/null
+++ b/vendor/golang.org/x/net/context/context.go
@@ -0,0 +1,56 @@
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package context defines the Context type, which carries deadlines,
+// cancelation signals, and other request-scoped values across API boundaries
+// and between processes.
+// As of Go 1.7 this package is available in the standard library under the
+// name context. https://golang.org/pkg/context.
+//
+// Incoming requests to a server should create a Context, and outgoing calls to
+// servers should accept a Context. The chain of function calls between must
+// propagate the Context, optionally replacing it with a modified copy created
+// using WithDeadline, WithTimeout, WithCancel, or WithValue.
+//
+// Programs that use Contexts should follow these rules to keep interfaces
+// consistent across packages and enable static analysis tools to check context
+// propagation:
+//
+// Do not store Contexts inside a struct type; instead, pass a Context
+// explicitly to each function that needs it. The Context should be the first
+// parameter, typically named ctx:
+//
+// func DoSomething(ctx context.Context, arg Arg) error {
+// // ... use ctx ...
+// }
+//
+// Do not pass a nil Context, even if a function permits it. Pass context.TODO
+// if you are unsure about which Context to use.
+//
+// Use context Values only for request-scoped data that transits processes and
+// APIs, not for passing optional parameters to functions.
+//
+// The same Context may be passed to functions running in different goroutines;
+// Contexts are safe for simultaneous use by multiple goroutines.
+//
+// See http://blog.golang.org/context for example code for a server that uses
+// Contexts.
+package context // import "golang.org/x/net/context"
+
+// Background returns a non-nil, empty Context. It is never canceled, has no
+// values, and has no deadline. It is typically used by the main function,
+// initialization, and tests, and as the top-level Context for incoming
+// requests.
+func Background() Context {
+ return background
+}
+
+// TODO returns a non-nil, empty Context. Code should use context.TODO when
+// it's unclear which Context to use or it is not yet available (because the
+// surrounding function has not yet been extended to accept a Context
+// parameter). TODO is recognized by static analysis tools that determine
+// whether Contexts are propagated correctly in a program.
+func TODO() Context {
+ return todo
+}
diff --git a/vendor/golang.org/x/net/context/ctxhttp/ctxhttp.go b/vendor/golang.org/x/net/context/ctxhttp/ctxhttp.go
new file mode 100644
index 0000000000000000000000000000000000000000..37dc0cfdb5b0dbb48f26c922050421bf5c757d05
--- /dev/null
+++ b/vendor/golang.org/x/net/context/ctxhttp/ctxhttp.go
@@ -0,0 +1,71 @@
+// Copyright 2016 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package ctxhttp provides helper functions for performing context-aware HTTP requests.
+package ctxhttp // import "golang.org/x/net/context/ctxhttp"
+
+import (
+ "context"
+ "io"
+ "net/http"
+ "net/url"
+ "strings"
+)
+
+// Do sends an HTTP request with the provided http.Client and returns
+// an HTTP response.
+//
+// If the client is nil, http.DefaultClient is used.
+//
+// The provided ctx must be non-nil. If it is canceled or times out,
+// ctx.Err() will be returned.
+func Do(ctx context.Context, client *http.Client, req *http.Request) (*http.Response, error) {
+ if client == nil {
+ client = http.DefaultClient
+ }
+ resp, err := client.Do(req.WithContext(ctx))
+ // If we got an error, and the context has been canceled,
+ // the context's error is probably more useful.
+ if err != nil {
+ select {
+ case <-ctx.Done():
+ err = ctx.Err()
+ default:
+ }
+ }
+ return resp, err
+}
+
+// Get issues a GET request via the Do function.
+func Get(ctx context.Context, client *http.Client, url string) (*http.Response, error) {
+ req, err := http.NewRequest("GET", url, nil)
+ if err != nil {
+ return nil, err
+ }
+ return Do(ctx, client, req)
+}
+
+// Head issues a HEAD request via the Do function.
+func Head(ctx context.Context, client *http.Client, url string) (*http.Response, error) {
+ req, err := http.NewRequest("HEAD", url, nil)
+ if err != nil {
+ return nil, err
+ }
+ return Do(ctx, client, req)
+}
+
+// Post issues a POST request via the Do function.
+func Post(ctx context.Context, client *http.Client, url string, bodyType string, body io.Reader) (*http.Response, error) {
+ req, err := http.NewRequest("POST", url, body)
+ if err != nil {
+ return nil, err
+ }
+ req.Header.Set("Content-Type", bodyType)
+ return Do(ctx, client, req)
+}
+
+// PostForm issues a POST request via the Do function.
+func PostForm(ctx context.Context, client *http.Client, url string, data url.Values) (*http.Response, error) {
+ return Post(ctx, client, url, "application/x-www-form-urlencoded", strings.NewReader(data.Encode()))
+}
diff --git a/vendor/golang.org/x/net/context/go17.go b/vendor/golang.org/x/net/context/go17.go
new file mode 100644
index 0000000000000000000000000000000000000000..d20f52b7de93f81675cb405bd4309af9ee61d2d1
--- /dev/null
+++ b/vendor/golang.org/x/net/context/go17.go
@@ -0,0 +1,72 @@
+// Copyright 2016 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build go1.7
+
+package context
+
+import (
+ "context" // standard library's context, as of Go 1.7
+ "time"
+)
+
+var (
+ todo = context.TODO()
+ background = context.Background()
+)
+
+// Canceled is the error returned by Context.Err when the context is canceled.
+var Canceled = context.Canceled
+
+// DeadlineExceeded is the error returned by Context.Err when the context's
+// deadline passes.
+var DeadlineExceeded = context.DeadlineExceeded
+
+// WithCancel returns a copy of parent with a new Done channel. The returned
+// context's Done channel is closed when the returned cancel function is called
+// or when the parent context's Done channel is closed, whichever happens first.
+//
+// Canceling this context releases resources associated with it, so code should
+// call cancel as soon as the operations running in this Context complete.
+func WithCancel(parent Context) (ctx Context, cancel CancelFunc) {
+ ctx, f := context.WithCancel(parent)
+ return ctx, CancelFunc(f)
+}
+
+// WithDeadline returns a copy of the parent context with the deadline adjusted
+// to be no later than d. If the parent's deadline is already earlier than d,
+// WithDeadline(parent, d) is semantically equivalent to parent. The returned
+// context's Done channel is closed when the deadline expires, when the returned
+// cancel function is called, or when the parent context's Done channel is
+// closed, whichever happens first.
+//
+// Canceling this context releases resources associated with it, so code should
+// call cancel as soon as the operations running in this Context complete.
+func WithDeadline(parent Context, deadline time.Time) (Context, CancelFunc) {
+ ctx, f := context.WithDeadline(parent, deadline)
+ return ctx, CancelFunc(f)
+}
+
+// WithTimeout returns WithDeadline(parent, time.Now().Add(timeout)).
+//
+// Canceling this context releases resources associated with it, so code should
+// call cancel as soon as the operations running in this Context complete:
+//
+// func slowOperationWithTimeout(ctx context.Context) (Result, error) {
+// ctx, cancel := context.WithTimeout(ctx, 100*time.Millisecond)
+// defer cancel() // releases resources if slowOperation completes before timeout elapses
+// return slowOperation(ctx)
+// }
+func WithTimeout(parent Context, timeout time.Duration) (Context, CancelFunc) {
+ return WithDeadline(parent, time.Now().Add(timeout))
+}
+
+// WithValue returns a copy of parent in which the value associated with key is
+// val.
+//
+// Use context Values only for request-scoped data that transits processes and
+// APIs, not for passing optional parameters to functions.
+func WithValue(parent Context, key interface{}, val interface{}) Context {
+ return context.WithValue(parent, key, val)
+}
diff --git a/vendor/golang.org/x/net/context/go19.go b/vendor/golang.org/x/net/context/go19.go
new file mode 100644
index 0000000000000000000000000000000000000000..d88bd1db127dd8154ca418b459efa269197f1508
--- /dev/null
+++ b/vendor/golang.org/x/net/context/go19.go
@@ -0,0 +1,20 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build go1.9
+
+package context
+
+import "context" // standard library's context, as of Go 1.7
+
+// A Context carries a deadline, a cancelation signal, and other values across
+// API boundaries.
+//
+// Context's methods may be called by multiple goroutines simultaneously.
+type Context = context.Context
+
+// A CancelFunc tells an operation to abandon its work.
+// A CancelFunc does not wait for the work to stop.
+// After the first call, subsequent calls to a CancelFunc do nothing.
+type CancelFunc = context.CancelFunc
diff --git a/vendor/golang.org/x/net/context/pre_go17.go b/vendor/golang.org/x/net/context/pre_go17.go
new file mode 100644
index 0000000000000000000000000000000000000000..0f35592df51885abc1eb01b2e58318590df65874
--- /dev/null
+++ b/vendor/golang.org/x/net/context/pre_go17.go
@@ -0,0 +1,300 @@
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build !go1.7
+
+package context
+
+import (
+ "errors"
+ "fmt"
+ "sync"
+ "time"
+)
+
+// An emptyCtx is never canceled, has no values, and has no deadline. It is not
+// struct{}, since vars of this type must have distinct addresses.
+type emptyCtx int
+
+func (*emptyCtx) Deadline() (deadline time.Time, ok bool) {
+ return
+}
+
+func (*emptyCtx) Done() <-chan struct{} {
+ return nil
+}
+
+func (*emptyCtx) Err() error {
+ return nil
+}
+
+func (*emptyCtx) Value(key interface{}) interface{} {
+ return nil
+}
+
+func (e *emptyCtx) String() string {
+ switch e {
+ case background:
+ return "context.Background"
+ case todo:
+ return "context.TODO"
+ }
+ return "unknown empty Context"
+}
+
+var (
+ background = new(emptyCtx)
+ todo = new(emptyCtx)
+)
+
+// Canceled is the error returned by Context.Err when the context is canceled.
+var Canceled = errors.New("context canceled")
+
+// DeadlineExceeded is the error returned by Context.Err when the context's
+// deadline passes.
+var DeadlineExceeded = errors.New("context deadline exceeded")
+
+// WithCancel returns a copy of parent with a new Done channel. The returned
+// context's Done channel is closed when the returned cancel function is called
+// or when the parent context's Done channel is closed, whichever happens first.
+//
+// Canceling this context releases resources associated with it, so code should
+// call cancel as soon as the operations running in this Context complete.
+func WithCancel(parent Context) (ctx Context, cancel CancelFunc) {
+ c := newCancelCtx(parent)
+ propagateCancel(parent, c)
+ return c, func() { c.cancel(true, Canceled) }
+}
+
+// newCancelCtx returns an initialized cancelCtx.
+func newCancelCtx(parent Context) *cancelCtx {
+ return &cancelCtx{
+ Context: parent,
+ done: make(chan struct{}),
+ }
+}
+
+// propagateCancel arranges for child to be canceled when parent is.
+func propagateCancel(parent Context, child canceler) {
+ if parent.Done() == nil {
+ return // parent is never canceled
+ }
+ if p, ok := parentCancelCtx(parent); ok {
+ p.mu.Lock()
+ if p.err != nil {
+ // parent has already been canceled
+ child.cancel(false, p.err)
+ } else {
+ if p.children == nil {
+ p.children = make(map[canceler]bool)
+ }
+ p.children[child] = true
+ }
+ p.mu.Unlock()
+ } else {
+ go func() {
+ select {
+ case <-parent.Done():
+ child.cancel(false, parent.Err())
+ case <-child.Done():
+ }
+ }()
+ }
+}
+
+// parentCancelCtx follows a chain of parent references until it finds a
+// *cancelCtx. This function understands how each of the concrete types in this
+// package represents its parent.
+func parentCancelCtx(parent Context) (*cancelCtx, bool) {
+ for {
+ switch c := parent.(type) {
+ case *cancelCtx:
+ return c, true
+ case *timerCtx:
+ return c.cancelCtx, true
+ case *valueCtx:
+ parent = c.Context
+ default:
+ return nil, false
+ }
+ }
+}
+
+// removeChild removes a context from its parent.
+func removeChild(parent Context, child canceler) {
+ p, ok := parentCancelCtx(parent)
+ if !ok {
+ return
+ }
+ p.mu.Lock()
+ if p.children != nil {
+ delete(p.children, child)
+ }
+ p.mu.Unlock()
+}
+
+// A canceler is a context type that can be canceled directly. The
+// implementations are *cancelCtx and *timerCtx.
+type canceler interface {
+ cancel(removeFromParent bool, err error)
+ Done() <-chan struct{}
+}
+
+// A cancelCtx can be canceled. When canceled, it also cancels any children
+// that implement canceler.
+type cancelCtx struct {
+ Context
+
+ done chan struct{} // closed by the first cancel call.
+
+ mu sync.Mutex
+ children map[canceler]bool // set to nil by the first cancel call
+ err error // set to non-nil by the first cancel call
+}
+
+func (c *cancelCtx) Done() <-chan struct{} {
+ return c.done
+}
+
+func (c *cancelCtx) Err() error {
+ c.mu.Lock()
+ defer c.mu.Unlock()
+ return c.err
+}
+
+func (c *cancelCtx) String() string {
+ return fmt.Sprintf("%v.WithCancel", c.Context)
+}
+
+// cancel closes c.done, cancels each of c's children, and, if
+// removeFromParent is true, removes c from its parent's children.
+func (c *cancelCtx) cancel(removeFromParent bool, err error) {
+ if err == nil {
+ panic("context: internal error: missing cancel error")
+ }
+ c.mu.Lock()
+ if c.err != nil {
+ c.mu.Unlock()
+ return // already canceled
+ }
+ c.err = err
+ close(c.done)
+ for child := range c.children {
+ // NOTE: acquiring the child's lock while holding parent's lock.
+ child.cancel(false, err)
+ }
+ c.children = nil
+ c.mu.Unlock()
+
+ if removeFromParent {
+ removeChild(c.Context, c)
+ }
+}
+
+// WithDeadline returns a copy of the parent context with the deadline adjusted
+// to be no later than d. If the parent's deadline is already earlier than d,
+// WithDeadline(parent, d) is semantically equivalent to parent. The returned
+// context's Done channel is closed when the deadline expires, when the returned
+// cancel function is called, or when the parent context's Done channel is
+// closed, whichever happens first.
+//
+// Canceling this context releases resources associated with it, so code should
+// call cancel as soon as the operations running in this Context complete.
+func WithDeadline(parent Context, deadline time.Time) (Context, CancelFunc) {
+ if cur, ok := parent.Deadline(); ok && cur.Before(deadline) {
+ // The current deadline is already sooner than the new one.
+ return WithCancel(parent)
+ }
+ c := &timerCtx{
+ cancelCtx: newCancelCtx(parent),
+ deadline: deadline,
+ }
+ propagateCancel(parent, c)
+ d := deadline.Sub(time.Now())
+ if d <= 0 {
+ c.cancel(true, DeadlineExceeded) // deadline has already passed
+ return c, func() { c.cancel(true, Canceled) }
+ }
+ c.mu.Lock()
+ defer c.mu.Unlock()
+ if c.err == nil {
+ c.timer = time.AfterFunc(d, func() {
+ c.cancel(true, DeadlineExceeded)
+ })
+ }
+ return c, func() { c.cancel(true, Canceled) }
+}
+
+// A timerCtx carries a timer and a deadline. It embeds a cancelCtx to
+// implement Done and Err. It implements cancel by stopping its timer then
+// delegating to cancelCtx.cancel.
+type timerCtx struct {
+ *cancelCtx
+ timer *time.Timer // Under cancelCtx.mu.
+
+ deadline time.Time
+}
+
+func (c *timerCtx) Deadline() (deadline time.Time, ok bool) {
+ return c.deadline, true
+}
+
+func (c *timerCtx) String() string {
+ return fmt.Sprintf("%v.WithDeadline(%s [%s])", c.cancelCtx.Context, c.deadline, c.deadline.Sub(time.Now()))
+}
+
+func (c *timerCtx) cancel(removeFromParent bool, err error) {
+ c.cancelCtx.cancel(false, err)
+ if removeFromParent {
+ // Remove this timerCtx from its parent cancelCtx's children.
+ removeChild(c.cancelCtx.Context, c)
+ }
+ c.mu.Lock()
+ if c.timer != nil {
+ c.timer.Stop()
+ c.timer = nil
+ }
+ c.mu.Unlock()
+}
+
+// WithTimeout returns WithDeadline(parent, time.Now().Add(timeout)).
+//
+// Canceling this context releases resources associated with it, so code should
+// call cancel as soon as the operations running in this Context complete:
+//
+// func slowOperationWithTimeout(ctx context.Context) (Result, error) {
+// ctx, cancel := context.WithTimeout(ctx, 100*time.Millisecond)
+// defer cancel() // releases resources if slowOperation completes before timeout elapses
+// return slowOperation(ctx)
+// }
+func WithTimeout(parent Context, timeout time.Duration) (Context, CancelFunc) {
+ return WithDeadline(parent, time.Now().Add(timeout))
+}
+
+// WithValue returns a copy of parent in which the value associated with key is
+// val.
+//
+// Use context Values only for request-scoped data that transits processes and
+// APIs, not for passing optional parameters to functions.
+func WithValue(parent Context, key interface{}, val interface{}) Context {
+ return &valueCtx{parent, key, val}
+}
+
+// A valueCtx carries a key-value pair. It implements Value for that key and
+// delegates all other calls to the embedded Context.
+type valueCtx struct {
+ Context
+ key, val interface{}
+}
+
+func (c *valueCtx) String() string {
+ return fmt.Sprintf("%v.WithValue(%#v, %#v)", c.Context, c.key, c.val)
+}
+
+func (c *valueCtx) Value(key interface{}) interface{} {
+ if c.key == key {
+ return c.val
+ }
+ return c.Context.Value(key)
+}
diff --git a/vendor/golang.org/x/net/context/pre_go19.go b/vendor/golang.org/x/net/context/pre_go19.go
new file mode 100644
index 0000000000000000000000000000000000000000..b105f80be4fe2bbcb225ae4343b551fc6d851b15
--- /dev/null
+++ b/vendor/golang.org/x/net/context/pre_go19.go
@@ -0,0 +1,109 @@
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build !go1.9
+
+package context
+
+import "time"
+
+// A Context carries a deadline, a cancelation signal, and other values across
+// API boundaries.
+//
+// Context's methods may be called by multiple goroutines simultaneously.
+type Context interface {
+ // Deadline returns the time when work done on behalf of this context
+ // should be canceled. Deadline returns ok==false when no deadline is
+ // set. Successive calls to Deadline return the same results.
+ Deadline() (deadline time.Time, ok bool)
+
+ // Done returns a channel that's closed when work done on behalf of this
+ // context should be canceled. Done may return nil if this context can
+ // never be canceled. Successive calls to Done return the same value.
+ //
+ // WithCancel arranges for Done to be closed when cancel is called;
+ // WithDeadline arranges for Done to be closed when the deadline
+ // expires; WithTimeout arranges for Done to be closed when the timeout
+ // elapses.
+ //
+ // Done is provided for use in select statements:
+ //
+ // // Stream generates values with DoSomething and sends them to out
+ // // until DoSomething returns an error or ctx.Done is closed.
+ // func Stream(ctx context.Context, out chan<- Value) error {
+ // for {
+ // v, err := DoSomething(ctx)
+ // if err != nil {
+ // return err
+ // }
+ // select {
+ // case <-ctx.Done():
+ // return ctx.Err()
+ // case out <- v:
+ // }
+ // }
+ // }
+ //
+ // See http://blog.golang.org/pipelines for more examples of how to use
+ // a Done channel for cancelation.
+ Done() <-chan struct{}
+
+ // Err returns a non-nil error value after Done is closed. Err returns
+ // Canceled if the context was canceled or DeadlineExceeded if the
+ // context's deadline passed. No other values for Err are defined.
+ // After Done is closed, successive calls to Err return the same value.
+ Err() error
+
+ // Value returns the value associated with this context for key, or nil
+ // if no value is associated with key. Successive calls to Value with
+ // the same key returns the same result.
+ //
+ // Use context values only for request-scoped data that transits
+ // processes and API boundaries, not for passing optional parameters to
+ // functions.
+ //
+ // A key identifies a specific value in a Context. Functions that wish
+ // to store values in Context typically allocate a key in a global
+ // variable then use that key as the argument to context.WithValue and
+ // Context.Value. A key can be any type that supports equality;
+ // packages should define keys as an unexported type to avoid
+ // collisions.
+ //
+ // Packages that define a Context key should provide type-safe accessors
+ // for the values stores using that key:
+ //
+ // // Package user defines a User type that's stored in Contexts.
+ // package user
+ //
+ // import "golang.org/x/net/context"
+ //
+ // // User is the type of value stored in the Contexts.
+ // type User struct {...}
+ //
+ // // key is an unexported type for keys defined in this package.
+ // // This prevents collisions with keys defined in other packages.
+ // type key int
+ //
+ // // userKey is the key for user.User values in Contexts. It is
+ // // unexported; clients use user.NewContext and user.FromContext
+ // // instead of using this key directly.
+ // var userKey key = 0
+ //
+ // // NewContext returns a new Context that carries value u.
+ // func NewContext(ctx context.Context, u *User) context.Context {
+ // return context.WithValue(ctx, userKey, u)
+ // }
+ //
+ // // FromContext returns the User value stored in ctx, if any.
+ // func FromContext(ctx context.Context) (*User, bool) {
+ // u, ok := ctx.Value(userKey).(*User)
+ // return u, ok
+ // }
+ Value(key interface{}) interface{}
+}
+
+// A CancelFunc tells an operation to abandon its work.
+// A CancelFunc does not wait for the work to stop.
+// After the first call, subsequent calls to a CancelFunc do nothing.
+type CancelFunc func()
diff --git a/vendor/golang.org/x/oauth2/.travis.yml b/vendor/golang.org/x/oauth2/.travis.yml
new file mode 100644
index 0000000000000000000000000000000000000000..fa139db225190948bfffb552fbe2d3e13659ec2a
--- /dev/null
+++ b/vendor/golang.org/x/oauth2/.travis.yml
@@ -0,0 +1,13 @@
+language: go
+
+go:
+ - tip
+
+install:
+ - export GOPATH="$HOME/gopath"
+ - mkdir -p "$GOPATH/src/golang.org/x"
+ - mv "$TRAVIS_BUILD_DIR" "$GOPATH/src/golang.org/x/oauth2"
+ - go get -v -t -d golang.org/x/oauth2/...
+
+script:
+ - go test -v golang.org/x/oauth2/...
diff --git a/vendor/golang.org/x/oauth2/AUTHORS b/vendor/golang.org/x/oauth2/AUTHORS
new file mode 100644
index 0000000000000000000000000000000000000000..15167cd746c560e5b3d3b233a169aa64d3e9101e
--- /dev/null
+++ b/vendor/golang.org/x/oauth2/AUTHORS
@@ -0,0 +1,3 @@
+# This source code refers to The Go Authors for copyright purposes.
+# The master list of authors is in the main Go distribution,
+# visible at http://tip.golang.org/AUTHORS.
diff --git a/vendor/golang.org/x/oauth2/CONTRIBUTING.md b/vendor/golang.org/x/oauth2/CONTRIBUTING.md
new file mode 100644
index 0000000000000000000000000000000000000000..dfbed62cf546d1a3cdef7bf31f965f8a1c6bc4ff
--- /dev/null
+++ b/vendor/golang.org/x/oauth2/CONTRIBUTING.md
@@ -0,0 +1,26 @@
+# Contributing to Go
+
+Go is an open source project.
+
+It is the work of hundreds of contributors. We appreciate your help!
+
+## Filing issues
+
+When [filing an issue](https://github.com/golang/oauth2/issues), make sure to answer these five questions:
+
+1. What version of Go are you using (`go version`)?
+2. What operating system and processor architecture are you using?
+3. What did you do?
+4. What did you expect to see?
+5. What did you see instead?
+
+General questions should go to the [golang-nuts mailing list](https://groups.google.com/group/golang-nuts) instead of the issue tracker.
+The gophers there will answer or ask you to file an issue if you've tripped over a bug.
+
+## Contributing code
+
+Please read the [Contribution Guidelines](https://golang.org/doc/contribute.html)
+before sending patches.
+
+Unless otherwise noted, the Go source files are distributed under
+the BSD-style license found in the LICENSE file.
diff --git a/vendor/golang.org/x/oauth2/CONTRIBUTORS b/vendor/golang.org/x/oauth2/CONTRIBUTORS
new file mode 100644
index 0000000000000000000000000000000000000000..1c4577e9680611383f46044d17fa343a96997c3c
--- /dev/null
+++ b/vendor/golang.org/x/oauth2/CONTRIBUTORS
@@ -0,0 +1,3 @@
+# This source code was written by the Go contributors.
+# The master list of contributors is in the main Go distribution,
+# visible at http://tip.golang.org/CONTRIBUTORS.
diff --git a/vendor/golang.org/x/oauth2/LICENSE b/vendor/golang.org/x/oauth2/LICENSE
new file mode 100644
index 0000000000000000000000000000000000000000..6a66aea5eafe0ca6a688840c47219556c552488e
--- /dev/null
+++ b/vendor/golang.org/x/oauth2/LICENSE
@@ -0,0 +1,27 @@
+Copyright (c) 2009 The Go Authors. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+ * Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above
+copyright notice, this list of conditions and the following disclaimer
+in the documentation and/or other materials provided with the
+distribution.
+ * Neither the name of Google Inc. nor the names of its
+contributors may be used to endorse or promote products derived from
+this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/vendor/golang.org/x/oauth2/README.md b/vendor/golang.org/x/oauth2/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..0f443e6934d9980f58a3d8327d4e8b6836de09cf
--- /dev/null
+++ b/vendor/golang.org/x/oauth2/README.md
@@ -0,0 +1,35 @@
+# OAuth2 for Go
+
+[](https://travis-ci.org/golang/oauth2)
+[](https://godoc.org/golang.org/x/oauth2)
+
+oauth2 package contains a client implementation for OAuth 2.0 spec.
+
+## Installation
+
+~~~~
+go get golang.org/x/oauth2
+~~~~
+
+Or you can manually git clone the repository to
+`$(go env GOPATH)/src/golang.org/x/oauth2`.
+
+See godoc for further documentation and examples.
+
+* [godoc.org/golang.org/x/oauth2](http://godoc.org/golang.org/x/oauth2)
+* [godoc.org/golang.org/x/oauth2/google](http://godoc.org/golang.org/x/oauth2/google)
+
+## Policy for new packages
+
+We no longer accept new provider-specific packages in this repo. For
+defining provider endpoints and provider-specific OAuth2 behavior, we
+encourage you to create packages elsewhere. We'll keep the existing
+packages for compatibility.
+
+## Report Issues / Send Patches
+
+This repository uses Gerrit for code changes. To learn how to submit changes to
+this repository, see https://golang.org/doc/contribute.html.
+
+The main issue tracker for the oauth2 repository is located at
+https://github.com/golang/oauth2/issues.
diff --git a/vendor/golang.org/x/oauth2/go.mod b/vendor/golang.org/x/oauth2/go.mod
new file mode 100644
index 0000000000000000000000000000000000000000..b3457815528f589ba43a7d45081346e313c2e9cd
--- /dev/null
+++ b/vendor/golang.org/x/oauth2/go.mod
@@ -0,0 +1,10 @@
+module golang.org/x/oauth2
+
+go 1.11
+
+require (
+ cloud.google.com/go v0.34.0
+ golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e
+ golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4 // indirect
+ google.golang.org/appengine v1.4.0
+)
diff --git a/vendor/golang.org/x/oauth2/go.sum b/vendor/golang.org/x/oauth2/go.sum
new file mode 100644
index 0000000000000000000000000000000000000000..6f0079b0d7f9eb51b8fd1d3c6943bd376b29d7c3
--- /dev/null
+++ b/vendor/golang.org/x/oauth2/go.sum
@@ -0,0 +1,12 @@
+cloud.google.com/go v0.34.0 h1:eOI3/cP2VTU6uZLDYAoic+eyzzB9YyGmJ7eIjl8rOPg=
+cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
+github.com/golang/protobuf v1.2.0 h1:P3YflyNX/ehuJFLhxviNdFxQPkGK5cDcApsge1SqnvM=
+github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
+golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e h1:bRhVy7zSSasaqNksaRZiA5EEI+Ei4I1nO5Jh72wfHlg=
+golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4 h1:YUO/7uOKsKeq9UokNS62b8FYywz3ker1l1vDZRCRefw=
+golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
+google.golang.org/appengine v1.4.0 h1:/wp5JvzpHIxhs/dumFmF7BXTf3Z+dd4uXta4kVyO508=
+google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
diff --git a/vendor/golang.org/x/oauth2/internal/client_appengine.go b/vendor/golang.org/x/oauth2/internal/client_appengine.go
new file mode 100644
index 0000000000000000000000000000000000000000..7434871880a7910907116fb9c925dd8c4f5a1480
--- /dev/null
+++ b/vendor/golang.org/x/oauth2/internal/client_appengine.go
@@ -0,0 +1,13 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build appengine
+
+package internal
+
+import "google.golang.org/appengine/urlfetch"
+
+func init() {
+ appengineClientHook = urlfetch.Client
+}
diff --git a/vendor/golang.org/x/oauth2/internal/doc.go b/vendor/golang.org/x/oauth2/internal/doc.go
new file mode 100644
index 0000000000000000000000000000000000000000..03265e888af46a5c338b178a9ce775da83474f38
--- /dev/null
+++ b/vendor/golang.org/x/oauth2/internal/doc.go
@@ -0,0 +1,6 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package internal contains support packages for oauth2 package.
+package internal
diff --git a/vendor/golang.org/x/oauth2/internal/oauth2.go b/vendor/golang.org/x/oauth2/internal/oauth2.go
new file mode 100644
index 0000000000000000000000000000000000000000..c0ab196cf461cf3eb159d732e29f41a880d5a125
--- /dev/null
+++ b/vendor/golang.org/x/oauth2/internal/oauth2.go
@@ -0,0 +1,37 @@
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package internal
+
+import (
+ "crypto/rsa"
+ "crypto/x509"
+ "encoding/pem"
+ "errors"
+ "fmt"
+)
+
+// ParseKey converts the binary contents of a private key file
+// to an *rsa.PrivateKey. It detects whether the private key is in a
+// PEM container or not. If so, it extracts the the private key
+// from PEM container before conversion. It only supports PEM
+// containers with no passphrase.
+func ParseKey(key []byte) (*rsa.PrivateKey, error) {
+ block, _ := pem.Decode(key)
+ if block != nil {
+ key = block.Bytes
+ }
+ parsedKey, err := x509.ParsePKCS8PrivateKey(key)
+ if err != nil {
+ parsedKey, err = x509.ParsePKCS1PrivateKey(key)
+ if err != nil {
+ return nil, fmt.Errorf("private key should be a PEM or plain PKCS1 or PKCS8; parse error: %v", err)
+ }
+ }
+ parsed, ok := parsedKey.(*rsa.PrivateKey)
+ if !ok {
+ return nil, errors.New("private key is invalid")
+ }
+ return parsed, nil
+}
diff --git a/vendor/golang.org/x/oauth2/internal/token.go b/vendor/golang.org/x/oauth2/internal/token.go
new file mode 100644
index 0000000000000000000000000000000000000000..355c386961dd427f8b2ca44bf5328c135087311b
--- /dev/null
+++ b/vendor/golang.org/x/oauth2/internal/token.go
@@ -0,0 +1,294 @@
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package internal
+
+import (
+ "context"
+ "encoding/json"
+ "errors"
+ "fmt"
+ "io"
+ "io/ioutil"
+ "math"
+ "mime"
+ "net/http"
+ "net/url"
+ "strconv"
+ "strings"
+ "sync"
+ "time"
+
+ "golang.org/x/net/context/ctxhttp"
+)
+
+// Token represents the credentials used to authorize
+// the requests to access protected resources on the OAuth 2.0
+// provider's backend.
+//
+// This type is a mirror of oauth2.Token and exists to break
+// an otherwise-circular dependency. Other internal packages
+// should convert this Token into an oauth2.Token before use.
+type Token struct {
+ // AccessToken is the token that authorizes and authenticates
+ // the requests.
+ AccessToken string
+
+ // TokenType is the type of token.
+ // The Type method returns either this or "Bearer", the default.
+ TokenType string
+
+ // RefreshToken is a token that's used by the application
+ // (as opposed to the user) to refresh the access token
+ // if it expires.
+ RefreshToken string
+
+ // Expiry is the optional expiration time of the access token.
+ //
+ // If zero, TokenSource implementations will reuse the same
+ // token forever and RefreshToken or equivalent
+ // mechanisms for that TokenSource will not be used.
+ Expiry time.Time
+
+ // Raw optionally contains extra metadata from the server
+ // when updating a token.
+ Raw interface{}
+}
+
+// tokenJSON is the struct representing the HTTP response from OAuth2
+// providers returning a token in JSON form.
+type tokenJSON struct {
+ AccessToken string `json:"access_token"`
+ TokenType string `json:"token_type"`
+ RefreshToken string `json:"refresh_token"`
+ ExpiresIn expirationTime `json:"expires_in"` // at least PayPal returns string, while most return number
+}
+
+func (e *tokenJSON) expiry() (t time.Time) {
+ if v := e.ExpiresIn; v != 0 {
+ return time.Now().Add(time.Duration(v) * time.Second)
+ }
+ return
+}
+
+type expirationTime int32
+
+func (e *expirationTime) UnmarshalJSON(b []byte) error {
+ if len(b) == 0 || string(b) == "null" {
+ return nil
+ }
+ var n json.Number
+ err := json.Unmarshal(b, &n)
+ if err != nil {
+ return err
+ }
+ i, err := n.Int64()
+ if err != nil {
+ return err
+ }
+ if i > math.MaxInt32 {
+ i = math.MaxInt32
+ }
+ *e = expirationTime(i)
+ return nil
+}
+
+// RegisterBrokenAuthHeaderProvider previously did something. It is now a no-op.
+//
+// Deprecated: this function no longer does anything. Caller code that
+// wants to avoid potential extra HTTP requests made during
+// auto-probing of the provider's auth style should set
+// Endpoint.AuthStyle.
+func RegisterBrokenAuthHeaderProvider(tokenURL string) {}
+
+// AuthStyle is a copy of the golang.org/x/oauth2 package's AuthStyle type.
+type AuthStyle int
+
+const (
+ AuthStyleUnknown AuthStyle = 0
+ AuthStyleInParams AuthStyle = 1
+ AuthStyleInHeader AuthStyle = 2
+)
+
+// authStyleCache is the set of tokenURLs we've successfully used via
+// RetrieveToken and which style auth we ended up using.
+// It's called a cache, but it doesn't (yet?) shrink. It's expected that
+// the set of OAuth2 servers a program contacts over time is fixed and
+// small.
+var authStyleCache struct {
+ sync.Mutex
+ m map[string]AuthStyle // keyed by tokenURL
+}
+
+// ResetAuthCache resets the global authentication style cache used
+// for AuthStyleUnknown token requests.
+func ResetAuthCache() {
+ authStyleCache.Lock()
+ defer authStyleCache.Unlock()
+ authStyleCache.m = nil
+}
+
+// lookupAuthStyle reports which auth style we last used with tokenURL
+// when calling RetrieveToken and whether we have ever done so.
+func lookupAuthStyle(tokenURL string) (style AuthStyle, ok bool) {
+ authStyleCache.Lock()
+ defer authStyleCache.Unlock()
+ style, ok = authStyleCache.m[tokenURL]
+ return
+}
+
+// setAuthStyle adds an entry to authStyleCache, documented above.
+func setAuthStyle(tokenURL string, v AuthStyle) {
+ authStyleCache.Lock()
+ defer authStyleCache.Unlock()
+ if authStyleCache.m == nil {
+ authStyleCache.m = make(map[string]AuthStyle)
+ }
+ authStyleCache.m[tokenURL] = v
+}
+
+// newTokenRequest returns a new *http.Request to retrieve a new token
+// from tokenURL using the provided clientID, clientSecret, and POST
+// body parameters.
+//
+// inParams is whether the clientID & clientSecret should be encoded
+// as the POST body. An 'inParams' value of true means to send it in
+// the POST body (along with any values in v); false means to send it
+// in the Authorization header.
+func newTokenRequest(tokenURL, clientID, clientSecret string, v url.Values, authStyle AuthStyle) (*http.Request, error) {
+ if authStyle == AuthStyleInParams {
+ v = cloneURLValues(v)
+ if clientID != "" {
+ v.Set("client_id", clientID)
+ }
+ if clientSecret != "" {
+ v.Set("client_secret", clientSecret)
+ }
+ }
+ req, err := http.NewRequest("POST", tokenURL, strings.NewReader(v.Encode()))
+ if err != nil {
+ return nil, err
+ }
+ req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
+ if authStyle == AuthStyleInHeader {
+ req.SetBasicAuth(url.QueryEscape(clientID), url.QueryEscape(clientSecret))
+ }
+ return req, nil
+}
+
+func cloneURLValues(v url.Values) url.Values {
+ v2 := make(url.Values, len(v))
+ for k, vv := range v {
+ v2[k] = append([]string(nil), vv...)
+ }
+ return v2
+}
+
+func RetrieveToken(ctx context.Context, clientID, clientSecret, tokenURL string, v url.Values, authStyle AuthStyle) (*Token, error) {
+ needsAuthStyleProbe := authStyle == 0
+ if needsAuthStyleProbe {
+ if style, ok := lookupAuthStyle(tokenURL); ok {
+ authStyle = style
+ needsAuthStyleProbe = false
+ } else {
+ authStyle = AuthStyleInHeader // the first way we'll try
+ }
+ }
+ req, err := newTokenRequest(tokenURL, clientID, clientSecret, v, authStyle)
+ if err != nil {
+ return nil, err
+ }
+ token, err := doTokenRoundTrip(ctx, req)
+ if err != nil && needsAuthStyleProbe {
+ // If we get an error, assume the server wants the
+ // clientID & clientSecret in a different form.
+ // See https://code.google.com/p/goauth2/issues/detail?id=31 for background.
+ // In summary:
+ // - Reddit only accepts client secret in the Authorization header
+ // - Dropbox accepts either it in URL param or Auth header, but not both.
+ // - Google only accepts URL param (not spec compliant?), not Auth header
+ // - Stripe only accepts client secret in Auth header with Bearer method, not Basic
+ //
+ // We used to maintain a big table in this code of all the sites and which way
+ // they went, but maintaining it didn't scale & got annoying.
+ // So just try both ways.
+ authStyle = AuthStyleInParams // the second way we'll try
+ req, _ = newTokenRequest(tokenURL, clientID, clientSecret, v, authStyle)
+ token, err = doTokenRoundTrip(ctx, req)
+ }
+ if needsAuthStyleProbe && err == nil {
+ setAuthStyle(tokenURL, authStyle)
+ }
+ // Don't overwrite `RefreshToken` with an empty value
+ // if this was a token refreshing request.
+ if token != nil && token.RefreshToken == "" {
+ token.RefreshToken = v.Get("refresh_token")
+ }
+ return token, err
+}
+
+func doTokenRoundTrip(ctx context.Context, req *http.Request) (*Token, error) {
+ r, err := ctxhttp.Do(ctx, ContextClient(ctx), req)
+ if err != nil {
+ return nil, err
+ }
+ body, err := ioutil.ReadAll(io.LimitReader(r.Body, 1<<20))
+ r.Body.Close()
+ if err != nil {
+ return nil, fmt.Errorf("oauth2: cannot fetch token: %v", err)
+ }
+ if code := r.StatusCode; code < 200 || code > 299 {
+ return nil, &RetrieveError{
+ Response: r,
+ Body: body,
+ }
+ }
+
+ var token *Token
+ content, _, _ := mime.ParseMediaType(r.Header.Get("Content-Type"))
+ switch content {
+ case "application/x-www-form-urlencoded", "text/plain":
+ vals, err := url.ParseQuery(string(body))
+ if err != nil {
+ return nil, err
+ }
+ token = &Token{
+ AccessToken: vals.Get("access_token"),
+ TokenType: vals.Get("token_type"),
+ RefreshToken: vals.Get("refresh_token"),
+ Raw: vals,
+ }
+ e := vals.Get("expires_in")
+ expires, _ := strconv.Atoi(e)
+ if expires != 0 {
+ token.Expiry = time.Now().Add(time.Duration(expires) * time.Second)
+ }
+ default:
+ var tj tokenJSON
+ if err = json.Unmarshal(body, &tj); err != nil {
+ return nil, err
+ }
+ token = &Token{
+ AccessToken: tj.AccessToken,
+ TokenType: tj.TokenType,
+ RefreshToken: tj.RefreshToken,
+ Expiry: tj.expiry(),
+ Raw: make(map[string]interface{}),
+ }
+ json.Unmarshal(body, &token.Raw) // no error checks for optional fields
+ }
+ if token.AccessToken == "" {
+ return nil, errors.New("oauth2: server response missing access_token")
+ }
+ return token, nil
+}
+
+type RetrieveError struct {
+ Response *http.Response
+ Body []byte
+}
+
+func (r *RetrieveError) Error() string {
+ return fmt.Sprintf("oauth2: cannot fetch token: %v\nResponse: %s", r.Response.Status, r.Body)
+}
diff --git a/vendor/golang.org/x/oauth2/internal/transport.go b/vendor/golang.org/x/oauth2/internal/transport.go
new file mode 100644
index 0000000000000000000000000000000000000000..572074a637dd6fbf13571900bac00289871d9dcc
--- /dev/null
+++ b/vendor/golang.org/x/oauth2/internal/transport.go
@@ -0,0 +1,33 @@
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package internal
+
+import (
+ "context"
+ "net/http"
+)
+
+// HTTPClient is the context key to use with golang.org/x/net/context's
+// WithValue function to associate an *http.Client value with a context.
+var HTTPClient ContextKey
+
+// ContextKey is just an empty struct. It exists so HTTPClient can be
+// an immutable public variable with a unique type. It's immutable
+// because nobody else can create a ContextKey, being unexported.
+type ContextKey struct{}
+
+var appengineClientHook func(context.Context) *http.Client
+
+func ContextClient(ctx context.Context) *http.Client {
+ if ctx != nil {
+ if hc, ok := ctx.Value(HTTPClient).(*http.Client); ok {
+ return hc
+ }
+ }
+ if appengineClientHook != nil {
+ return appengineClientHook(ctx)
+ }
+ return http.DefaultClient
+}
diff --git a/vendor/golang.org/x/oauth2/oauth2.go b/vendor/golang.org/x/oauth2/oauth2.go
new file mode 100644
index 0000000000000000000000000000000000000000..291df5c833f961d7fe6e3dc35792bffa6fdebabb
--- /dev/null
+++ b/vendor/golang.org/x/oauth2/oauth2.go
@@ -0,0 +1,381 @@
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package oauth2 provides support for making
+// OAuth2 authorized and authenticated HTTP requests,
+// as specified in RFC 6749.
+// It can additionally grant authorization with Bearer JWT.
+package oauth2 // import "golang.org/x/oauth2"
+
+import (
+ "bytes"
+ "context"
+ "errors"
+ "net/http"
+ "net/url"
+ "strings"
+ "sync"
+
+ "golang.org/x/oauth2/internal"
+)
+
+// NoContext is the default context you should supply if not using
+// your own context.Context (see https://golang.org/x/net/context).
+//
+// Deprecated: Use context.Background() or context.TODO() instead.
+var NoContext = context.TODO()
+
+// RegisterBrokenAuthHeaderProvider previously did something. It is now a no-op.
+//
+// Deprecated: this function no longer does anything. Caller code that
+// wants to avoid potential extra HTTP requests made during
+// auto-probing of the provider's auth style should set
+// Endpoint.AuthStyle.
+func RegisterBrokenAuthHeaderProvider(tokenURL string) {}
+
+// Config describes a typical 3-legged OAuth2 flow, with both the
+// client application information and the server's endpoint URLs.
+// For the client credentials 2-legged OAuth2 flow, see the clientcredentials
+// package (https://golang.org/x/oauth2/clientcredentials).
+type Config struct {
+ // ClientID is the application's ID.
+ ClientID string
+
+ // ClientSecret is the application's secret.
+ ClientSecret string
+
+ // Endpoint contains the resource server's token endpoint
+ // URLs. These are constants specific to each server and are
+ // often available via site-specific packages, such as
+ // google.Endpoint or github.Endpoint.
+ Endpoint Endpoint
+
+ // RedirectURL is the URL to redirect users going through
+ // the OAuth flow, after the resource owner's URLs.
+ RedirectURL string
+
+ // Scope specifies optional requested permissions.
+ Scopes []string
+}
+
+// A TokenSource is anything that can return a token.
+type TokenSource interface {
+ // Token returns a token or an error.
+ // Token must be safe for concurrent use by multiple goroutines.
+ // The returned Token must not be modified.
+ Token() (*Token, error)
+}
+
+// Endpoint represents an OAuth 2.0 provider's authorization and token
+// endpoint URLs.
+type Endpoint struct {
+ AuthURL string
+ TokenURL string
+
+ // AuthStyle optionally specifies how the endpoint wants the
+ // client ID & client secret sent. The zero value means to
+ // auto-detect.
+ AuthStyle AuthStyle
+}
+
+// AuthStyle represents how requests for tokens are authenticated
+// to the server.
+type AuthStyle int
+
+const (
+ // AuthStyleAutoDetect means to auto-detect which authentication
+ // style the provider wants by trying both ways and caching
+ // the successful way for the future.
+ AuthStyleAutoDetect AuthStyle = 0
+
+ // AuthStyleInParams sends the "client_id" and "client_secret"
+ // in the POST body as application/x-www-form-urlencoded parameters.
+ AuthStyleInParams AuthStyle = 1
+
+ // AuthStyleInHeader sends the client_id and client_password
+ // using HTTP Basic Authorization. This is an optional style
+ // described in the OAuth2 RFC 6749 section 2.3.1.
+ AuthStyleInHeader AuthStyle = 2
+)
+
+var (
+ // AccessTypeOnline and AccessTypeOffline are options passed
+ // to the Options.AuthCodeURL method. They modify the
+ // "access_type" field that gets sent in the URL returned by
+ // AuthCodeURL.
+ //
+ // Online is the default if neither is specified. If your
+ // application needs to refresh access tokens when the user
+ // is not present at the browser, then use offline. This will
+ // result in your application obtaining a refresh token the
+ // first time your application exchanges an authorization
+ // code for a user.
+ AccessTypeOnline AuthCodeOption = SetAuthURLParam("access_type", "online")
+ AccessTypeOffline AuthCodeOption = SetAuthURLParam("access_type", "offline")
+
+ // ApprovalForce forces the users to view the consent dialog
+ // and confirm the permissions request at the URL returned
+ // from AuthCodeURL, even if they've already done so.
+ ApprovalForce AuthCodeOption = SetAuthURLParam("prompt", "consent")
+)
+
+// An AuthCodeOption is passed to Config.AuthCodeURL.
+type AuthCodeOption interface {
+ setValue(url.Values)
+}
+
+type setParam struct{ k, v string }
+
+func (p setParam) setValue(m url.Values) { m.Set(p.k, p.v) }
+
+// SetAuthURLParam builds an AuthCodeOption which passes key/value parameters
+// to a provider's authorization endpoint.
+func SetAuthURLParam(key, value string) AuthCodeOption {
+ return setParam{key, value}
+}
+
+// AuthCodeURL returns a URL to OAuth 2.0 provider's consent page
+// that asks for permissions for the required scopes explicitly.
+//
+// State is a token to protect the user from CSRF attacks. You must
+// always provide a non-empty string and validate that it matches the
+// the state query parameter on your redirect callback.
+// See http://tools.ietf.org/html/rfc6749#section-10.12 for more info.
+//
+// Opts may include AccessTypeOnline or AccessTypeOffline, as well
+// as ApprovalForce.
+// It can also be used to pass the PKCE challenge.
+// See https://www.oauth.com/oauth2-servers/pkce/ for more info.
+func (c *Config) AuthCodeURL(state string, opts ...AuthCodeOption) string {
+ var buf bytes.Buffer
+ buf.WriteString(c.Endpoint.AuthURL)
+ v := url.Values{
+ "response_type": {"code"},
+ "client_id": {c.ClientID},
+ }
+ if c.RedirectURL != "" {
+ v.Set("redirect_uri", c.RedirectURL)
+ }
+ if len(c.Scopes) > 0 {
+ v.Set("scope", strings.Join(c.Scopes, " "))
+ }
+ if state != "" {
+ // TODO(light): Docs say never to omit state; don't allow empty.
+ v.Set("state", state)
+ }
+ for _, opt := range opts {
+ opt.setValue(v)
+ }
+ if strings.Contains(c.Endpoint.AuthURL, "?") {
+ buf.WriteByte('&')
+ } else {
+ buf.WriteByte('?')
+ }
+ buf.WriteString(v.Encode())
+ return buf.String()
+}
+
+// PasswordCredentialsToken converts a resource owner username and password
+// pair into a token.
+//
+// Per the RFC, this grant type should only be used "when there is a high
+// degree of trust between the resource owner and the client (e.g., the client
+// is part of the device operating system or a highly privileged application),
+// and when other authorization grant types are not available."
+// See https://tools.ietf.org/html/rfc6749#section-4.3 for more info.
+//
+// The provided context optionally controls which HTTP client is used. See the HTTPClient variable.
+func (c *Config) PasswordCredentialsToken(ctx context.Context, username, password string) (*Token, error) {
+ v := url.Values{
+ "grant_type": {"password"},
+ "username": {username},
+ "password": {password},
+ }
+ if len(c.Scopes) > 0 {
+ v.Set("scope", strings.Join(c.Scopes, " "))
+ }
+ return retrieveToken(ctx, c, v)
+}
+
+// Exchange converts an authorization code into a token.
+//
+// It is used after a resource provider redirects the user back
+// to the Redirect URI (the URL obtained from AuthCodeURL).
+//
+// The provided context optionally controls which HTTP client is used. See the HTTPClient variable.
+//
+// The code will be in the *http.Request.FormValue("code"). Before
+// calling Exchange, be sure to validate FormValue("state").
+//
+// Opts may include the PKCE verifier code if previously used in AuthCodeURL.
+// See https://www.oauth.com/oauth2-servers/pkce/ for more info.
+func (c *Config) Exchange(ctx context.Context, code string, opts ...AuthCodeOption) (*Token, error) {
+ v := url.Values{
+ "grant_type": {"authorization_code"},
+ "code": {code},
+ }
+ if c.RedirectURL != "" {
+ v.Set("redirect_uri", c.RedirectURL)
+ }
+ for _, opt := range opts {
+ opt.setValue(v)
+ }
+ return retrieveToken(ctx, c, v)
+}
+
+// Client returns an HTTP client using the provided token.
+// The token will auto-refresh as necessary. The underlying
+// HTTP transport will be obtained using the provided context.
+// The returned client and its Transport should not be modified.
+func (c *Config) Client(ctx context.Context, t *Token) *http.Client {
+ return NewClient(ctx, c.TokenSource(ctx, t))
+}
+
+// TokenSource returns a TokenSource that returns t until t expires,
+// automatically refreshing it as necessary using the provided context.
+//
+// Most users will use Config.Client instead.
+func (c *Config) TokenSource(ctx context.Context, t *Token) TokenSource {
+ tkr := &tokenRefresher{
+ ctx: ctx,
+ conf: c,
+ }
+ if t != nil {
+ tkr.refreshToken = t.RefreshToken
+ }
+ return &reuseTokenSource{
+ t: t,
+ new: tkr,
+ }
+}
+
+// tokenRefresher is a TokenSource that makes "grant_type"=="refresh_token"
+// HTTP requests to renew a token using a RefreshToken.
+type tokenRefresher struct {
+ ctx context.Context // used to get HTTP requests
+ conf *Config
+ refreshToken string
+}
+
+// WARNING: Token is not safe for concurrent access, as it
+// updates the tokenRefresher's refreshToken field.
+// Within this package, it is used by reuseTokenSource which
+// synchronizes calls to this method with its own mutex.
+func (tf *tokenRefresher) Token() (*Token, error) {
+ if tf.refreshToken == "" {
+ return nil, errors.New("oauth2: token expired and refresh token is not set")
+ }
+
+ tk, err := retrieveToken(tf.ctx, tf.conf, url.Values{
+ "grant_type": {"refresh_token"},
+ "refresh_token": {tf.refreshToken},
+ })
+
+ if err != nil {
+ return nil, err
+ }
+ if tf.refreshToken != tk.RefreshToken {
+ tf.refreshToken = tk.RefreshToken
+ }
+ return tk, err
+}
+
+// reuseTokenSource is a TokenSource that holds a single token in memory
+// and validates its expiry before each call to retrieve it with
+// Token. If it's expired, it will be auto-refreshed using the
+// new TokenSource.
+type reuseTokenSource struct {
+ new TokenSource // called when t is expired.
+
+ mu sync.Mutex // guards t
+ t *Token
+}
+
+// Token returns the current token if it's still valid, else will
+// refresh the current token (using r.Context for HTTP client
+// information) and return the new one.
+func (s *reuseTokenSource) Token() (*Token, error) {
+ s.mu.Lock()
+ defer s.mu.Unlock()
+ if s.t.Valid() {
+ return s.t, nil
+ }
+ t, err := s.new.Token()
+ if err != nil {
+ return nil, err
+ }
+ s.t = t
+ return t, nil
+}
+
+// StaticTokenSource returns a TokenSource that always returns the same token.
+// Because the provided token t is never refreshed, StaticTokenSource is only
+// useful for tokens that never expire.
+func StaticTokenSource(t *Token) TokenSource {
+ return staticTokenSource{t}
+}
+
+// staticTokenSource is a TokenSource that always returns the same Token.
+type staticTokenSource struct {
+ t *Token
+}
+
+func (s staticTokenSource) Token() (*Token, error) {
+ return s.t, nil
+}
+
+// HTTPClient is the context key to use with golang.org/x/net/context's
+// WithValue function to associate an *http.Client value with a context.
+var HTTPClient internal.ContextKey
+
+// NewClient creates an *http.Client from a Context and TokenSource.
+// The returned client is not valid beyond the lifetime of the context.
+//
+// Note that if a custom *http.Client is provided via the Context it
+// is used only for token acquisition and is not used to configure the
+// *http.Client returned from NewClient.
+//
+// As a special case, if src is nil, a non-OAuth2 client is returned
+// using the provided context. This exists to support related OAuth2
+// packages.
+func NewClient(ctx context.Context, src TokenSource) *http.Client {
+ if src == nil {
+ return internal.ContextClient(ctx)
+ }
+ return &http.Client{
+ Transport: &Transport{
+ Base: internal.ContextClient(ctx).Transport,
+ Source: ReuseTokenSource(nil, src),
+ },
+ }
+}
+
+// ReuseTokenSource returns a TokenSource which repeatedly returns the
+// same token as long as it's valid, starting with t.
+// When its cached token is invalid, a new token is obtained from src.
+//
+// ReuseTokenSource is typically used to reuse tokens from a cache
+// (such as a file on disk) between runs of a program, rather than
+// obtaining new tokens unnecessarily.
+//
+// The initial token t may be nil, in which case the TokenSource is
+// wrapped in a caching version if it isn't one already. This also
+// means it's always safe to wrap ReuseTokenSource around any other
+// TokenSource without adverse effects.
+func ReuseTokenSource(t *Token, src TokenSource) TokenSource {
+ // Don't wrap a reuseTokenSource in itself. That would work,
+ // but cause an unnecessary number of mutex operations.
+ // Just build the equivalent one.
+ if rt, ok := src.(*reuseTokenSource); ok {
+ if t == nil {
+ // Just use it directly.
+ return rt
+ }
+ src = rt.new
+ }
+ return &reuseTokenSource{
+ t: t,
+ new: src,
+ }
+}
diff --git a/vendor/golang.org/x/oauth2/token.go b/vendor/golang.org/x/oauth2/token.go
new file mode 100644
index 0000000000000000000000000000000000000000..822720341af143a33c4585dd9d8219d231ee5921
--- /dev/null
+++ b/vendor/golang.org/x/oauth2/token.go
@@ -0,0 +1,178 @@
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package oauth2
+
+import (
+ "context"
+ "fmt"
+ "net/http"
+ "net/url"
+ "strconv"
+ "strings"
+ "time"
+
+ "golang.org/x/oauth2/internal"
+)
+
+// expiryDelta determines how earlier a token should be considered
+// expired than its actual expiration time. It is used to avoid late
+// expirations due to client-server time mismatches.
+const expiryDelta = 10 * time.Second
+
+// Token represents the credentials used to authorize
+// the requests to access protected resources on the OAuth 2.0
+// provider's backend.
+//
+// Most users of this package should not access fields of Token
+// directly. They're exported mostly for use by related packages
+// implementing derivative OAuth2 flows.
+type Token struct {
+ // AccessToken is the token that authorizes and authenticates
+ // the requests.
+ AccessToken string `json:"access_token"`
+
+ // TokenType is the type of token.
+ // The Type method returns either this or "Bearer", the default.
+ TokenType string `json:"token_type,omitempty"`
+
+ // RefreshToken is a token that's used by the application
+ // (as opposed to the user) to refresh the access token
+ // if it expires.
+ RefreshToken string `json:"refresh_token,omitempty"`
+
+ // Expiry is the optional expiration time of the access token.
+ //
+ // If zero, TokenSource implementations will reuse the same
+ // token forever and RefreshToken or equivalent
+ // mechanisms for that TokenSource will not be used.
+ Expiry time.Time `json:"expiry,omitempty"`
+
+ // raw optionally contains extra metadata from the server
+ // when updating a token.
+ raw interface{}
+}
+
+// Type returns t.TokenType if non-empty, else "Bearer".
+func (t *Token) Type() string {
+ if strings.EqualFold(t.TokenType, "bearer") {
+ return "Bearer"
+ }
+ if strings.EqualFold(t.TokenType, "mac") {
+ return "MAC"
+ }
+ if strings.EqualFold(t.TokenType, "basic") {
+ return "Basic"
+ }
+ if t.TokenType != "" {
+ return t.TokenType
+ }
+ return "Bearer"
+}
+
+// SetAuthHeader sets the Authorization header to r using the access
+// token in t.
+//
+// This method is unnecessary when using Transport or an HTTP Client
+// returned by this package.
+func (t *Token) SetAuthHeader(r *http.Request) {
+ r.Header.Set("Authorization", t.Type()+" "+t.AccessToken)
+}
+
+// WithExtra returns a new Token that's a clone of t, but using the
+// provided raw extra map. This is only intended for use by packages
+// implementing derivative OAuth2 flows.
+func (t *Token) WithExtra(extra interface{}) *Token {
+ t2 := new(Token)
+ *t2 = *t
+ t2.raw = extra
+ return t2
+}
+
+// Extra returns an extra field.
+// Extra fields are key-value pairs returned by the server as a
+// part of the token retrieval response.
+func (t *Token) Extra(key string) interface{} {
+ if raw, ok := t.raw.(map[string]interface{}); ok {
+ return raw[key]
+ }
+
+ vals, ok := t.raw.(url.Values)
+ if !ok {
+ return nil
+ }
+
+ v := vals.Get(key)
+ switch s := strings.TrimSpace(v); strings.Count(s, ".") {
+ case 0: // Contains no "."; try to parse as int
+ if i, err := strconv.ParseInt(s, 10, 64); err == nil {
+ return i
+ }
+ case 1: // Contains a single "."; try to parse as float
+ if f, err := strconv.ParseFloat(s, 64); err == nil {
+ return f
+ }
+ }
+
+ return v
+}
+
+// timeNow is time.Now but pulled out as a variable for tests.
+var timeNow = time.Now
+
+// expired reports whether the token is expired.
+// t must be non-nil.
+func (t *Token) expired() bool {
+ if t.Expiry.IsZero() {
+ return false
+ }
+ return t.Expiry.Round(0).Add(-expiryDelta).Before(timeNow())
+}
+
+// Valid reports whether t is non-nil, has an AccessToken, and is not expired.
+func (t *Token) Valid() bool {
+ return t != nil && t.AccessToken != "" && !t.expired()
+}
+
+// tokenFromInternal maps an *internal.Token struct into
+// a *Token struct.
+func tokenFromInternal(t *internal.Token) *Token {
+ if t == nil {
+ return nil
+ }
+ return &Token{
+ AccessToken: t.AccessToken,
+ TokenType: t.TokenType,
+ RefreshToken: t.RefreshToken,
+ Expiry: t.Expiry,
+ raw: t.Raw,
+ }
+}
+
+// retrieveToken takes a *Config and uses that to retrieve an *internal.Token.
+// This token is then mapped from *internal.Token into an *oauth2.Token which is returned along
+// with an error..
+func retrieveToken(ctx context.Context, c *Config, v url.Values) (*Token, error) {
+ tk, err := internal.RetrieveToken(ctx, c.ClientID, c.ClientSecret, c.Endpoint.TokenURL, v, internal.AuthStyle(c.Endpoint.AuthStyle))
+ if err != nil {
+ if rErr, ok := err.(*internal.RetrieveError); ok {
+ return nil, (*RetrieveError)(rErr)
+ }
+ return nil, err
+ }
+ return tokenFromInternal(tk), nil
+}
+
+// RetrieveError is the error returned when the token endpoint returns a
+// non-2XX HTTP status code.
+type RetrieveError struct {
+ Response *http.Response
+ // Body is the body that was consumed by reading Response.Body.
+ // It may be truncated.
+ Body []byte
+}
+
+func (r *RetrieveError) Error() string {
+ return fmt.Sprintf("oauth2: cannot fetch token: %v\nResponse: %s", r.Response.Status, r.Body)
+}
diff --git a/vendor/golang.org/x/oauth2/transport.go b/vendor/golang.org/x/oauth2/transport.go
new file mode 100644
index 0000000000000000000000000000000000000000..aa0d34f1e0eaf5b4ab9f35244ebe3503bd34e689
--- /dev/null
+++ b/vendor/golang.org/x/oauth2/transport.go
@@ -0,0 +1,144 @@
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package oauth2
+
+import (
+ "errors"
+ "io"
+ "net/http"
+ "sync"
+)
+
+// Transport is an http.RoundTripper that makes OAuth 2.0 HTTP requests,
+// wrapping a base RoundTripper and adding an Authorization header
+// with a token from the supplied Sources.
+//
+// Transport is a low-level mechanism. Most code will use the
+// higher-level Config.Client method instead.
+type Transport struct {
+ // Source supplies the token to add to outgoing requests'
+ // Authorization headers.
+ Source TokenSource
+
+ // Base is the base RoundTripper used to make HTTP requests.
+ // If nil, http.DefaultTransport is used.
+ Base http.RoundTripper
+
+ mu sync.Mutex // guards modReq
+ modReq map[*http.Request]*http.Request // original -> modified
+}
+
+// RoundTrip authorizes and authenticates the request with an
+// access token from Transport's Source.
+func (t *Transport) RoundTrip(req *http.Request) (*http.Response, error) {
+ reqBodyClosed := false
+ if req.Body != nil {
+ defer func() {
+ if !reqBodyClosed {
+ req.Body.Close()
+ }
+ }()
+ }
+
+ if t.Source == nil {
+ return nil, errors.New("oauth2: Transport's Source is nil")
+ }
+ token, err := t.Source.Token()
+ if err != nil {
+ return nil, err
+ }
+
+ req2 := cloneRequest(req) // per RoundTripper contract
+ token.SetAuthHeader(req2)
+ t.setModReq(req, req2)
+ res, err := t.base().RoundTrip(req2)
+
+ // req.Body is assumed to have been closed by the base RoundTripper.
+ reqBodyClosed = true
+
+ if err != nil {
+ t.setModReq(req, nil)
+ return nil, err
+ }
+ res.Body = &onEOFReader{
+ rc: res.Body,
+ fn: func() { t.setModReq(req, nil) },
+ }
+ return res, nil
+}
+
+// CancelRequest cancels an in-flight request by closing its connection.
+func (t *Transport) CancelRequest(req *http.Request) {
+ type canceler interface {
+ CancelRequest(*http.Request)
+ }
+ if cr, ok := t.base().(canceler); ok {
+ t.mu.Lock()
+ modReq := t.modReq[req]
+ delete(t.modReq, req)
+ t.mu.Unlock()
+ cr.CancelRequest(modReq)
+ }
+}
+
+func (t *Transport) base() http.RoundTripper {
+ if t.Base != nil {
+ return t.Base
+ }
+ return http.DefaultTransport
+}
+
+func (t *Transport) setModReq(orig, mod *http.Request) {
+ t.mu.Lock()
+ defer t.mu.Unlock()
+ if t.modReq == nil {
+ t.modReq = make(map[*http.Request]*http.Request)
+ }
+ if mod == nil {
+ delete(t.modReq, orig)
+ } else {
+ t.modReq[orig] = mod
+ }
+}
+
+// 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
+}
+
+type onEOFReader struct {
+ rc io.ReadCloser
+ fn func()
+}
+
+func (r *onEOFReader) Read(p []byte) (n int, err error) {
+ n, err = r.rc.Read(p)
+ if err == io.EOF {
+ r.runFunc()
+ }
+ return
+}
+
+func (r *onEOFReader) Close() error {
+ err := r.rc.Close()
+ r.runFunc()
+ return err
+}
+
+func (r *onEOFReader) runFunc() {
+ if fn := r.fn; fn != nil {
+ fn()
+ r.fn = nil
+ }
+}
diff --git a/vendor/google.golang.org/appengine/LICENSE b/vendor/google.golang.org/appengine/LICENSE
new file mode 100644
index 0000000000000000000000000000000000000000..d645695673349e3947e8e5ae42332d0ac3164cd7
--- /dev/null
+++ b/vendor/google.golang.org/appengine/LICENSE
@@ -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.
diff --git a/vendor/google.golang.org/appengine/cloudsql/cloudsql.go b/vendor/google.golang.org/appengine/cloudsql/cloudsql.go
new file mode 100644
index 0000000000000000000000000000000000000000..7b27e6b12d457ac05abcd2e761921a13dd4b66c0
--- /dev/null
+++ b/vendor/google.golang.org/appengine/cloudsql/cloudsql.go
@@ -0,0 +1,62 @@
+// Copyright 2013 Google Inc. All rights reserved.
+// Use of this source code is governed by the Apache 2.0
+// license that can be found in the LICENSE file.
+
+/*
+Package cloudsql exposes access to Google Cloud SQL databases.
+
+This package does not work in App Engine "flexible environment".
+
+This package is intended for MySQL drivers to make App Engine-specific
+connections. Applications should use this package through database/sql:
+Select a pure Go MySQL driver that supports this package, and use sql.Open
+with protocol "cloudsql" and an address of the Cloud SQL instance.
+
+A Go MySQL driver that has been tested to work well with Cloud SQL
+is the go-sql-driver:
+ import "database/sql"
+ import _ "github.com/go-sql-driver/mysql"
+
+ db, err := sql.Open("mysql", "user@cloudsql(project-id:instance-name)/dbname")
+
+
+Another driver that works well with Cloud SQL is the mymysql driver:
+ import "database/sql"
+ import _ "github.com/ziutek/mymysql/godrv"
+
+ db, err := sql.Open("mymysql", "cloudsql:instance-name*dbname/user/password")
+
+
+Using either of these drivers, you can perform a standard SQL query.
+This example assumes there is a table named 'users' with
+columns 'first_name' and 'last_name':
+
+ rows, err := db.Query("SELECT first_name, last_name FROM users")
+ if err != nil {
+ log.Errorf(ctx, "db.Query: %v", err)
+ }
+ defer rows.Close()
+
+ for rows.Next() {
+ var firstName string
+ var lastName string
+ if err := rows.Scan(&firstName, &lastName); err != nil {
+ log.Errorf(ctx, "rows.Scan: %v", err)
+ continue
+ }
+ log.Infof(ctx, "First: %v - Last: %v", firstName, lastName)
+ }
+ if err := rows.Err(); err != nil {
+ log.Errorf(ctx, "Row error: %v", err)
+ }
+*/
+package cloudsql
+
+import (
+ "net"
+)
+
+// Dial connects to the named Cloud SQL instance.
+func Dial(instance string) (net.Conn, error) {
+ return connect(instance)
+}
diff --git a/vendor/google.golang.org/appengine/cloudsql/cloudsql_classic.go b/vendor/google.golang.org/appengine/cloudsql/cloudsql_classic.go
new file mode 100644
index 0000000000000000000000000000000000000000..af62dba1467f1ed601889ace8fbb1df755cb5898
--- /dev/null
+++ b/vendor/google.golang.org/appengine/cloudsql/cloudsql_classic.go
@@ -0,0 +1,17 @@
+// Copyright 2013 Google Inc. All rights reserved.
+// Use of this source code is governed by the Apache 2.0
+// license that can be found in the LICENSE file.
+
+// +build appengine
+
+package cloudsql
+
+import (
+ "net"
+
+ "appengine/cloudsql"
+)
+
+func connect(instance string) (net.Conn, error) {
+ return cloudsql.Dial(instance)
+}
diff --git a/vendor/google.golang.org/appengine/cloudsql/cloudsql_vm.go b/vendor/google.golang.org/appengine/cloudsql/cloudsql_vm.go
new file mode 100644
index 0000000000000000000000000000000000000000..90fa7b31e08fe9fa8ab27a78a22023c17f1d9f53
--- /dev/null
+++ b/vendor/google.golang.org/appengine/cloudsql/cloudsql_vm.go
@@ -0,0 +1,16 @@
+// Copyright 2013 Google Inc. All rights reserved.
+// Use of this source code is governed by the Apache 2.0
+// license that can be found in the LICENSE file.
+
+// +build !appengine
+
+package cloudsql
+
+import (
+ "errors"
+ "net"
+)
+
+func connect(instance string) (net.Conn, error) {
+ return nil, errors.New(`cloudsql: not supported in App Engine "flexible environment"`)
+}
diff --git a/vendor/google.golang.org/appengine/internal/api.go b/vendor/google.golang.org/appengine/internal/api.go
new file mode 100644
index 0000000000000000000000000000000000000000..a6ec19e14cfc4c7d7f69d8b28d0cab8665232bb3
--- /dev/null
+++ b/vendor/google.golang.org/appengine/internal/api.go
@@ -0,0 +1,675 @@
+// Copyright 2011 Google Inc. All rights reserved.
+// Use of this source code is governed by the Apache 2.0
+// license that can be found in the LICENSE file.
+
+// +build !appengine
+
+package internal
+
+import (
+ "bytes"
+ "errors"
+ "fmt"
+ "io/ioutil"
+ "log"
+ "net"
+ "net/http"
+ "net/url"
+ "os"
+ "runtime"
+ "strconv"
+ "strings"
+ "sync"
+ "sync/atomic"
+ "time"
+
+ "github.com/golang/protobuf/proto"
+ netcontext "golang.org/x/net/context"
+
+ basepb "google.golang.org/appengine/internal/base"
+ logpb "google.golang.org/appengine/internal/log"
+ remotepb "google.golang.org/appengine/internal/remote_api"
+)
+
+const (
+ apiPath = "/rpc_http"
+ defaultTicketSuffix = "/default.20150612t184001.0"
+)
+
+var (
+ // Incoming headers.
+ ticketHeader = http.CanonicalHeaderKey("X-AppEngine-API-Ticket")
+ dapperHeader = http.CanonicalHeaderKey("X-Google-DapperTraceInfo")
+ traceHeader = http.CanonicalHeaderKey("X-Cloud-Trace-Context")
+ curNamespaceHeader = http.CanonicalHeaderKey("X-AppEngine-Current-Namespace")
+ userIPHeader = http.CanonicalHeaderKey("X-AppEngine-User-IP")
+ remoteAddrHeader = http.CanonicalHeaderKey("X-AppEngine-Remote-Addr")
+ devRequestIdHeader = http.CanonicalHeaderKey("X-Appengine-Dev-Request-Id")
+
+ // Outgoing headers.
+ apiEndpointHeader = http.CanonicalHeaderKey("X-Google-RPC-Service-Endpoint")
+ apiEndpointHeaderValue = []string{"app-engine-apis"}
+ apiMethodHeader = http.CanonicalHeaderKey("X-Google-RPC-Service-Method")
+ apiMethodHeaderValue = []string{"/VMRemoteAPI.CallRemoteAPI"}
+ apiDeadlineHeader = http.CanonicalHeaderKey("X-Google-RPC-Service-Deadline")
+ apiContentType = http.CanonicalHeaderKey("Content-Type")
+ apiContentTypeValue = []string{"application/octet-stream"}
+ logFlushHeader = http.CanonicalHeaderKey("X-AppEngine-Log-Flush-Count")
+
+ apiHTTPClient = &http.Client{
+ Transport: &http.Transport{
+ Proxy: http.ProxyFromEnvironment,
+ Dial: limitDial,
+ },
+ }
+
+ defaultTicketOnce sync.Once
+ defaultTicket string
+ backgroundContextOnce sync.Once
+ backgroundContext netcontext.Context
+)
+
+func apiURL() *url.URL {
+ host, port := "appengine.googleapis.internal", "10001"
+ if h := os.Getenv("API_HOST"); h != "" {
+ host = h
+ }
+ if p := os.Getenv("API_PORT"); p != "" {
+ port = p
+ }
+ return &url.URL{
+ Scheme: "http",
+ Host: host + ":" + port,
+ Path: apiPath,
+ }
+}
+
+func handleHTTP(w http.ResponseWriter, r *http.Request) {
+ c := &context{
+ req: r,
+ outHeader: w.Header(),
+ apiURL: apiURL(),
+ }
+ r = r.WithContext(withContext(r.Context(), c))
+ c.req = r
+
+ stopFlushing := make(chan int)
+
+ // Patch up RemoteAddr so it looks reasonable.
+ if addr := r.Header.Get(userIPHeader); addr != "" {
+ r.RemoteAddr = addr
+ } else if addr = r.Header.Get(remoteAddrHeader); addr != "" {
+ r.RemoteAddr = addr
+ } else {
+ // Should not normally reach here, but pick a sensible default anyway.
+ r.RemoteAddr = "127.0.0.1"
+ }
+ // The address in the headers will most likely be of these forms:
+ // 123.123.123.123
+ // 2001:db8::1
+ // net/http.Request.RemoteAddr is specified to be in "IP:port" form.
+ if _, _, err := net.SplitHostPort(r.RemoteAddr); err != nil {
+ // Assume the remote address is only a host; add a default port.
+ r.RemoteAddr = net.JoinHostPort(r.RemoteAddr, "80")
+ }
+
+ // Start goroutine responsible for flushing app logs.
+ // This is done after adding c to ctx.m (and stopped before removing it)
+ // because flushing logs requires making an API call.
+ go c.logFlusher(stopFlushing)
+
+ executeRequestSafely(c, r)
+ c.outHeader = nil // make sure header changes aren't respected any more
+
+ stopFlushing <- 1 // any logging beyond this point will be dropped
+
+ // Flush any pending logs asynchronously.
+ c.pendingLogs.Lock()
+ flushes := c.pendingLogs.flushes
+ if len(c.pendingLogs.lines) > 0 {
+ flushes++
+ }
+ c.pendingLogs.Unlock()
+ flushed := make(chan struct{})
+ go func() {
+ defer close(flushed)
+ // Force a log flush, because with very short requests we
+ // may not ever flush logs.
+ c.flushLog(true)
+ }()
+ w.Header().Set(logFlushHeader, strconv.Itoa(flushes))
+
+ // Avoid nil Write call if c.Write is never called.
+ if c.outCode != 0 {
+ w.WriteHeader(c.outCode)
+ }
+ if c.outBody != nil {
+ w.Write(c.outBody)
+ }
+ // Wait for the last flush to complete before returning,
+ // otherwise the security ticket will not be valid.
+ <-flushed
+}
+
+func executeRequestSafely(c *context, r *http.Request) {
+ defer func() {
+ if x := recover(); x != nil {
+ logf(c, 4, "%s", renderPanic(x)) // 4 == critical
+ c.outCode = 500
+ }
+ }()
+
+ http.DefaultServeMux.ServeHTTP(c, r)
+}
+
+func renderPanic(x interface{}) string {
+ buf := make([]byte, 16<<10) // 16 KB should be plenty
+ buf = buf[:runtime.Stack(buf, false)]
+
+ // Remove the first few stack frames:
+ // this func
+ // the recover closure in the caller
+ // That will root the stack trace at the site of the panic.
+ const (
+ skipStart = "internal.renderPanic"
+ skipFrames = 2
+ )
+ start := bytes.Index(buf, []byte(skipStart))
+ p := start
+ for i := 0; i < skipFrames*2 && p+1 < len(buf); i++ {
+ p = bytes.IndexByte(buf[p+1:], '\n') + p + 1
+ if p < 0 {
+ break
+ }
+ }
+ if p >= 0 {
+ // buf[start:p+1] is the block to remove.
+ // Copy buf[p+1:] over buf[start:] and shrink buf.
+ copy(buf[start:], buf[p+1:])
+ buf = buf[:len(buf)-(p+1-start)]
+ }
+
+ // Add panic heading.
+ head := fmt.Sprintf("panic: %v\n\n", x)
+ if len(head) > len(buf) {
+ // Extremely unlikely to happen.
+ return head
+ }
+ copy(buf[len(head):], buf)
+ copy(buf, head)
+
+ return string(buf)
+}
+
+// context represents the context of an in-flight HTTP request.
+// It implements the appengine.Context and http.ResponseWriter interfaces.
+type context struct {
+ req *http.Request
+
+ outCode int
+ outHeader http.Header
+ outBody []byte
+
+ pendingLogs struct {
+ sync.Mutex
+ lines []*logpb.UserAppLogLine
+ flushes int
+ }
+
+ apiURL *url.URL
+}
+
+var contextKey = "holds a *context"
+
+// jointContext joins two contexts in a superficial way.
+// It takes values and timeouts from a base context, and only values from another context.
+type jointContext struct {
+ base netcontext.Context
+ valuesOnly netcontext.Context
+}
+
+func (c jointContext) Deadline() (time.Time, bool) {
+ return c.base.Deadline()
+}
+
+func (c jointContext) Done() <-chan struct{} {
+ return c.base.Done()
+}
+
+func (c jointContext) Err() error {
+ return c.base.Err()
+}
+
+func (c jointContext) Value(key interface{}) interface{} {
+ if val := c.base.Value(key); val != nil {
+ return val
+ }
+ return c.valuesOnly.Value(key)
+}
+
+// fromContext returns the App Engine context or nil if ctx is not
+// derived from an App Engine context.
+func fromContext(ctx netcontext.Context) *context {
+ c, _ := ctx.Value(&contextKey).(*context)
+ return c
+}
+
+func withContext(parent netcontext.Context, c *context) netcontext.Context {
+ ctx := netcontext.WithValue(parent, &contextKey, c)
+ if ns := c.req.Header.Get(curNamespaceHeader); ns != "" {
+ ctx = withNamespace(ctx, ns)
+ }
+ return ctx
+}
+
+func toContext(c *context) netcontext.Context {
+ return withContext(netcontext.Background(), c)
+}
+
+func IncomingHeaders(ctx netcontext.Context) http.Header {
+ if c := fromContext(ctx); c != nil {
+ return c.req.Header
+ }
+ return nil
+}
+
+func ReqContext(req *http.Request) netcontext.Context {
+ return req.Context()
+}
+
+func WithContext(parent netcontext.Context, req *http.Request) netcontext.Context {
+ return jointContext{
+ base: parent,
+ valuesOnly: req.Context(),
+ }
+}
+
+// DefaultTicket returns a ticket used for background context or dev_appserver.
+func DefaultTicket() string {
+ defaultTicketOnce.Do(func() {
+ if IsDevAppServer() {
+ defaultTicket = "testapp" + defaultTicketSuffix
+ return
+ }
+ appID := partitionlessAppID()
+ escAppID := strings.Replace(strings.Replace(appID, ":", "_", -1), ".", "_", -1)
+ majVersion := VersionID(nil)
+ if i := strings.Index(majVersion, "."); i > 0 {
+ majVersion = majVersion[:i]
+ }
+ defaultTicket = fmt.Sprintf("%s/%s.%s.%s", escAppID, ModuleName(nil), majVersion, InstanceID())
+ })
+ return defaultTicket
+}
+
+func BackgroundContext() netcontext.Context {
+ backgroundContextOnce.Do(func() {
+ // Compute background security ticket.
+ ticket := DefaultTicket()
+
+ c := &context{
+ req: &http.Request{
+ Header: http.Header{
+ ticketHeader: []string{ticket},
+ },
+ },
+ apiURL: apiURL(),
+ }
+ backgroundContext = toContext(c)
+
+ // TODO(dsymonds): Wire up the shutdown handler to do a final flush.
+ go c.logFlusher(make(chan int))
+ })
+
+ return backgroundContext
+}
+
+// RegisterTestRequest registers the HTTP request req for testing, such that
+// any API calls are sent to the provided URL. It returns a closure to delete
+// the registration.
+// It should only be used by aetest package.
+func RegisterTestRequest(req *http.Request, apiURL *url.URL, decorate func(netcontext.Context) netcontext.Context) (*http.Request, func()) {
+ c := &context{
+ req: req,
+ apiURL: apiURL,
+ }
+ ctx := withContext(decorate(req.Context()), c)
+ req = req.WithContext(ctx)
+ c.req = req
+ return req, func() {}
+}
+
+var errTimeout = &CallError{
+ Detail: "Deadline exceeded",
+ Code: int32(remotepb.RpcError_CANCELLED),
+ Timeout: true,
+}
+
+func (c *context) Header() http.Header { return c.outHeader }
+
+// Copied from $GOROOT/src/pkg/net/http/transfer.go. Some response status
+// codes do not permit a response body (nor response entity headers such as
+// Content-Length, Content-Type, etc).
+func bodyAllowedForStatus(status int) bool {
+ switch {
+ case status >= 100 && status <= 199:
+ return false
+ case status == 204:
+ return false
+ case status == 304:
+ return false
+ }
+ return true
+}
+
+func (c *context) Write(b []byte) (int, error) {
+ if c.outCode == 0 {
+ c.WriteHeader(http.StatusOK)
+ }
+ if len(b) > 0 && !bodyAllowedForStatus(c.outCode) {
+ return 0, http.ErrBodyNotAllowed
+ }
+ c.outBody = append(c.outBody, b...)
+ return len(b), nil
+}
+
+func (c *context) WriteHeader(code int) {
+ if c.outCode != 0 {
+ logf(c, 3, "WriteHeader called multiple times on request.") // error level
+ return
+ }
+ c.outCode = code
+}
+
+func (c *context) post(body []byte, timeout time.Duration) (b []byte, err error) {
+ hreq := &http.Request{
+ Method: "POST",
+ URL: c.apiURL,
+ Header: http.Header{
+ apiEndpointHeader: apiEndpointHeaderValue,
+ apiMethodHeader: apiMethodHeaderValue,
+ apiContentType: apiContentTypeValue,
+ apiDeadlineHeader: []string{strconv.FormatFloat(timeout.Seconds(), 'f', -1, 64)},
+ },
+ Body: ioutil.NopCloser(bytes.NewReader(body)),
+ ContentLength: int64(len(body)),
+ Host: c.apiURL.Host,
+ }
+ if info := c.req.Header.Get(dapperHeader); info != "" {
+ hreq.Header.Set(dapperHeader, info)
+ }
+ if info := c.req.Header.Get(traceHeader); info != "" {
+ hreq.Header.Set(traceHeader, info)
+ }
+
+ tr := apiHTTPClient.Transport.(*http.Transport)
+
+ var timedOut int32 // atomic; set to 1 if timed out
+ t := time.AfterFunc(timeout, func() {
+ atomic.StoreInt32(&timedOut, 1)
+ tr.CancelRequest(hreq)
+ })
+ defer t.Stop()
+ defer func() {
+ // Check if timeout was exceeded.
+ if atomic.LoadInt32(&timedOut) != 0 {
+ err = errTimeout
+ }
+ }()
+
+ hresp, err := apiHTTPClient.Do(hreq)
+ if err != nil {
+ return nil, &CallError{
+ Detail: fmt.Sprintf("service bridge HTTP failed: %v", err),
+ Code: int32(remotepb.RpcError_UNKNOWN),
+ }
+ }
+ defer hresp.Body.Close()
+ hrespBody, err := ioutil.ReadAll(hresp.Body)
+ if hresp.StatusCode != 200 {
+ return nil, &CallError{
+ Detail: fmt.Sprintf("service bridge returned HTTP %d (%q)", hresp.StatusCode, hrespBody),
+ Code: int32(remotepb.RpcError_UNKNOWN),
+ }
+ }
+ if err != nil {
+ return nil, &CallError{
+ Detail: fmt.Sprintf("service bridge response bad: %v", err),
+ Code: int32(remotepb.RpcError_UNKNOWN),
+ }
+ }
+ return hrespBody, nil
+}
+
+func Call(ctx netcontext.Context, service, method string, in, out proto.Message) error {
+ if ns := NamespaceFromContext(ctx); ns != "" {
+ if fn, ok := NamespaceMods[service]; ok {
+ fn(in, ns)
+ }
+ }
+
+ if f, ctx, ok := callOverrideFromContext(ctx); ok {
+ return f(ctx, service, method, in, out)
+ }
+
+ // Handle already-done contexts quickly.
+ select {
+ case <-ctx.Done():
+ return ctx.Err()
+ default:
+ }
+
+ c := fromContext(ctx)
+ if c == nil {
+ // Give a good error message rather than a panic lower down.
+ return errNotAppEngineContext
+ }
+
+ // Apply transaction modifications if we're in a transaction.
+ if t := transactionFromContext(ctx); t != nil {
+ if t.finished {
+ return errors.New("transaction context has expired")
+ }
+ applyTransaction(in, &t.transaction)
+ }
+
+ // Default RPC timeout is 60s.
+ timeout := 60 * time.Second
+ if deadline, ok := ctx.Deadline(); ok {
+ timeout = deadline.Sub(time.Now())
+ }
+
+ data, err := proto.Marshal(in)
+ if err != nil {
+ return err
+ }
+
+ ticket := c.req.Header.Get(ticketHeader)
+ // Use a test ticket under test environment.
+ if ticket == "" {
+ if appid := ctx.Value(&appIDOverrideKey); appid != nil {
+ ticket = appid.(string) + defaultTicketSuffix
+ }
+ }
+ // Fall back to use background ticket when the request ticket is not available in Flex or dev_appserver.
+ if ticket == "" {
+ ticket = DefaultTicket()
+ }
+ if dri := c.req.Header.Get(devRequestIdHeader); IsDevAppServer() && dri != "" {
+ ticket = dri
+ }
+ req := &remotepb.Request{
+ ServiceName: &service,
+ Method: &method,
+ Request: data,
+ RequestId: &ticket,
+ }
+ hreqBody, err := proto.Marshal(req)
+ if err != nil {
+ return err
+ }
+
+ hrespBody, err := c.post(hreqBody, timeout)
+ if err != nil {
+ return err
+ }
+
+ res := &remotepb.Response{}
+ if err := proto.Unmarshal(hrespBody, res); err != nil {
+ return err
+ }
+ if res.RpcError != nil {
+ ce := &CallError{
+ Detail: res.RpcError.GetDetail(),
+ Code: *res.RpcError.Code,
+ }
+ switch remotepb.RpcError_ErrorCode(ce.Code) {
+ case remotepb.RpcError_CANCELLED, remotepb.RpcError_DEADLINE_EXCEEDED:
+ ce.Timeout = true
+ }
+ return ce
+ }
+ if res.ApplicationError != nil {
+ return &APIError{
+ Service: *req.ServiceName,
+ Detail: res.ApplicationError.GetDetail(),
+ Code: *res.ApplicationError.Code,
+ }
+ }
+ if res.Exception != nil || res.JavaException != nil {
+ // This shouldn't happen, but let's be defensive.
+ return &CallError{
+ Detail: "service bridge returned exception",
+ Code: int32(remotepb.RpcError_UNKNOWN),
+ }
+ }
+ return proto.Unmarshal(res.Response, out)
+}
+
+func (c *context) Request() *http.Request {
+ return c.req
+}
+
+func (c *context) addLogLine(ll *logpb.UserAppLogLine) {
+ // Truncate long log lines.
+ // TODO(dsymonds): Check if this is still necessary.
+ const lim = 8 << 10
+ if len(*ll.Message) > lim {
+ suffix := fmt.Sprintf("...(length %d)", len(*ll.Message))
+ ll.Message = proto.String((*ll.Message)[:lim-len(suffix)] + suffix)
+ }
+
+ c.pendingLogs.Lock()
+ c.pendingLogs.lines = append(c.pendingLogs.lines, ll)
+ c.pendingLogs.Unlock()
+}
+
+var logLevelName = map[int64]string{
+ 0: "DEBUG",
+ 1: "INFO",
+ 2: "WARNING",
+ 3: "ERROR",
+ 4: "CRITICAL",
+}
+
+func logf(c *context, level int64, format string, args ...interface{}) {
+ if c == nil {
+ panic("not an App Engine context")
+ }
+ s := fmt.Sprintf(format, args...)
+ s = strings.TrimRight(s, "\n") // Remove any trailing newline characters.
+ c.addLogLine(&logpb.UserAppLogLine{
+ TimestampUsec: proto.Int64(time.Now().UnixNano() / 1e3),
+ Level: &level,
+ Message: &s,
+ })
+ // Only duplicate log to stderr if not running on App Engine second generation
+ if !IsSecondGen() {
+ log.Print(logLevelName[level] + ": " + s)
+ }
+}
+
+// flushLog attempts to flush any pending logs to the appserver.
+// It should not be called concurrently.
+func (c *context) flushLog(force bool) (flushed bool) {
+ c.pendingLogs.Lock()
+ // Grab up to 30 MB. We can get away with up to 32 MB, but let's be cautious.
+ n, rem := 0, 30<<20
+ for ; n < len(c.pendingLogs.lines); n++ {
+ ll := c.pendingLogs.lines[n]
+ // Each log line will require about 3 bytes of overhead.
+ nb := proto.Size(ll) + 3
+ if nb > rem {
+ break
+ }
+ rem -= nb
+ }
+ lines := c.pendingLogs.lines[:n]
+ c.pendingLogs.lines = c.pendingLogs.lines[n:]
+ c.pendingLogs.Unlock()
+
+ if len(lines) == 0 && !force {
+ // Nothing to flush.
+ return false
+ }
+
+ rescueLogs := false
+ defer func() {
+ if rescueLogs {
+ c.pendingLogs.Lock()
+ c.pendingLogs.lines = append(lines, c.pendingLogs.lines...)
+ c.pendingLogs.Unlock()
+ }
+ }()
+
+ buf, err := proto.Marshal(&logpb.UserAppLogGroup{
+ LogLine: lines,
+ })
+ if err != nil {
+ log.Printf("internal.flushLog: marshaling UserAppLogGroup: %v", err)
+ rescueLogs = true
+ return false
+ }
+
+ req := &logpb.FlushRequest{
+ Logs: buf,
+ }
+ res := &basepb.VoidProto{}
+ c.pendingLogs.Lock()
+ c.pendingLogs.flushes++
+ c.pendingLogs.Unlock()
+ if err := Call(toContext(c), "logservice", "Flush", req, res); err != nil {
+ log.Printf("internal.flushLog: Flush RPC: %v", err)
+ rescueLogs = true
+ return false
+ }
+ return true
+}
+
+const (
+ // Log flushing parameters.
+ flushInterval = 1 * time.Second
+ forceFlushInterval = 60 * time.Second
+)
+
+func (c *context) logFlusher(stop <-chan int) {
+ lastFlush := time.Now()
+ tick := time.NewTicker(flushInterval)
+ for {
+ select {
+ case <-stop:
+ // Request finished.
+ tick.Stop()
+ return
+ case <-tick.C:
+ force := time.Now().Sub(lastFlush) > forceFlushInterval
+ if c.flushLog(force) {
+ lastFlush = time.Now()
+ }
+ }
+ }
+}
+
+func ContextForTesting(req *http.Request) netcontext.Context {
+ return toContext(&context{req: req})
+}
diff --git a/vendor/google.golang.org/appengine/internal/api_classic.go b/vendor/google.golang.org/appengine/internal/api_classic.go
new file mode 100644
index 0000000000000000000000000000000000000000..f0f40b2e35c2c35904b1c079eb0e5e54027ed0de
--- /dev/null
+++ b/vendor/google.golang.org/appengine/internal/api_classic.go
@@ -0,0 +1,169 @@
+// Copyright 2015 Google Inc. All rights reserved.
+// Use of this source code is governed by the Apache 2.0
+// license that can be found in the LICENSE file.
+
+// +build appengine
+
+package internal
+
+import (
+ "errors"
+ "fmt"
+ "net/http"
+ "time"
+
+ "appengine"
+ "appengine_internal"
+ basepb "appengine_internal/base"
+
+ "github.com/golang/protobuf/proto"
+ netcontext "golang.org/x/net/context"
+)
+
+var contextKey = "holds an appengine.Context"
+
+// fromContext returns the App Engine context or nil if ctx is not
+// derived from an App Engine context.
+func fromContext(ctx netcontext.Context) appengine.Context {
+ c, _ := ctx.Value(&contextKey).(appengine.Context)
+ return c
+}
+
+// This is only for classic App Engine adapters.
+func ClassicContextFromContext(ctx netcontext.Context) (appengine.Context, error) {
+ c := fromContext(ctx)
+ if c == nil {
+ return nil, errNotAppEngineContext
+ }
+ return c, nil
+}
+
+func withContext(parent netcontext.Context, c appengine.Context) netcontext.Context {
+ ctx := netcontext.WithValue(parent, &contextKey, c)
+
+ s := &basepb.StringProto{}
+ c.Call("__go__", "GetNamespace", &basepb.VoidProto{}, s, nil)
+ if ns := s.GetValue(); ns != "" {
+ ctx = NamespacedContext(ctx, ns)
+ }
+
+ return ctx
+}
+
+func IncomingHeaders(ctx netcontext.Context) http.Header {
+ if c := fromContext(ctx); c != nil {
+ if req, ok := c.Request().(*http.Request); ok {
+ return req.Header
+ }
+ }
+ return nil
+}
+
+func ReqContext(req *http.Request) netcontext.Context {
+ return WithContext(netcontext.Background(), req)
+}
+
+func WithContext(parent netcontext.Context, req *http.Request) netcontext.Context {
+ c := appengine.NewContext(req)
+ return withContext(parent, c)
+}
+
+type testingContext struct {
+ appengine.Context
+
+ req *http.Request
+}
+
+func (t *testingContext) FullyQualifiedAppID() string { return "dev~testcontext" }
+func (t *testingContext) Call(service, method string, _, _ appengine_internal.ProtoMessage, _ *appengine_internal.CallOptions) error {
+ if service == "__go__" && method == "GetNamespace" {
+ return nil
+ }
+ return fmt.Errorf("testingContext: unsupported Call")
+}
+func (t *testingContext) Request() interface{} { return t.req }
+
+func ContextForTesting(req *http.Request) netcontext.Context {
+ return withContext(netcontext.Background(), &testingContext{req: req})
+}
+
+func Call(ctx netcontext.Context, service, method string, in, out proto.Message) error {
+ if ns := NamespaceFromContext(ctx); ns != "" {
+ if fn, ok := NamespaceMods[service]; ok {
+ fn(in, ns)
+ }
+ }
+
+ if f, ctx, ok := callOverrideFromContext(ctx); ok {
+ return f(ctx, service, method, in, out)
+ }
+
+ // Handle already-done contexts quickly.
+ select {
+ case <-ctx.Done():
+ return ctx.Err()
+ default:
+ }
+
+ c := fromContext(ctx)
+ if c == nil {
+ // Give a good error message rather than a panic lower down.
+ return errNotAppEngineContext
+ }
+
+ // Apply transaction modifications if we're in a transaction.
+ if t := transactionFromContext(ctx); t != nil {
+ if t.finished {
+ return errors.New("transaction context has expired")
+ }
+ applyTransaction(in, &t.transaction)
+ }
+
+ var opts *appengine_internal.CallOptions
+ if d, ok := ctx.Deadline(); ok {
+ opts = &appengine_internal.CallOptions{
+ Timeout: d.Sub(time.Now()),
+ }
+ }
+
+ err := c.Call(service, method, in, out, opts)
+ switch v := err.(type) {
+ case *appengine_internal.APIError:
+ return &APIError{
+ Service: v.Service,
+ Detail: v.Detail,
+ Code: v.Code,
+ }
+ case *appengine_internal.CallError:
+ return &CallError{
+ Detail: v.Detail,
+ Code: v.Code,
+ Timeout: v.Timeout,
+ }
+ }
+ return err
+}
+
+func handleHTTP(w http.ResponseWriter, r *http.Request) {
+ panic("handleHTTP called; this should be impossible")
+}
+
+func logf(c appengine.Context, level int64, format string, args ...interface{}) {
+ var fn func(format string, args ...interface{})
+ switch level {
+ case 0:
+ fn = c.Debugf
+ case 1:
+ fn = c.Infof
+ case 2:
+ fn = c.Warningf
+ case 3:
+ fn = c.Errorf
+ case 4:
+ fn = c.Criticalf
+ default:
+ // This shouldn't happen.
+ fn = c.Criticalf
+ }
+ fn(format, args...)
+}
diff --git a/vendor/google.golang.org/appengine/internal/api_common.go b/vendor/google.golang.org/appengine/internal/api_common.go
new file mode 100644
index 0000000000000000000000000000000000000000..e0c0b214b724212071f072eadd289c73af3d154b
--- /dev/null
+++ b/vendor/google.golang.org/appengine/internal/api_common.go
@@ -0,0 +1,123 @@
+// Copyright 2015 Google Inc. All rights reserved.
+// Use of this source code is governed by the Apache 2.0
+// license that can be found in the LICENSE file.
+
+package internal
+
+import (
+ "errors"
+ "os"
+
+ "github.com/golang/protobuf/proto"
+ netcontext "golang.org/x/net/context"
+)
+
+var errNotAppEngineContext = errors.New("not an App Engine context")
+
+type CallOverrideFunc func(ctx netcontext.Context, service, method string, in, out proto.Message) error
+
+var callOverrideKey = "holds []CallOverrideFunc"
+
+func WithCallOverride(ctx netcontext.Context, f CallOverrideFunc) netcontext.Context {
+ // We avoid appending to any existing call override
+ // so we don't risk overwriting a popped stack below.
+ var cofs []CallOverrideFunc
+ if uf, ok := ctx.Value(&callOverrideKey).([]CallOverrideFunc); ok {
+ cofs = append(cofs, uf...)
+ }
+ cofs = append(cofs, f)
+ return netcontext.WithValue(ctx, &callOverrideKey, cofs)
+}
+
+func callOverrideFromContext(ctx netcontext.Context) (CallOverrideFunc, netcontext.Context, bool) {
+ cofs, _ := ctx.Value(&callOverrideKey).([]CallOverrideFunc)
+ if len(cofs) == 0 {
+ return nil, nil, false
+ }
+ // We found a list of overrides; grab the last, and reconstitute a
+ // context that will hide it.
+ f := cofs[len(cofs)-1]
+ ctx = netcontext.WithValue(ctx, &callOverrideKey, cofs[:len(cofs)-1])
+ return f, ctx, true
+}
+
+type logOverrideFunc func(level int64, format string, args ...interface{})
+
+var logOverrideKey = "holds a logOverrideFunc"
+
+func WithLogOverride(ctx netcontext.Context, f logOverrideFunc) netcontext.Context {
+ return netcontext.WithValue(ctx, &logOverrideKey, f)
+}
+
+var appIDOverrideKey = "holds a string, being the full app ID"
+
+func WithAppIDOverride(ctx netcontext.Context, appID string) netcontext.Context {
+ return netcontext.WithValue(ctx, &appIDOverrideKey, appID)
+}
+
+var namespaceKey = "holds the namespace string"
+
+func withNamespace(ctx netcontext.Context, ns string) netcontext.Context {
+ return netcontext.WithValue(ctx, &namespaceKey, ns)
+}
+
+func NamespaceFromContext(ctx netcontext.Context) string {
+ // If there's no namespace, return the empty string.
+ ns, _ := ctx.Value(&namespaceKey).(string)
+ return ns
+}
+
+// FullyQualifiedAppID returns the fully-qualified application ID.
+// This may contain a partition prefix (e.g. "s~" for High Replication apps),
+// or a domain prefix (e.g. "example.com:").
+func FullyQualifiedAppID(ctx netcontext.Context) string {
+ if id, ok := ctx.Value(&appIDOverrideKey).(string); ok {
+ return id
+ }
+ return fullyQualifiedAppID(ctx)
+}
+
+func Logf(ctx netcontext.Context, level int64, format string, args ...interface{}) {
+ if f, ok := ctx.Value(&logOverrideKey).(logOverrideFunc); ok {
+ f(level, format, args...)
+ return
+ }
+ c := fromContext(ctx)
+ if c == nil {
+ panic(errNotAppEngineContext)
+ }
+ logf(c, level, format, args...)
+}
+
+// NamespacedContext wraps a Context to support namespaces.
+func NamespacedContext(ctx netcontext.Context, namespace string) netcontext.Context {
+ return withNamespace(ctx, namespace)
+}
+
+// SetTestEnv sets the env variables for testing background ticket in Flex.
+func SetTestEnv() func() {
+ var environ = []struct {
+ key, value string
+ }{
+ {"GAE_LONG_APP_ID", "my-app-id"},
+ {"GAE_MINOR_VERSION", "067924799508853122"},
+ {"GAE_MODULE_INSTANCE", "0"},
+ {"GAE_MODULE_NAME", "default"},
+ {"GAE_MODULE_VERSION", "20150612t184001"},
+ }
+
+ for _, v := range environ {
+ old := os.Getenv(v.key)
+ os.Setenv(v.key, v.value)
+ v.value = old
+ }
+ return func() { // Restore old environment after the test completes.
+ for _, v := range environ {
+ if v.value == "" {
+ os.Unsetenv(v.key)
+ continue
+ }
+ os.Setenv(v.key, v.value)
+ }
+ }
+}
diff --git a/vendor/google.golang.org/appengine/internal/app_id.go b/vendor/google.golang.org/appengine/internal/app_id.go
new file mode 100644
index 0000000000000000000000000000000000000000..11df8c07b53863dc159518a47ee5b906bdc7c4f1
--- /dev/null
+++ b/vendor/google.golang.org/appengine/internal/app_id.go
@@ -0,0 +1,28 @@
+// Copyright 2011 Google Inc. All rights reserved.
+// Use of this source code is governed by the Apache 2.0
+// license that can be found in the LICENSE file.
+
+package internal
+
+import (
+ "strings"
+)
+
+func parseFullAppID(appid string) (partition, domain, displayID string) {
+ if i := strings.Index(appid, "~"); i != -1 {
+ partition, appid = appid[:i], appid[i+1:]
+ }
+ if i := strings.Index(appid, ":"); i != -1 {
+ domain, appid = appid[:i], appid[i+1:]
+ }
+ return partition, domain, appid
+}
+
+// appID returns "appid" or "domain.com:appid".
+func appID(fullAppID string) string {
+ _, dom, dis := parseFullAppID(fullAppID)
+ if dom != "" {
+ return dom + ":" + dis
+ }
+ return dis
+}
diff --git a/vendor/google.golang.org/appengine/internal/base/api_base.pb.go b/vendor/google.golang.org/appengine/internal/base/api_base.pb.go
new file mode 100644
index 0000000000000000000000000000000000000000..db4777e68e5b4082a54dcea89544d18c5ec9f84c
--- /dev/null
+++ b/vendor/google.golang.org/appengine/internal/base/api_base.pb.go
@@ -0,0 +1,308 @@
+// Code generated by protoc-gen-go. DO NOT EDIT.
+// source: google.golang.org/appengine/internal/base/api_base.proto
+
+package base
+
+import proto "github.com/golang/protobuf/proto"
+import fmt "fmt"
+import math "math"
+
+// Reference imports to suppress errors if they are not otherwise used.
+var _ = proto.Marshal
+var _ = fmt.Errorf
+var _ = math.Inf
+
+// This is a compile-time assertion to ensure that this generated file
+// is compatible with the proto package it is being compiled against.
+// A compilation error at this line likely means your copy of the
+// proto package needs to be updated.
+const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package
+
+type StringProto struct {
+ Value *string `protobuf:"bytes,1,req,name=value" json:"value,omitempty"`
+ XXX_NoUnkeyedLiteral struct{} `json:"-"`
+ XXX_unrecognized []byte `json:"-"`
+ XXX_sizecache int32 `json:"-"`
+}
+
+func (m *StringProto) Reset() { *m = StringProto{} }
+func (m *StringProto) String() string { return proto.CompactTextString(m) }
+func (*StringProto) ProtoMessage() {}
+func (*StringProto) Descriptor() ([]byte, []int) {
+ return fileDescriptor_api_base_9d49f8792e0c1140, []int{0}
+}
+func (m *StringProto) XXX_Unmarshal(b []byte) error {
+ return xxx_messageInfo_StringProto.Unmarshal(m, b)
+}
+func (m *StringProto) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ return xxx_messageInfo_StringProto.Marshal(b, m, deterministic)
+}
+func (dst *StringProto) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_StringProto.Merge(dst, src)
+}
+func (m *StringProto) XXX_Size() int {
+ return xxx_messageInfo_StringProto.Size(m)
+}
+func (m *StringProto) XXX_DiscardUnknown() {
+ xxx_messageInfo_StringProto.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_StringProto proto.InternalMessageInfo
+
+func (m *StringProto) GetValue() string {
+ if m != nil && m.Value != nil {
+ return *m.Value
+ }
+ return ""
+}
+
+type Integer32Proto struct {
+ Value *int32 `protobuf:"varint,1,req,name=value" json:"value,omitempty"`
+ XXX_NoUnkeyedLiteral struct{} `json:"-"`
+ XXX_unrecognized []byte `json:"-"`
+ XXX_sizecache int32 `json:"-"`
+}
+
+func (m *Integer32Proto) Reset() { *m = Integer32Proto{} }
+func (m *Integer32Proto) String() string { return proto.CompactTextString(m) }
+func (*Integer32Proto) ProtoMessage() {}
+func (*Integer32Proto) Descriptor() ([]byte, []int) {
+ return fileDescriptor_api_base_9d49f8792e0c1140, []int{1}
+}
+func (m *Integer32Proto) XXX_Unmarshal(b []byte) error {
+ return xxx_messageInfo_Integer32Proto.Unmarshal(m, b)
+}
+func (m *Integer32Proto) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ return xxx_messageInfo_Integer32Proto.Marshal(b, m, deterministic)
+}
+func (dst *Integer32Proto) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_Integer32Proto.Merge(dst, src)
+}
+func (m *Integer32Proto) XXX_Size() int {
+ return xxx_messageInfo_Integer32Proto.Size(m)
+}
+func (m *Integer32Proto) XXX_DiscardUnknown() {
+ xxx_messageInfo_Integer32Proto.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_Integer32Proto proto.InternalMessageInfo
+
+func (m *Integer32Proto) GetValue() int32 {
+ if m != nil && m.Value != nil {
+ return *m.Value
+ }
+ return 0
+}
+
+type Integer64Proto struct {
+ Value *int64 `protobuf:"varint,1,req,name=value" json:"value,omitempty"`
+ XXX_NoUnkeyedLiteral struct{} `json:"-"`
+ XXX_unrecognized []byte `json:"-"`
+ XXX_sizecache int32 `json:"-"`
+}
+
+func (m *Integer64Proto) Reset() { *m = Integer64Proto{} }
+func (m *Integer64Proto) String() string { return proto.CompactTextString(m) }
+func (*Integer64Proto) ProtoMessage() {}
+func (*Integer64Proto) Descriptor() ([]byte, []int) {
+ return fileDescriptor_api_base_9d49f8792e0c1140, []int{2}
+}
+func (m *Integer64Proto) XXX_Unmarshal(b []byte) error {
+ return xxx_messageInfo_Integer64Proto.Unmarshal(m, b)
+}
+func (m *Integer64Proto) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ return xxx_messageInfo_Integer64Proto.Marshal(b, m, deterministic)
+}
+func (dst *Integer64Proto) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_Integer64Proto.Merge(dst, src)
+}
+func (m *Integer64Proto) XXX_Size() int {
+ return xxx_messageInfo_Integer64Proto.Size(m)
+}
+func (m *Integer64Proto) XXX_DiscardUnknown() {
+ xxx_messageInfo_Integer64Proto.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_Integer64Proto proto.InternalMessageInfo
+
+func (m *Integer64Proto) GetValue() int64 {
+ if m != nil && m.Value != nil {
+ return *m.Value
+ }
+ return 0
+}
+
+type BoolProto struct {
+ Value *bool `protobuf:"varint,1,req,name=value" json:"value,omitempty"`
+ XXX_NoUnkeyedLiteral struct{} `json:"-"`
+ XXX_unrecognized []byte `json:"-"`
+ XXX_sizecache int32 `json:"-"`
+}
+
+func (m *BoolProto) Reset() { *m = BoolProto{} }
+func (m *BoolProto) String() string { return proto.CompactTextString(m) }
+func (*BoolProto) ProtoMessage() {}
+func (*BoolProto) Descriptor() ([]byte, []int) {
+ return fileDescriptor_api_base_9d49f8792e0c1140, []int{3}
+}
+func (m *BoolProto) XXX_Unmarshal(b []byte) error {
+ return xxx_messageInfo_BoolProto.Unmarshal(m, b)
+}
+func (m *BoolProto) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ return xxx_messageInfo_BoolProto.Marshal(b, m, deterministic)
+}
+func (dst *BoolProto) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_BoolProto.Merge(dst, src)
+}
+func (m *BoolProto) XXX_Size() int {
+ return xxx_messageInfo_BoolProto.Size(m)
+}
+func (m *BoolProto) XXX_DiscardUnknown() {
+ xxx_messageInfo_BoolProto.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_BoolProto proto.InternalMessageInfo
+
+func (m *BoolProto) GetValue() bool {
+ if m != nil && m.Value != nil {
+ return *m.Value
+ }
+ return false
+}
+
+type DoubleProto struct {
+ Value *float64 `protobuf:"fixed64,1,req,name=value" json:"value,omitempty"`
+ XXX_NoUnkeyedLiteral struct{} `json:"-"`
+ XXX_unrecognized []byte `json:"-"`
+ XXX_sizecache int32 `json:"-"`
+}
+
+func (m *DoubleProto) Reset() { *m = DoubleProto{} }
+func (m *DoubleProto) String() string { return proto.CompactTextString(m) }
+func (*DoubleProto) ProtoMessage() {}
+func (*DoubleProto) Descriptor() ([]byte, []int) {
+ return fileDescriptor_api_base_9d49f8792e0c1140, []int{4}
+}
+func (m *DoubleProto) XXX_Unmarshal(b []byte) error {
+ return xxx_messageInfo_DoubleProto.Unmarshal(m, b)
+}
+func (m *DoubleProto) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ return xxx_messageInfo_DoubleProto.Marshal(b, m, deterministic)
+}
+func (dst *DoubleProto) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_DoubleProto.Merge(dst, src)
+}
+func (m *DoubleProto) XXX_Size() int {
+ return xxx_messageInfo_DoubleProto.Size(m)
+}
+func (m *DoubleProto) XXX_DiscardUnknown() {
+ xxx_messageInfo_DoubleProto.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_DoubleProto proto.InternalMessageInfo
+
+func (m *DoubleProto) GetValue() float64 {
+ if m != nil && m.Value != nil {
+ return *m.Value
+ }
+ return 0
+}
+
+type BytesProto struct {
+ Value []byte `protobuf:"bytes,1,req,name=value" json:"value,omitempty"`
+ XXX_NoUnkeyedLiteral struct{} `json:"-"`
+ XXX_unrecognized []byte `json:"-"`
+ XXX_sizecache int32 `json:"-"`
+}
+
+func (m *BytesProto) Reset() { *m = BytesProto{} }
+func (m *BytesProto) String() string { return proto.CompactTextString(m) }
+func (*BytesProto) ProtoMessage() {}
+func (*BytesProto) Descriptor() ([]byte, []int) {
+ return fileDescriptor_api_base_9d49f8792e0c1140, []int{5}
+}
+func (m *BytesProto) XXX_Unmarshal(b []byte) error {
+ return xxx_messageInfo_BytesProto.Unmarshal(m, b)
+}
+func (m *BytesProto) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ return xxx_messageInfo_BytesProto.Marshal(b, m, deterministic)
+}
+func (dst *BytesProto) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_BytesProto.Merge(dst, src)
+}
+func (m *BytesProto) XXX_Size() int {
+ return xxx_messageInfo_BytesProto.Size(m)
+}
+func (m *BytesProto) XXX_DiscardUnknown() {
+ xxx_messageInfo_BytesProto.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_BytesProto proto.InternalMessageInfo
+
+func (m *BytesProto) GetValue() []byte {
+ if m != nil {
+ return m.Value
+ }
+ return nil
+}
+
+type VoidProto struct {
+ XXX_NoUnkeyedLiteral struct{} `json:"-"`
+ XXX_unrecognized []byte `json:"-"`
+ XXX_sizecache int32 `json:"-"`
+}
+
+func (m *VoidProto) Reset() { *m = VoidProto{} }
+func (m *VoidProto) String() string { return proto.CompactTextString(m) }
+func (*VoidProto) ProtoMessage() {}
+func (*VoidProto) Descriptor() ([]byte, []int) {
+ return fileDescriptor_api_base_9d49f8792e0c1140, []int{6}
+}
+func (m *VoidProto) XXX_Unmarshal(b []byte) error {
+ return xxx_messageInfo_VoidProto.Unmarshal(m, b)
+}
+func (m *VoidProto) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ return xxx_messageInfo_VoidProto.Marshal(b, m, deterministic)
+}
+func (dst *VoidProto) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_VoidProto.Merge(dst, src)
+}
+func (m *VoidProto) XXX_Size() int {
+ return xxx_messageInfo_VoidProto.Size(m)
+}
+func (m *VoidProto) XXX_DiscardUnknown() {
+ xxx_messageInfo_VoidProto.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_VoidProto proto.InternalMessageInfo
+
+func init() {
+ proto.RegisterType((*StringProto)(nil), "appengine.base.StringProto")
+ proto.RegisterType((*Integer32Proto)(nil), "appengine.base.Integer32Proto")
+ proto.RegisterType((*Integer64Proto)(nil), "appengine.base.Integer64Proto")
+ proto.RegisterType((*BoolProto)(nil), "appengine.base.BoolProto")
+ proto.RegisterType((*DoubleProto)(nil), "appengine.base.DoubleProto")
+ proto.RegisterType((*BytesProto)(nil), "appengine.base.BytesProto")
+ proto.RegisterType((*VoidProto)(nil), "appengine.base.VoidProto")
+}
+
+func init() {
+ proto.RegisterFile("google.golang.org/appengine/internal/base/api_base.proto", fileDescriptor_api_base_9d49f8792e0c1140)
+}
+
+var fileDescriptor_api_base_9d49f8792e0c1140 = []byte{
+ // 199 bytes of a gzipped FileDescriptorProto
+ 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x6c, 0xcf, 0x3f, 0x4b, 0xc6, 0x30,
+ 0x10, 0x06, 0x70, 0x5a, 0xad, 0xb4, 0x57, 0xe9, 0x20, 0x0e, 0x1d, 0xb5, 0x05, 0x71, 0x4a, 0x40,
+ 0x45, 0x9c, 0x83, 0x8b, 0x9b, 0x28, 0x38, 0xb8, 0x48, 0x8a, 0xc7, 0x11, 0x08, 0xb9, 0x90, 0xa6,
+ 0x82, 0xdf, 0x5e, 0xda, 0xd2, 0xfa, 0xc2, 0x9b, 0xed, 0xfe, 0xfc, 0xe0, 0xe1, 0x81, 0x27, 0x62,
+ 0x26, 0x8b, 0x82, 0xd8, 0x6a, 0x47, 0x82, 0x03, 0x49, 0xed, 0x3d, 0x3a, 0x32, 0x0e, 0xa5, 0x71,
+ 0x11, 0x83, 0xd3, 0x56, 0x0e, 0x7a, 0x44, 0xa9, 0xbd, 0xf9, 0x9a, 0x07, 0xe1, 0x03, 0x47, 0xbe,
+ 0x68, 0x76, 0x27, 0xe6, 0x6b, 0xd7, 0x43, 0xfd, 0x1e, 0x83, 0x71, 0xf4, 0xba, 0xbc, 0x2f, 0xa1,
+ 0xf8, 0xd1, 0x76, 0xc2, 0x36, 0xbb, 0xca, 0x6f, 0xab, 0xb7, 0x75, 0xe9, 0x6e, 0xa0, 0x79, 0x71,
+ 0x11, 0x09, 0xc3, 0xfd, 0x5d, 0xc2, 0x15, 0xc7, 0xee, 0xf1, 0x21, 0xe1, 0x4e, 0x36, 0x77, 0x0d,
+ 0x95, 0x62, 0xb6, 0x09, 0x52, 0x6e, 0xa4, 0x87, 0xfa, 0x99, 0xa7, 0xc1, 0x62, 0x02, 0x65, 0xff,
+ 0x79, 0xa0, 0x7e, 0x23, 0x8e, 0xab, 0x69, 0x0f, 0xcd, 0xb9, 0xca, 0xcb, 0xdd, 0xd5, 0x50, 0x7d,
+ 0xb0, 0xf9, 0x5e, 0x98, 0x3a, 0xfb, 0x3c, 0x9d, 0x9b, 0xff, 0x05, 0x00, 0x00, 0xff, 0xff, 0xba,
+ 0x37, 0x25, 0xea, 0x44, 0x01, 0x00, 0x00,
+}
diff --git a/vendor/google.golang.org/appengine/internal/base/api_base.proto b/vendor/google.golang.org/appengine/internal/base/api_base.proto
new file mode 100644
index 0000000000000000000000000000000000000000..56cd7a3cad05e290f84a97ce8d55ffd4d1a6e299
--- /dev/null
+++ b/vendor/google.golang.org/appengine/internal/base/api_base.proto
@@ -0,0 +1,33 @@
+// Built-in base types for API calls. Primarily useful as return types.
+
+syntax = "proto2";
+option go_package = "base";
+
+package appengine.base;
+
+message StringProto {
+ required string value = 1;
+}
+
+message Integer32Proto {
+ required int32 value = 1;
+}
+
+message Integer64Proto {
+ required int64 value = 1;
+}
+
+message BoolProto {
+ required bool value = 1;
+}
+
+message DoubleProto {
+ required double value = 1;
+}
+
+message BytesProto {
+ required bytes value = 1 [ctype=CORD];
+}
+
+message VoidProto {
+}
diff --git a/vendor/google.golang.org/appengine/internal/datastore/datastore_v3.pb.go b/vendor/google.golang.org/appengine/internal/datastore/datastore_v3.pb.go
new file mode 100644
index 0000000000000000000000000000000000000000..2fb74828969cc1688ce0f52b13d063446335bd41
--- /dev/null
+++ b/vendor/google.golang.org/appengine/internal/datastore/datastore_v3.pb.go
@@ -0,0 +1,4367 @@
+// Code generated by protoc-gen-go. DO NOT EDIT.
+// source: google.golang.org/appengine/internal/datastore/datastore_v3.proto
+
+package datastore
+
+import proto "github.com/golang/protobuf/proto"
+import fmt "fmt"
+import math "math"
+
+// Reference imports to suppress errors if they are not otherwise used.
+var _ = proto.Marshal
+var _ = fmt.Errorf
+var _ = math.Inf
+
+// This is a compile-time assertion to ensure that this generated file
+// is compatible with the proto package it is being compiled against.
+// A compilation error at this line likely means your copy of the
+// proto package needs to be updated.
+const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package
+
+type Property_Meaning int32
+
+const (
+ Property_NO_MEANING Property_Meaning = 0
+ Property_BLOB Property_Meaning = 14
+ Property_TEXT Property_Meaning = 15
+ Property_BYTESTRING Property_Meaning = 16
+ Property_ATOM_CATEGORY Property_Meaning = 1
+ Property_ATOM_LINK Property_Meaning = 2
+ Property_ATOM_TITLE Property_Meaning = 3
+ Property_ATOM_CONTENT Property_Meaning = 4
+ Property_ATOM_SUMMARY Property_Meaning = 5
+ Property_ATOM_AUTHOR Property_Meaning = 6
+ Property_GD_WHEN Property_Meaning = 7
+ Property_GD_EMAIL Property_Meaning = 8
+ Property_GEORSS_POINT Property_Meaning = 9
+ Property_GD_IM Property_Meaning = 10
+ Property_GD_PHONENUMBER Property_Meaning = 11
+ Property_GD_POSTALADDRESS Property_Meaning = 12
+ Property_GD_RATING Property_Meaning = 13
+ Property_BLOBKEY Property_Meaning = 17
+ Property_ENTITY_PROTO Property_Meaning = 19
+ Property_INDEX_VALUE Property_Meaning = 18
+)
+
+var Property_Meaning_name = map[int32]string{
+ 0: "NO_MEANING",
+ 14: "BLOB",
+ 15: "TEXT",
+ 16: "BYTESTRING",
+ 1: "ATOM_CATEGORY",
+ 2: "ATOM_LINK",
+ 3: "ATOM_TITLE",
+ 4: "ATOM_CONTENT",
+ 5: "ATOM_SUMMARY",
+ 6: "ATOM_AUTHOR",
+ 7: "GD_WHEN",
+ 8: "GD_EMAIL",
+ 9: "GEORSS_POINT",
+ 10: "GD_IM",
+ 11: "GD_PHONENUMBER",
+ 12: "GD_POSTALADDRESS",
+ 13: "GD_RATING",
+ 17: "BLOBKEY",
+ 19: "ENTITY_PROTO",
+ 18: "INDEX_VALUE",
+}
+var Property_Meaning_value = map[string]int32{
+ "NO_MEANING": 0,
+ "BLOB": 14,
+ "TEXT": 15,
+ "BYTESTRING": 16,
+ "ATOM_CATEGORY": 1,
+ "ATOM_LINK": 2,
+ "ATOM_TITLE": 3,
+ "ATOM_CONTENT": 4,
+ "ATOM_SUMMARY": 5,
+ "ATOM_AUTHOR": 6,
+ "GD_WHEN": 7,
+ "GD_EMAIL": 8,
+ "GEORSS_POINT": 9,
+ "GD_IM": 10,
+ "GD_PHONENUMBER": 11,
+ "GD_POSTALADDRESS": 12,
+ "GD_RATING": 13,
+ "BLOBKEY": 17,
+ "ENTITY_PROTO": 19,
+ "INDEX_VALUE": 18,
+}
+
+func (x Property_Meaning) Enum() *Property_Meaning {
+ p := new(Property_Meaning)
+ *p = x
+ return p
+}
+func (x Property_Meaning) String() string {
+ return proto.EnumName(Property_Meaning_name, int32(x))
+}
+func (x *Property_Meaning) UnmarshalJSON(data []byte) error {
+ value, err := proto.UnmarshalJSONEnum(Property_Meaning_value, data, "Property_Meaning")
+ if err != nil {
+ return err
+ }
+ *x = Property_Meaning(value)
+ return nil
+}
+func (Property_Meaning) EnumDescriptor() ([]byte, []int) {
+ return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{2, 0}
+}
+
+type Property_FtsTokenizationOption int32
+
+const (
+ Property_HTML Property_FtsTokenizationOption = 1
+ Property_ATOM Property_FtsTokenizationOption = 2
+)
+
+var Property_FtsTokenizationOption_name = map[int32]string{
+ 1: "HTML",
+ 2: "ATOM",
+}
+var Property_FtsTokenizationOption_value = map[string]int32{
+ "HTML": 1,
+ "ATOM": 2,
+}
+
+func (x Property_FtsTokenizationOption) Enum() *Property_FtsTokenizationOption {
+ p := new(Property_FtsTokenizationOption)
+ *p = x
+ return p
+}
+func (x Property_FtsTokenizationOption) String() string {
+ return proto.EnumName(Property_FtsTokenizationOption_name, int32(x))
+}
+func (x *Property_FtsTokenizationOption) UnmarshalJSON(data []byte) error {
+ value, err := proto.UnmarshalJSONEnum(Property_FtsTokenizationOption_value, data, "Property_FtsTokenizationOption")
+ if err != nil {
+ return err
+ }
+ *x = Property_FtsTokenizationOption(value)
+ return nil
+}
+func (Property_FtsTokenizationOption) EnumDescriptor() ([]byte, []int) {
+ return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{2, 1}
+}
+
+type EntityProto_Kind int32
+
+const (
+ EntityProto_GD_CONTACT EntityProto_Kind = 1
+ EntityProto_GD_EVENT EntityProto_Kind = 2
+ EntityProto_GD_MESSAGE EntityProto_Kind = 3
+)
+
+var EntityProto_Kind_name = map[int32]string{
+ 1: "GD_CONTACT",
+ 2: "GD_EVENT",
+ 3: "GD_MESSAGE",
+}
+var EntityProto_Kind_value = map[string]int32{
+ "GD_CONTACT": 1,
+ "GD_EVENT": 2,
+ "GD_MESSAGE": 3,
+}
+
+func (x EntityProto_Kind) Enum() *EntityProto_Kind {
+ p := new(EntityProto_Kind)
+ *p = x
+ return p
+}
+func (x EntityProto_Kind) String() string {
+ return proto.EnumName(EntityProto_Kind_name, int32(x))
+}
+func (x *EntityProto_Kind) UnmarshalJSON(data []byte) error {
+ value, err := proto.UnmarshalJSONEnum(EntityProto_Kind_value, data, "EntityProto_Kind")
+ if err != nil {
+ return err
+ }
+ *x = EntityProto_Kind(value)
+ return nil
+}
+func (EntityProto_Kind) EnumDescriptor() ([]byte, []int) {
+ return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{6, 0}
+}
+
+type Index_Property_Direction int32
+
+const (
+ Index_Property_ASCENDING Index_Property_Direction = 1
+ Index_Property_DESCENDING Index_Property_Direction = 2
+)
+
+var Index_Property_Direction_name = map[int32]string{
+ 1: "ASCENDING",
+ 2: "DESCENDING",
+}
+var Index_Property_Direction_value = map[string]int32{
+ "ASCENDING": 1,
+ "DESCENDING": 2,
+}
+
+func (x Index_Property_Direction) Enum() *Index_Property_Direction {
+ p := new(Index_Property_Direction)
+ *p = x
+ return p
+}
+func (x Index_Property_Direction) String() string {
+ return proto.EnumName(Index_Property_Direction_name, int32(x))
+}
+func (x *Index_Property_Direction) UnmarshalJSON(data []byte) error {
+ value, err := proto.UnmarshalJSONEnum(Index_Property_Direction_value, data, "Index_Property_Direction")
+ if err != nil {
+ return err
+ }
+ *x = Index_Property_Direction(value)
+ return nil
+}
+func (Index_Property_Direction) EnumDescriptor() ([]byte, []int) {
+ return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{8, 0, 0}
+}
+
+type CompositeIndex_State int32
+
+const (
+ CompositeIndex_WRITE_ONLY CompositeIndex_State = 1
+ CompositeIndex_READ_WRITE CompositeIndex_State = 2
+ CompositeIndex_DELETED CompositeIndex_State = 3
+ CompositeIndex_ERROR CompositeIndex_State = 4
+)
+
+var CompositeIndex_State_name = map[int32]string{
+ 1: "WRITE_ONLY",
+ 2: "READ_WRITE",
+ 3: "DELETED",
+ 4: "ERROR",
+}
+var CompositeIndex_State_value = map[string]int32{
+ "WRITE_ONLY": 1,
+ "READ_WRITE": 2,
+ "DELETED": 3,
+ "ERROR": 4,
+}
+
+func (x CompositeIndex_State) Enum() *CompositeIndex_State {
+ p := new(CompositeIndex_State)
+ *p = x
+ return p
+}
+func (x CompositeIndex_State) String() string {
+ return proto.EnumName(CompositeIndex_State_name, int32(x))
+}
+func (x *CompositeIndex_State) UnmarshalJSON(data []byte) error {
+ value, err := proto.UnmarshalJSONEnum(CompositeIndex_State_value, data, "CompositeIndex_State")
+ if err != nil {
+ return err
+ }
+ *x = CompositeIndex_State(value)
+ return nil
+}
+func (CompositeIndex_State) EnumDescriptor() ([]byte, []int) {
+ return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{9, 0}
+}
+
+type Snapshot_Status int32
+
+const (
+ Snapshot_INACTIVE Snapshot_Status = 0
+ Snapshot_ACTIVE Snapshot_Status = 1
+)
+
+var Snapshot_Status_name = map[int32]string{
+ 0: "INACTIVE",
+ 1: "ACTIVE",
+}
+var Snapshot_Status_value = map[string]int32{
+ "INACTIVE": 0,
+ "ACTIVE": 1,
+}
+
+func (x Snapshot_Status) Enum() *Snapshot_Status {
+ p := new(Snapshot_Status)
+ *p = x
+ return p
+}
+func (x Snapshot_Status) String() string {
+ return proto.EnumName(Snapshot_Status_name, int32(x))
+}
+func (x *Snapshot_Status) UnmarshalJSON(data []byte) error {
+ value, err := proto.UnmarshalJSONEnum(Snapshot_Status_value, data, "Snapshot_Status")
+ if err != nil {
+ return err
+ }
+ *x = Snapshot_Status(value)
+ return nil
+}
+func (Snapshot_Status) EnumDescriptor() ([]byte, []int) {
+ return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{12, 0}
+}
+
+type Query_Hint int32
+
+const (
+ Query_ORDER_FIRST Query_Hint = 1
+ Query_ANCESTOR_FIRST Query_Hint = 2
+ Query_FILTER_FIRST Query_Hint = 3
+)
+
+var Query_Hint_name = map[int32]string{
+ 1: "ORDER_FIRST",
+ 2: "ANCESTOR_FIRST",
+ 3: "FILTER_FIRST",
+}
+var Query_Hint_value = map[string]int32{
+ "ORDER_FIRST": 1,
+ "ANCESTOR_FIRST": 2,
+ "FILTER_FIRST": 3,
+}
+
+func (x Query_Hint) Enum() *Query_Hint {
+ p := new(Query_Hint)
+ *p = x
+ return p
+}
+func (x Query_Hint) String() string {
+ return proto.EnumName(Query_Hint_name, int32(x))
+}
+func (x *Query_Hint) UnmarshalJSON(data []byte) error {
+ value, err := proto.UnmarshalJSONEnum(Query_Hint_value, data, "Query_Hint")
+ if err != nil {
+ return err
+ }
+ *x = Query_Hint(value)
+ return nil
+}
+func (Query_Hint) EnumDescriptor() ([]byte, []int) {
+ return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{15, 0}
+}
+
+type Query_Filter_Operator int32
+
+const (
+ Query_Filter_LESS_THAN Query_Filter_Operator = 1
+ Query_Filter_LESS_THAN_OR_EQUAL Query_Filter_Operator = 2
+ Query_Filter_GREATER_THAN Query_Filter_Operator = 3
+ Query_Filter_GREATER_THAN_OR_EQUAL Query_Filter_Operator = 4
+ Query_Filter_EQUAL Query_Filter_Operator = 5
+ Query_Filter_IN Query_Filter_Operator = 6
+ Query_Filter_EXISTS Query_Filter_Operator = 7
+)
+
+var Query_Filter_Operator_name = map[int32]string{
+ 1: "LESS_THAN",
+ 2: "LESS_THAN_OR_EQUAL",
+ 3: "GREATER_THAN",
+ 4: "GREATER_THAN_OR_EQUAL",
+ 5: "EQUAL",
+ 6: "IN",
+ 7: "EXISTS",
+}
+var Query_Filter_Operator_value = map[string]int32{
+ "LESS_THAN": 1,
+ "LESS_THAN_OR_EQUAL": 2,
+ "GREATER_THAN": 3,
+ "GREATER_THAN_OR_EQUAL": 4,
+ "EQUAL": 5,
+ "IN": 6,
+ "EXISTS": 7,
+}
+
+func (x Query_Filter_Operator) Enum() *Query_Filter_Operator {
+ p := new(Query_Filter_Operator)
+ *p = x
+ return p
+}
+func (x Query_Filter_Operator) String() string {
+ return proto.EnumName(Query_Filter_Operator_name, int32(x))
+}
+func (x *Query_Filter_Operator) UnmarshalJSON(data []byte) error {
+ value, err := proto.UnmarshalJSONEnum(Query_Filter_Operator_value, data, "Query_Filter_Operator")
+ if err != nil {
+ return err
+ }
+ *x = Query_Filter_Operator(value)
+ return nil
+}
+func (Query_Filter_Operator) EnumDescriptor() ([]byte, []int) {
+ return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{15, 0, 0}
+}
+
+type Query_Order_Direction int32
+
+const (
+ Query_Order_ASCENDING Query_Order_Direction = 1
+ Query_Order_DESCENDING Query_Order_Direction = 2
+)
+
+var Query_Order_Direction_name = map[int32]string{
+ 1: "ASCENDING",
+ 2: "DESCENDING",
+}
+var Query_Order_Direction_value = map[string]int32{
+ "ASCENDING": 1,
+ "DESCENDING": 2,
+}
+
+func (x Query_Order_Direction) Enum() *Query_Order_Direction {
+ p := new(Query_Order_Direction)
+ *p = x
+ return p
+}
+func (x Query_Order_Direction) String() string {
+ return proto.EnumName(Query_Order_Direction_name, int32(x))
+}
+func (x *Query_Order_Direction) UnmarshalJSON(data []byte) error {
+ value, err := proto.UnmarshalJSONEnum(Query_Order_Direction_value, data, "Query_Order_Direction")
+ if err != nil {
+ return err
+ }
+ *x = Query_Order_Direction(value)
+ return nil
+}
+func (Query_Order_Direction) EnumDescriptor() ([]byte, []int) {
+ return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{15, 1, 0}
+}
+
+type Error_ErrorCode int32
+
+const (
+ Error_BAD_REQUEST Error_ErrorCode = 1
+ Error_CONCURRENT_TRANSACTION Error_ErrorCode = 2
+ Error_INTERNAL_ERROR Error_ErrorCode = 3
+ Error_NEED_INDEX Error_ErrorCode = 4
+ Error_TIMEOUT Error_ErrorCode = 5
+ Error_PERMISSION_DENIED Error_ErrorCode = 6
+ Error_BIGTABLE_ERROR Error_ErrorCode = 7
+ Error_COMMITTED_BUT_STILL_APPLYING Error_ErrorCode = 8
+ Error_CAPABILITY_DISABLED Error_ErrorCode = 9
+ Error_TRY_ALTERNATE_BACKEND Error_ErrorCode = 10
+ Error_SAFE_TIME_TOO_OLD Error_ErrorCode = 11
+)
+
+var Error_ErrorCode_name = map[int32]string{
+ 1: "BAD_REQUEST",
+ 2: "CONCURRENT_TRANSACTION",
+ 3: "INTERNAL_ERROR",
+ 4: "NEED_INDEX",
+ 5: "TIMEOUT",
+ 6: "PERMISSION_DENIED",
+ 7: "BIGTABLE_ERROR",
+ 8: "COMMITTED_BUT_STILL_APPLYING",
+ 9: "CAPABILITY_DISABLED",
+ 10: "TRY_ALTERNATE_BACKEND",
+ 11: "SAFE_TIME_TOO_OLD",
+}
+var Error_ErrorCode_value = map[string]int32{
+ "BAD_REQUEST": 1,
+ "CONCURRENT_TRANSACTION": 2,
+ "INTERNAL_ERROR": 3,
+ "NEED_INDEX": 4,
+ "TIMEOUT": 5,
+ "PERMISSION_DENIED": 6,
+ "BIGTABLE_ERROR": 7,
+ "COMMITTED_BUT_STILL_APPLYING": 8,
+ "CAPABILITY_DISABLED": 9,
+ "TRY_ALTERNATE_BACKEND": 10,
+ "SAFE_TIME_TOO_OLD": 11,
+}
+
+func (x Error_ErrorCode) Enum() *Error_ErrorCode {
+ p := new(Error_ErrorCode)
+ *p = x
+ return p
+}
+func (x Error_ErrorCode) String() string {
+ return proto.EnumName(Error_ErrorCode_name, int32(x))
+}
+func (x *Error_ErrorCode) UnmarshalJSON(data []byte) error {
+ value, err := proto.UnmarshalJSONEnum(Error_ErrorCode_value, data, "Error_ErrorCode")
+ if err != nil {
+ return err
+ }
+ *x = Error_ErrorCode(value)
+ return nil
+}
+func (Error_ErrorCode) EnumDescriptor() ([]byte, []int) {
+ return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{19, 0}
+}
+
+type PutRequest_AutoIdPolicy int32
+
+const (
+ PutRequest_CURRENT PutRequest_AutoIdPolicy = 0
+ PutRequest_SEQUENTIAL PutRequest_AutoIdPolicy = 1
+)
+
+var PutRequest_AutoIdPolicy_name = map[int32]string{
+ 0: "CURRENT",
+ 1: "SEQUENTIAL",
+}
+var PutRequest_AutoIdPolicy_value = map[string]int32{
+ "CURRENT": 0,
+ "SEQUENTIAL": 1,
+}
+
+func (x PutRequest_AutoIdPolicy) Enum() *PutRequest_AutoIdPolicy {
+ p := new(PutRequest_AutoIdPolicy)
+ *p = x
+ return p
+}
+func (x PutRequest_AutoIdPolicy) String() string {
+ return proto.EnumName(PutRequest_AutoIdPolicy_name, int32(x))
+}
+func (x *PutRequest_AutoIdPolicy) UnmarshalJSON(data []byte) error {
+ value, err := proto.UnmarshalJSONEnum(PutRequest_AutoIdPolicy_value, data, "PutRequest_AutoIdPolicy")
+ if err != nil {
+ return err
+ }
+ *x = PutRequest_AutoIdPolicy(value)
+ return nil
+}
+func (PutRequest_AutoIdPolicy) EnumDescriptor() ([]byte, []int) {
+ return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{23, 0}
+}
+
+type BeginTransactionRequest_TransactionMode int32
+
+const (
+ BeginTransactionRequest_UNKNOWN BeginTransactionRequest_TransactionMode = 0
+ BeginTransactionRequest_READ_ONLY BeginTransactionRequest_TransactionMode = 1
+ BeginTransactionRequest_READ_WRITE BeginTransactionRequest_TransactionMode = 2
+)
+
+var BeginTransactionRequest_TransactionMode_name = map[int32]string{
+ 0: "UNKNOWN",
+ 1: "READ_ONLY",
+ 2: "READ_WRITE",
+}
+var BeginTransactionRequest_TransactionMode_value = map[string]int32{
+ "UNKNOWN": 0,
+ "READ_ONLY": 1,
+ "READ_WRITE": 2,
+}
+
+func (x BeginTransactionRequest_TransactionMode) Enum() *BeginTransactionRequest_TransactionMode {
+ p := new(BeginTransactionRequest_TransactionMode)
+ *p = x
+ return p
+}
+func (x BeginTransactionRequest_TransactionMode) String() string {
+ return proto.EnumName(BeginTransactionRequest_TransactionMode_name, int32(x))
+}
+func (x *BeginTransactionRequest_TransactionMode) UnmarshalJSON(data []byte) error {
+ value, err := proto.UnmarshalJSONEnum(BeginTransactionRequest_TransactionMode_value, data, "BeginTransactionRequest_TransactionMode")
+ if err != nil {
+ return err
+ }
+ *x = BeginTransactionRequest_TransactionMode(value)
+ return nil
+}
+func (BeginTransactionRequest_TransactionMode) EnumDescriptor() ([]byte, []int) {
+ return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{36, 0}
+}
+
+type Action struct {
+ XXX_NoUnkeyedLiteral struct{} `json:"-"`
+ XXX_unrecognized []byte `json:"-"`
+ XXX_sizecache int32 `json:"-"`
+}
+
+func (m *Action) Reset() { *m = Action{} }
+func (m *Action) String() string { return proto.CompactTextString(m) }
+func (*Action) ProtoMessage() {}
+func (*Action) Descriptor() ([]byte, []int) {
+ return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{0}
+}
+func (m *Action) XXX_Unmarshal(b []byte) error {
+ return xxx_messageInfo_Action.Unmarshal(m, b)
+}
+func (m *Action) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ return xxx_messageInfo_Action.Marshal(b, m, deterministic)
+}
+func (dst *Action) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_Action.Merge(dst, src)
+}
+func (m *Action) XXX_Size() int {
+ return xxx_messageInfo_Action.Size(m)
+}
+func (m *Action) XXX_DiscardUnknown() {
+ xxx_messageInfo_Action.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_Action proto.InternalMessageInfo
+
+type PropertyValue struct {
+ Int64Value *int64 `protobuf:"varint,1,opt,name=int64Value" json:"int64Value,omitempty"`
+ BooleanValue *bool `protobuf:"varint,2,opt,name=booleanValue" json:"booleanValue,omitempty"`
+ StringValue *string `protobuf:"bytes,3,opt,name=stringValue" json:"stringValue,omitempty"`
+ DoubleValue *float64 `protobuf:"fixed64,4,opt,name=doubleValue" json:"doubleValue,omitempty"`
+ Pointvalue *PropertyValue_PointValue `protobuf:"group,5,opt,name=PointValue,json=pointvalue" json:"pointvalue,omitempty"`
+ Uservalue *PropertyValue_UserValue `protobuf:"group,8,opt,name=UserValue,json=uservalue" json:"uservalue,omitempty"`
+ Referencevalue *PropertyValue_ReferenceValue `protobuf:"group,12,opt,name=ReferenceValue,json=referencevalue" json:"referencevalue,omitempty"`
+ XXX_NoUnkeyedLiteral struct{} `json:"-"`
+ XXX_unrecognized []byte `json:"-"`
+ XXX_sizecache int32 `json:"-"`
+}
+
+func (m *PropertyValue) Reset() { *m = PropertyValue{} }
+func (m *PropertyValue) String() string { return proto.CompactTextString(m) }
+func (*PropertyValue) ProtoMessage() {}
+func (*PropertyValue) Descriptor() ([]byte, []int) {
+ return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{1}
+}
+func (m *PropertyValue) XXX_Unmarshal(b []byte) error {
+ return xxx_messageInfo_PropertyValue.Unmarshal(m, b)
+}
+func (m *PropertyValue) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ return xxx_messageInfo_PropertyValue.Marshal(b, m, deterministic)
+}
+func (dst *PropertyValue) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_PropertyValue.Merge(dst, src)
+}
+func (m *PropertyValue) XXX_Size() int {
+ return xxx_messageInfo_PropertyValue.Size(m)
+}
+func (m *PropertyValue) XXX_DiscardUnknown() {
+ xxx_messageInfo_PropertyValue.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_PropertyValue proto.InternalMessageInfo
+
+func (m *PropertyValue) GetInt64Value() int64 {
+ if m != nil && m.Int64Value != nil {
+ return *m.Int64Value
+ }
+ return 0
+}
+
+func (m *PropertyValue) GetBooleanValue() bool {
+ if m != nil && m.BooleanValue != nil {
+ return *m.BooleanValue
+ }
+ return false
+}
+
+func (m *PropertyValue) GetStringValue() string {
+ if m != nil && m.StringValue != nil {
+ return *m.StringValue
+ }
+ return ""
+}
+
+func (m *PropertyValue) GetDoubleValue() float64 {
+ if m != nil && m.DoubleValue != nil {
+ return *m.DoubleValue
+ }
+ return 0
+}
+
+func (m *PropertyValue) GetPointvalue() *PropertyValue_PointValue {
+ if m != nil {
+ return m.Pointvalue
+ }
+ return nil
+}
+
+func (m *PropertyValue) GetUservalue() *PropertyValue_UserValue {
+ if m != nil {
+ return m.Uservalue
+ }
+ return nil
+}
+
+func (m *PropertyValue) GetReferencevalue() *PropertyValue_ReferenceValue {
+ if m != nil {
+ return m.Referencevalue
+ }
+ return nil
+}
+
+type PropertyValue_PointValue struct {
+ X *float64 `protobuf:"fixed64,6,req,name=x" json:"x,omitempty"`
+ Y *float64 `protobuf:"fixed64,7,req,name=y" json:"y,omitempty"`
+ XXX_NoUnkeyedLiteral struct{} `json:"-"`
+ XXX_unrecognized []byte `json:"-"`
+ XXX_sizecache int32 `json:"-"`
+}
+
+func (m *PropertyValue_PointValue) Reset() { *m = PropertyValue_PointValue{} }
+func (m *PropertyValue_PointValue) String() string { return proto.CompactTextString(m) }
+func (*PropertyValue_PointValue) ProtoMessage() {}
+func (*PropertyValue_PointValue) Descriptor() ([]byte, []int) {
+ return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{1, 0}
+}
+func (m *PropertyValue_PointValue) XXX_Unmarshal(b []byte) error {
+ return xxx_messageInfo_PropertyValue_PointValue.Unmarshal(m, b)
+}
+func (m *PropertyValue_PointValue) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ return xxx_messageInfo_PropertyValue_PointValue.Marshal(b, m, deterministic)
+}
+func (dst *PropertyValue_PointValue) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_PropertyValue_PointValue.Merge(dst, src)
+}
+func (m *PropertyValue_PointValue) XXX_Size() int {
+ return xxx_messageInfo_PropertyValue_PointValue.Size(m)
+}
+func (m *PropertyValue_PointValue) XXX_DiscardUnknown() {
+ xxx_messageInfo_PropertyValue_PointValue.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_PropertyValue_PointValue proto.InternalMessageInfo
+
+func (m *PropertyValue_PointValue) GetX() float64 {
+ if m != nil && m.X != nil {
+ return *m.X
+ }
+ return 0
+}
+
+func (m *PropertyValue_PointValue) GetY() float64 {
+ if m != nil && m.Y != nil {
+ return *m.Y
+ }
+ return 0
+}
+
+type PropertyValue_UserValue struct {
+ Email *string `protobuf:"bytes,9,req,name=email" json:"email,omitempty"`
+ AuthDomain *string `protobuf:"bytes,10,req,name=auth_domain,json=authDomain" json:"auth_domain,omitempty"`
+ Nickname *string `protobuf:"bytes,11,opt,name=nickname" json:"nickname,omitempty"`
+ FederatedIdentity *string `protobuf:"bytes,21,opt,name=federated_identity,json=federatedIdentity" json:"federated_identity,omitempty"`
+ FederatedProvider *string `protobuf:"bytes,22,opt,name=federated_provider,json=federatedProvider" json:"federated_provider,omitempty"`
+ XXX_NoUnkeyedLiteral struct{} `json:"-"`
+ XXX_unrecognized []byte `json:"-"`
+ XXX_sizecache int32 `json:"-"`
+}
+
+func (m *PropertyValue_UserValue) Reset() { *m = PropertyValue_UserValue{} }
+func (m *PropertyValue_UserValue) String() string { return proto.CompactTextString(m) }
+func (*PropertyValue_UserValue) ProtoMessage() {}
+func (*PropertyValue_UserValue) Descriptor() ([]byte, []int) {
+ return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{1, 1}
+}
+func (m *PropertyValue_UserValue) XXX_Unmarshal(b []byte) error {
+ return xxx_messageInfo_PropertyValue_UserValue.Unmarshal(m, b)
+}
+func (m *PropertyValue_UserValue) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ return xxx_messageInfo_PropertyValue_UserValue.Marshal(b, m, deterministic)
+}
+func (dst *PropertyValue_UserValue) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_PropertyValue_UserValue.Merge(dst, src)
+}
+func (m *PropertyValue_UserValue) XXX_Size() int {
+ return xxx_messageInfo_PropertyValue_UserValue.Size(m)
+}
+func (m *PropertyValue_UserValue) XXX_DiscardUnknown() {
+ xxx_messageInfo_PropertyValue_UserValue.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_PropertyValue_UserValue proto.InternalMessageInfo
+
+func (m *PropertyValue_UserValue) GetEmail() string {
+ if m != nil && m.Email != nil {
+ return *m.Email
+ }
+ return ""
+}
+
+func (m *PropertyValue_UserValue) GetAuthDomain() string {
+ if m != nil && m.AuthDomain != nil {
+ return *m.AuthDomain
+ }
+ return ""
+}
+
+func (m *PropertyValue_UserValue) GetNickname() string {
+ if m != nil && m.Nickname != nil {
+ return *m.Nickname
+ }
+ return ""
+}
+
+func (m *PropertyValue_UserValue) GetFederatedIdentity() string {
+ if m != nil && m.FederatedIdentity != nil {
+ return *m.FederatedIdentity
+ }
+ return ""
+}
+
+func (m *PropertyValue_UserValue) GetFederatedProvider() string {
+ if m != nil && m.FederatedProvider != nil {
+ return *m.FederatedProvider
+ }
+ return ""
+}
+
+type PropertyValue_ReferenceValue struct {
+ App *string `protobuf:"bytes,13,req,name=app" json:"app,omitempty"`
+ NameSpace *string `protobuf:"bytes,20,opt,name=name_space,json=nameSpace" json:"name_space,omitempty"`
+ Pathelement []*PropertyValue_ReferenceValue_PathElement `protobuf:"group,14,rep,name=PathElement,json=pathelement" json:"pathelement,omitempty"`
+ XXX_NoUnkeyedLiteral struct{} `json:"-"`
+ XXX_unrecognized []byte `json:"-"`
+ XXX_sizecache int32 `json:"-"`
+}
+
+func (m *PropertyValue_ReferenceValue) Reset() { *m = PropertyValue_ReferenceValue{} }
+func (m *PropertyValue_ReferenceValue) String() string { return proto.CompactTextString(m) }
+func (*PropertyValue_ReferenceValue) ProtoMessage() {}
+func (*PropertyValue_ReferenceValue) Descriptor() ([]byte, []int) {
+ return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{1, 2}
+}
+func (m *PropertyValue_ReferenceValue) XXX_Unmarshal(b []byte) error {
+ return xxx_messageInfo_PropertyValue_ReferenceValue.Unmarshal(m, b)
+}
+func (m *PropertyValue_ReferenceValue) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ return xxx_messageInfo_PropertyValue_ReferenceValue.Marshal(b, m, deterministic)
+}
+func (dst *PropertyValue_ReferenceValue) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_PropertyValue_ReferenceValue.Merge(dst, src)
+}
+func (m *PropertyValue_ReferenceValue) XXX_Size() int {
+ return xxx_messageInfo_PropertyValue_ReferenceValue.Size(m)
+}
+func (m *PropertyValue_ReferenceValue) XXX_DiscardUnknown() {
+ xxx_messageInfo_PropertyValue_ReferenceValue.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_PropertyValue_ReferenceValue proto.InternalMessageInfo
+
+func (m *PropertyValue_ReferenceValue) GetApp() string {
+ if m != nil && m.App != nil {
+ return *m.App
+ }
+ return ""
+}
+
+func (m *PropertyValue_ReferenceValue) GetNameSpace() string {
+ if m != nil && m.NameSpace != nil {
+ return *m.NameSpace
+ }
+ return ""
+}
+
+func (m *PropertyValue_ReferenceValue) GetPathelement() []*PropertyValue_ReferenceValue_PathElement {
+ if m != nil {
+ return m.Pathelement
+ }
+ return nil
+}
+
+type PropertyValue_ReferenceValue_PathElement struct {
+ Type *string `protobuf:"bytes,15,req,name=type" json:"type,omitempty"`
+ Id *int64 `protobuf:"varint,16,opt,name=id" json:"id,omitempty"`
+ Name *string `protobuf:"bytes,17,opt,name=name" json:"name,omitempty"`
+ XXX_NoUnkeyedLiteral struct{} `json:"-"`
+ XXX_unrecognized []byte `json:"-"`
+ XXX_sizecache int32 `json:"-"`
+}
+
+func (m *PropertyValue_ReferenceValue_PathElement) Reset() {
+ *m = PropertyValue_ReferenceValue_PathElement{}
+}
+func (m *PropertyValue_ReferenceValue_PathElement) String() string { return proto.CompactTextString(m) }
+func (*PropertyValue_ReferenceValue_PathElement) ProtoMessage() {}
+func (*PropertyValue_ReferenceValue_PathElement) Descriptor() ([]byte, []int) {
+ return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{1, 2, 0}
+}
+func (m *PropertyValue_ReferenceValue_PathElement) XXX_Unmarshal(b []byte) error {
+ return xxx_messageInfo_PropertyValue_ReferenceValue_PathElement.Unmarshal(m, b)
+}
+func (m *PropertyValue_ReferenceValue_PathElement) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ return xxx_messageInfo_PropertyValue_ReferenceValue_PathElement.Marshal(b, m, deterministic)
+}
+func (dst *PropertyValue_ReferenceValue_PathElement) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_PropertyValue_ReferenceValue_PathElement.Merge(dst, src)
+}
+func (m *PropertyValue_ReferenceValue_PathElement) XXX_Size() int {
+ return xxx_messageInfo_PropertyValue_ReferenceValue_PathElement.Size(m)
+}
+func (m *PropertyValue_ReferenceValue_PathElement) XXX_DiscardUnknown() {
+ xxx_messageInfo_PropertyValue_ReferenceValue_PathElement.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_PropertyValue_ReferenceValue_PathElement proto.InternalMessageInfo
+
+func (m *PropertyValue_ReferenceValue_PathElement) GetType() string {
+ if m != nil && m.Type != nil {
+ return *m.Type
+ }
+ return ""
+}
+
+func (m *PropertyValue_ReferenceValue_PathElement) GetId() int64 {
+ if m != nil && m.Id != nil {
+ return *m.Id
+ }
+ return 0
+}
+
+func (m *PropertyValue_ReferenceValue_PathElement) GetName() string {
+ if m != nil && m.Name != nil {
+ return *m.Name
+ }
+ return ""
+}
+
+type Property struct {
+ Meaning *Property_Meaning `protobuf:"varint,1,opt,name=meaning,enum=appengine.Property_Meaning,def=0" json:"meaning,omitempty"`
+ MeaningUri *string `protobuf:"bytes,2,opt,name=meaning_uri,json=meaningUri" json:"meaning_uri,omitempty"`
+ Name *string `protobuf:"bytes,3,req,name=name" json:"name,omitempty"`
+ Value *PropertyValue `protobuf:"bytes,5,req,name=value" json:"value,omitempty"`
+ Multiple *bool `protobuf:"varint,4,req,name=multiple" json:"multiple,omitempty"`
+ Searchable *bool `protobuf:"varint,6,opt,name=searchable,def=0" json:"searchable,omitempty"`
+ FtsTokenizationOption *Property_FtsTokenizationOption `protobuf:"varint,8,opt,name=fts_tokenization_option,json=ftsTokenizationOption,enum=appengine.Property_FtsTokenizationOption" json:"fts_tokenization_option,omitempty"`
+ Locale *string `protobuf:"bytes,9,opt,name=locale,def=en" json:"locale,omitempty"`
+ XXX_NoUnkeyedLiteral struct{} `json:"-"`
+ XXX_unrecognized []byte `json:"-"`
+ XXX_sizecache int32 `json:"-"`
+}
+
+func (m *Property) Reset() { *m = Property{} }
+func (m *Property) String() string { return proto.CompactTextString(m) }
+func (*Property) ProtoMessage() {}
+func (*Property) Descriptor() ([]byte, []int) {
+ return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{2}
+}
+func (m *Property) XXX_Unmarshal(b []byte) error {
+ return xxx_messageInfo_Property.Unmarshal(m, b)
+}
+func (m *Property) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ return xxx_messageInfo_Property.Marshal(b, m, deterministic)
+}
+func (dst *Property) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_Property.Merge(dst, src)
+}
+func (m *Property) XXX_Size() int {
+ return xxx_messageInfo_Property.Size(m)
+}
+func (m *Property) XXX_DiscardUnknown() {
+ xxx_messageInfo_Property.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_Property proto.InternalMessageInfo
+
+const Default_Property_Meaning Property_Meaning = Property_NO_MEANING
+const Default_Property_Searchable bool = false
+const Default_Property_Locale string = "en"
+
+func (m *Property) GetMeaning() Property_Meaning {
+ if m != nil && m.Meaning != nil {
+ return *m.Meaning
+ }
+ return Default_Property_Meaning
+}
+
+func (m *Property) GetMeaningUri() string {
+ if m != nil && m.MeaningUri != nil {
+ return *m.MeaningUri
+ }
+ return ""
+}
+
+func (m *Property) GetName() string {
+ if m != nil && m.Name != nil {
+ return *m.Name
+ }
+ return ""
+}
+
+func (m *Property) GetValue() *PropertyValue {
+ if m != nil {
+ return m.Value
+ }
+ return nil
+}
+
+func (m *Property) GetMultiple() bool {
+ if m != nil && m.Multiple != nil {
+ return *m.Multiple
+ }
+ return false
+}
+
+func (m *Property) GetSearchable() bool {
+ if m != nil && m.Searchable != nil {
+ return *m.Searchable
+ }
+ return Default_Property_Searchable
+}
+
+func (m *Property) GetFtsTokenizationOption() Property_FtsTokenizationOption {
+ if m != nil && m.FtsTokenizationOption != nil {
+ return *m.FtsTokenizationOption
+ }
+ return Property_HTML
+}
+
+func (m *Property) GetLocale() string {
+ if m != nil && m.Locale != nil {
+ return *m.Locale
+ }
+ return Default_Property_Locale
+}
+
+type Path struct {
+ Element []*Path_Element `protobuf:"group,1,rep,name=Element,json=element" json:"element,omitempty"`
+ XXX_NoUnkeyedLiteral struct{} `json:"-"`
+ XXX_unrecognized []byte `json:"-"`
+ XXX_sizecache int32 `json:"-"`
+}
+
+func (m *Path) Reset() { *m = Path{} }
+func (m *Path) String() string { return proto.CompactTextString(m) }
+func (*Path) ProtoMessage() {}
+func (*Path) Descriptor() ([]byte, []int) {
+ return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{3}
+}
+func (m *Path) XXX_Unmarshal(b []byte) error {
+ return xxx_messageInfo_Path.Unmarshal(m, b)
+}
+func (m *Path) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ return xxx_messageInfo_Path.Marshal(b, m, deterministic)
+}
+func (dst *Path) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_Path.Merge(dst, src)
+}
+func (m *Path) XXX_Size() int {
+ return xxx_messageInfo_Path.Size(m)
+}
+func (m *Path) XXX_DiscardUnknown() {
+ xxx_messageInfo_Path.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_Path proto.InternalMessageInfo
+
+func (m *Path) GetElement() []*Path_Element {
+ if m != nil {
+ return m.Element
+ }
+ return nil
+}
+
+type Path_Element struct {
+ Type *string `protobuf:"bytes,2,req,name=type" json:"type,omitempty"`
+ Id *int64 `protobuf:"varint,3,opt,name=id" json:"id,omitempty"`
+ Name *string `protobuf:"bytes,4,opt,name=name" json:"name,omitempty"`
+ XXX_NoUnkeyedLiteral struct{} `json:"-"`
+ XXX_unrecognized []byte `json:"-"`
+ XXX_sizecache int32 `json:"-"`
+}
+
+func (m *Path_Element) Reset() { *m = Path_Element{} }
+func (m *Path_Element) String() string { return proto.CompactTextString(m) }
+func (*Path_Element) ProtoMessage() {}
+func (*Path_Element) Descriptor() ([]byte, []int) {
+ return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{3, 0}
+}
+func (m *Path_Element) XXX_Unmarshal(b []byte) error {
+ return xxx_messageInfo_Path_Element.Unmarshal(m, b)
+}
+func (m *Path_Element) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ return xxx_messageInfo_Path_Element.Marshal(b, m, deterministic)
+}
+func (dst *Path_Element) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_Path_Element.Merge(dst, src)
+}
+func (m *Path_Element) XXX_Size() int {
+ return xxx_messageInfo_Path_Element.Size(m)
+}
+func (m *Path_Element) XXX_DiscardUnknown() {
+ xxx_messageInfo_Path_Element.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_Path_Element proto.InternalMessageInfo
+
+func (m *Path_Element) GetType() string {
+ if m != nil && m.Type != nil {
+ return *m.Type
+ }
+ return ""
+}
+
+func (m *Path_Element) GetId() int64 {
+ if m != nil && m.Id != nil {
+ return *m.Id
+ }
+ return 0
+}
+
+func (m *Path_Element) GetName() string {
+ if m != nil && m.Name != nil {
+ return *m.Name
+ }
+ return ""
+}
+
+type Reference struct {
+ App *string `protobuf:"bytes,13,req,name=app" json:"app,omitempty"`
+ NameSpace *string `protobuf:"bytes,20,opt,name=name_space,json=nameSpace" json:"name_space,omitempty"`
+ Path *Path `protobuf:"bytes,14,req,name=path" json:"path,omitempty"`
+ XXX_NoUnkeyedLiteral struct{} `json:"-"`
+ XXX_unrecognized []byte `json:"-"`
+ XXX_sizecache int32 `json:"-"`
+}
+
+func (m *Reference) Reset() { *m = Reference{} }
+func (m *Reference) String() string { return proto.CompactTextString(m) }
+func (*Reference) ProtoMessage() {}
+func (*Reference) Descriptor() ([]byte, []int) {
+ return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{4}
+}
+func (m *Reference) XXX_Unmarshal(b []byte) error {
+ return xxx_messageInfo_Reference.Unmarshal(m, b)
+}
+func (m *Reference) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ return xxx_messageInfo_Reference.Marshal(b, m, deterministic)
+}
+func (dst *Reference) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_Reference.Merge(dst, src)
+}
+func (m *Reference) XXX_Size() int {
+ return xxx_messageInfo_Reference.Size(m)
+}
+func (m *Reference) XXX_DiscardUnknown() {
+ xxx_messageInfo_Reference.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_Reference proto.InternalMessageInfo
+
+func (m *Reference) GetApp() string {
+ if m != nil && m.App != nil {
+ return *m.App
+ }
+ return ""
+}
+
+func (m *Reference) GetNameSpace() string {
+ if m != nil && m.NameSpace != nil {
+ return *m.NameSpace
+ }
+ return ""
+}
+
+func (m *Reference) GetPath() *Path {
+ if m != nil {
+ return m.Path
+ }
+ return nil
+}
+
+type User struct {
+ Email *string `protobuf:"bytes,1,req,name=email" json:"email,omitempty"`
+ AuthDomain *string `protobuf:"bytes,2,req,name=auth_domain,json=authDomain" json:"auth_domain,omitempty"`
+ Nickname *string `protobuf:"bytes,3,opt,name=nickname" json:"nickname,omitempty"`
+ FederatedIdentity *string `protobuf:"bytes,6,opt,name=federated_identity,json=federatedIdentity" json:"federated_identity,omitempty"`
+ FederatedProvider *string `protobuf:"bytes,7,opt,name=federated_provider,json=federatedProvider" json:"federated_provider,omitempty"`
+ XXX_NoUnkeyedLiteral struct{} `json:"-"`
+ XXX_unrecognized []byte `json:"-"`
+ XXX_sizecache int32 `json:"-"`
+}
+
+func (m *User) Reset() { *m = User{} }
+func (m *User) String() string { return proto.CompactTextString(m) }
+func (*User) ProtoMessage() {}
+func (*User) Descriptor() ([]byte, []int) {
+ return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{5}
+}
+func (m *User) XXX_Unmarshal(b []byte) error {
+ return xxx_messageInfo_User.Unmarshal(m, b)
+}
+func (m *User) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ return xxx_messageInfo_User.Marshal(b, m, deterministic)
+}
+func (dst *User) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_User.Merge(dst, src)
+}
+func (m *User) XXX_Size() int {
+ return xxx_messageInfo_User.Size(m)
+}
+func (m *User) XXX_DiscardUnknown() {
+ xxx_messageInfo_User.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_User proto.InternalMessageInfo
+
+func (m *User) GetEmail() string {
+ if m != nil && m.Email != nil {
+ return *m.Email
+ }
+ return ""
+}
+
+func (m *User) GetAuthDomain() string {
+ if m != nil && m.AuthDomain != nil {
+ return *m.AuthDomain
+ }
+ return ""
+}
+
+func (m *User) GetNickname() string {
+ if m != nil && m.Nickname != nil {
+ return *m.Nickname
+ }
+ return ""
+}
+
+func (m *User) GetFederatedIdentity() string {
+ if m != nil && m.FederatedIdentity != nil {
+ return *m.FederatedIdentity
+ }
+ return ""
+}
+
+func (m *User) GetFederatedProvider() string {
+ if m != nil && m.FederatedProvider != nil {
+ return *m.FederatedProvider
+ }
+ return ""
+}
+
+type EntityProto struct {
+ Key *Reference `protobuf:"bytes,13,req,name=key" json:"key,omitempty"`
+ EntityGroup *Path `protobuf:"bytes,16,req,name=entity_group,json=entityGroup" json:"entity_group,omitempty"`
+ Owner *User `protobuf:"bytes,17,opt,name=owner" json:"owner,omitempty"`
+ Kind *EntityProto_Kind `protobuf:"varint,4,opt,name=kind,enum=appengine.EntityProto_Kind" json:"kind,omitempty"`
+ KindUri *string `protobuf:"bytes,5,opt,name=kind_uri,json=kindUri" json:"kind_uri,omitempty"`
+ Property []*Property `protobuf:"bytes,14,rep,name=property" json:"property,omitempty"`
+ RawProperty []*Property `protobuf:"bytes,15,rep,name=raw_property,json=rawProperty" json:"raw_property,omitempty"`
+ Rank *int32 `protobuf:"varint,18,opt,name=rank" json:"rank,omitempty"`
+ XXX_NoUnkeyedLiteral struct{} `json:"-"`
+ XXX_unrecognized []byte `json:"-"`
+ XXX_sizecache int32 `json:"-"`
+}
+
+func (m *EntityProto) Reset() { *m = EntityProto{} }
+func (m *EntityProto) String() string { return proto.CompactTextString(m) }
+func (*EntityProto) ProtoMessage() {}
+func (*EntityProto) Descriptor() ([]byte, []int) {
+ return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{6}
+}
+func (m *EntityProto) XXX_Unmarshal(b []byte) error {
+ return xxx_messageInfo_EntityProto.Unmarshal(m, b)
+}
+func (m *EntityProto) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ return xxx_messageInfo_EntityProto.Marshal(b, m, deterministic)
+}
+func (dst *EntityProto) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_EntityProto.Merge(dst, src)
+}
+func (m *EntityProto) XXX_Size() int {
+ return xxx_messageInfo_EntityProto.Size(m)
+}
+func (m *EntityProto) XXX_DiscardUnknown() {
+ xxx_messageInfo_EntityProto.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_EntityProto proto.InternalMessageInfo
+
+func (m *EntityProto) GetKey() *Reference {
+ if m != nil {
+ return m.Key
+ }
+ return nil
+}
+
+func (m *EntityProto) GetEntityGroup() *Path {
+ if m != nil {
+ return m.EntityGroup
+ }
+ return nil
+}
+
+func (m *EntityProto) GetOwner() *User {
+ if m != nil {
+ return m.Owner
+ }
+ return nil
+}
+
+func (m *EntityProto) GetKind() EntityProto_Kind {
+ if m != nil && m.Kind != nil {
+ return *m.Kind
+ }
+ return EntityProto_GD_CONTACT
+}
+
+func (m *EntityProto) GetKindUri() string {
+ if m != nil && m.KindUri != nil {
+ return *m.KindUri
+ }
+ return ""
+}
+
+func (m *EntityProto) GetProperty() []*Property {
+ if m != nil {
+ return m.Property
+ }
+ return nil
+}
+
+func (m *EntityProto) GetRawProperty() []*Property {
+ if m != nil {
+ return m.RawProperty
+ }
+ return nil
+}
+
+func (m *EntityProto) GetRank() int32 {
+ if m != nil && m.Rank != nil {
+ return *m.Rank
+ }
+ return 0
+}
+
+type CompositeProperty struct {
+ IndexId *int64 `protobuf:"varint,1,req,name=index_id,json=indexId" json:"index_id,omitempty"`
+ Value []string `protobuf:"bytes,2,rep,name=value" json:"value,omitempty"`
+ XXX_NoUnkeyedLiteral struct{} `json:"-"`
+ XXX_unrecognized []byte `json:"-"`
+ XXX_sizecache int32 `json:"-"`
+}
+
+func (m *CompositeProperty) Reset() { *m = CompositeProperty{} }
+func (m *CompositeProperty) String() string { return proto.CompactTextString(m) }
+func (*CompositeProperty) ProtoMessage() {}
+func (*CompositeProperty) Descriptor() ([]byte, []int) {
+ return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{7}
+}
+func (m *CompositeProperty) XXX_Unmarshal(b []byte) error {
+ return xxx_messageInfo_CompositeProperty.Unmarshal(m, b)
+}
+func (m *CompositeProperty) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ return xxx_messageInfo_CompositeProperty.Marshal(b, m, deterministic)
+}
+func (dst *CompositeProperty) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_CompositeProperty.Merge(dst, src)
+}
+func (m *CompositeProperty) XXX_Size() int {
+ return xxx_messageInfo_CompositeProperty.Size(m)
+}
+func (m *CompositeProperty) XXX_DiscardUnknown() {
+ xxx_messageInfo_CompositeProperty.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_CompositeProperty proto.InternalMessageInfo
+
+func (m *CompositeProperty) GetIndexId() int64 {
+ if m != nil && m.IndexId != nil {
+ return *m.IndexId
+ }
+ return 0
+}
+
+func (m *CompositeProperty) GetValue() []string {
+ if m != nil {
+ return m.Value
+ }
+ return nil
+}
+
+type Index struct {
+ EntityType *string `protobuf:"bytes,1,req,name=entity_type,json=entityType" json:"entity_type,omitempty"`
+ Ancestor *bool `protobuf:"varint,5,req,name=ancestor" json:"ancestor,omitempty"`
+ Property []*Index_Property `protobuf:"group,2,rep,name=Property,json=property" json:"property,omitempty"`
+ XXX_NoUnkeyedLiteral struct{} `json:"-"`
+ XXX_unrecognized []byte `json:"-"`
+ XXX_sizecache int32 `json:"-"`
+}
+
+func (m *Index) Reset() { *m = Index{} }
+func (m *Index) String() string { return proto.CompactTextString(m) }
+func (*Index) ProtoMessage() {}
+func (*Index) Descriptor() ([]byte, []int) {
+ return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{8}
+}
+func (m *Index) XXX_Unmarshal(b []byte) error {
+ return xxx_messageInfo_Index.Unmarshal(m, b)
+}
+func (m *Index) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ return xxx_messageInfo_Index.Marshal(b, m, deterministic)
+}
+func (dst *Index) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_Index.Merge(dst, src)
+}
+func (m *Index) XXX_Size() int {
+ return xxx_messageInfo_Index.Size(m)
+}
+func (m *Index) XXX_DiscardUnknown() {
+ xxx_messageInfo_Index.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_Index proto.InternalMessageInfo
+
+func (m *Index) GetEntityType() string {
+ if m != nil && m.EntityType != nil {
+ return *m.EntityType
+ }
+ return ""
+}
+
+func (m *Index) GetAncestor() bool {
+ if m != nil && m.Ancestor != nil {
+ return *m.Ancestor
+ }
+ return false
+}
+
+func (m *Index) GetProperty() []*Index_Property {
+ if m != nil {
+ return m.Property
+ }
+ return nil
+}
+
+type Index_Property struct {
+ Name *string `protobuf:"bytes,3,req,name=name" json:"name,omitempty"`
+ Direction *Index_Property_Direction `protobuf:"varint,4,opt,name=direction,enum=appengine.Index_Property_Direction,def=1" json:"direction,omitempty"`
+ XXX_NoUnkeyedLiteral struct{} `json:"-"`
+ XXX_unrecognized []byte `json:"-"`
+ XXX_sizecache int32 `json:"-"`
+}
+
+func (m *Index_Property) Reset() { *m = Index_Property{} }
+func (m *Index_Property) String() string { return proto.CompactTextString(m) }
+func (*Index_Property) ProtoMessage() {}
+func (*Index_Property) Descriptor() ([]byte, []int) {
+ return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{8, 0}
+}
+func (m *Index_Property) XXX_Unmarshal(b []byte) error {
+ return xxx_messageInfo_Index_Property.Unmarshal(m, b)
+}
+func (m *Index_Property) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ return xxx_messageInfo_Index_Property.Marshal(b, m, deterministic)
+}
+func (dst *Index_Property) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_Index_Property.Merge(dst, src)
+}
+func (m *Index_Property) XXX_Size() int {
+ return xxx_messageInfo_Index_Property.Size(m)
+}
+func (m *Index_Property) XXX_DiscardUnknown() {
+ xxx_messageInfo_Index_Property.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_Index_Property proto.InternalMessageInfo
+
+const Default_Index_Property_Direction Index_Property_Direction = Index_Property_ASCENDING
+
+func (m *Index_Property) GetName() string {
+ if m != nil && m.Name != nil {
+ return *m.Name
+ }
+ return ""
+}
+
+func (m *Index_Property) GetDirection() Index_Property_Direction {
+ if m != nil && m.Direction != nil {
+ return *m.Direction
+ }
+ return Default_Index_Property_Direction
+}
+
+type CompositeIndex struct {
+ AppId *string `protobuf:"bytes,1,req,name=app_id,json=appId" json:"app_id,omitempty"`
+ Id *int64 `protobuf:"varint,2,req,name=id" json:"id,omitempty"`
+ Definition *Index `protobuf:"bytes,3,req,name=definition" json:"definition,omitempty"`
+ State *CompositeIndex_State `protobuf:"varint,4,req,name=state,enum=appengine.CompositeIndex_State" json:"state,omitempty"`
+ OnlyUseIfRequired *bool `protobuf:"varint,6,opt,name=only_use_if_required,json=onlyUseIfRequired,def=0" json:"only_use_if_required,omitempty"`
+ XXX_NoUnkeyedLiteral struct{} `json:"-"`
+ XXX_unrecognized []byte `json:"-"`
+ XXX_sizecache int32 `json:"-"`
+}
+
+func (m *CompositeIndex) Reset() { *m = CompositeIndex{} }
+func (m *CompositeIndex) String() string { return proto.CompactTextString(m) }
+func (*CompositeIndex) ProtoMessage() {}
+func (*CompositeIndex) Descriptor() ([]byte, []int) {
+ return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{9}
+}
+func (m *CompositeIndex) XXX_Unmarshal(b []byte) error {
+ return xxx_messageInfo_CompositeIndex.Unmarshal(m, b)
+}
+func (m *CompositeIndex) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ return xxx_messageInfo_CompositeIndex.Marshal(b, m, deterministic)
+}
+func (dst *CompositeIndex) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_CompositeIndex.Merge(dst, src)
+}
+func (m *CompositeIndex) XXX_Size() int {
+ return xxx_messageInfo_CompositeIndex.Size(m)
+}
+func (m *CompositeIndex) XXX_DiscardUnknown() {
+ xxx_messageInfo_CompositeIndex.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_CompositeIndex proto.InternalMessageInfo
+
+const Default_CompositeIndex_OnlyUseIfRequired bool = false
+
+func (m *CompositeIndex) GetAppId() string {
+ if m != nil && m.AppId != nil {
+ return *m.AppId
+ }
+ return ""
+}
+
+func (m *CompositeIndex) GetId() int64 {
+ if m != nil && m.Id != nil {
+ return *m.Id
+ }
+ return 0
+}
+
+func (m *CompositeIndex) GetDefinition() *Index {
+ if m != nil {
+ return m.Definition
+ }
+ return nil
+}
+
+func (m *CompositeIndex) GetState() CompositeIndex_State {
+ if m != nil && m.State != nil {
+ return *m.State
+ }
+ return CompositeIndex_WRITE_ONLY
+}
+
+func (m *CompositeIndex) GetOnlyUseIfRequired() bool {
+ if m != nil && m.OnlyUseIfRequired != nil {
+ return *m.OnlyUseIfRequired
+ }
+ return Default_CompositeIndex_OnlyUseIfRequired
+}
+
+type IndexPostfix struct {
+ IndexValue []*IndexPostfix_IndexValue `protobuf:"bytes,1,rep,name=index_value,json=indexValue" json:"index_value,omitempty"`
+ Key *Reference `protobuf:"bytes,2,opt,name=key" json:"key,omitempty"`
+ Before *bool `protobuf:"varint,3,opt,name=before,def=1" json:"before,omitempty"`
+ XXX_NoUnkeyedLiteral struct{} `json:"-"`
+ XXX_unrecognized []byte `json:"-"`
+ XXX_sizecache int32 `json:"-"`
+}
+
+func (m *IndexPostfix) Reset() { *m = IndexPostfix{} }
+func (m *IndexPostfix) String() string { return proto.CompactTextString(m) }
+func (*IndexPostfix) ProtoMessage() {}
+func (*IndexPostfix) Descriptor() ([]byte, []int) {
+ return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{10}
+}
+func (m *IndexPostfix) XXX_Unmarshal(b []byte) error {
+ return xxx_messageInfo_IndexPostfix.Unmarshal(m, b)
+}
+func (m *IndexPostfix) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ return xxx_messageInfo_IndexPostfix.Marshal(b, m, deterministic)
+}
+func (dst *IndexPostfix) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_IndexPostfix.Merge(dst, src)
+}
+func (m *IndexPostfix) XXX_Size() int {
+ return xxx_messageInfo_IndexPostfix.Size(m)
+}
+func (m *IndexPostfix) XXX_DiscardUnknown() {
+ xxx_messageInfo_IndexPostfix.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_IndexPostfix proto.InternalMessageInfo
+
+const Default_IndexPostfix_Before bool = true
+
+func (m *IndexPostfix) GetIndexValue() []*IndexPostfix_IndexValue {
+ if m != nil {
+ return m.IndexValue
+ }
+ return nil
+}
+
+func (m *IndexPostfix) GetKey() *Reference {
+ if m != nil {
+ return m.Key
+ }
+ return nil
+}
+
+func (m *IndexPostfix) GetBefore() bool {
+ if m != nil && m.Before != nil {
+ return *m.Before
+ }
+ return Default_IndexPostfix_Before
+}
+
+type IndexPostfix_IndexValue struct {
+ PropertyName *string `protobuf:"bytes,1,req,name=property_name,json=propertyName" json:"property_name,omitempty"`
+ Value *PropertyValue `protobuf:"bytes,2,req,name=value" json:"value,omitempty"`
+ XXX_NoUnkeyedLiteral struct{} `json:"-"`
+ XXX_unrecognized []byte `json:"-"`
+ XXX_sizecache int32 `json:"-"`
+}
+
+func (m *IndexPostfix_IndexValue) Reset() { *m = IndexPostfix_IndexValue{} }
+func (m *IndexPostfix_IndexValue) String() string { return proto.CompactTextString(m) }
+func (*IndexPostfix_IndexValue) ProtoMessage() {}
+func (*IndexPostfix_IndexValue) Descriptor() ([]byte, []int) {
+ return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{10, 0}
+}
+func (m *IndexPostfix_IndexValue) XXX_Unmarshal(b []byte) error {
+ return xxx_messageInfo_IndexPostfix_IndexValue.Unmarshal(m, b)
+}
+func (m *IndexPostfix_IndexValue) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ return xxx_messageInfo_IndexPostfix_IndexValue.Marshal(b, m, deterministic)
+}
+func (dst *IndexPostfix_IndexValue) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_IndexPostfix_IndexValue.Merge(dst, src)
+}
+func (m *IndexPostfix_IndexValue) XXX_Size() int {
+ return xxx_messageInfo_IndexPostfix_IndexValue.Size(m)
+}
+func (m *IndexPostfix_IndexValue) XXX_DiscardUnknown() {
+ xxx_messageInfo_IndexPostfix_IndexValue.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_IndexPostfix_IndexValue proto.InternalMessageInfo
+
+func (m *IndexPostfix_IndexValue) GetPropertyName() string {
+ if m != nil && m.PropertyName != nil {
+ return *m.PropertyName
+ }
+ return ""
+}
+
+func (m *IndexPostfix_IndexValue) GetValue() *PropertyValue {
+ if m != nil {
+ return m.Value
+ }
+ return nil
+}
+
+type IndexPosition struct {
+ Key *string `protobuf:"bytes,1,opt,name=key" json:"key,omitempty"`
+ Before *bool `protobuf:"varint,2,opt,name=before,def=1" json:"before,omitempty"`
+ XXX_NoUnkeyedLiteral struct{} `json:"-"`
+ XXX_unrecognized []byte `json:"-"`
+ XXX_sizecache int32 `json:"-"`
+}
+
+func (m *IndexPosition) Reset() { *m = IndexPosition{} }
+func (m *IndexPosition) String() string { return proto.CompactTextString(m) }
+func (*IndexPosition) ProtoMessage() {}
+func (*IndexPosition) Descriptor() ([]byte, []int) {
+ return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{11}
+}
+func (m *IndexPosition) XXX_Unmarshal(b []byte) error {
+ return xxx_messageInfo_IndexPosition.Unmarshal(m, b)
+}
+func (m *IndexPosition) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ return xxx_messageInfo_IndexPosition.Marshal(b, m, deterministic)
+}
+func (dst *IndexPosition) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_IndexPosition.Merge(dst, src)
+}
+func (m *IndexPosition) XXX_Size() int {
+ return xxx_messageInfo_IndexPosition.Size(m)
+}
+func (m *IndexPosition) XXX_DiscardUnknown() {
+ xxx_messageInfo_IndexPosition.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_IndexPosition proto.InternalMessageInfo
+
+const Default_IndexPosition_Before bool = true
+
+func (m *IndexPosition) GetKey() string {
+ if m != nil && m.Key != nil {
+ return *m.Key
+ }
+ return ""
+}
+
+func (m *IndexPosition) GetBefore() bool {
+ if m != nil && m.Before != nil {
+ return *m.Before
+ }
+ return Default_IndexPosition_Before
+}
+
+type Snapshot struct {
+ Ts *int64 `protobuf:"varint,1,req,name=ts" json:"ts,omitempty"`
+ XXX_NoUnkeyedLiteral struct{} `json:"-"`
+ XXX_unrecognized []byte `json:"-"`
+ XXX_sizecache int32 `json:"-"`
+}
+
+func (m *Snapshot) Reset() { *m = Snapshot{} }
+func (m *Snapshot) String() string { return proto.CompactTextString(m) }
+func (*Snapshot) ProtoMessage() {}
+func (*Snapshot) Descriptor() ([]byte, []int) {
+ return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{12}
+}
+func (m *Snapshot) XXX_Unmarshal(b []byte) error {
+ return xxx_messageInfo_Snapshot.Unmarshal(m, b)
+}
+func (m *Snapshot) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ return xxx_messageInfo_Snapshot.Marshal(b, m, deterministic)
+}
+func (dst *Snapshot) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_Snapshot.Merge(dst, src)
+}
+func (m *Snapshot) XXX_Size() int {
+ return xxx_messageInfo_Snapshot.Size(m)
+}
+func (m *Snapshot) XXX_DiscardUnknown() {
+ xxx_messageInfo_Snapshot.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_Snapshot proto.InternalMessageInfo
+
+func (m *Snapshot) GetTs() int64 {
+ if m != nil && m.Ts != nil {
+ return *m.Ts
+ }
+ return 0
+}
+
+type InternalHeader struct {
+ Qos *string `protobuf:"bytes,1,opt,name=qos" json:"qos,omitempty"`
+ XXX_NoUnkeyedLiteral struct{} `json:"-"`
+ XXX_unrecognized []byte `json:"-"`
+ XXX_sizecache int32 `json:"-"`
+}
+
+func (m *InternalHeader) Reset() { *m = InternalHeader{} }
+func (m *InternalHeader) String() string { return proto.CompactTextString(m) }
+func (*InternalHeader) ProtoMessage() {}
+func (*InternalHeader) Descriptor() ([]byte, []int) {
+ return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{13}
+}
+func (m *InternalHeader) XXX_Unmarshal(b []byte) error {
+ return xxx_messageInfo_InternalHeader.Unmarshal(m, b)
+}
+func (m *InternalHeader) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ return xxx_messageInfo_InternalHeader.Marshal(b, m, deterministic)
+}
+func (dst *InternalHeader) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_InternalHeader.Merge(dst, src)
+}
+func (m *InternalHeader) XXX_Size() int {
+ return xxx_messageInfo_InternalHeader.Size(m)
+}
+func (m *InternalHeader) XXX_DiscardUnknown() {
+ xxx_messageInfo_InternalHeader.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_InternalHeader proto.InternalMessageInfo
+
+func (m *InternalHeader) GetQos() string {
+ if m != nil && m.Qos != nil {
+ return *m.Qos
+ }
+ return ""
+}
+
+type Transaction struct {
+ Header *InternalHeader `protobuf:"bytes,4,opt,name=header" json:"header,omitempty"`
+ Handle *uint64 `protobuf:"fixed64,1,req,name=handle" json:"handle,omitempty"`
+ App *string `protobuf:"bytes,2,req,name=app" json:"app,omitempty"`
+ MarkChanges *bool `protobuf:"varint,3,opt,name=mark_changes,json=markChanges,def=0" json:"mark_changes,omitempty"`
+ XXX_NoUnkeyedLiteral struct{} `json:"-"`
+ XXX_unrecognized []byte `json:"-"`
+ XXX_sizecache int32 `json:"-"`
+}
+
+func (m *Transaction) Reset() { *m = Transaction{} }
+func (m *Transaction) String() string { return proto.CompactTextString(m) }
+func (*Transaction) ProtoMessage() {}
+func (*Transaction) Descriptor() ([]byte, []int) {
+ return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{14}
+}
+func (m *Transaction) XXX_Unmarshal(b []byte) error {
+ return xxx_messageInfo_Transaction.Unmarshal(m, b)
+}
+func (m *Transaction) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ return xxx_messageInfo_Transaction.Marshal(b, m, deterministic)
+}
+func (dst *Transaction) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_Transaction.Merge(dst, src)
+}
+func (m *Transaction) XXX_Size() int {
+ return xxx_messageInfo_Transaction.Size(m)
+}
+func (m *Transaction) XXX_DiscardUnknown() {
+ xxx_messageInfo_Transaction.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_Transaction proto.InternalMessageInfo
+
+const Default_Transaction_MarkChanges bool = false
+
+func (m *Transaction) GetHeader() *InternalHeader {
+ if m != nil {
+ return m.Header
+ }
+ return nil
+}
+
+func (m *Transaction) GetHandle() uint64 {
+ if m != nil && m.Handle != nil {
+ return *m.Handle
+ }
+ return 0
+}
+
+func (m *Transaction) GetApp() string {
+ if m != nil && m.App != nil {
+ return *m.App
+ }
+ return ""
+}
+
+func (m *Transaction) GetMarkChanges() bool {
+ if m != nil && m.MarkChanges != nil {
+ return *m.MarkChanges
+ }
+ return Default_Transaction_MarkChanges
+}
+
+type Query struct {
+ Header *InternalHeader `protobuf:"bytes,39,opt,name=header" json:"header,omitempty"`
+ App *string `protobuf:"bytes,1,req,name=app" json:"app,omitempty"`
+ NameSpace *string `protobuf:"bytes,29,opt,name=name_space,json=nameSpace" json:"name_space,omitempty"`
+ Kind *string `protobuf:"bytes,3,opt,name=kind" json:"kind,omitempty"`
+ Ancestor *Reference `protobuf:"bytes,17,opt,name=ancestor" json:"ancestor,omitempty"`
+ Filter []*Query_Filter `protobuf:"group,4,rep,name=Filter,json=filter" json:"filter,omitempty"`
+ SearchQuery *string `protobuf:"bytes,8,opt,name=search_query,json=searchQuery" json:"search_query,omitempty"`
+ Order []*Query_Order `protobuf:"group,9,rep,name=Order,json=order" json:"order,omitempty"`
+ Hint *Query_Hint `protobuf:"varint,18,opt,name=hint,enum=appengine.Query_Hint" json:"hint,omitempty"`
+ Count *int32 `protobuf:"varint,23,opt,name=count" json:"count,omitempty"`
+ Offset *int32 `protobuf:"varint,12,opt,name=offset,def=0" json:"offset,omitempty"`
+ Limit *int32 `protobuf:"varint,16,opt,name=limit" json:"limit,omitempty"`
+ CompiledCursor *CompiledCursor `protobuf:"bytes,30,opt,name=compiled_cursor,json=compiledCursor" json:"compiled_cursor,omitempty"`
+ EndCompiledCursor *CompiledCursor `protobuf:"bytes,31,opt,name=end_compiled_cursor,json=endCompiledCursor" json:"end_compiled_cursor,omitempty"`
+ CompositeIndex []*CompositeIndex `protobuf:"bytes,19,rep,name=composite_index,json=compositeIndex" json:"composite_index,omitempty"`
+ RequirePerfectPlan *bool `protobuf:"varint,20,opt,name=require_perfect_plan,json=requirePerfectPlan,def=0" json:"require_perfect_plan,omitempty"`
+ KeysOnly *bool `protobuf:"varint,21,opt,name=keys_only,json=keysOnly,def=0" json:"keys_only,omitempty"`
+ Transaction *Transaction `protobuf:"bytes,22,opt,name=transaction" json:"transaction,omitempty"`
+ Compile *bool `protobuf:"varint,25,opt,name=compile,def=0" json:"compile,omitempty"`
+ FailoverMs *int64 `protobuf:"varint,26,opt,name=failover_ms,json=failoverMs" json:"failover_ms,omitempty"`
+ Strong *bool `protobuf:"varint,32,opt,name=strong" json:"strong,omitempty"`
+ PropertyName []string `protobuf:"bytes,33,rep,name=property_name,json=propertyName" json:"property_name,omitempty"`
+ GroupByPropertyName []string `protobuf:"bytes,34,rep,name=group_by_property_name,json=groupByPropertyName" json:"group_by_property_name,omitempty"`
+ Distinct *bool `protobuf:"varint,24,opt,name=distinct" json:"distinct,omitempty"`
+ MinSafeTimeSeconds *int64 `protobuf:"varint,35,opt,name=min_safe_time_seconds,json=minSafeTimeSeconds" json:"min_safe_time_seconds,omitempty"`
+ SafeReplicaName []string `protobuf:"bytes,36,rep,name=safe_replica_name,json=safeReplicaName" json:"safe_replica_name,omitempty"`
+ PersistOffset *bool `protobuf:"varint,37,opt,name=persist_offset,json=persistOffset,def=0" json:"persist_offset,omitempty"`
+ XXX_NoUnkeyedLiteral struct{} `json:"-"`
+ XXX_unrecognized []byte `json:"-"`
+ XXX_sizecache int32 `json:"-"`
+}
+
+func (m *Query) Reset() { *m = Query{} }
+func (m *Query) String() string { return proto.CompactTextString(m) }
+func (*Query) ProtoMessage() {}
+func (*Query) Descriptor() ([]byte, []int) {
+ return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{15}
+}
+func (m *Query) XXX_Unmarshal(b []byte) error {
+ return xxx_messageInfo_Query.Unmarshal(m, b)
+}
+func (m *Query) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ return xxx_messageInfo_Query.Marshal(b, m, deterministic)
+}
+func (dst *Query) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_Query.Merge(dst, src)
+}
+func (m *Query) XXX_Size() int {
+ return xxx_messageInfo_Query.Size(m)
+}
+func (m *Query) XXX_DiscardUnknown() {
+ xxx_messageInfo_Query.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_Query proto.InternalMessageInfo
+
+const Default_Query_Offset int32 = 0
+const Default_Query_RequirePerfectPlan bool = false
+const Default_Query_KeysOnly bool = false
+const Default_Query_Compile bool = false
+const Default_Query_PersistOffset bool = false
+
+func (m *Query) GetHeader() *InternalHeader {
+ if m != nil {
+ return m.Header
+ }
+ return nil
+}
+
+func (m *Query) GetApp() string {
+ if m != nil && m.App != nil {
+ return *m.App
+ }
+ return ""
+}
+
+func (m *Query) GetNameSpace() string {
+ if m != nil && m.NameSpace != nil {
+ return *m.NameSpace
+ }
+ return ""
+}
+
+func (m *Query) GetKind() string {
+ if m != nil && m.Kind != nil {
+ return *m.Kind
+ }
+ return ""
+}
+
+func (m *Query) GetAncestor() *Reference {
+ if m != nil {
+ return m.Ancestor
+ }
+ return nil
+}
+
+func (m *Query) GetFilter() []*Query_Filter {
+ if m != nil {
+ return m.Filter
+ }
+ return nil
+}
+
+func (m *Query) GetSearchQuery() string {
+ if m != nil && m.SearchQuery != nil {
+ return *m.SearchQuery
+ }
+ return ""
+}
+
+func (m *Query) GetOrder() []*Query_Order {
+ if m != nil {
+ return m.Order
+ }
+ return nil
+}
+
+func (m *Query) GetHint() Query_Hint {
+ if m != nil && m.Hint != nil {
+ return *m.Hint
+ }
+ return Query_ORDER_FIRST
+}
+
+func (m *Query) GetCount() int32 {
+ if m != nil && m.Count != nil {
+ return *m.Count
+ }
+ return 0
+}
+
+func (m *Query) GetOffset() int32 {
+ if m != nil && m.Offset != nil {
+ return *m.Offset
+ }
+ return Default_Query_Offset
+}
+
+func (m *Query) GetLimit() int32 {
+ if m != nil && m.Limit != nil {
+ return *m.Limit
+ }
+ return 0
+}
+
+func (m *Query) GetCompiledCursor() *CompiledCursor {
+ if m != nil {
+ return m.CompiledCursor
+ }
+ return nil
+}
+
+func (m *Query) GetEndCompiledCursor() *CompiledCursor {
+ if m != nil {
+ return m.EndCompiledCursor
+ }
+ return nil
+}
+
+func (m *Query) GetCompositeIndex() []*CompositeIndex {
+ if m != nil {
+ return m.CompositeIndex
+ }
+ return nil
+}
+
+func (m *Query) GetRequirePerfectPlan() bool {
+ if m != nil && m.RequirePerfectPlan != nil {
+ return *m.RequirePerfectPlan
+ }
+ return Default_Query_RequirePerfectPlan
+}
+
+func (m *Query) GetKeysOnly() bool {
+ if m != nil && m.KeysOnly != nil {
+ return *m.KeysOnly
+ }
+ return Default_Query_KeysOnly
+}
+
+func (m *Query) GetTransaction() *Transaction {
+ if m != nil {
+ return m.Transaction
+ }
+ return nil
+}
+
+func (m *Query) GetCompile() bool {
+ if m != nil && m.Compile != nil {
+ return *m.Compile
+ }
+ return Default_Query_Compile
+}
+
+func (m *Query) GetFailoverMs() int64 {
+ if m != nil && m.FailoverMs != nil {
+ return *m.FailoverMs
+ }
+ return 0
+}
+
+func (m *Query) GetStrong() bool {
+ if m != nil && m.Strong != nil {
+ return *m.Strong
+ }
+ return false
+}
+
+func (m *Query) GetPropertyName() []string {
+ if m != nil {
+ return m.PropertyName
+ }
+ return nil
+}
+
+func (m *Query) GetGroupByPropertyName() []string {
+ if m != nil {
+ return m.GroupByPropertyName
+ }
+ return nil
+}
+
+func (m *Query) GetDistinct() bool {
+ if m != nil && m.Distinct != nil {
+ return *m.Distinct
+ }
+ return false
+}
+
+func (m *Query) GetMinSafeTimeSeconds() int64 {
+ if m != nil && m.MinSafeTimeSeconds != nil {
+ return *m.MinSafeTimeSeconds
+ }
+ return 0
+}
+
+func (m *Query) GetSafeReplicaName() []string {
+ if m != nil {
+ return m.SafeReplicaName
+ }
+ return nil
+}
+
+func (m *Query) GetPersistOffset() bool {
+ if m != nil && m.PersistOffset != nil {
+ return *m.PersistOffset
+ }
+ return Default_Query_PersistOffset
+}
+
+type Query_Filter struct {
+ Op *Query_Filter_Operator `protobuf:"varint,6,req,name=op,enum=appengine.Query_Filter_Operator" json:"op,omitempty"`
+ Property []*Property `protobuf:"bytes,14,rep,name=property" json:"property,omitempty"`
+ XXX_NoUnkeyedLiteral struct{} `json:"-"`
+ XXX_unrecognized []byte `json:"-"`
+ XXX_sizecache int32 `json:"-"`
+}
+
+func (m *Query_Filter) Reset() { *m = Query_Filter{} }
+func (m *Query_Filter) String() string { return proto.CompactTextString(m) }
+func (*Query_Filter) ProtoMessage() {}
+func (*Query_Filter) Descriptor() ([]byte, []int) {
+ return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{15, 0}
+}
+func (m *Query_Filter) XXX_Unmarshal(b []byte) error {
+ return xxx_messageInfo_Query_Filter.Unmarshal(m, b)
+}
+func (m *Query_Filter) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ return xxx_messageInfo_Query_Filter.Marshal(b, m, deterministic)
+}
+func (dst *Query_Filter) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_Query_Filter.Merge(dst, src)
+}
+func (m *Query_Filter) XXX_Size() int {
+ return xxx_messageInfo_Query_Filter.Size(m)
+}
+func (m *Query_Filter) XXX_DiscardUnknown() {
+ xxx_messageInfo_Query_Filter.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_Query_Filter proto.InternalMessageInfo
+
+func (m *Query_Filter) GetOp() Query_Filter_Operator {
+ if m != nil && m.Op != nil {
+ return *m.Op
+ }
+ return Query_Filter_LESS_THAN
+}
+
+func (m *Query_Filter) GetProperty() []*Property {
+ if m != nil {
+ return m.Property
+ }
+ return nil
+}
+
+type Query_Order struct {
+ Property *string `protobuf:"bytes,10,req,name=property" json:"property,omitempty"`
+ Direction *Query_Order_Direction `protobuf:"varint,11,opt,name=direction,enum=appengine.Query_Order_Direction,def=1" json:"direction,omitempty"`
+ XXX_NoUnkeyedLiteral struct{} `json:"-"`
+ XXX_unrecognized []byte `json:"-"`
+ XXX_sizecache int32 `json:"-"`
+}
+
+func (m *Query_Order) Reset() { *m = Query_Order{} }
+func (m *Query_Order) String() string { return proto.CompactTextString(m) }
+func (*Query_Order) ProtoMessage() {}
+func (*Query_Order) Descriptor() ([]byte, []int) {
+ return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{15, 1}
+}
+func (m *Query_Order) XXX_Unmarshal(b []byte) error {
+ return xxx_messageInfo_Query_Order.Unmarshal(m, b)
+}
+func (m *Query_Order) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ return xxx_messageInfo_Query_Order.Marshal(b, m, deterministic)
+}
+func (dst *Query_Order) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_Query_Order.Merge(dst, src)
+}
+func (m *Query_Order) XXX_Size() int {
+ return xxx_messageInfo_Query_Order.Size(m)
+}
+func (m *Query_Order) XXX_DiscardUnknown() {
+ xxx_messageInfo_Query_Order.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_Query_Order proto.InternalMessageInfo
+
+const Default_Query_Order_Direction Query_Order_Direction = Query_Order_ASCENDING
+
+func (m *Query_Order) GetProperty() string {
+ if m != nil && m.Property != nil {
+ return *m.Property
+ }
+ return ""
+}
+
+func (m *Query_Order) GetDirection() Query_Order_Direction {
+ if m != nil && m.Direction != nil {
+ return *m.Direction
+ }
+ return Default_Query_Order_Direction
+}
+
+type CompiledQuery struct {
+ Primaryscan *CompiledQuery_PrimaryScan `protobuf:"group,1,req,name=PrimaryScan,json=primaryscan" json:"primaryscan,omitempty"`
+ Mergejoinscan []*CompiledQuery_MergeJoinScan `protobuf:"group,7,rep,name=MergeJoinScan,json=mergejoinscan" json:"mergejoinscan,omitempty"`
+ IndexDef *Index `protobuf:"bytes,21,opt,name=index_def,json=indexDef" json:"index_def,omitempty"`
+ Offset *int32 `protobuf:"varint,10,opt,name=offset,def=0" json:"offset,omitempty"`
+ Limit *int32 `protobuf:"varint,11,opt,name=limit" json:"limit,omitempty"`
+ KeysOnly *bool `protobuf:"varint,12,req,name=keys_only,json=keysOnly" json:"keys_only,omitempty"`
+ PropertyName []string `protobuf:"bytes,24,rep,name=property_name,json=propertyName" json:"property_name,omitempty"`
+ DistinctInfixSize *int32 `protobuf:"varint,25,opt,name=distinct_infix_size,json=distinctInfixSize" json:"distinct_infix_size,omitempty"`
+ Entityfilter *CompiledQuery_EntityFilter `protobuf:"group,13,opt,name=EntityFilter,json=entityfilter" json:"entityfilter,omitempty"`
+ XXX_NoUnkeyedLiteral struct{} `json:"-"`
+ XXX_unrecognized []byte `json:"-"`
+ XXX_sizecache int32 `json:"-"`
+}
+
+func (m *CompiledQuery) Reset() { *m = CompiledQuery{} }
+func (m *CompiledQuery) String() string { return proto.CompactTextString(m) }
+func (*CompiledQuery) ProtoMessage() {}
+func (*CompiledQuery) Descriptor() ([]byte, []int) {
+ return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{16}
+}
+func (m *CompiledQuery) XXX_Unmarshal(b []byte) error {
+ return xxx_messageInfo_CompiledQuery.Unmarshal(m, b)
+}
+func (m *CompiledQuery) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ return xxx_messageInfo_CompiledQuery.Marshal(b, m, deterministic)
+}
+func (dst *CompiledQuery) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_CompiledQuery.Merge(dst, src)
+}
+func (m *CompiledQuery) XXX_Size() int {
+ return xxx_messageInfo_CompiledQuery.Size(m)
+}
+func (m *CompiledQuery) XXX_DiscardUnknown() {
+ xxx_messageInfo_CompiledQuery.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_CompiledQuery proto.InternalMessageInfo
+
+const Default_CompiledQuery_Offset int32 = 0
+
+func (m *CompiledQuery) GetPrimaryscan() *CompiledQuery_PrimaryScan {
+ if m != nil {
+ return m.Primaryscan
+ }
+ return nil
+}
+
+func (m *CompiledQuery) GetMergejoinscan() []*CompiledQuery_MergeJoinScan {
+ if m != nil {
+ return m.Mergejoinscan
+ }
+ return nil
+}
+
+func (m *CompiledQuery) GetIndexDef() *Index {
+ if m != nil {
+ return m.IndexDef
+ }
+ return nil
+}
+
+func (m *CompiledQuery) GetOffset() int32 {
+ if m != nil && m.Offset != nil {
+ return *m.Offset
+ }
+ return Default_CompiledQuery_Offset
+}
+
+func (m *CompiledQuery) GetLimit() int32 {
+ if m != nil && m.Limit != nil {
+ return *m.Limit
+ }
+ return 0
+}
+
+func (m *CompiledQuery) GetKeysOnly() bool {
+ if m != nil && m.KeysOnly != nil {
+ return *m.KeysOnly
+ }
+ return false
+}
+
+func (m *CompiledQuery) GetPropertyName() []string {
+ if m != nil {
+ return m.PropertyName
+ }
+ return nil
+}
+
+func (m *CompiledQuery) GetDistinctInfixSize() int32 {
+ if m != nil && m.DistinctInfixSize != nil {
+ return *m.DistinctInfixSize
+ }
+ return 0
+}
+
+func (m *CompiledQuery) GetEntityfilter() *CompiledQuery_EntityFilter {
+ if m != nil {
+ return m.Entityfilter
+ }
+ return nil
+}
+
+type CompiledQuery_PrimaryScan struct {
+ IndexName *string `protobuf:"bytes,2,opt,name=index_name,json=indexName" json:"index_name,omitempty"`
+ StartKey *string `protobuf:"bytes,3,opt,name=start_key,json=startKey" json:"start_key,omitempty"`
+ StartInclusive *bool `protobuf:"varint,4,opt,name=start_inclusive,json=startInclusive" json:"start_inclusive,omitempty"`
+ EndKey *string `protobuf:"bytes,5,opt,name=end_key,json=endKey" json:"end_key,omitempty"`
+ EndInclusive *bool `protobuf:"varint,6,opt,name=end_inclusive,json=endInclusive" json:"end_inclusive,omitempty"`
+ StartPostfixValue []string `protobuf:"bytes,22,rep,name=start_postfix_value,json=startPostfixValue" json:"start_postfix_value,omitempty"`
+ EndPostfixValue []string `protobuf:"bytes,23,rep,name=end_postfix_value,json=endPostfixValue" json:"end_postfix_value,omitempty"`
+ EndUnappliedLogTimestampUs *int64 `protobuf:"varint,19,opt,name=end_unapplied_log_timestamp_us,json=endUnappliedLogTimestampUs" json:"end_unapplied_log_timestamp_us,omitempty"`
+ XXX_NoUnkeyedLiteral struct{} `json:"-"`
+ XXX_unrecognized []byte `json:"-"`
+ XXX_sizecache int32 `json:"-"`
+}
+
+func (m *CompiledQuery_PrimaryScan) Reset() { *m = CompiledQuery_PrimaryScan{} }
+func (m *CompiledQuery_PrimaryScan) String() string { return proto.CompactTextString(m) }
+func (*CompiledQuery_PrimaryScan) ProtoMessage() {}
+func (*CompiledQuery_PrimaryScan) Descriptor() ([]byte, []int) {
+ return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{16, 0}
+}
+func (m *CompiledQuery_PrimaryScan) XXX_Unmarshal(b []byte) error {
+ return xxx_messageInfo_CompiledQuery_PrimaryScan.Unmarshal(m, b)
+}
+func (m *CompiledQuery_PrimaryScan) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ return xxx_messageInfo_CompiledQuery_PrimaryScan.Marshal(b, m, deterministic)
+}
+func (dst *CompiledQuery_PrimaryScan) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_CompiledQuery_PrimaryScan.Merge(dst, src)
+}
+func (m *CompiledQuery_PrimaryScan) XXX_Size() int {
+ return xxx_messageInfo_CompiledQuery_PrimaryScan.Size(m)
+}
+func (m *CompiledQuery_PrimaryScan) XXX_DiscardUnknown() {
+ xxx_messageInfo_CompiledQuery_PrimaryScan.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_CompiledQuery_PrimaryScan proto.InternalMessageInfo
+
+func (m *CompiledQuery_PrimaryScan) GetIndexName() string {
+ if m != nil && m.IndexName != nil {
+ return *m.IndexName
+ }
+ return ""
+}
+
+func (m *CompiledQuery_PrimaryScan) GetStartKey() string {
+ if m != nil && m.StartKey != nil {
+ return *m.StartKey
+ }
+ return ""
+}
+
+func (m *CompiledQuery_PrimaryScan) GetStartInclusive() bool {
+ if m != nil && m.StartInclusive != nil {
+ return *m.StartInclusive
+ }
+ return false
+}
+
+func (m *CompiledQuery_PrimaryScan) GetEndKey() string {
+ if m != nil && m.EndKey != nil {
+ return *m.EndKey
+ }
+ return ""
+}
+
+func (m *CompiledQuery_PrimaryScan) GetEndInclusive() bool {
+ if m != nil && m.EndInclusive != nil {
+ return *m.EndInclusive
+ }
+ return false
+}
+
+func (m *CompiledQuery_PrimaryScan) GetStartPostfixValue() []string {
+ if m != nil {
+ return m.StartPostfixValue
+ }
+ return nil
+}
+
+func (m *CompiledQuery_PrimaryScan) GetEndPostfixValue() []string {
+ if m != nil {
+ return m.EndPostfixValue
+ }
+ return nil
+}
+
+func (m *CompiledQuery_PrimaryScan) GetEndUnappliedLogTimestampUs() int64 {
+ if m != nil && m.EndUnappliedLogTimestampUs != nil {
+ return *m.EndUnappliedLogTimestampUs
+ }
+ return 0
+}
+
+type CompiledQuery_MergeJoinScan struct {
+ IndexName *string `protobuf:"bytes,8,req,name=index_name,json=indexName" json:"index_name,omitempty"`
+ PrefixValue []string `protobuf:"bytes,9,rep,name=prefix_value,json=prefixValue" json:"prefix_value,omitempty"`
+ ValuePrefix *bool `protobuf:"varint,20,opt,name=value_prefix,json=valuePrefix,def=0" json:"value_prefix,omitempty"`
+ XXX_NoUnkeyedLiteral struct{} `json:"-"`
+ XXX_unrecognized []byte `json:"-"`
+ XXX_sizecache int32 `json:"-"`
+}
+
+func (m *CompiledQuery_MergeJoinScan) Reset() { *m = CompiledQuery_MergeJoinScan{} }
+func (m *CompiledQuery_MergeJoinScan) String() string { return proto.CompactTextString(m) }
+func (*CompiledQuery_MergeJoinScan) ProtoMessage() {}
+func (*CompiledQuery_MergeJoinScan) Descriptor() ([]byte, []int) {
+ return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{16, 1}
+}
+func (m *CompiledQuery_MergeJoinScan) XXX_Unmarshal(b []byte) error {
+ return xxx_messageInfo_CompiledQuery_MergeJoinScan.Unmarshal(m, b)
+}
+func (m *CompiledQuery_MergeJoinScan) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ return xxx_messageInfo_CompiledQuery_MergeJoinScan.Marshal(b, m, deterministic)
+}
+func (dst *CompiledQuery_MergeJoinScan) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_CompiledQuery_MergeJoinScan.Merge(dst, src)
+}
+func (m *CompiledQuery_MergeJoinScan) XXX_Size() int {
+ return xxx_messageInfo_CompiledQuery_MergeJoinScan.Size(m)
+}
+func (m *CompiledQuery_MergeJoinScan) XXX_DiscardUnknown() {
+ xxx_messageInfo_CompiledQuery_MergeJoinScan.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_CompiledQuery_MergeJoinScan proto.InternalMessageInfo
+
+const Default_CompiledQuery_MergeJoinScan_ValuePrefix bool = false
+
+func (m *CompiledQuery_MergeJoinScan) GetIndexName() string {
+ if m != nil && m.IndexName != nil {
+ return *m.IndexName
+ }
+ return ""
+}
+
+func (m *CompiledQuery_MergeJoinScan) GetPrefixValue() []string {
+ if m != nil {
+ return m.PrefixValue
+ }
+ return nil
+}
+
+func (m *CompiledQuery_MergeJoinScan) GetValuePrefix() bool {
+ if m != nil && m.ValuePrefix != nil {
+ return *m.ValuePrefix
+ }
+ return Default_CompiledQuery_MergeJoinScan_ValuePrefix
+}
+
+type CompiledQuery_EntityFilter struct {
+ Distinct *bool `protobuf:"varint,14,opt,name=distinct,def=0" json:"distinct,omitempty"`
+ Kind *string `protobuf:"bytes,17,opt,name=kind" json:"kind,omitempty"`
+ Ancestor *Reference `protobuf:"bytes,18,opt,name=ancestor" json:"ancestor,omitempty"`
+ XXX_NoUnkeyedLiteral struct{} `json:"-"`
+ XXX_unrecognized []byte `json:"-"`
+ XXX_sizecache int32 `json:"-"`
+}
+
+func (m *CompiledQuery_EntityFilter) Reset() { *m = CompiledQuery_EntityFilter{} }
+func (m *CompiledQuery_EntityFilter) String() string { return proto.CompactTextString(m) }
+func (*CompiledQuery_EntityFilter) ProtoMessage() {}
+func (*CompiledQuery_EntityFilter) Descriptor() ([]byte, []int) {
+ return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{16, 2}
+}
+func (m *CompiledQuery_EntityFilter) XXX_Unmarshal(b []byte) error {
+ return xxx_messageInfo_CompiledQuery_EntityFilter.Unmarshal(m, b)
+}
+func (m *CompiledQuery_EntityFilter) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ return xxx_messageInfo_CompiledQuery_EntityFilter.Marshal(b, m, deterministic)
+}
+func (dst *CompiledQuery_EntityFilter) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_CompiledQuery_EntityFilter.Merge(dst, src)
+}
+func (m *CompiledQuery_EntityFilter) XXX_Size() int {
+ return xxx_messageInfo_CompiledQuery_EntityFilter.Size(m)
+}
+func (m *CompiledQuery_EntityFilter) XXX_DiscardUnknown() {
+ xxx_messageInfo_CompiledQuery_EntityFilter.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_CompiledQuery_EntityFilter proto.InternalMessageInfo
+
+const Default_CompiledQuery_EntityFilter_Distinct bool = false
+
+func (m *CompiledQuery_EntityFilter) GetDistinct() bool {
+ if m != nil && m.Distinct != nil {
+ return *m.Distinct
+ }
+ return Default_CompiledQuery_EntityFilter_Distinct
+}
+
+func (m *CompiledQuery_EntityFilter) GetKind() string {
+ if m != nil && m.Kind != nil {
+ return *m.Kind
+ }
+ return ""
+}
+
+func (m *CompiledQuery_EntityFilter) GetAncestor() *Reference {
+ if m != nil {
+ return m.Ancestor
+ }
+ return nil
+}
+
+type CompiledCursor struct {
+ Position *CompiledCursor_Position `protobuf:"group,2,opt,name=Position,json=position" json:"position,omitempty"`
+ XXX_NoUnkeyedLiteral struct{} `json:"-"`
+ XXX_unrecognized []byte `json:"-"`
+ XXX_sizecache int32 `json:"-"`
+}
+
+func (m *CompiledCursor) Reset() { *m = CompiledCursor{} }
+func (m *CompiledCursor) String() string { return proto.CompactTextString(m) }
+func (*CompiledCursor) ProtoMessage() {}
+func (*CompiledCursor) Descriptor() ([]byte, []int) {
+ return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{17}
+}
+func (m *CompiledCursor) XXX_Unmarshal(b []byte) error {
+ return xxx_messageInfo_CompiledCursor.Unmarshal(m, b)
+}
+func (m *CompiledCursor) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ return xxx_messageInfo_CompiledCursor.Marshal(b, m, deterministic)
+}
+func (dst *CompiledCursor) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_CompiledCursor.Merge(dst, src)
+}
+func (m *CompiledCursor) XXX_Size() int {
+ return xxx_messageInfo_CompiledCursor.Size(m)
+}
+func (m *CompiledCursor) XXX_DiscardUnknown() {
+ xxx_messageInfo_CompiledCursor.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_CompiledCursor proto.InternalMessageInfo
+
+func (m *CompiledCursor) GetPosition() *CompiledCursor_Position {
+ if m != nil {
+ return m.Position
+ }
+ return nil
+}
+
+type CompiledCursor_Position struct {
+ StartKey *string `protobuf:"bytes,27,opt,name=start_key,json=startKey" json:"start_key,omitempty"`
+ Indexvalue []*CompiledCursor_Position_IndexValue `protobuf:"group,29,rep,name=IndexValue,json=indexvalue" json:"indexvalue,omitempty"`
+ Key *Reference `protobuf:"bytes,32,opt,name=key" json:"key,omitempty"`
+ StartInclusive *bool `protobuf:"varint,28,opt,name=start_inclusive,json=startInclusive,def=1" json:"start_inclusive,omitempty"`
+ XXX_NoUnkeyedLiteral struct{} `json:"-"`
+ XXX_unrecognized []byte `json:"-"`
+ XXX_sizecache int32 `json:"-"`
+}
+
+func (m *CompiledCursor_Position) Reset() { *m = CompiledCursor_Position{} }
+func (m *CompiledCursor_Position) String() string { return proto.CompactTextString(m) }
+func (*CompiledCursor_Position) ProtoMessage() {}
+func (*CompiledCursor_Position) Descriptor() ([]byte, []int) {
+ return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{17, 0}
+}
+func (m *CompiledCursor_Position) XXX_Unmarshal(b []byte) error {
+ return xxx_messageInfo_CompiledCursor_Position.Unmarshal(m, b)
+}
+func (m *CompiledCursor_Position) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ return xxx_messageInfo_CompiledCursor_Position.Marshal(b, m, deterministic)
+}
+func (dst *CompiledCursor_Position) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_CompiledCursor_Position.Merge(dst, src)
+}
+func (m *CompiledCursor_Position) XXX_Size() int {
+ return xxx_messageInfo_CompiledCursor_Position.Size(m)
+}
+func (m *CompiledCursor_Position) XXX_DiscardUnknown() {
+ xxx_messageInfo_CompiledCursor_Position.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_CompiledCursor_Position proto.InternalMessageInfo
+
+const Default_CompiledCursor_Position_StartInclusive bool = true
+
+func (m *CompiledCursor_Position) GetStartKey() string {
+ if m != nil && m.StartKey != nil {
+ return *m.StartKey
+ }
+ return ""
+}
+
+func (m *CompiledCursor_Position) GetIndexvalue() []*CompiledCursor_Position_IndexValue {
+ if m != nil {
+ return m.Indexvalue
+ }
+ return nil
+}
+
+func (m *CompiledCursor_Position) GetKey() *Reference {
+ if m != nil {
+ return m.Key
+ }
+ return nil
+}
+
+func (m *CompiledCursor_Position) GetStartInclusive() bool {
+ if m != nil && m.StartInclusive != nil {
+ return *m.StartInclusive
+ }
+ return Default_CompiledCursor_Position_StartInclusive
+}
+
+type CompiledCursor_Position_IndexValue struct {
+ Property *string `protobuf:"bytes,30,opt,name=property" json:"property,omitempty"`
+ Value *PropertyValue `protobuf:"bytes,31,req,name=value" json:"value,omitempty"`
+ XXX_NoUnkeyedLiteral struct{} `json:"-"`
+ XXX_unrecognized []byte `json:"-"`
+ XXX_sizecache int32 `json:"-"`
+}
+
+func (m *CompiledCursor_Position_IndexValue) Reset() { *m = CompiledCursor_Position_IndexValue{} }
+func (m *CompiledCursor_Position_IndexValue) String() string { return proto.CompactTextString(m) }
+func (*CompiledCursor_Position_IndexValue) ProtoMessage() {}
+func (*CompiledCursor_Position_IndexValue) Descriptor() ([]byte, []int) {
+ return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{17, 0, 0}
+}
+func (m *CompiledCursor_Position_IndexValue) XXX_Unmarshal(b []byte) error {
+ return xxx_messageInfo_CompiledCursor_Position_IndexValue.Unmarshal(m, b)
+}
+func (m *CompiledCursor_Position_IndexValue) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ return xxx_messageInfo_CompiledCursor_Position_IndexValue.Marshal(b, m, deterministic)
+}
+func (dst *CompiledCursor_Position_IndexValue) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_CompiledCursor_Position_IndexValue.Merge(dst, src)
+}
+func (m *CompiledCursor_Position_IndexValue) XXX_Size() int {
+ return xxx_messageInfo_CompiledCursor_Position_IndexValue.Size(m)
+}
+func (m *CompiledCursor_Position_IndexValue) XXX_DiscardUnknown() {
+ xxx_messageInfo_CompiledCursor_Position_IndexValue.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_CompiledCursor_Position_IndexValue proto.InternalMessageInfo
+
+func (m *CompiledCursor_Position_IndexValue) GetProperty() string {
+ if m != nil && m.Property != nil {
+ return *m.Property
+ }
+ return ""
+}
+
+func (m *CompiledCursor_Position_IndexValue) GetValue() *PropertyValue {
+ if m != nil {
+ return m.Value
+ }
+ return nil
+}
+
+type Cursor struct {
+ Cursor *uint64 `protobuf:"fixed64,1,req,name=cursor" json:"cursor,omitempty"`
+ App *string `protobuf:"bytes,2,opt,name=app" json:"app,omitempty"`
+ XXX_NoUnkeyedLiteral struct{} `json:"-"`
+ XXX_unrecognized []byte `json:"-"`
+ XXX_sizecache int32 `json:"-"`
+}
+
+func (m *Cursor) Reset() { *m = Cursor{} }
+func (m *Cursor) String() string { return proto.CompactTextString(m) }
+func (*Cursor) ProtoMessage() {}
+func (*Cursor) Descriptor() ([]byte, []int) {
+ return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{18}
+}
+func (m *Cursor) XXX_Unmarshal(b []byte) error {
+ return xxx_messageInfo_Cursor.Unmarshal(m, b)
+}
+func (m *Cursor) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ return xxx_messageInfo_Cursor.Marshal(b, m, deterministic)
+}
+func (dst *Cursor) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_Cursor.Merge(dst, src)
+}
+func (m *Cursor) XXX_Size() int {
+ return xxx_messageInfo_Cursor.Size(m)
+}
+func (m *Cursor) XXX_DiscardUnknown() {
+ xxx_messageInfo_Cursor.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_Cursor proto.InternalMessageInfo
+
+func (m *Cursor) GetCursor() uint64 {
+ if m != nil && m.Cursor != nil {
+ return *m.Cursor
+ }
+ return 0
+}
+
+func (m *Cursor) GetApp() string {
+ if m != nil && m.App != nil {
+ return *m.App
+ }
+ return ""
+}
+
+type Error struct {
+ XXX_NoUnkeyedLiteral struct{} `json:"-"`
+ XXX_unrecognized []byte `json:"-"`
+ XXX_sizecache int32 `json:"-"`
+}
+
+func (m *Error) Reset() { *m = Error{} }
+func (m *Error) String() string { return proto.CompactTextString(m) }
+func (*Error) ProtoMessage() {}
+func (*Error) Descriptor() ([]byte, []int) {
+ return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{19}
+}
+func (m *Error) XXX_Unmarshal(b []byte) error {
+ return xxx_messageInfo_Error.Unmarshal(m, b)
+}
+func (m *Error) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ return xxx_messageInfo_Error.Marshal(b, m, deterministic)
+}
+func (dst *Error) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_Error.Merge(dst, src)
+}
+func (m *Error) XXX_Size() int {
+ return xxx_messageInfo_Error.Size(m)
+}
+func (m *Error) XXX_DiscardUnknown() {
+ xxx_messageInfo_Error.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_Error proto.InternalMessageInfo
+
+type Cost struct {
+ IndexWrites *int32 `protobuf:"varint,1,opt,name=index_writes,json=indexWrites" json:"index_writes,omitempty"`
+ IndexWriteBytes *int32 `protobuf:"varint,2,opt,name=index_write_bytes,json=indexWriteBytes" json:"index_write_bytes,omitempty"`
+ EntityWrites *int32 `protobuf:"varint,3,opt,name=entity_writes,json=entityWrites" json:"entity_writes,omitempty"`
+ EntityWriteBytes *int32 `protobuf:"varint,4,opt,name=entity_write_bytes,json=entityWriteBytes" json:"entity_write_bytes,omitempty"`
+ Commitcost *Cost_CommitCost `protobuf:"group,5,opt,name=CommitCost,json=commitcost" json:"commitcost,omitempty"`
+ ApproximateStorageDelta *int32 `protobuf:"varint,8,opt,name=approximate_storage_delta,json=approximateStorageDelta" json:"approximate_storage_delta,omitempty"`
+ IdSequenceUpdates *int32 `protobuf:"varint,9,opt,name=id_sequence_updates,json=idSequenceUpdates" json:"id_sequence_updates,omitempty"`
+ XXX_NoUnkeyedLiteral struct{} `json:"-"`
+ XXX_unrecognized []byte `json:"-"`
+ XXX_sizecache int32 `json:"-"`
+}
+
+func (m *Cost) Reset() { *m = Cost{} }
+func (m *Cost) String() string { return proto.CompactTextString(m) }
+func (*Cost) ProtoMessage() {}
+func (*Cost) Descriptor() ([]byte, []int) {
+ return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{20}
+}
+func (m *Cost) XXX_Unmarshal(b []byte) error {
+ return xxx_messageInfo_Cost.Unmarshal(m, b)
+}
+func (m *Cost) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ return xxx_messageInfo_Cost.Marshal(b, m, deterministic)
+}
+func (dst *Cost) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_Cost.Merge(dst, src)
+}
+func (m *Cost) XXX_Size() int {
+ return xxx_messageInfo_Cost.Size(m)
+}
+func (m *Cost) XXX_DiscardUnknown() {
+ xxx_messageInfo_Cost.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_Cost proto.InternalMessageInfo
+
+func (m *Cost) GetIndexWrites() int32 {
+ if m != nil && m.IndexWrites != nil {
+ return *m.IndexWrites
+ }
+ return 0
+}
+
+func (m *Cost) GetIndexWriteBytes() int32 {
+ if m != nil && m.IndexWriteBytes != nil {
+ return *m.IndexWriteBytes
+ }
+ return 0
+}
+
+func (m *Cost) GetEntityWrites() int32 {
+ if m != nil && m.EntityWrites != nil {
+ return *m.EntityWrites
+ }
+ return 0
+}
+
+func (m *Cost) GetEntityWriteBytes() int32 {
+ if m != nil && m.EntityWriteBytes != nil {
+ return *m.EntityWriteBytes
+ }
+ return 0
+}
+
+func (m *Cost) GetCommitcost() *Cost_CommitCost {
+ if m != nil {
+ return m.Commitcost
+ }
+ return nil
+}
+
+func (m *Cost) GetApproximateStorageDelta() int32 {
+ if m != nil && m.ApproximateStorageDelta != nil {
+ return *m.ApproximateStorageDelta
+ }
+ return 0
+}
+
+func (m *Cost) GetIdSequenceUpdates() int32 {
+ if m != nil && m.IdSequenceUpdates != nil {
+ return *m.IdSequenceUpdates
+ }
+ return 0
+}
+
+type Cost_CommitCost struct {
+ RequestedEntityPuts *int32 `protobuf:"varint,6,opt,name=requested_entity_puts,json=requestedEntityPuts" json:"requested_entity_puts,omitempty"`
+ RequestedEntityDeletes *int32 `protobuf:"varint,7,opt,name=requested_entity_deletes,json=requestedEntityDeletes" json:"requested_entity_deletes,omitempty"`
+ XXX_NoUnkeyedLiteral struct{} `json:"-"`
+ XXX_unrecognized []byte `json:"-"`
+ XXX_sizecache int32 `json:"-"`
+}
+
+func (m *Cost_CommitCost) Reset() { *m = Cost_CommitCost{} }
+func (m *Cost_CommitCost) String() string { return proto.CompactTextString(m) }
+func (*Cost_CommitCost) ProtoMessage() {}
+func (*Cost_CommitCost) Descriptor() ([]byte, []int) {
+ return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{20, 0}
+}
+func (m *Cost_CommitCost) XXX_Unmarshal(b []byte) error {
+ return xxx_messageInfo_Cost_CommitCost.Unmarshal(m, b)
+}
+func (m *Cost_CommitCost) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ return xxx_messageInfo_Cost_CommitCost.Marshal(b, m, deterministic)
+}
+func (dst *Cost_CommitCost) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_Cost_CommitCost.Merge(dst, src)
+}
+func (m *Cost_CommitCost) XXX_Size() int {
+ return xxx_messageInfo_Cost_CommitCost.Size(m)
+}
+func (m *Cost_CommitCost) XXX_DiscardUnknown() {
+ xxx_messageInfo_Cost_CommitCost.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_Cost_CommitCost proto.InternalMessageInfo
+
+func (m *Cost_CommitCost) GetRequestedEntityPuts() int32 {
+ if m != nil && m.RequestedEntityPuts != nil {
+ return *m.RequestedEntityPuts
+ }
+ return 0
+}
+
+func (m *Cost_CommitCost) GetRequestedEntityDeletes() int32 {
+ if m != nil && m.RequestedEntityDeletes != nil {
+ return *m.RequestedEntityDeletes
+ }
+ return 0
+}
+
+type GetRequest struct {
+ Header *InternalHeader `protobuf:"bytes,6,opt,name=header" json:"header,omitempty"`
+ Key []*Reference `protobuf:"bytes,1,rep,name=key" json:"key,omitempty"`
+ Transaction *Transaction `protobuf:"bytes,2,opt,name=transaction" json:"transaction,omitempty"`
+ FailoverMs *int64 `protobuf:"varint,3,opt,name=failover_ms,json=failoverMs" json:"failover_ms,omitempty"`
+ Strong *bool `protobuf:"varint,4,opt,name=strong" json:"strong,omitempty"`
+ AllowDeferred *bool `protobuf:"varint,5,opt,name=allow_deferred,json=allowDeferred,def=0" json:"allow_deferred,omitempty"`
+ XXX_NoUnkeyedLiteral struct{} `json:"-"`
+ XXX_unrecognized []byte `json:"-"`
+ XXX_sizecache int32 `json:"-"`
+}
+
+func (m *GetRequest) Reset() { *m = GetRequest{} }
+func (m *GetRequest) String() string { return proto.CompactTextString(m) }
+func (*GetRequest) ProtoMessage() {}
+func (*GetRequest) Descriptor() ([]byte, []int) {
+ return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{21}
+}
+func (m *GetRequest) XXX_Unmarshal(b []byte) error {
+ return xxx_messageInfo_GetRequest.Unmarshal(m, b)
+}
+func (m *GetRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ return xxx_messageInfo_GetRequest.Marshal(b, m, deterministic)
+}
+func (dst *GetRequest) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_GetRequest.Merge(dst, src)
+}
+func (m *GetRequest) XXX_Size() int {
+ return xxx_messageInfo_GetRequest.Size(m)
+}
+func (m *GetRequest) XXX_DiscardUnknown() {
+ xxx_messageInfo_GetRequest.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_GetRequest proto.InternalMessageInfo
+
+const Default_GetRequest_AllowDeferred bool = false
+
+func (m *GetRequest) GetHeader() *InternalHeader {
+ if m != nil {
+ return m.Header
+ }
+ return nil
+}
+
+func (m *GetRequest) GetKey() []*Reference {
+ if m != nil {
+ return m.Key
+ }
+ return nil
+}
+
+func (m *GetRequest) GetTransaction() *Transaction {
+ if m != nil {
+ return m.Transaction
+ }
+ return nil
+}
+
+func (m *GetRequest) GetFailoverMs() int64 {
+ if m != nil && m.FailoverMs != nil {
+ return *m.FailoverMs
+ }
+ return 0
+}
+
+func (m *GetRequest) GetStrong() bool {
+ if m != nil && m.Strong != nil {
+ return *m.Strong
+ }
+ return false
+}
+
+func (m *GetRequest) GetAllowDeferred() bool {
+ if m != nil && m.AllowDeferred != nil {
+ return *m.AllowDeferred
+ }
+ return Default_GetRequest_AllowDeferred
+}
+
+type GetResponse struct {
+ Entity []*GetResponse_Entity `protobuf:"group,1,rep,name=Entity,json=entity" json:"entity,omitempty"`
+ Deferred []*Reference `protobuf:"bytes,5,rep,name=deferred" json:"deferred,omitempty"`
+ InOrder *bool `protobuf:"varint,6,opt,name=in_order,json=inOrder,def=1" json:"in_order,omitempty"`
+ XXX_NoUnkeyedLiteral struct{} `json:"-"`
+ XXX_unrecognized []byte `json:"-"`
+ XXX_sizecache int32 `json:"-"`
+}
+
+func (m *GetResponse) Reset() { *m = GetResponse{} }
+func (m *GetResponse) String() string { return proto.CompactTextString(m) }
+func (*GetResponse) ProtoMessage() {}
+func (*GetResponse) Descriptor() ([]byte, []int) {
+ return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{22}
+}
+func (m *GetResponse) XXX_Unmarshal(b []byte) error {
+ return xxx_messageInfo_GetResponse.Unmarshal(m, b)
+}
+func (m *GetResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ return xxx_messageInfo_GetResponse.Marshal(b, m, deterministic)
+}
+func (dst *GetResponse) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_GetResponse.Merge(dst, src)
+}
+func (m *GetResponse) XXX_Size() int {
+ return xxx_messageInfo_GetResponse.Size(m)
+}
+func (m *GetResponse) XXX_DiscardUnknown() {
+ xxx_messageInfo_GetResponse.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_GetResponse proto.InternalMessageInfo
+
+const Default_GetResponse_InOrder bool = true
+
+func (m *GetResponse) GetEntity() []*GetResponse_Entity {
+ if m != nil {
+ return m.Entity
+ }
+ return nil
+}
+
+func (m *GetResponse) GetDeferred() []*Reference {
+ if m != nil {
+ return m.Deferred
+ }
+ return nil
+}
+
+func (m *GetResponse) GetInOrder() bool {
+ if m != nil && m.InOrder != nil {
+ return *m.InOrder
+ }
+ return Default_GetResponse_InOrder
+}
+
+type GetResponse_Entity struct {
+ Entity *EntityProto `protobuf:"bytes,2,opt,name=entity" json:"entity,omitempty"`
+ Key *Reference `protobuf:"bytes,4,opt,name=key" json:"key,omitempty"`
+ Version *int64 `protobuf:"varint,3,opt,name=version" json:"version,omitempty"`
+ XXX_NoUnkeyedLiteral struct{} `json:"-"`
+ XXX_unrecognized []byte `json:"-"`
+ XXX_sizecache int32 `json:"-"`
+}
+
+func (m *GetResponse_Entity) Reset() { *m = GetResponse_Entity{} }
+func (m *GetResponse_Entity) String() string { return proto.CompactTextString(m) }
+func (*GetResponse_Entity) ProtoMessage() {}
+func (*GetResponse_Entity) Descriptor() ([]byte, []int) {
+ return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{22, 0}
+}
+func (m *GetResponse_Entity) XXX_Unmarshal(b []byte) error {
+ return xxx_messageInfo_GetResponse_Entity.Unmarshal(m, b)
+}
+func (m *GetResponse_Entity) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ return xxx_messageInfo_GetResponse_Entity.Marshal(b, m, deterministic)
+}
+func (dst *GetResponse_Entity) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_GetResponse_Entity.Merge(dst, src)
+}
+func (m *GetResponse_Entity) XXX_Size() int {
+ return xxx_messageInfo_GetResponse_Entity.Size(m)
+}
+func (m *GetResponse_Entity) XXX_DiscardUnknown() {
+ xxx_messageInfo_GetResponse_Entity.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_GetResponse_Entity proto.InternalMessageInfo
+
+func (m *GetResponse_Entity) GetEntity() *EntityProto {
+ if m != nil {
+ return m.Entity
+ }
+ return nil
+}
+
+func (m *GetResponse_Entity) GetKey() *Reference {
+ if m != nil {
+ return m.Key
+ }
+ return nil
+}
+
+func (m *GetResponse_Entity) GetVersion() int64 {
+ if m != nil && m.Version != nil {
+ return *m.Version
+ }
+ return 0
+}
+
+type PutRequest struct {
+ Header *InternalHeader `protobuf:"bytes,11,opt,name=header" json:"header,omitempty"`
+ Entity []*EntityProto `protobuf:"bytes,1,rep,name=entity" json:"entity,omitempty"`
+ Transaction *Transaction `protobuf:"bytes,2,opt,name=transaction" json:"transaction,omitempty"`
+ CompositeIndex []*CompositeIndex `protobuf:"bytes,3,rep,name=composite_index,json=compositeIndex" json:"composite_index,omitempty"`
+ Trusted *bool `protobuf:"varint,4,opt,name=trusted,def=0" json:"trusted,omitempty"`
+ Force *bool `protobuf:"varint,7,opt,name=force,def=0" json:"force,omitempty"`
+ MarkChanges *bool `protobuf:"varint,8,opt,name=mark_changes,json=markChanges,def=0" json:"mark_changes,omitempty"`
+ Snapshot []*Snapshot `protobuf:"bytes,9,rep,name=snapshot" json:"snapshot,omitempty"`
+ AutoIdPolicy *PutRequest_AutoIdPolicy `protobuf:"varint,10,opt,name=auto_id_policy,json=autoIdPolicy,enum=appengine.PutRequest_AutoIdPolicy,def=0" json:"auto_id_policy,omitempty"`
+ XXX_NoUnkeyedLiteral struct{} `json:"-"`
+ XXX_unrecognized []byte `json:"-"`
+ XXX_sizecache int32 `json:"-"`
+}
+
+func (m *PutRequest) Reset() { *m = PutRequest{} }
+func (m *PutRequest) String() string { return proto.CompactTextString(m) }
+func (*PutRequest) ProtoMessage() {}
+func (*PutRequest) Descriptor() ([]byte, []int) {
+ return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{23}
+}
+func (m *PutRequest) XXX_Unmarshal(b []byte) error {
+ return xxx_messageInfo_PutRequest.Unmarshal(m, b)
+}
+func (m *PutRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ return xxx_messageInfo_PutRequest.Marshal(b, m, deterministic)
+}
+func (dst *PutRequest) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_PutRequest.Merge(dst, src)
+}
+func (m *PutRequest) XXX_Size() int {
+ return xxx_messageInfo_PutRequest.Size(m)
+}
+func (m *PutRequest) XXX_DiscardUnknown() {
+ xxx_messageInfo_PutRequest.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_PutRequest proto.InternalMessageInfo
+
+const Default_PutRequest_Trusted bool = false
+const Default_PutRequest_Force bool = false
+const Default_PutRequest_MarkChanges bool = false
+const Default_PutRequest_AutoIdPolicy PutRequest_AutoIdPolicy = PutRequest_CURRENT
+
+func (m *PutRequest) GetHeader() *InternalHeader {
+ if m != nil {
+ return m.Header
+ }
+ return nil
+}
+
+func (m *PutRequest) GetEntity() []*EntityProto {
+ if m != nil {
+ return m.Entity
+ }
+ return nil
+}
+
+func (m *PutRequest) GetTransaction() *Transaction {
+ if m != nil {
+ return m.Transaction
+ }
+ return nil
+}
+
+func (m *PutRequest) GetCompositeIndex() []*CompositeIndex {
+ if m != nil {
+ return m.CompositeIndex
+ }
+ return nil
+}
+
+func (m *PutRequest) GetTrusted() bool {
+ if m != nil && m.Trusted != nil {
+ return *m.Trusted
+ }
+ return Default_PutRequest_Trusted
+}
+
+func (m *PutRequest) GetForce() bool {
+ if m != nil && m.Force != nil {
+ return *m.Force
+ }
+ return Default_PutRequest_Force
+}
+
+func (m *PutRequest) GetMarkChanges() bool {
+ if m != nil && m.MarkChanges != nil {
+ return *m.MarkChanges
+ }
+ return Default_PutRequest_MarkChanges
+}
+
+func (m *PutRequest) GetSnapshot() []*Snapshot {
+ if m != nil {
+ return m.Snapshot
+ }
+ return nil
+}
+
+func (m *PutRequest) GetAutoIdPolicy() PutRequest_AutoIdPolicy {
+ if m != nil && m.AutoIdPolicy != nil {
+ return *m.AutoIdPolicy
+ }
+ return Default_PutRequest_AutoIdPolicy
+}
+
+type PutResponse struct {
+ Key []*Reference `protobuf:"bytes,1,rep,name=key" json:"key,omitempty"`
+ Cost *Cost `protobuf:"bytes,2,opt,name=cost" json:"cost,omitempty"`
+ Version []int64 `protobuf:"varint,3,rep,name=version" json:"version,omitempty"`
+ XXX_NoUnkeyedLiteral struct{} `json:"-"`
+ XXX_unrecognized []byte `json:"-"`
+ XXX_sizecache int32 `json:"-"`
+}
+
+func (m *PutResponse) Reset() { *m = PutResponse{} }
+func (m *PutResponse) String() string { return proto.CompactTextString(m) }
+func (*PutResponse) ProtoMessage() {}
+func (*PutResponse) Descriptor() ([]byte, []int) {
+ return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{24}
+}
+func (m *PutResponse) XXX_Unmarshal(b []byte) error {
+ return xxx_messageInfo_PutResponse.Unmarshal(m, b)
+}
+func (m *PutResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ return xxx_messageInfo_PutResponse.Marshal(b, m, deterministic)
+}
+func (dst *PutResponse) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_PutResponse.Merge(dst, src)
+}
+func (m *PutResponse) XXX_Size() int {
+ return xxx_messageInfo_PutResponse.Size(m)
+}
+func (m *PutResponse) XXX_DiscardUnknown() {
+ xxx_messageInfo_PutResponse.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_PutResponse proto.InternalMessageInfo
+
+func (m *PutResponse) GetKey() []*Reference {
+ if m != nil {
+ return m.Key
+ }
+ return nil
+}
+
+func (m *PutResponse) GetCost() *Cost {
+ if m != nil {
+ return m.Cost
+ }
+ return nil
+}
+
+func (m *PutResponse) GetVersion() []int64 {
+ if m != nil {
+ return m.Version
+ }
+ return nil
+}
+
+type TouchRequest struct {
+ Header *InternalHeader `protobuf:"bytes,10,opt,name=header" json:"header,omitempty"`
+ Key []*Reference `protobuf:"bytes,1,rep,name=key" json:"key,omitempty"`
+ CompositeIndex []*CompositeIndex `protobuf:"bytes,2,rep,name=composite_index,json=compositeIndex" json:"composite_index,omitempty"`
+ Force *bool `protobuf:"varint,3,opt,name=force,def=0" json:"force,omitempty"`
+ Snapshot []*Snapshot `protobuf:"bytes,9,rep,name=snapshot" json:"snapshot,omitempty"`
+ XXX_NoUnkeyedLiteral struct{} `json:"-"`
+ XXX_unrecognized []byte `json:"-"`
+ XXX_sizecache int32 `json:"-"`
+}
+
+func (m *TouchRequest) Reset() { *m = TouchRequest{} }
+func (m *TouchRequest) String() string { return proto.CompactTextString(m) }
+func (*TouchRequest) ProtoMessage() {}
+func (*TouchRequest) Descriptor() ([]byte, []int) {
+ return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{25}
+}
+func (m *TouchRequest) XXX_Unmarshal(b []byte) error {
+ return xxx_messageInfo_TouchRequest.Unmarshal(m, b)
+}
+func (m *TouchRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ return xxx_messageInfo_TouchRequest.Marshal(b, m, deterministic)
+}
+func (dst *TouchRequest) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_TouchRequest.Merge(dst, src)
+}
+func (m *TouchRequest) XXX_Size() int {
+ return xxx_messageInfo_TouchRequest.Size(m)
+}
+func (m *TouchRequest) XXX_DiscardUnknown() {
+ xxx_messageInfo_TouchRequest.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_TouchRequest proto.InternalMessageInfo
+
+const Default_TouchRequest_Force bool = false
+
+func (m *TouchRequest) GetHeader() *InternalHeader {
+ if m != nil {
+ return m.Header
+ }
+ return nil
+}
+
+func (m *TouchRequest) GetKey() []*Reference {
+ if m != nil {
+ return m.Key
+ }
+ return nil
+}
+
+func (m *TouchRequest) GetCompositeIndex() []*CompositeIndex {
+ if m != nil {
+ return m.CompositeIndex
+ }
+ return nil
+}
+
+func (m *TouchRequest) GetForce() bool {
+ if m != nil && m.Force != nil {
+ return *m.Force
+ }
+ return Default_TouchRequest_Force
+}
+
+func (m *TouchRequest) GetSnapshot() []*Snapshot {
+ if m != nil {
+ return m.Snapshot
+ }
+ return nil
+}
+
+type TouchResponse struct {
+ Cost *Cost `protobuf:"bytes,1,opt,name=cost" json:"cost,omitempty"`
+ XXX_NoUnkeyedLiteral struct{} `json:"-"`
+ XXX_unrecognized []byte `json:"-"`
+ XXX_sizecache int32 `json:"-"`
+}
+
+func (m *TouchResponse) Reset() { *m = TouchResponse{} }
+func (m *TouchResponse) String() string { return proto.CompactTextString(m) }
+func (*TouchResponse) ProtoMessage() {}
+func (*TouchResponse) Descriptor() ([]byte, []int) {
+ return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{26}
+}
+func (m *TouchResponse) XXX_Unmarshal(b []byte) error {
+ return xxx_messageInfo_TouchResponse.Unmarshal(m, b)
+}
+func (m *TouchResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ return xxx_messageInfo_TouchResponse.Marshal(b, m, deterministic)
+}
+func (dst *TouchResponse) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_TouchResponse.Merge(dst, src)
+}
+func (m *TouchResponse) XXX_Size() int {
+ return xxx_messageInfo_TouchResponse.Size(m)
+}
+func (m *TouchResponse) XXX_DiscardUnknown() {
+ xxx_messageInfo_TouchResponse.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_TouchResponse proto.InternalMessageInfo
+
+func (m *TouchResponse) GetCost() *Cost {
+ if m != nil {
+ return m.Cost
+ }
+ return nil
+}
+
+type DeleteRequest struct {
+ Header *InternalHeader `protobuf:"bytes,10,opt,name=header" json:"header,omitempty"`
+ Key []*Reference `protobuf:"bytes,6,rep,name=key" json:"key,omitempty"`
+ Transaction *Transaction `protobuf:"bytes,5,opt,name=transaction" json:"transaction,omitempty"`
+ Trusted *bool `protobuf:"varint,4,opt,name=trusted,def=0" json:"trusted,omitempty"`
+ Force *bool `protobuf:"varint,7,opt,name=force,def=0" json:"force,omitempty"`
+ MarkChanges *bool `protobuf:"varint,8,opt,name=mark_changes,json=markChanges,def=0" json:"mark_changes,omitempty"`
+ Snapshot []*Snapshot `protobuf:"bytes,9,rep,name=snapshot" json:"snapshot,omitempty"`
+ XXX_NoUnkeyedLiteral struct{} `json:"-"`
+ XXX_unrecognized []byte `json:"-"`
+ XXX_sizecache int32 `json:"-"`
+}
+
+func (m *DeleteRequest) Reset() { *m = DeleteRequest{} }
+func (m *DeleteRequest) String() string { return proto.CompactTextString(m) }
+func (*DeleteRequest) ProtoMessage() {}
+func (*DeleteRequest) Descriptor() ([]byte, []int) {
+ return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{27}
+}
+func (m *DeleteRequest) XXX_Unmarshal(b []byte) error {
+ return xxx_messageInfo_DeleteRequest.Unmarshal(m, b)
+}
+func (m *DeleteRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ return xxx_messageInfo_DeleteRequest.Marshal(b, m, deterministic)
+}
+func (dst *DeleteRequest) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_DeleteRequest.Merge(dst, src)
+}
+func (m *DeleteRequest) XXX_Size() int {
+ return xxx_messageInfo_DeleteRequest.Size(m)
+}
+func (m *DeleteRequest) XXX_DiscardUnknown() {
+ xxx_messageInfo_DeleteRequest.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_DeleteRequest proto.InternalMessageInfo
+
+const Default_DeleteRequest_Trusted bool = false
+const Default_DeleteRequest_Force bool = false
+const Default_DeleteRequest_MarkChanges bool = false
+
+func (m *DeleteRequest) GetHeader() *InternalHeader {
+ if m != nil {
+ return m.Header
+ }
+ return nil
+}
+
+func (m *DeleteRequest) GetKey() []*Reference {
+ if m != nil {
+ return m.Key
+ }
+ return nil
+}
+
+func (m *DeleteRequest) GetTransaction() *Transaction {
+ if m != nil {
+ return m.Transaction
+ }
+ return nil
+}
+
+func (m *DeleteRequest) GetTrusted() bool {
+ if m != nil && m.Trusted != nil {
+ return *m.Trusted
+ }
+ return Default_DeleteRequest_Trusted
+}
+
+func (m *DeleteRequest) GetForce() bool {
+ if m != nil && m.Force != nil {
+ return *m.Force
+ }
+ return Default_DeleteRequest_Force
+}
+
+func (m *DeleteRequest) GetMarkChanges() bool {
+ if m != nil && m.MarkChanges != nil {
+ return *m.MarkChanges
+ }
+ return Default_DeleteRequest_MarkChanges
+}
+
+func (m *DeleteRequest) GetSnapshot() []*Snapshot {
+ if m != nil {
+ return m.Snapshot
+ }
+ return nil
+}
+
+type DeleteResponse struct {
+ Cost *Cost `protobuf:"bytes,1,opt,name=cost" json:"cost,omitempty"`
+ Version []int64 `protobuf:"varint,3,rep,name=version" json:"version,omitempty"`
+ XXX_NoUnkeyedLiteral struct{} `json:"-"`
+ XXX_unrecognized []byte `json:"-"`
+ XXX_sizecache int32 `json:"-"`
+}
+
+func (m *DeleteResponse) Reset() { *m = DeleteResponse{} }
+func (m *DeleteResponse) String() string { return proto.CompactTextString(m) }
+func (*DeleteResponse) ProtoMessage() {}
+func (*DeleteResponse) Descriptor() ([]byte, []int) {
+ return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{28}
+}
+func (m *DeleteResponse) XXX_Unmarshal(b []byte) error {
+ return xxx_messageInfo_DeleteResponse.Unmarshal(m, b)
+}
+func (m *DeleteResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ return xxx_messageInfo_DeleteResponse.Marshal(b, m, deterministic)
+}
+func (dst *DeleteResponse) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_DeleteResponse.Merge(dst, src)
+}
+func (m *DeleteResponse) XXX_Size() int {
+ return xxx_messageInfo_DeleteResponse.Size(m)
+}
+func (m *DeleteResponse) XXX_DiscardUnknown() {
+ xxx_messageInfo_DeleteResponse.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_DeleteResponse proto.InternalMessageInfo
+
+func (m *DeleteResponse) GetCost() *Cost {
+ if m != nil {
+ return m.Cost
+ }
+ return nil
+}
+
+func (m *DeleteResponse) GetVersion() []int64 {
+ if m != nil {
+ return m.Version
+ }
+ return nil
+}
+
+type NextRequest struct {
+ Header *InternalHeader `protobuf:"bytes,5,opt,name=header" json:"header,omitempty"`
+ Cursor *Cursor `protobuf:"bytes,1,req,name=cursor" json:"cursor,omitempty"`
+ Count *int32 `protobuf:"varint,2,opt,name=count" json:"count,omitempty"`
+ Offset *int32 `protobuf:"varint,4,opt,name=offset,def=0" json:"offset,omitempty"`
+ Compile *bool `protobuf:"varint,3,opt,name=compile,def=0" json:"compile,omitempty"`
+ XXX_NoUnkeyedLiteral struct{} `json:"-"`
+ XXX_unrecognized []byte `json:"-"`
+ XXX_sizecache int32 `json:"-"`
+}
+
+func (m *NextRequest) Reset() { *m = NextRequest{} }
+func (m *NextRequest) String() string { return proto.CompactTextString(m) }
+func (*NextRequest) ProtoMessage() {}
+func (*NextRequest) Descriptor() ([]byte, []int) {
+ return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{29}
+}
+func (m *NextRequest) XXX_Unmarshal(b []byte) error {
+ return xxx_messageInfo_NextRequest.Unmarshal(m, b)
+}
+func (m *NextRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ return xxx_messageInfo_NextRequest.Marshal(b, m, deterministic)
+}
+func (dst *NextRequest) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_NextRequest.Merge(dst, src)
+}
+func (m *NextRequest) XXX_Size() int {
+ return xxx_messageInfo_NextRequest.Size(m)
+}
+func (m *NextRequest) XXX_DiscardUnknown() {
+ xxx_messageInfo_NextRequest.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_NextRequest proto.InternalMessageInfo
+
+const Default_NextRequest_Offset int32 = 0
+const Default_NextRequest_Compile bool = false
+
+func (m *NextRequest) GetHeader() *InternalHeader {
+ if m != nil {
+ return m.Header
+ }
+ return nil
+}
+
+func (m *NextRequest) GetCursor() *Cursor {
+ if m != nil {
+ return m.Cursor
+ }
+ return nil
+}
+
+func (m *NextRequest) GetCount() int32 {
+ if m != nil && m.Count != nil {
+ return *m.Count
+ }
+ return 0
+}
+
+func (m *NextRequest) GetOffset() int32 {
+ if m != nil && m.Offset != nil {
+ return *m.Offset
+ }
+ return Default_NextRequest_Offset
+}
+
+func (m *NextRequest) GetCompile() bool {
+ if m != nil && m.Compile != nil {
+ return *m.Compile
+ }
+ return Default_NextRequest_Compile
+}
+
+type QueryResult struct {
+ Cursor *Cursor `protobuf:"bytes,1,opt,name=cursor" json:"cursor,omitempty"`
+ Result []*EntityProto `protobuf:"bytes,2,rep,name=result" json:"result,omitempty"`
+ SkippedResults *int32 `protobuf:"varint,7,opt,name=skipped_results,json=skippedResults" json:"skipped_results,omitempty"`
+ MoreResults *bool `protobuf:"varint,3,req,name=more_results,json=moreResults" json:"more_results,omitempty"`
+ KeysOnly *bool `protobuf:"varint,4,opt,name=keys_only,json=keysOnly" json:"keys_only,omitempty"`
+ IndexOnly *bool `protobuf:"varint,9,opt,name=index_only,json=indexOnly" json:"index_only,omitempty"`
+ SmallOps *bool `protobuf:"varint,10,opt,name=small_ops,json=smallOps" json:"small_ops,omitempty"`
+ CompiledQuery *CompiledQuery `protobuf:"bytes,5,opt,name=compiled_query,json=compiledQuery" json:"compiled_query,omitempty"`
+ CompiledCursor *CompiledCursor `protobuf:"bytes,6,opt,name=compiled_cursor,json=compiledCursor" json:"compiled_cursor,omitempty"`
+ Index []*CompositeIndex `protobuf:"bytes,8,rep,name=index" json:"index,omitempty"`
+ Version []int64 `protobuf:"varint,11,rep,name=version" json:"version,omitempty"`
+ XXX_NoUnkeyedLiteral struct{} `json:"-"`
+ XXX_unrecognized []byte `json:"-"`
+ XXX_sizecache int32 `json:"-"`
+}
+
+func (m *QueryResult) Reset() { *m = QueryResult{} }
+func (m *QueryResult) String() string { return proto.CompactTextString(m) }
+func (*QueryResult) ProtoMessage() {}
+func (*QueryResult) Descriptor() ([]byte, []int) {
+ return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{30}
+}
+func (m *QueryResult) XXX_Unmarshal(b []byte) error {
+ return xxx_messageInfo_QueryResult.Unmarshal(m, b)
+}
+func (m *QueryResult) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ return xxx_messageInfo_QueryResult.Marshal(b, m, deterministic)
+}
+func (dst *QueryResult) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_QueryResult.Merge(dst, src)
+}
+func (m *QueryResult) XXX_Size() int {
+ return xxx_messageInfo_QueryResult.Size(m)
+}
+func (m *QueryResult) XXX_DiscardUnknown() {
+ xxx_messageInfo_QueryResult.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_QueryResult proto.InternalMessageInfo
+
+func (m *QueryResult) GetCursor() *Cursor {
+ if m != nil {
+ return m.Cursor
+ }
+ return nil
+}
+
+func (m *QueryResult) GetResult() []*EntityProto {
+ if m != nil {
+ return m.Result
+ }
+ return nil
+}
+
+func (m *QueryResult) GetSkippedResults() int32 {
+ if m != nil && m.SkippedResults != nil {
+ return *m.SkippedResults
+ }
+ return 0
+}
+
+func (m *QueryResult) GetMoreResults() bool {
+ if m != nil && m.MoreResults != nil {
+ return *m.MoreResults
+ }
+ return false
+}
+
+func (m *QueryResult) GetKeysOnly() bool {
+ if m != nil && m.KeysOnly != nil {
+ return *m.KeysOnly
+ }
+ return false
+}
+
+func (m *QueryResult) GetIndexOnly() bool {
+ if m != nil && m.IndexOnly != nil {
+ return *m.IndexOnly
+ }
+ return false
+}
+
+func (m *QueryResult) GetSmallOps() bool {
+ if m != nil && m.SmallOps != nil {
+ return *m.SmallOps
+ }
+ return false
+}
+
+func (m *QueryResult) GetCompiledQuery() *CompiledQuery {
+ if m != nil {
+ return m.CompiledQuery
+ }
+ return nil
+}
+
+func (m *QueryResult) GetCompiledCursor() *CompiledCursor {
+ if m != nil {
+ return m.CompiledCursor
+ }
+ return nil
+}
+
+func (m *QueryResult) GetIndex() []*CompositeIndex {
+ if m != nil {
+ return m.Index
+ }
+ return nil
+}
+
+func (m *QueryResult) GetVersion() []int64 {
+ if m != nil {
+ return m.Version
+ }
+ return nil
+}
+
+type AllocateIdsRequest struct {
+ Header *InternalHeader `protobuf:"bytes,4,opt,name=header" json:"header,omitempty"`
+ ModelKey *Reference `protobuf:"bytes,1,opt,name=model_key,json=modelKey" json:"model_key,omitempty"`
+ Size *int64 `protobuf:"varint,2,opt,name=size" json:"size,omitempty"`
+ Max *int64 `protobuf:"varint,3,opt,name=max" json:"max,omitempty"`
+ Reserve []*Reference `protobuf:"bytes,5,rep,name=reserve" json:"reserve,omitempty"`
+ XXX_NoUnkeyedLiteral struct{} `json:"-"`
+ XXX_unrecognized []byte `json:"-"`
+ XXX_sizecache int32 `json:"-"`
+}
+
+func (m *AllocateIdsRequest) Reset() { *m = AllocateIdsRequest{} }
+func (m *AllocateIdsRequest) String() string { return proto.CompactTextString(m) }
+func (*AllocateIdsRequest) ProtoMessage() {}
+func (*AllocateIdsRequest) Descriptor() ([]byte, []int) {
+ return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{31}
+}
+func (m *AllocateIdsRequest) XXX_Unmarshal(b []byte) error {
+ return xxx_messageInfo_AllocateIdsRequest.Unmarshal(m, b)
+}
+func (m *AllocateIdsRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ return xxx_messageInfo_AllocateIdsRequest.Marshal(b, m, deterministic)
+}
+func (dst *AllocateIdsRequest) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_AllocateIdsRequest.Merge(dst, src)
+}
+func (m *AllocateIdsRequest) XXX_Size() int {
+ return xxx_messageInfo_AllocateIdsRequest.Size(m)
+}
+func (m *AllocateIdsRequest) XXX_DiscardUnknown() {
+ xxx_messageInfo_AllocateIdsRequest.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_AllocateIdsRequest proto.InternalMessageInfo
+
+func (m *AllocateIdsRequest) GetHeader() *InternalHeader {
+ if m != nil {
+ return m.Header
+ }
+ return nil
+}
+
+func (m *AllocateIdsRequest) GetModelKey() *Reference {
+ if m != nil {
+ return m.ModelKey
+ }
+ return nil
+}
+
+func (m *AllocateIdsRequest) GetSize() int64 {
+ if m != nil && m.Size != nil {
+ return *m.Size
+ }
+ return 0
+}
+
+func (m *AllocateIdsRequest) GetMax() int64 {
+ if m != nil && m.Max != nil {
+ return *m.Max
+ }
+ return 0
+}
+
+func (m *AllocateIdsRequest) GetReserve() []*Reference {
+ if m != nil {
+ return m.Reserve
+ }
+ return nil
+}
+
+type AllocateIdsResponse struct {
+ Start *int64 `protobuf:"varint,1,req,name=start" json:"start,omitempty"`
+ End *int64 `protobuf:"varint,2,req,name=end" json:"end,omitempty"`
+ Cost *Cost `protobuf:"bytes,3,opt,name=cost" json:"cost,omitempty"`
+ XXX_NoUnkeyedLiteral struct{} `json:"-"`
+ XXX_unrecognized []byte `json:"-"`
+ XXX_sizecache int32 `json:"-"`
+}
+
+func (m *AllocateIdsResponse) Reset() { *m = AllocateIdsResponse{} }
+func (m *AllocateIdsResponse) String() string { return proto.CompactTextString(m) }
+func (*AllocateIdsResponse) ProtoMessage() {}
+func (*AllocateIdsResponse) Descriptor() ([]byte, []int) {
+ return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{32}
+}
+func (m *AllocateIdsResponse) XXX_Unmarshal(b []byte) error {
+ return xxx_messageInfo_AllocateIdsResponse.Unmarshal(m, b)
+}
+func (m *AllocateIdsResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ return xxx_messageInfo_AllocateIdsResponse.Marshal(b, m, deterministic)
+}
+func (dst *AllocateIdsResponse) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_AllocateIdsResponse.Merge(dst, src)
+}
+func (m *AllocateIdsResponse) XXX_Size() int {
+ return xxx_messageInfo_AllocateIdsResponse.Size(m)
+}
+func (m *AllocateIdsResponse) XXX_DiscardUnknown() {
+ xxx_messageInfo_AllocateIdsResponse.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_AllocateIdsResponse proto.InternalMessageInfo
+
+func (m *AllocateIdsResponse) GetStart() int64 {
+ if m != nil && m.Start != nil {
+ return *m.Start
+ }
+ return 0
+}
+
+func (m *AllocateIdsResponse) GetEnd() int64 {
+ if m != nil && m.End != nil {
+ return *m.End
+ }
+ return 0
+}
+
+func (m *AllocateIdsResponse) GetCost() *Cost {
+ if m != nil {
+ return m.Cost
+ }
+ return nil
+}
+
+type CompositeIndices struct {
+ Index []*CompositeIndex `protobuf:"bytes,1,rep,name=index" json:"index,omitempty"`
+ XXX_NoUnkeyedLiteral struct{} `json:"-"`
+ XXX_unrecognized []byte `json:"-"`
+ XXX_sizecache int32 `json:"-"`
+}
+
+func (m *CompositeIndices) Reset() { *m = CompositeIndices{} }
+func (m *CompositeIndices) String() string { return proto.CompactTextString(m) }
+func (*CompositeIndices) ProtoMessage() {}
+func (*CompositeIndices) Descriptor() ([]byte, []int) {
+ return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{33}
+}
+func (m *CompositeIndices) XXX_Unmarshal(b []byte) error {
+ return xxx_messageInfo_CompositeIndices.Unmarshal(m, b)
+}
+func (m *CompositeIndices) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ return xxx_messageInfo_CompositeIndices.Marshal(b, m, deterministic)
+}
+func (dst *CompositeIndices) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_CompositeIndices.Merge(dst, src)
+}
+func (m *CompositeIndices) XXX_Size() int {
+ return xxx_messageInfo_CompositeIndices.Size(m)
+}
+func (m *CompositeIndices) XXX_DiscardUnknown() {
+ xxx_messageInfo_CompositeIndices.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_CompositeIndices proto.InternalMessageInfo
+
+func (m *CompositeIndices) GetIndex() []*CompositeIndex {
+ if m != nil {
+ return m.Index
+ }
+ return nil
+}
+
+type AddActionsRequest struct {
+ Header *InternalHeader `protobuf:"bytes,3,opt,name=header" json:"header,omitempty"`
+ Transaction *Transaction `protobuf:"bytes,1,req,name=transaction" json:"transaction,omitempty"`
+ Action []*Action `protobuf:"bytes,2,rep,name=action" json:"action,omitempty"`
+ XXX_NoUnkeyedLiteral struct{} `json:"-"`
+ XXX_unrecognized []byte `json:"-"`
+ XXX_sizecache int32 `json:"-"`
+}
+
+func (m *AddActionsRequest) Reset() { *m = AddActionsRequest{} }
+func (m *AddActionsRequest) String() string { return proto.CompactTextString(m) }
+func (*AddActionsRequest) ProtoMessage() {}
+func (*AddActionsRequest) Descriptor() ([]byte, []int) {
+ return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{34}
+}
+func (m *AddActionsRequest) XXX_Unmarshal(b []byte) error {
+ return xxx_messageInfo_AddActionsRequest.Unmarshal(m, b)
+}
+func (m *AddActionsRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ return xxx_messageInfo_AddActionsRequest.Marshal(b, m, deterministic)
+}
+func (dst *AddActionsRequest) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_AddActionsRequest.Merge(dst, src)
+}
+func (m *AddActionsRequest) XXX_Size() int {
+ return xxx_messageInfo_AddActionsRequest.Size(m)
+}
+func (m *AddActionsRequest) XXX_DiscardUnknown() {
+ xxx_messageInfo_AddActionsRequest.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_AddActionsRequest proto.InternalMessageInfo
+
+func (m *AddActionsRequest) GetHeader() *InternalHeader {
+ if m != nil {
+ return m.Header
+ }
+ return nil
+}
+
+func (m *AddActionsRequest) GetTransaction() *Transaction {
+ if m != nil {
+ return m.Transaction
+ }
+ return nil
+}
+
+func (m *AddActionsRequest) GetAction() []*Action {
+ if m != nil {
+ return m.Action
+ }
+ return nil
+}
+
+type AddActionsResponse struct {
+ XXX_NoUnkeyedLiteral struct{} `json:"-"`
+ XXX_unrecognized []byte `json:"-"`
+ XXX_sizecache int32 `json:"-"`
+}
+
+func (m *AddActionsResponse) Reset() { *m = AddActionsResponse{} }
+func (m *AddActionsResponse) String() string { return proto.CompactTextString(m) }
+func (*AddActionsResponse) ProtoMessage() {}
+func (*AddActionsResponse) Descriptor() ([]byte, []int) {
+ return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{35}
+}
+func (m *AddActionsResponse) XXX_Unmarshal(b []byte) error {
+ return xxx_messageInfo_AddActionsResponse.Unmarshal(m, b)
+}
+func (m *AddActionsResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ return xxx_messageInfo_AddActionsResponse.Marshal(b, m, deterministic)
+}
+func (dst *AddActionsResponse) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_AddActionsResponse.Merge(dst, src)
+}
+func (m *AddActionsResponse) XXX_Size() int {
+ return xxx_messageInfo_AddActionsResponse.Size(m)
+}
+func (m *AddActionsResponse) XXX_DiscardUnknown() {
+ xxx_messageInfo_AddActionsResponse.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_AddActionsResponse proto.InternalMessageInfo
+
+type BeginTransactionRequest struct {
+ Header *InternalHeader `protobuf:"bytes,3,opt,name=header" json:"header,omitempty"`
+ App *string `protobuf:"bytes,1,req,name=app" json:"app,omitempty"`
+ AllowMultipleEg *bool `protobuf:"varint,2,opt,name=allow_multiple_eg,json=allowMultipleEg,def=0" json:"allow_multiple_eg,omitempty"`
+ DatabaseId *string `protobuf:"bytes,4,opt,name=database_id,json=databaseId" json:"database_id,omitempty"`
+ Mode *BeginTransactionRequest_TransactionMode `protobuf:"varint,5,opt,name=mode,enum=appengine.BeginTransactionRequest_TransactionMode,def=0" json:"mode,omitempty"`
+ PreviousTransaction *Transaction `protobuf:"bytes,7,opt,name=previous_transaction,json=previousTransaction" json:"previous_transaction,omitempty"`
+ XXX_NoUnkeyedLiteral struct{} `json:"-"`
+ XXX_unrecognized []byte `json:"-"`
+ XXX_sizecache int32 `json:"-"`
+}
+
+func (m *BeginTransactionRequest) Reset() { *m = BeginTransactionRequest{} }
+func (m *BeginTransactionRequest) String() string { return proto.CompactTextString(m) }
+func (*BeginTransactionRequest) ProtoMessage() {}
+func (*BeginTransactionRequest) Descriptor() ([]byte, []int) {
+ return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{36}
+}
+func (m *BeginTransactionRequest) XXX_Unmarshal(b []byte) error {
+ return xxx_messageInfo_BeginTransactionRequest.Unmarshal(m, b)
+}
+func (m *BeginTransactionRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ return xxx_messageInfo_BeginTransactionRequest.Marshal(b, m, deterministic)
+}
+func (dst *BeginTransactionRequest) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_BeginTransactionRequest.Merge(dst, src)
+}
+func (m *BeginTransactionRequest) XXX_Size() int {
+ return xxx_messageInfo_BeginTransactionRequest.Size(m)
+}
+func (m *BeginTransactionRequest) XXX_DiscardUnknown() {
+ xxx_messageInfo_BeginTransactionRequest.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_BeginTransactionRequest proto.InternalMessageInfo
+
+const Default_BeginTransactionRequest_AllowMultipleEg bool = false
+const Default_BeginTransactionRequest_Mode BeginTransactionRequest_TransactionMode = BeginTransactionRequest_UNKNOWN
+
+func (m *BeginTransactionRequest) GetHeader() *InternalHeader {
+ if m != nil {
+ return m.Header
+ }
+ return nil
+}
+
+func (m *BeginTransactionRequest) GetApp() string {
+ if m != nil && m.App != nil {
+ return *m.App
+ }
+ return ""
+}
+
+func (m *BeginTransactionRequest) GetAllowMultipleEg() bool {
+ if m != nil && m.AllowMultipleEg != nil {
+ return *m.AllowMultipleEg
+ }
+ return Default_BeginTransactionRequest_AllowMultipleEg
+}
+
+func (m *BeginTransactionRequest) GetDatabaseId() string {
+ if m != nil && m.DatabaseId != nil {
+ return *m.DatabaseId
+ }
+ return ""
+}
+
+func (m *BeginTransactionRequest) GetMode() BeginTransactionRequest_TransactionMode {
+ if m != nil && m.Mode != nil {
+ return *m.Mode
+ }
+ return Default_BeginTransactionRequest_Mode
+}
+
+func (m *BeginTransactionRequest) GetPreviousTransaction() *Transaction {
+ if m != nil {
+ return m.PreviousTransaction
+ }
+ return nil
+}
+
+type CommitResponse struct {
+ Cost *Cost `protobuf:"bytes,1,opt,name=cost" json:"cost,omitempty"`
+ Version []*CommitResponse_Version `protobuf:"group,3,rep,name=Version,json=version" json:"version,omitempty"`
+ XXX_NoUnkeyedLiteral struct{} `json:"-"`
+ XXX_unrecognized []byte `json:"-"`
+ XXX_sizecache int32 `json:"-"`
+}
+
+func (m *CommitResponse) Reset() { *m = CommitResponse{} }
+func (m *CommitResponse) String() string { return proto.CompactTextString(m) }
+func (*CommitResponse) ProtoMessage() {}
+func (*CommitResponse) Descriptor() ([]byte, []int) {
+ return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{37}
+}
+func (m *CommitResponse) XXX_Unmarshal(b []byte) error {
+ return xxx_messageInfo_CommitResponse.Unmarshal(m, b)
+}
+func (m *CommitResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ return xxx_messageInfo_CommitResponse.Marshal(b, m, deterministic)
+}
+func (dst *CommitResponse) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_CommitResponse.Merge(dst, src)
+}
+func (m *CommitResponse) XXX_Size() int {
+ return xxx_messageInfo_CommitResponse.Size(m)
+}
+func (m *CommitResponse) XXX_DiscardUnknown() {
+ xxx_messageInfo_CommitResponse.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_CommitResponse proto.InternalMessageInfo
+
+func (m *CommitResponse) GetCost() *Cost {
+ if m != nil {
+ return m.Cost
+ }
+ return nil
+}
+
+func (m *CommitResponse) GetVersion() []*CommitResponse_Version {
+ if m != nil {
+ return m.Version
+ }
+ return nil
+}
+
+type CommitResponse_Version struct {
+ RootEntityKey *Reference `protobuf:"bytes,4,req,name=root_entity_key,json=rootEntityKey" json:"root_entity_key,omitempty"`
+ Version *int64 `protobuf:"varint,5,req,name=version" json:"version,omitempty"`
+ XXX_NoUnkeyedLiteral struct{} `json:"-"`
+ XXX_unrecognized []byte `json:"-"`
+ XXX_sizecache int32 `json:"-"`
+}
+
+func (m *CommitResponse_Version) Reset() { *m = CommitResponse_Version{} }
+func (m *CommitResponse_Version) String() string { return proto.CompactTextString(m) }
+func (*CommitResponse_Version) ProtoMessage() {}
+func (*CommitResponse_Version) Descriptor() ([]byte, []int) {
+ return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{37, 0}
+}
+func (m *CommitResponse_Version) XXX_Unmarshal(b []byte) error {
+ return xxx_messageInfo_CommitResponse_Version.Unmarshal(m, b)
+}
+func (m *CommitResponse_Version) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ return xxx_messageInfo_CommitResponse_Version.Marshal(b, m, deterministic)
+}
+func (dst *CommitResponse_Version) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_CommitResponse_Version.Merge(dst, src)
+}
+func (m *CommitResponse_Version) XXX_Size() int {
+ return xxx_messageInfo_CommitResponse_Version.Size(m)
+}
+func (m *CommitResponse_Version) XXX_DiscardUnknown() {
+ xxx_messageInfo_CommitResponse_Version.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_CommitResponse_Version proto.InternalMessageInfo
+
+func (m *CommitResponse_Version) GetRootEntityKey() *Reference {
+ if m != nil {
+ return m.RootEntityKey
+ }
+ return nil
+}
+
+func (m *CommitResponse_Version) GetVersion() int64 {
+ if m != nil && m.Version != nil {
+ return *m.Version
+ }
+ return 0
+}
+
+func init() {
+ proto.RegisterType((*Action)(nil), "appengine.Action")
+ proto.RegisterType((*PropertyValue)(nil), "appengine.PropertyValue")
+ proto.RegisterType((*PropertyValue_PointValue)(nil), "appengine.PropertyValue.PointValue")
+ proto.RegisterType((*PropertyValue_UserValue)(nil), "appengine.PropertyValue.UserValue")
+ proto.RegisterType((*PropertyValue_ReferenceValue)(nil), "appengine.PropertyValue.ReferenceValue")
+ proto.RegisterType((*PropertyValue_ReferenceValue_PathElement)(nil), "appengine.PropertyValue.ReferenceValue.PathElement")
+ proto.RegisterType((*Property)(nil), "appengine.Property")
+ proto.RegisterType((*Path)(nil), "appengine.Path")
+ proto.RegisterType((*Path_Element)(nil), "appengine.Path.Element")
+ proto.RegisterType((*Reference)(nil), "appengine.Reference")
+ proto.RegisterType((*User)(nil), "appengine.User")
+ proto.RegisterType((*EntityProto)(nil), "appengine.EntityProto")
+ proto.RegisterType((*CompositeProperty)(nil), "appengine.CompositeProperty")
+ proto.RegisterType((*Index)(nil), "appengine.Index")
+ proto.RegisterType((*Index_Property)(nil), "appengine.Index.Property")
+ proto.RegisterType((*CompositeIndex)(nil), "appengine.CompositeIndex")
+ proto.RegisterType((*IndexPostfix)(nil), "appengine.IndexPostfix")
+ proto.RegisterType((*IndexPostfix_IndexValue)(nil), "appengine.IndexPostfix.IndexValue")
+ proto.RegisterType((*IndexPosition)(nil), "appengine.IndexPosition")
+ proto.RegisterType((*Snapshot)(nil), "appengine.Snapshot")
+ proto.RegisterType((*InternalHeader)(nil), "appengine.InternalHeader")
+ proto.RegisterType((*Transaction)(nil), "appengine.Transaction")
+ proto.RegisterType((*Query)(nil), "appengine.Query")
+ proto.RegisterType((*Query_Filter)(nil), "appengine.Query.Filter")
+ proto.RegisterType((*Query_Order)(nil), "appengine.Query.Order")
+ proto.RegisterType((*CompiledQuery)(nil), "appengine.CompiledQuery")
+ proto.RegisterType((*CompiledQuery_PrimaryScan)(nil), "appengine.CompiledQuery.PrimaryScan")
+ proto.RegisterType((*CompiledQuery_MergeJoinScan)(nil), "appengine.CompiledQuery.MergeJoinScan")
+ proto.RegisterType((*CompiledQuery_EntityFilter)(nil), "appengine.CompiledQuery.EntityFilter")
+ proto.RegisterType((*CompiledCursor)(nil), "appengine.CompiledCursor")
+ proto.RegisterType((*CompiledCursor_Position)(nil), "appengine.CompiledCursor.Position")
+ proto.RegisterType((*CompiledCursor_Position_IndexValue)(nil), "appengine.CompiledCursor.Position.IndexValue")
+ proto.RegisterType((*Cursor)(nil), "appengine.Cursor")
+ proto.RegisterType((*Error)(nil), "appengine.Error")
+ proto.RegisterType((*Cost)(nil), "appengine.Cost")
+ proto.RegisterType((*Cost_CommitCost)(nil), "appengine.Cost.CommitCost")
+ proto.RegisterType((*GetRequest)(nil), "appengine.GetRequest")
+ proto.RegisterType((*GetResponse)(nil), "appengine.GetResponse")
+ proto.RegisterType((*GetResponse_Entity)(nil), "appengine.GetResponse.Entity")
+ proto.RegisterType((*PutRequest)(nil), "appengine.PutRequest")
+ proto.RegisterType((*PutResponse)(nil), "appengine.PutResponse")
+ proto.RegisterType((*TouchRequest)(nil), "appengine.TouchRequest")
+ proto.RegisterType((*TouchResponse)(nil), "appengine.TouchResponse")
+ proto.RegisterType((*DeleteRequest)(nil), "appengine.DeleteRequest")
+ proto.RegisterType((*DeleteResponse)(nil), "appengine.DeleteResponse")
+ proto.RegisterType((*NextRequest)(nil), "appengine.NextRequest")
+ proto.RegisterType((*QueryResult)(nil), "appengine.QueryResult")
+ proto.RegisterType((*AllocateIdsRequest)(nil), "appengine.AllocateIdsRequest")
+ proto.RegisterType((*AllocateIdsResponse)(nil), "appengine.AllocateIdsResponse")
+ proto.RegisterType((*CompositeIndices)(nil), "appengine.CompositeIndices")
+ proto.RegisterType((*AddActionsRequest)(nil), "appengine.AddActionsRequest")
+ proto.RegisterType((*AddActionsResponse)(nil), "appengine.AddActionsResponse")
+ proto.RegisterType((*BeginTransactionRequest)(nil), "appengine.BeginTransactionRequest")
+ proto.RegisterType((*CommitResponse)(nil), "appengine.CommitResponse")
+ proto.RegisterType((*CommitResponse_Version)(nil), "appengine.CommitResponse.Version")
+}
+
+func init() {
+ proto.RegisterFile("google.golang.org/appengine/internal/datastore/datastore_v3.proto", fileDescriptor_datastore_v3_83b17b80c34f6179)
+}
+
+var fileDescriptor_datastore_v3_83b17b80c34f6179 = []byte{
+ // 4156 bytes of a gzipped FileDescriptorProto
+ 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xcc, 0x5a, 0xcd, 0x73, 0xe3, 0x46,
+ 0x76, 0x37, 0xc1, 0xef, 0x47, 0x89, 0x82, 0x5a, 0xf3, 0xc1, 0xa1, 0x3f, 0x46, 0xc6, 0xac, 0x6d,
+ 0xd9, 0x6b, 0x73, 0x6c, 0xf9, 0x23, 0x5b, 0x4a, 0x76, 0x1d, 0x4a, 0xc4, 0x68, 0x90, 0xa1, 0x48,
+ 0xb9, 0x09, 0xd9, 0x9e, 0x5c, 0x50, 0x18, 0xa2, 0x29, 0x21, 0x43, 0x02, 0x30, 0x00, 0x6a, 0x46,
+ 0x93, 0xe4, 0x90, 0x4b, 0x2a, 0x55, 0x5b, 0xa9, 0x1c, 0x92, 0x4a, 0x25, 0xf9, 0x07, 0x72, 0xc8,
+ 0x39, 0x95, 0xaa, 0x54, 0xf6, 0x98, 0x5b, 0x0e, 0x7b, 0xc9, 0x31, 0x95, 0x73, 0xf2, 0x27, 0x24,
+ 0x39, 0xa4, 0xfa, 0x75, 0x03, 0x02, 0x28, 0x4a, 0x23, 0x6d, 0xf6, 0x90, 0x13, 0xd1, 0xef, 0xfd,
+ 0xba, 0xf1, 0xfa, 0xf5, 0xfb, 0x6c, 0x10, 0xba, 0xc7, 0xbe, 0x7f, 0x3c, 0x65, 0x9d, 0x63, 0x7f,
+ 0x6a, 0x7b, 0xc7, 0x1d, 0x3f, 0x3c, 0x7e, 0x68, 0x07, 0x01, 0xf3, 0x8e, 0x5d, 0x8f, 0x3d, 0x74,
+ 0xbd, 0x98, 0x85, 0x9e, 0x3d, 0x7d, 0xe8, 0xd8, 0xb1, 0x1d, 0xc5, 0x7e, 0xc8, 0xce, 0x9f, 0xac,
+ 0xd3, 0xcf, 0x3b, 0x41, 0xe8, 0xc7, 0x3e, 0xa9, 0xa7, 0x13, 0xb4, 0x1a, 0x54, 0xba, 0xe3, 0xd8,
+ 0xf5, 0x3d, 0xed, 0x1f, 0x2b, 0xb0, 0x7a, 0x18, 0xfa, 0x01, 0x0b, 0xe3, 0xb3, 0x6f, 0xed, 0xe9,
+ 0x9c, 0x91, 0x77, 0x00, 0x5c, 0x2f, 0xfe, 0xea, 0x0b, 0x1c, 0xb5, 0x0a, 0x9b, 0x85, 0xad, 0x22,
+ 0xcd, 0x50, 0x88, 0x06, 0x2b, 0xcf, 0x7c, 0x7f, 0xca, 0x6c, 0x4f, 0x20, 0x94, 0xcd, 0xc2, 0x56,
+ 0x8d, 0xe6, 0x68, 0x64, 0x13, 0x1a, 0x51, 0x1c, 0xba, 0xde, 0xb1, 0x80, 0x14, 0x37, 0x0b, 0x5b,
+ 0x75, 0x9a, 0x25, 0x71, 0x84, 0xe3, 0xcf, 0x9f, 0x4d, 0x99, 0x40, 0x94, 0x36, 0x0b, 0x5b, 0x05,
+ 0x9a, 0x25, 0x91, 0x3d, 0x80, 0xc0, 0x77, 0xbd, 0xf8, 0x14, 0x01, 0xe5, 0xcd, 0xc2, 0x16, 0x6c,
+ 0x3f, 0xe8, 0xa4, 0x7b, 0xe8, 0xe4, 0xa4, 0xee, 0x1c, 0x72, 0x28, 0x3e, 0xd2, 0xcc, 0x34, 0xf2,
+ 0xdb, 0x50, 0x9f, 0x47, 0x2c, 0x14, 0x6b, 0xd4, 0x70, 0x0d, 0xed, 0xd2, 0x35, 0x8e, 0x22, 0x16,
+ 0x8a, 0x25, 0xce, 0x27, 0x91, 0x21, 0x34, 0x43, 0x36, 0x61, 0x21, 0xf3, 0xc6, 0x4c, 0x2c, 0xb3,
+ 0x82, 0xcb, 0x7c, 0x70, 0xe9, 0x32, 0x34, 0x81, 0x8b, 0xb5, 0x16, 0xa6, 0xb7, 0xb7, 0x00, 0xce,
+ 0x85, 0x25, 0x2b, 0x50, 0x78, 0xd9, 0xaa, 0x6c, 0x2a, 0x5b, 0x05, 0x5a, 0x78, 0xc9, 0x47, 0x67,
+ 0xad, 0xaa, 0x18, 0x9d, 0xb5, 0xff, 0xa9, 0x00, 0xf5, 0x54, 0x26, 0x72, 0x0b, 0xca, 0x6c, 0x66,
+ 0xbb, 0xd3, 0x56, 0x7d, 0x53, 0xd9, 0xaa, 0x53, 0x31, 0x20, 0xf7, 0xa1, 0x61, 0xcf, 0xe3, 0x13,
+ 0xcb, 0xf1, 0x67, 0xb6, 0xeb, 0xb5, 0x00, 0x79, 0xc0, 0x49, 0x3d, 0xa4, 0x90, 0x36, 0xd4, 0x3c,
+ 0x77, 0xfc, 0xdc, 0xb3, 0x67, 0xac, 0xd5, 0xc0, 0x73, 0x48, 0xc7, 0xe4, 0x13, 0x20, 0x13, 0xe6,
+ 0xb0, 0xd0, 0x8e, 0x99, 0x63, 0xb9, 0x0e, 0xf3, 0x62, 0x37, 0x3e, 0x6b, 0xdd, 0x46, 0xd4, 0x7a,
+ 0xca, 0x31, 0x24, 0x23, 0x0f, 0x0f, 0x42, 0xff, 0xd4, 0x75, 0x58, 0xd8, 0xba, 0xb3, 0x00, 0x3f,
+ 0x94, 0x8c, 0xf6, 0xbf, 0x17, 0xa0, 0x99, 0xd7, 0x05, 0x51, 0xa1, 0x68, 0x07, 0x41, 0x6b, 0x15,
+ 0xa5, 0xe4, 0x8f, 0xe4, 0x6d, 0x00, 0x2e, 0x8a, 0x15, 0x05, 0xf6, 0x98, 0xb5, 0x6e, 0xe1, 0x5a,
+ 0x75, 0x4e, 0x19, 0x71, 0x02, 0x39, 0x82, 0x46, 0x60, 0xc7, 0x27, 0x6c, 0xca, 0x66, 0xcc, 0x8b,
+ 0x5b, 0xcd, 0xcd, 0xe2, 0x16, 0x6c, 0x7f, 0x7e, 0x4d, 0xd5, 0x77, 0x0e, 0xed, 0xf8, 0x44, 0x17,
+ 0x53, 0x69, 0x76, 0x9d, 0xb6, 0x0e, 0x8d, 0x0c, 0x8f, 0x10, 0x28, 0xc5, 0x67, 0x01, 0x6b, 0xad,
+ 0xa1, 0x5c, 0xf8, 0x4c, 0x9a, 0xa0, 0xb8, 0x4e, 0x4b, 0x45, 0xf3, 0x57, 0x5c, 0x87, 0x63, 0x50,
+ 0x87, 0xeb, 0x28, 0x22, 0x3e, 0x6b, 0xff, 0x51, 0x86, 0x5a, 0x22, 0x00, 0xe9, 0x42, 0x75, 0xc6,
+ 0x6c, 0xcf, 0xf5, 0x8e, 0xd1, 0x69, 0x9a, 0xdb, 0x6f, 0x2e, 0x11, 0xb3, 0x73, 0x20, 0x20, 0x3b,
+ 0x30, 0x18, 0x5a, 0x07, 0x7a, 0x77, 0x60, 0x0c, 0xf6, 0x69, 0x32, 0x8f, 0x1f, 0xa6, 0x7c, 0xb4,
+ 0xe6, 0xa1, 0x8b, 0x9e, 0x55, 0xa7, 0x20, 0x49, 0x47, 0xa1, 0x9b, 0x0a, 0x51, 0x14, 0x82, 0xe2,
+ 0x21, 0x76, 0xa0, 0x9c, 0xb8, 0x88, 0xb2, 0xd5, 0xd8, 0x6e, 0x5d, 0xa6, 0x1c, 0x2a, 0x60, 0xdc,
+ 0x20, 0x66, 0xf3, 0x69, 0xec, 0x06, 0x53, 0xee, 0x76, 0xca, 0x56, 0x8d, 0xa6, 0x63, 0xf2, 0x1e,
+ 0x40, 0xc4, 0xec, 0x70, 0x7c, 0x62, 0x3f, 0x9b, 0xb2, 0x56, 0x85, 0x7b, 0xf6, 0x4e, 0x79, 0x62,
+ 0x4f, 0x23, 0x46, 0x33, 0x0c, 0x62, 0xc3, 0xdd, 0x49, 0x1c, 0x59, 0xb1, 0xff, 0x9c, 0x79, 0xee,
+ 0x2b, 0x9b, 0x07, 0x12, 0xcb, 0x0f, 0xf8, 0x0f, 0xfa, 0x58, 0x73, 0xfb, 0xc3, 0x65, 0x5b, 0x7f,
+ 0x14, 0x47, 0x66, 0x66, 0xc6, 0x10, 0x27, 0xd0, 0xdb, 0x93, 0x65, 0x64, 0xd2, 0x86, 0xca, 0xd4,
+ 0x1f, 0xdb, 0x53, 0xd6, 0xaa, 0x73, 0x2d, 0xec, 0x28, 0xcc, 0xa3, 0x92, 0xa2, 0xfd, 0xb3, 0x02,
+ 0x55, 0xa9, 0x47, 0xd2, 0x84, 0x8c, 0x26, 0xd5, 0x37, 0x48, 0x0d, 0x4a, 0xbb, 0xfd, 0xe1, 0xae,
+ 0xda, 0xe4, 0x4f, 0xa6, 0xfe, 0xbd, 0xa9, 0xae, 0x71, 0xcc, 0xee, 0x53, 0x53, 0x1f, 0x99, 0x94,
+ 0x63, 0x54, 0xb2, 0x0e, 0xab, 0x5d, 0x73, 0x78, 0x60, 0xed, 0x75, 0x4d, 0x7d, 0x7f, 0x48, 0x9f,
+ 0xaa, 0x05, 0xb2, 0x0a, 0x75, 0x24, 0xf5, 0x8d, 0xc1, 0x13, 0x55, 0xe1, 0x33, 0x70, 0x68, 0x1a,
+ 0x66, 0x5f, 0x57, 0x8b, 0x44, 0x85, 0x15, 0x31, 0x63, 0x38, 0x30, 0xf5, 0x81, 0xa9, 0x96, 0x52,
+ 0xca, 0xe8, 0xe8, 0xe0, 0xa0, 0x4b, 0x9f, 0xaa, 0x65, 0xb2, 0x06, 0x0d, 0xa4, 0x74, 0x8f, 0xcc,
+ 0xc7, 0x43, 0xaa, 0x56, 0x48, 0x03, 0xaa, 0xfb, 0x3d, 0xeb, 0xbb, 0xc7, 0xfa, 0x40, 0xad, 0x92,
+ 0x15, 0xa8, 0xed, 0xf7, 0x2c, 0xfd, 0xa0, 0x6b, 0xf4, 0xd5, 0x1a, 0x9f, 0xbd, 0xaf, 0x0f, 0xe9,
+ 0x68, 0x64, 0x1d, 0x0e, 0x8d, 0x81, 0xa9, 0xd6, 0x49, 0x1d, 0xca, 0xfb, 0x3d, 0xcb, 0x38, 0x50,
+ 0x81, 0x10, 0x68, 0xee, 0xf7, 0xac, 0xc3, 0xc7, 0xc3, 0x81, 0x3e, 0x38, 0x3a, 0xd8, 0xd5, 0xa9,
+ 0xda, 0x20, 0xb7, 0x40, 0xe5, 0xb4, 0xe1, 0xc8, 0xec, 0xf6, 0xbb, 0xbd, 0x1e, 0xd5, 0x47, 0x23,
+ 0x75, 0x85, 0x4b, 0xbd, 0xdf, 0xb3, 0x68, 0xd7, 0xe4, 0xfb, 0x5a, 0xe5, 0x2f, 0xe4, 0x7b, 0x7f,
+ 0xa2, 0x3f, 0x55, 0xd7, 0xf9, 0x2b, 0xf4, 0x81, 0x69, 0x98, 0x4f, 0xad, 0x43, 0x3a, 0x34, 0x87,
+ 0xea, 0x06, 0x17, 0xd0, 0x18, 0xf4, 0xf4, 0xef, 0xad, 0x6f, 0xbb, 0xfd, 0x23, 0x5d, 0x25, 0xda,
+ 0x8f, 0xe1, 0xf6, 0xd2, 0x33, 0xe1, 0xaa, 0x7b, 0x6c, 0x1e, 0xf4, 0xd5, 0x02, 0x7f, 0xe2, 0x9b,
+ 0x52, 0x15, 0xed, 0x0f, 0xa0, 0xc4, 0x5d, 0x86, 0x7c, 0x06, 0xd5, 0xc4, 0x1b, 0x0b, 0xe8, 0x8d,
+ 0x77, 0xb3, 0x67, 0x6d, 0xc7, 0x27, 0x9d, 0xc4, 0xe3, 0x12, 0x5c, 0xbb, 0x0b, 0xd5, 0x45, 0x4f,
+ 0x53, 0x2e, 0x78, 0x5a, 0xf1, 0x82, 0xa7, 0x95, 0x32, 0x9e, 0x66, 0x43, 0x3d, 0xf5, 0xed, 0x9b,
+ 0x47, 0x91, 0x07, 0x50, 0xe2, 0xde, 0xdf, 0x6a, 0xa2, 0x87, 0xac, 0x2d, 0x08, 0x4c, 0x91, 0xa9,
+ 0xfd, 0x43, 0x01, 0x4a, 0x3c, 0xda, 0x9e, 0x07, 0xda, 0xc2, 0x15, 0x81, 0x56, 0xb9, 0x32, 0xd0,
+ 0x16, 0xaf, 0x15, 0x68, 0x2b, 0x37, 0x0b, 0xb4, 0xd5, 0x4b, 0x02, 0xad, 0xf6, 0x67, 0x45, 0x68,
+ 0xe8, 0x38, 0xf3, 0x10, 0x13, 0xfd, 0xfb, 0x50, 0x7c, 0xce, 0xce, 0x50, 0x3f, 0x8d, 0xed, 0x5b,
+ 0x99, 0xdd, 0xa6, 0x2a, 0xa4, 0x1c, 0x40, 0xb6, 0x61, 0x45, 0xbc, 0xd0, 0x3a, 0x0e, 0xfd, 0x79,
+ 0xd0, 0x52, 0x97, 0xab, 0xa7, 0x21, 0x40, 0xfb, 0x1c, 0x43, 0xde, 0x83, 0xb2, 0xff, 0xc2, 0x63,
+ 0x21, 0xc6, 0xc1, 0x3c, 0x98, 0x2b, 0x8f, 0x0a, 0x2e, 0x79, 0x08, 0xa5, 0xe7, 0xae, 0xe7, 0xe0,
+ 0x19, 0xe6, 0x23, 0x61, 0x46, 0xd0, 0xce, 0x13, 0xd7, 0x73, 0x28, 0x02, 0xc9, 0x3d, 0xa8, 0xf1,
+ 0x5f, 0x8c, 0x7b, 0x65, 0xdc, 0x68, 0x95, 0x8f, 0x79, 0xd0, 0x7b, 0x08, 0xb5, 0x40, 0xc6, 0x10,
+ 0x4c, 0x00, 0x8d, 0xed, 0x8d, 0x25, 0xe1, 0x85, 0xa6, 0x20, 0xf2, 0x15, 0xac, 0x84, 0xf6, 0x0b,
+ 0x2b, 0x9d, 0xb4, 0x76, 0xf9, 0xa4, 0x46, 0x68, 0xbf, 0x48, 0x23, 0x38, 0x81, 0x52, 0x68, 0x7b,
+ 0xcf, 0x5b, 0x64, 0xb3, 0xb0, 0x55, 0xa6, 0xf8, 0xac, 0x7d, 0x01, 0x25, 0x2e, 0x25, 0x8f, 0x08,
+ 0xfb, 0x3d, 0xf4, 0xff, 0xee, 0x9e, 0xa9, 0x16, 0x12, 0x7f, 0xfe, 0x96, 0x47, 0x03, 0x45, 0x72,
+ 0x0f, 0xf4, 0xd1, 0xa8, 0xbb, 0xaf, 0xab, 0x45, 0xad, 0x07, 0xeb, 0x7b, 0xfe, 0x2c, 0xf0, 0x23,
+ 0x37, 0x66, 0xe9, 0xf2, 0xf7, 0xa0, 0xe6, 0x7a, 0x0e, 0x7b, 0x69, 0xb9, 0x0e, 0x9a, 0x56, 0x91,
+ 0x56, 0x71, 0x6c, 0x38, 0xdc, 0xe4, 0x4e, 0x65, 0x31, 0x55, 0xe4, 0x26, 0x87, 0x03, 0xed, 0x2f,
+ 0x15, 0x28, 0x1b, 0x1c, 0xc1, 0x8d, 0x4f, 0x9e, 0x14, 0x7a, 0x8f, 0x30, 0x4c, 0x10, 0x24, 0x93,
+ 0xfb, 0x50, 0x1b, 0x6a, 0xb6, 0x37, 0x66, 0xbc, 0xe2, 0xc3, 0x3c, 0x50, 0xa3, 0xe9, 0x98, 0x7c,
+ 0x99, 0xd1, 0x9f, 0x82, 0x2e, 0x7b, 0x2f, 0xa3, 0x0a, 0x7c, 0xc1, 0x12, 0x2d, 0xb6, 0xff, 0xaa,
+ 0x90, 0x49, 0x6e, 0xcb, 0x12, 0x4f, 0x1f, 0xea, 0x8e, 0x1b, 0x32, 0xac, 0x23, 0xe5, 0x41, 0x3f,
+ 0xb8, 0x74, 0xe1, 0x4e, 0x2f, 0x81, 0xee, 0xd4, 0xbb, 0xa3, 0x3d, 0x7d, 0xd0, 0xe3, 0x99, 0xef,
+ 0x7c, 0x01, 0xed, 0x23, 0xa8, 0xa7, 0x10, 0x0c, 0xc7, 0x09, 0x48, 0x2d, 0x70, 0xf5, 0xf6, 0xf4,
+ 0x74, 0xac, 0x68, 0x7f, 0xad, 0x40, 0x33, 0xd5, 0xaf, 0xd0, 0xd0, 0x6d, 0xa8, 0xd8, 0x41, 0x90,
+ 0xa8, 0xb6, 0x4e, 0xcb, 0x76, 0x10, 0x18, 0x8e, 0x8c, 0x2d, 0x0a, 0x6a, 0x9b, 0xc7, 0x96, 0x4f,
+ 0x01, 0x1c, 0x36, 0x71, 0x3d, 0x17, 0x85, 0x2e, 0xa2, 0xc1, 0xab, 0x8b, 0x42, 0xd3, 0x0c, 0x86,
+ 0x7c, 0x09, 0xe5, 0x28, 0xb6, 0x63, 0x91, 0x2b, 0x9b, 0xdb, 0xf7, 0x33, 0xe0, 0xbc, 0x08, 0x9d,
+ 0x11, 0x87, 0x51, 0x81, 0x26, 0x5f, 0xc1, 0x2d, 0xdf, 0x9b, 0x9e, 0x59, 0xf3, 0x88, 0x59, 0xee,
+ 0xc4, 0x0a, 0xd9, 0x0f, 0x73, 0x37, 0x64, 0x4e, 0x3e, 0xa7, 0xae, 0x73, 0xc8, 0x51, 0xc4, 0x8c,
+ 0x09, 0x95, 0x7c, 0xed, 0x6b, 0x28, 0xe3, 0x3a, 0x7c, 0xcf, 0xdf, 0x51, 0xc3, 0xd4, 0xad, 0xe1,
+ 0xa0, 0xff, 0x54, 0xe8, 0x80, 0xea, 0xdd, 0x9e, 0x85, 0x44, 0x55, 0xe1, 0xc1, 0xbe, 0xa7, 0xf7,
+ 0x75, 0x53, 0xef, 0xa9, 0x45, 0x9e, 0x3d, 0x74, 0x4a, 0x87, 0x54, 0x2d, 0x69, 0xff, 0x53, 0x80,
+ 0x15, 0x94, 0xe7, 0xd0, 0x8f, 0xe2, 0x89, 0xfb, 0x92, 0xec, 0x41, 0x43, 0x98, 0xdd, 0xa9, 0x2c,
+ 0xe8, 0xb9, 0x33, 0x68, 0x8b, 0x7b, 0x96, 0x68, 0x31, 0x90, 0x75, 0xb4, 0x9b, 0x3e, 0x27, 0x21,
+ 0x45, 0x41, 0xa7, 0xbf, 0x22, 0xa4, 0xbc, 0x05, 0x95, 0x67, 0x6c, 0xe2, 0x87, 0x22, 0x04, 0xd6,
+ 0x76, 0x4a, 0x71, 0x38, 0x67, 0x54, 0xd2, 0xda, 0x36, 0xc0, 0xf9, 0xfa, 0xe4, 0x01, 0xac, 0x26,
+ 0xc6, 0x66, 0xa1, 0x71, 0x89, 0x93, 0x5b, 0x49, 0x88, 0x83, 0x5c, 0x75, 0xa3, 0x5c, 0xab, 0xba,
+ 0xd1, 0xbe, 0x86, 0xd5, 0x64, 0x3f, 0xe2, 0xfc, 0x54, 0x21, 0x79, 0x01, 0x63, 0xca, 0x82, 0x8c,
+ 0xca, 0x45, 0x19, 0xb5, 0x9f, 0x41, 0x6d, 0xe4, 0xd9, 0x41, 0x74, 0xe2, 0xc7, 0xdc, 0x7a, 0xe2,
+ 0x48, 0xfa, 0xaa, 0x12, 0x47, 0x9a, 0x06, 0x15, 0x7e, 0x38, 0xf3, 0x88, 0xbb, 0xbf, 0x31, 0xe8,
+ 0xee, 0x99, 0xc6, 0xb7, 0xba, 0xfa, 0x06, 0x01, 0xa8, 0xc8, 0xe7, 0x82, 0xa6, 0x41, 0xd3, 0x90,
+ 0xed, 0xd8, 0x63, 0x66, 0x3b, 0x2c, 0xe4, 0x12, 0xfc, 0xe0, 0x47, 0x89, 0x04, 0x3f, 0xf8, 0x91,
+ 0xf6, 0x17, 0x05, 0x68, 0x98, 0xa1, 0xed, 0x45, 0xb6, 0x30, 0xf7, 0xcf, 0xa0, 0x72, 0x82, 0x58,
+ 0x74, 0xa3, 0xc6, 0x82, 0x7f, 0x66, 0x17, 0xa3, 0x12, 0x48, 0xee, 0x40, 0xe5, 0xc4, 0xf6, 0x9c,
+ 0xa9, 0xd0, 0x5a, 0x85, 0xca, 0x51, 0x92, 0x1b, 0x95, 0xf3, 0xdc, 0xb8, 0x05, 0x2b, 0x33, 0x3b,
+ 0x7c, 0x6e, 0x8d, 0x4f, 0x6c, 0xef, 0x98, 0x45, 0xf2, 0x60, 0xa4, 0x05, 0x36, 0x38, 0x6b, 0x4f,
+ 0x70, 0xb4, 0xbf, 0x5f, 0x81, 0xf2, 0x37, 0x73, 0x16, 0x9e, 0x65, 0x04, 0xfa, 0xe0, 0xba, 0x02,
+ 0xc9, 0x17, 0x17, 0x2e, 0x4b, 0xca, 0x6f, 0x2f, 0x26, 0x65, 0x22, 0x53, 0x84, 0xc8, 0x95, 0x22,
+ 0x0b, 0x7c, 0x9a, 0x09, 0x63, 0xeb, 0x57, 0xd8, 0xda, 0x79, 0x70, 0x7b, 0x08, 0x95, 0x89, 0x3b,
+ 0x8d, 0x51, 0x75, 0x8b, 0xd5, 0x08, 0xee, 0xa5, 0xf3, 0x08, 0xd9, 0x54, 0xc2, 0xc8, 0xbb, 0xb0,
+ 0x22, 0x2a, 0x59, 0xeb, 0x07, 0xce, 0xc6, 0x82, 0x95, 0xf7, 0xa6, 0x48, 0x13, 0xbb, 0xff, 0x18,
+ 0xca, 0x7e, 0xc8, 0x37, 0x5f, 0xc7, 0x25, 0xef, 0x5c, 0x58, 0x72, 0xc8, 0xb9, 0x54, 0x80, 0xc8,
+ 0x87, 0x50, 0x3a, 0x71, 0xbd, 0x18, 0xb3, 0x46, 0x73, 0xfb, 0xf6, 0x05, 0xf0, 0x63, 0xd7, 0x8b,
+ 0x29, 0x42, 0x78, 0x98, 0x1f, 0xfb, 0x73, 0x2f, 0x6e, 0xdd, 0xc5, 0x0c, 0x23, 0x06, 0xe4, 0x1e,
+ 0x54, 0xfc, 0xc9, 0x24, 0x62, 0x31, 0x76, 0x96, 0xe5, 0x9d, 0xc2, 0xa7, 0x54, 0x12, 0xf8, 0x84,
+ 0xa9, 0x3b, 0x73, 0x63, 0xec, 0x43, 0xca, 0x54, 0x0c, 0xc8, 0x2e, 0xac, 0x8d, 0xfd, 0x59, 0xe0,
+ 0x4e, 0x99, 0x63, 0x8d, 0xe7, 0x61, 0xe4, 0x87, 0xad, 0x77, 0x2e, 0x1c, 0xd3, 0x9e, 0x44, 0xec,
+ 0x21, 0x80, 0x36, 0xc7, 0xb9, 0x31, 0x31, 0x60, 0x83, 0x79, 0x8e, 0xb5, 0xb8, 0xce, 0xfd, 0xd7,
+ 0xad, 0xb3, 0xce, 0x3c, 0x27, 0x4f, 0x4a, 0xc4, 0xc1, 0x48, 0x68, 0x61, 0xcc, 0x68, 0x6d, 0x60,
+ 0x90, 0xb9, 0x77, 0x69, 0xac, 0x14, 0xe2, 0x64, 0xc2, 0xf7, 0x6f, 0xc0, 0x2d, 0x19, 0x22, 0xad,
+ 0x80, 0x85, 0x13, 0x36, 0x8e, 0xad, 0x60, 0x6a, 0x7b, 0x58, 0xca, 0xa5, 0xc6, 0x4a, 0x24, 0xe4,
+ 0x50, 0x20, 0x0e, 0xa7, 0xb6, 0x47, 0x34, 0xa8, 0x3f, 0x67, 0x67, 0x91, 0xc5, 0x23, 0x29, 0x76,
+ 0xae, 0x29, 0xba, 0xc6, 0xe9, 0x43, 0x6f, 0x7a, 0x46, 0x7e, 0x02, 0x8d, 0xf8, 0xdc, 0xdb, 0xb0,
+ 0x61, 0x6d, 0xe4, 0x4e, 0x35, 0xe3, 0x8b, 0x34, 0x0b, 0x25, 0xf7, 0xa1, 0x2a, 0x35, 0xd4, 0xba,
+ 0x97, 0x5d, 0x3b, 0xa1, 0xf2, 0xc4, 0x3c, 0xb1, 0xdd, 0xa9, 0x7f, 0xca, 0x42, 0x6b, 0x16, 0xb5,
+ 0xda, 0xe2, 0xb6, 0x24, 0x21, 0x1d, 0x44, 0xdc, 0x4f, 0xa3, 0x38, 0xf4, 0xbd, 0xe3, 0xd6, 0x26,
+ 0xde, 0x93, 0xc8, 0xd1, 0xc5, 0xe0, 0xf7, 0x2e, 0x66, 0xfe, 0x7c, 0xf0, 0xfb, 0x1c, 0xee, 0x60,
+ 0x65, 0x66, 0x3d, 0x3b, 0xb3, 0xf2, 0x68, 0x0d, 0xd1, 0x1b, 0xc8, 0xdd, 0x3d, 0x3b, 0xcc, 0x4e,
+ 0x6a, 0x43, 0xcd, 0x71, 0xa3, 0xd8, 0xf5, 0xc6, 0x71, 0xab, 0x85, 0xef, 0x4c, 0xc7, 0xe4, 0x33,
+ 0xb8, 0x3d, 0x73, 0x3d, 0x2b, 0xb2, 0x27, 0xcc, 0x8a, 0x5d, 0xee, 0x9b, 0x6c, 0xec, 0x7b, 0x4e,
+ 0xd4, 0x7a, 0x80, 0x82, 0x93, 0x99, 0xeb, 0x8d, 0xec, 0x09, 0x33, 0xdd, 0x19, 0x1b, 0x09, 0x0e,
+ 0xf9, 0x08, 0xd6, 0x11, 0x1e, 0xb2, 0x60, 0xea, 0x8e, 0x6d, 0xf1, 0xfa, 0x1f, 0xe1, 0xeb, 0xd7,
+ 0x38, 0x83, 0x0a, 0x3a, 0xbe, 0xfa, 0x63, 0x68, 0x06, 0x2c, 0x8c, 0xdc, 0x28, 0xb6, 0xa4, 0x45,
+ 0xbf, 0x97, 0xd5, 0xda, 0xaa, 0x64, 0x0e, 0x91, 0xd7, 0xfe, 0xcf, 0x02, 0x54, 0x84, 0x73, 0x92,
+ 0x4f, 0x41, 0xf1, 0x03, 0xbc, 0x06, 0x69, 0x6e, 0x6f, 0x5e, 0xe2, 0xc1, 0x9d, 0x61, 0xc0, 0xeb,
+ 0x5e, 0x3f, 0xa4, 0x8a, 0x1f, 0xdc, 0xb8, 0x28, 0xd4, 0xfe, 0x10, 0x6a, 0xc9, 0x02, 0xbc, 0xbc,
+ 0xe8, 0xeb, 0xa3, 0x91, 0x65, 0x3e, 0xee, 0x0e, 0xd4, 0x02, 0xb9, 0x03, 0x24, 0x1d, 0x5a, 0x43,
+ 0x6a, 0xe9, 0xdf, 0x1c, 0x75, 0xfb, 0xaa, 0x82, 0x5d, 0x1a, 0xd5, 0xbb, 0xa6, 0x4e, 0x05, 0xb2,
+ 0x48, 0xee, 0xc1, 0xed, 0x2c, 0xe5, 0x1c, 0x5c, 0xc2, 0x14, 0x8c, 0x8f, 0x65, 0x52, 0x01, 0xc5,
+ 0x18, 0xa8, 0x15, 0x9e, 0x16, 0xf4, 0xef, 0x8d, 0x91, 0x39, 0x52, 0xab, 0xed, 0xbf, 0x29, 0x40,
+ 0x19, 0xc3, 0x06, 0x3f, 0x9f, 0x54, 0x72, 0x71, 0x5d, 0x73, 0x5e, 0xb9, 0x1a, 0xd9, 0x92, 0xaa,
+ 0x81, 0x01, 0x65, 0x73, 0x79, 0xf4, 0xf9, 0xb5, 0xd6, 0x53, 0x3f, 0x85, 0x12, 0x8f, 0x52, 0xbc,
+ 0x43, 0x1c, 0xd2, 0x9e, 0x4e, 0xad, 0x47, 0x06, 0x1d, 0xf1, 0x2a, 0x97, 0x40, 0xb3, 0x3b, 0xd8,
+ 0xd3, 0x47, 0xe6, 0x30, 0xa1, 0xa1, 0x56, 0x1e, 0x19, 0x7d, 0x33, 0x45, 0x15, 0xb5, 0x9f, 0xd7,
+ 0x60, 0x35, 0x89, 0x09, 0x22, 0x82, 0x3e, 0x82, 0x46, 0x10, 0xba, 0x33, 0x3b, 0x3c, 0x8b, 0xc6,
+ 0xb6, 0x87, 0x49, 0x01, 0xb6, 0x7f, 0xb4, 0x24, 0xaa, 0x88, 0x1d, 0x1d, 0x0a, 0xec, 0x68, 0x6c,
+ 0x7b, 0x34, 0x3b, 0x91, 0xf4, 0x61, 0x75, 0xc6, 0xc2, 0x63, 0xf6, 0x7b, 0xbe, 0xeb, 0xe1, 0x4a,
+ 0x55, 0x8c, 0xc8, 0xef, 0x5f, 0xba, 0xd2, 0x01, 0x47, 0xff, 0x8e, 0xef, 0x7a, 0xb8, 0x56, 0x7e,
+ 0x32, 0xf9, 0x04, 0xea, 0xa2, 0x12, 0x72, 0xd8, 0x04, 0x63, 0xc5, 0xb2, 0xda, 0x4f, 0xd4, 0xe8,
+ 0x3d, 0x36, 0xc9, 0xc4, 0x65, 0xb8, 0x34, 0x2e, 0x37, 0xb2, 0x71, 0xf9, 0xcd, 0x6c, 0x2c, 0x5a,
+ 0x11, 0x55, 0x78, 0x1a, 0x84, 0x2e, 0x38, 0x7c, 0x6b, 0x89, 0xc3, 0x77, 0x60, 0x23, 0xf1, 0x55,
+ 0xcb, 0xf5, 0x26, 0xee, 0x4b, 0x2b, 0x72, 0x5f, 0x89, 0xd8, 0x53, 0xa6, 0xeb, 0x09, 0xcb, 0xe0,
+ 0x9c, 0x91, 0xfb, 0x8a, 0x11, 0x23, 0xe9, 0xe0, 0x64, 0x0e, 0x5c, 0xc5, 0xab, 0xc9, 0xf7, 0x2e,
+ 0x55, 0x8f, 0x68, 0xbe, 0x64, 0x46, 0xcc, 0x4d, 0x6d, 0xff, 0x52, 0x81, 0x46, 0xe6, 0x1c, 0x78,
+ 0xf6, 0x16, 0xca, 0x42, 0x61, 0xc5, 0x55, 0x94, 0x50, 0x1f, 0x4a, 0xfa, 0x26, 0xd4, 0xa3, 0xd8,
+ 0x0e, 0x63, 0x8b, 0x17, 0x57, 0xb2, 0xdd, 0x45, 0xc2, 0x13, 0x76, 0x46, 0x3e, 0x80, 0x35, 0xc1,
+ 0x74, 0xbd, 0xf1, 0x74, 0x1e, 0xb9, 0xa7, 0xa2, 0x99, 0xaf, 0xd1, 0x26, 0x92, 0x8d, 0x84, 0x4a,
+ 0xee, 0x42, 0x95, 0x67, 0x21, 0xbe, 0x86, 0x68, 0xfa, 0x2a, 0xcc, 0x73, 0xf8, 0x0a, 0x0f, 0x60,
+ 0x95, 0x33, 0xce, 0xe7, 0x57, 0xc4, 0x2d, 0x33, 0xf3, 0x9c, 0xf3, 0xd9, 0x1d, 0xd8, 0x10, 0xaf,
+ 0x09, 0x44, 0xf1, 0x2a, 0x2b, 0xdc, 0x3b, 0xa8, 0xd8, 0x75, 0x64, 0xc9, 0xb2, 0x56, 0x14, 0x9c,
+ 0x1f, 0x01, 0xcf, 0x5e, 0x0b, 0xe8, 0xbb, 0x22, 0x94, 0x31, 0xcf, 0xc9, 0x61, 0x77, 0xe1, 0x1d,
+ 0x8e, 0x9d, 0x7b, 0x76, 0x10, 0x4c, 0x5d, 0xe6, 0x58, 0x53, 0xff, 0x18, 0x43, 0x66, 0x14, 0xdb,
+ 0xb3, 0xc0, 0x9a, 0x47, 0xad, 0x0d, 0x0c, 0x99, 0x6d, 0xe6, 0x39, 0x47, 0x09, 0xa8, 0xef, 0x1f,
+ 0x9b, 0x09, 0xe4, 0x28, 0x6a, 0xff, 0x3e, 0xac, 0xe6, 0xec, 0x71, 0x41, 0xa7, 0x35, 0x74, 0xfe,
+ 0x8c, 0x4e, 0xdf, 0x85, 0x95, 0x20, 0x64, 0xe7, 0xa2, 0xd5, 0x51, 0xb4, 0x86, 0xa0, 0x09, 0xb1,
+ 0xb6, 0x60, 0x05, 0x79, 0x96, 0x20, 0xe6, 0xf3, 0x63, 0x03, 0x59, 0x87, 0xc8, 0x69, 0xbf, 0x80,
+ 0x95, 0xec, 0x69, 0x93, 0x77, 0x33, 0x69, 0xa1, 0x99, 0xcb, 0x93, 0x69, 0x76, 0x48, 0x2a, 0xb2,
+ 0xf5, 0x4b, 0x2a, 0x32, 0x72, 0x9d, 0x8a, 0x4c, 0xfb, 0x2f, 0xd9, 0x9c, 0x65, 0x2a, 0x84, 0x9f,
+ 0x41, 0x2d, 0x90, 0xf5, 0x38, 0x5a, 0x52, 0xfe, 0x12, 0x3e, 0x0f, 0xee, 0x24, 0x95, 0x3b, 0x4d,
+ 0xe7, 0xb4, 0xff, 0x56, 0x81, 0x5a, 0x5a, 0xd0, 0xe7, 0x2c, 0xef, 0xcd, 0x05, 0xcb, 0x3b, 0x90,
+ 0x1a, 0x16, 0x0a, 0x7c, 0x1b, 0xa3, 0xc5, 0x27, 0xaf, 0x7f, 0xd7, 0xc5, 0xb6, 0xe7, 0x34, 0xdb,
+ 0xf6, 0x6c, 0xbe, 0xae, 0xed, 0xf9, 0xe4, 0xa2, 0xc1, 0xbf, 0x95, 0xe9, 0x2d, 0x16, 0xcc, 0xbe,
+ 0xfd, 0x7d, 0xae, 0x0f, 0xca, 0x26, 0x84, 0x77, 0xc4, 0x7e, 0xd2, 0x84, 0x90, 0xb6, 0x3f, 0xf7,
+ 0xaf, 0xd7, 0xfe, 0x6c, 0x43, 0x45, 0xea, 0xfc, 0x0e, 0x54, 0x64, 0x4d, 0x27, 0x1b, 0x04, 0x31,
+ 0x3a, 0x6f, 0x10, 0x0a, 0xb2, 0x4e, 0xd7, 0x7e, 0xae, 0x40, 0x59, 0x0f, 0x43, 0x3f, 0xd4, 0xfe,
+ 0x48, 0x81, 0x3a, 0x3e, 0xed, 0xf9, 0x0e, 0xe3, 0xd9, 0x60, 0xb7, 0xdb, 0xb3, 0xa8, 0xfe, 0xcd,
+ 0x91, 0x8e, 0xd9, 0xa0, 0x0d, 0x77, 0xf6, 0x86, 0x83, 0xbd, 0x23, 0x4a, 0xf5, 0x81, 0x69, 0x99,
+ 0xb4, 0x3b, 0x18, 0xf1, 0xb6, 0x67, 0x38, 0x50, 0x15, 0x9e, 0x29, 0x8c, 0x81, 0xa9, 0xd3, 0x41,
+ 0xb7, 0x6f, 0x89, 0x56, 0xb4, 0x88, 0x77, 0xb3, 0xba, 0xde, 0xb3, 0xf0, 0xd6, 0x51, 0x2d, 0xf1,
+ 0x96, 0xd5, 0x34, 0x0e, 0xf4, 0xe1, 0x91, 0xa9, 0x96, 0xc9, 0x6d, 0x58, 0x3f, 0xd4, 0xe9, 0x81,
+ 0x31, 0x1a, 0x19, 0xc3, 0x81, 0xd5, 0xd3, 0x07, 0x86, 0xde, 0x53, 0x2b, 0x7c, 0x9d, 0x5d, 0x63,
+ 0xdf, 0xec, 0xee, 0xf6, 0x75, 0xb9, 0x4e, 0x95, 0x6c, 0xc2, 0x5b, 0x7b, 0xc3, 0x83, 0x03, 0xc3,
+ 0x34, 0xf5, 0x9e, 0xb5, 0x7b, 0x64, 0x5a, 0x23, 0xd3, 0xe8, 0xf7, 0xad, 0xee, 0xe1, 0x61, 0xff,
+ 0x29, 0x4f, 0x60, 0x35, 0x72, 0x17, 0x36, 0xf6, 0xba, 0x87, 0xdd, 0x5d, 0xa3, 0x6f, 0x98, 0x4f,
+ 0xad, 0x9e, 0x31, 0xe2, 0xf3, 0x7b, 0x6a, 0x9d, 0x27, 0x6c, 0x93, 0x3e, 0xb5, 0xba, 0x7d, 0x14,
+ 0xcd, 0xd4, 0xad, 0xdd, 0xee, 0xde, 0x13, 0x7d, 0xd0, 0x53, 0x81, 0x0b, 0x30, 0xea, 0x3e, 0xd2,
+ 0x2d, 0x2e, 0x92, 0x65, 0x0e, 0x87, 0xd6, 0xb0, 0xdf, 0x53, 0x1b, 0xda, 0xbf, 0x14, 0xa1, 0xb4,
+ 0xe7, 0x47, 0x31, 0xf7, 0x46, 0xe1, 0xac, 0x2f, 0x42, 0x37, 0x66, 0xa2, 0x7f, 0x2b, 0x53, 0xd1,
+ 0x4b, 0x7f, 0x87, 0x24, 0x1e, 0x50, 0x32, 0x10, 0xeb, 0xd9, 0x19, 0xc7, 0x29, 0x88, 0x5b, 0x3b,
+ 0xc7, 0xed, 0x72, 0xb2, 0x88, 0x68, 0x78, 0x85, 0x23, 0xd7, 0x2b, 0x22, 0x4e, 0x06, 0x61, 0xb9,
+ 0xe0, 0xc7, 0x40, 0xb2, 0x20, 0xb9, 0x62, 0x09, 0x91, 0x6a, 0x06, 0x29, 0x96, 0xdc, 0x01, 0x18,
+ 0xfb, 0xb3, 0x99, 0x1b, 0x8f, 0xfd, 0x28, 0x96, 0x5f, 0xc8, 0xda, 0x39, 0x63, 0x8f, 0x62, 0x6e,
+ 0xf1, 0x33, 0x37, 0xe6, 0x8f, 0x34, 0x83, 0x26, 0x3b, 0x70, 0xcf, 0x0e, 0x82, 0xd0, 0x7f, 0xe9,
+ 0xce, 0xec, 0x98, 0x59, 0xdc, 0x73, 0xed, 0x63, 0x66, 0x39, 0x6c, 0x1a, 0xdb, 0xd8, 0x13, 0x95,
+ 0xe9, 0xdd, 0x0c, 0x60, 0x24, 0xf8, 0x3d, 0xce, 0xe6, 0x71, 0xd7, 0x75, 0xac, 0x88, 0xfd, 0x30,
+ 0xe7, 0x1e, 0x60, 0xcd, 0x03, 0xc7, 0xe6, 0x62, 0xd6, 0x45, 0x96, 0x72, 0x9d, 0x91, 0xe4, 0x1c,
+ 0x09, 0x46, 0xfb, 0x15, 0xc0, 0xb9, 0x14, 0x64, 0x1b, 0x6e, 0xf3, 0x3a, 0x9e, 0x45, 0x31, 0x73,
+ 0x2c, 0xb9, 0xdb, 0x60, 0x1e, 0x47, 0x18, 0xe2, 0xcb, 0x74, 0x23, 0x65, 0xca, 0x9b, 0xc2, 0x79,
+ 0x1c, 0x91, 0x9f, 0x40, 0xeb, 0xc2, 0x1c, 0x87, 0x4d, 0x19, 0x7f, 0x6d, 0x15, 0xa7, 0xdd, 0x59,
+ 0x98, 0xd6, 0x13, 0x5c, 0xed, 0x4f, 0x14, 0x80, 0x7d, 0x16, 0x53, 0xc1, 0xcd, 0x34, 0xb6, 0x95,
+ 0xeb, 0x36, 0xb6, 0xef, 0x27, 0x17, 0x08, 0xc5, 0xab, 0x63, 0xc0, 0x42, 0x97, 0xa1, 0xdc, 0xa4,
+ 0xcb, 0xc8, 0x35, 0x11, 0xc5, 0x2b, 0x9a, 0x88, 0x52, 0xae, 0x89, 0xf8, 0x18, 0x9a, 0xf6, 0x74,
+ 0xea, 0xbf, 0xe0, 0x05, 0x0d, 0x0b, 0x43, 0xe6, 0xa0, 0x11, 0x9c, 0xd7, 0xdb, 0xc8, 0xec, 0x49,
+ 0x9e, 0xf6, 0xe7, 0x0a, 0x34, 0x50, 0x15, 0x51, 0xe0, 0x7b, 0x11, 0x23, 0x5f, 0x42, 0x45, 0x5e,
+ 0x44, 0x8b, 0x8b, 0xfc, 0xb7, 0x33, 0xb2, 0x66, 0x70, 0xb2, 0x68, 0xa0, 0x12, 0xcc, 0x33, 0x42,
+ 0xe6, 0x75, 0x97, 0x2b, 0x25, 0x45, 0x91, 0xfb, 0x50, 0x73, 0x3d, 0x4b, 0xb4, 0xd4, 0x95, 0x4c,
+ 0x58, 0xac, 0xba, 0x1e, 0xd6, 0xb2, 0xed, 0x57, 0x50, 0x11, 0x2f, 0x21, 0x9d, 0x54, 0xa6, 0x8b,
+ 0xfa, 0xcb, 0xdc, 0x1c, 0xa7, 0xc2, 0xc8, 0xc3, 0x29, 0xbd, 0x2e, 0x40, 0xb7, 0xa0, 0x7a, 0xca,
+ 0x9b, 0x0f, 0xbc, 0xf4, 0xe3, 0xea, 0x4d, 0x86, 0xda, 0x1f, 0x97, 0x00, 0x0e, 0xe7, 0x4b, 0x0c,
+ 0xa4, 0x71, 0x5d, 0x03, 0xe9, 0xe4, 0xf4, 0xf8, 0x7a, 0x99, 0x7f, 0x75, 0x43, 0x59, 0xd2, 0x69,
+ 0x17, 0x6f, 0xda, 0x69, 0xdf, 0x87, 0x6a, 0x1c, 0xce, 0xb9, 0xa3, 0x08, 0x63, 0x4a, 0x5b, 0x5a,
+ 0x49, 0x25, 0x6f, 0x42, 0x79, 0xe2, 0x87, 0x63, 0x86, 0x8e, 0x95, 0xb2, 0x05, 0xed, 0xc2, 0x65,
+ 0x52, 0xed, 0xb2, 0xcb, 0x24, 0xde, 0xa0, 0x45, 0xf2, 0x1e, 0x0d, 0x0b, 0x99, 0x7c, 0x83, 0x96,
+ 0x5c, 0xb1, 0xd1, 0x14, 0x44, 0xbe, 0x81, 0xa6, 0x3d, 0x8f, 0x7d, 0xcb, 0xe5, 0x15, 0xda, 0xd4,
+ 0x1d, 0x9f, 0x61, 0xd9, 0xdd, 0xcc, 0x7f, 0xaf, 0x4f, 0x0f, 0xaa, 0xd3, 0x9d, 0xc7, 0xbe, 0xe1,
+ 0x1c, 0x22, 0x72, 0xa7, 0x2a, 0x93, 0x12, 0x5d, 0xb1, 0x33, 0x64, 0xed, 0xc7, 0xb0, 0x92, 0x85,
+ 0xf1, 0x04, 0x24, 0x81, 0xea, 0x1b, 0x3c, 0x3b, 0x8d, 0x78, 0x6a, 0x1b, 0x98, 0x46, 0xb7, 0xaf,
+ 0x16, 0xb4, 0x18, 0x1a, 0xb8, 0xbc, 0xf4, 0x8e, 0xeb, 0xba, 0xfd, 0x03, 0x28, 0x61, 0xf8, 0x55,
+ 0x2e, 0x7c, 0x0f, 0xc1, 0x98, 0x8b, 0xcc, 0xbc, 0xf9, 0x15, 0xb3, 0xe6, 0xf7, 0xdf, 0x05, 0x58,
+ 0x31, 0xfd, 0xf9, 0xf8, 0xe4, 0xa2, 0x01, 0xc2, 0xaf, 0x3b, 0x42, 0x2d, 0x31, 0x1f, 0xe5, 0xa6,
+ 0xe6, 0x93, 0x5a, 0x47, 0x71, 0x89, 0x75, 0xdc, 0xf4, 0xcc, 0xb5, 0x2f, 0x60, 0x55, 0x6e, 0x5e,
+ 0x6a, 0x3d, 0xd1, 0x66, 0xe1, 0x0a, 0x6d, 0x6a, 0xbf, 0x50, 0x60, 0x55, 0xc4, 0xf7, 0xff, 0xbb,
+ 0xd2, 0x2a, 0x37, 0x0c, 0xeb, 0xe5, 0x1b, 0x5d, 0x1e, 0xfd, 0xbf, 0xf4, 0x34, 0x6d, 0x08, 0xcd,
+ 0x44, 0x7d, 0x37, 0x50, 0xfb, 0x15, 0x46, 0xfc, 0x8b, 0x02, 0x34, 0x06, 0xec, 0xe5, 0x92, 0x20,
+ 0x5a, 0xbe, 0xee, 0x71, 0x7c, 0x98, 0x2b, 0x57, 0x1b, 0xdb, 0xeb, 0x59, 0x19, 0xc4, 0xd5, 0x63,
+ 0x52, 0xc1, 0xa6, 0xb7, 0xa8, 0xca, 0xf2, 0x5b, 0xd4, 0xd2, 0x62, 0xb7, 0x9e, 0xb9, 0xc5, 0x2b,
+ 0x2e, 0xbb, 0xc5, 0xd3, 0xfe, 0xad, 0x08, 0x0d, 0x6c, 0x90, 0x29, 0x8b, 0xe6, 0xd3, 0x38, 0x27,
+ 0x4c, 0xe1, 0x6a, 0x61, 0x3a, 0x50, 0x09, 0x71, 0x92, 0x74, 0xa5, 0x4b, 0x83, 0xbf, 0x40, 0x61,
+ 0x6b, 0xfc, 0xdc, 0x0d, 0x02, 0xe6, 0x58, 0x82, 0x92, 0x14, 0x30, 0x4d, 0x49, 0x16, 0x22, 0x44,
+ 0xbc, 0xfc, 0x9c, 0xf9, 0x21, 0x4b, 0x51, 0x45, 0xbc, 0x4f, 0x68, 0x70, 0x5a, 0x02, 0xc9, 0xdd,
+ 0x37, 0x88, 0xca, 0xe0, 0xfc, 0xbe, 0x21, 0xed, 0x35, 0x91, 0x5b, 0x47, 0xae, 0xe8, 0x35, 0x91,
+ 0xcd, 0xbb, 0xa8, 0x99, 0x3d, 0x9d, 0x5a, 0x7e, 0x10, 0xa1, 0xd3, 0xd4, 0x68, 0x0d, 0x09, 0xc3,
+ 0x20, 0x22, 0x5f, 0x43, 0x7a, 0x5d, 0x2c, 0x6f, 0xc9, 0xc5, 0x39, 0xb6, 0x2e, 0xbb, 0x58, 0xa0,
+ 0xab, 0xe3, 0xdc, 0xfd, 0xcf, 0x92, 0x1b, 0xea, 0xca, 0x4d, 0x6f, 0xa8, 0x1f, 0x42, 0x59, 0xc4,
+ 0xa8, 0xda, 0xeb, 0x62, 0x94, 0xc0, 0x65, 0xed, 0xb3, 0x91, 0xb7, 0xcf, 0x5f, 0x16, 0x80, 0x74,
+ 0xa7, 0x53, 0x7f, 0x6c, 0xc7, 0xcc, 0x70, 0xa2, 0x8b, 0x66, 0x7a, 0xed, 0xcf, 0x2e, 0x9f, 0x41,
+ 0x7d, 0xe6, 0x3b, 0x6c, 0x6a, 0x25, 0xdf, 0x94, 0x2e, 0xad, 0x7e, 0x10, 0xc6, 0x5b, 0x52, 0x02,
+ 0x25, 0xbc, 0xc4, 0x51, 0xb0, 0xee, 0xc0, 0x67, 0xde, 0x84, 0xcd, 0xec, 0x97, 0xb2, 0x14, 0xe1,
+ 0x8f, 0xa4, 0x03, 0xd5, 0x90, 0x45, 0x2c, 0x3c, 0x65, 0x57, 0x16, 0x55, 0x09, 0x48, 0x7b, 0x06,
+ 0x1b, 0xb9, 0x1d, 0x49, 0x47, 0xbe, 0x85, 0x5f, 0x2b, 0xc3, 0x58, 0x7e, 0xb4, 0x12, 0x03, 0xfe,
+ 0x3a, 0xe6, 0x25, 0x9f, 0x41, 0xf9, 0x63, 0xea, 0xf0, 0xc5, 0xab, 0xe2, 0xec, 0x1e, 0xa8, 0x59,
+ 0x4d, 0xbb, 0x63, 0x0c, 0x36, 0xf2, 0x54, 0x0a, 0xd7, 0x3b, 0x15, 0xed, 0xef, 0x0a, 0xb0, 0xde,
+ 0x75, 0x1c, 0xf1, 0x77, 0xc3, 0x25, 0xaa, 0x2f, 0x5e, 0x57, 0xf5, 0x0b, 0x81, 0x58, 0x84, 0x89,
+ 0x6b, 0x05, 0xe2, 0x0f, 0xa1, 0x92, 0xd6, 0x5a, 0xc5, 0x05, 0x77, 0x16, 0x72, 0x51, 0x09, 0xd0,
+ 0x6e, 0x01, 0xc9, 0x0a, 0x2b, 0xb4, 0xaa, 0xfd, 0x69, 0x11, 0xee, 0xee, 0xb2, 0x63, 0xd7, 0xcb,
+ 0xbe, 0xe2, 0x57, 0xdf, 0xc9, 0xc5, 0x4f, 0x65, 0x9f, 0xc1, 0xba, 0x28, 0xe4, 0x93, 0x7f, 0x62,
+ 0x59, 0xec, 0x58, 0x7e, 0x9d, 0x94, 0xb1, 0x6a, 0x0d, 0xf9, 0x07, 0x92, 0xad, 0xe3, 0x7f, 0xc5,
+ 0x1c, 0x3b, 0xb6, 0x9f, 0xd9, 0x11, 0xb3, 0x5c, 0x47, 0xfe, 0x59, 0x06, 0x12, 0x92, 0xe1, 0x90,
+ 0x21, 0x94, 0xb8, 0x0d, 0xa2, 0xeb, 0x36, 0xb7, 0xb7, 0x33, 0x62, 0x5d, 0xb2, 0x95, 0xac, 0x02,
+ 0x0f, 0x7c, 0x87, 0xed, 0x54, 0x8f, 0x06, 0x4f, 0x06, 0xc3, 0xef, 0x06, 0x14, 0x17, 0x22, 0x06,
+ 0xdc, 0x0a, 0x42, 0x76, 0xea, 0xfa, 0xf3, 0xc8, 0xca, 0x9e, 0x44, 0xf5, 0xca, 0x94, 0xb8, 0x91,
+ 0xcc, 0xc9, 0x10, 0xb5, 0x9f, 0xc2, 0xda, 0xc2, 0xcb, 0x78, 0x6d, 0x26, 0x5f, 0xa7, 0xbe, 0x41,
+ 0x56, 0xa1, 0x8e, 0x1f, 0xbb, 0x97, 0x7f, 0xfb, 0xd6, 0xfe, 0xb5, 0x80, 0x57, 0x4c, 0x33, 0x37,
+ 0xbe, 0x59, 0x06, 0xfb, 0xcd, 0x7c, 0x06, 0x83, 0xed, 0x77, 0xf3, 0xe6, 0x9b, 0x59, 0xb0, 0xf3,
+ 0xad, 0x00, 0xa6, 0x41, 0xa4, 0x6d, 0x43, 0x55, 0xd2, 0xc8, 0x6f, 0xc1, 0x5a, 0xe8, 0xfb, 0x71,
+ 0xd2, 0x89, 0x8a, 0x0e, 0xe4, 0xf2, 0x3f, 0xdb, 0xac, 0x72, 0xb0, 0x48, 0x06, 0x4f, 0xf2, 0xbd,
+ 0x48, 0x59, 0xfc, 0x0d, 0x44, 0x0e, 0x77, 0x1b, 0xbf, 0x5b, 0x4f, 0xff, 0xb7, 0xfb, 0xbf, 0x01,
+ 0x00, 0x00, 0xff, 0xff, 0x35, 0x9f, 0x30, 0x98, 0xf2, 0x2b, 0x00, 0x00,
+}
diff --git a/vendor/google.golang.org/appengine/internal/datastore/datastore_v3.proto b/vendor/google.golang.org/appengine/internal/datastore/datastore_v3.proto
new file mode 100644
index 0000000000000000000000000000000000000000..497b4d9a9af51b2bf31ce2a11cc145e4f09d272a
--- /dev/null
+++ b/vendor/google.golang.org/appengine/internal/datastore/datastore_v3.proto
@@ -0,0 +1,551 @@
+syntax = "proto2";
+option go_package = "datastore";
+
+package appengine;
+
+message Action{}
+
+message PropertyValue {
+ optional int64 int64Value = 1;
+ optional bool booleanValue = 2;
+ optional string stringValue = 3;
+ optional double doubleValue = 4;
+
+ optional group PointValue = 5 {
+ required double x = 6;
+ required double y = 7;
+ }
+
+ optional group UserValue = 8 {
+ required string email = 9;
+ required string auth_domain = 10;
+ optional string nickname = 11;
+ optional string federated_identity = 21;
+ optional string federated_provider = 22;
+ }
+
+ optional group ReferenceValue = 12 {
+ required string app = 13;
+ optional string name_space = 20;
+ repeated group PathElement = 14 {
+ required string type = 15;
+ optional int64 id = 16;
+ optional string name = 17;
+ }
+ }
+}
+
+message Property {
+ enum Meaning {
+ NO_MEANING = 0;
+ BLOB = 14;
+ TEXT = 15;
+ BYTESTRING = 16;
+
+ ATOM_CATEGORY = 1;
+ ATOM_LINK = 2;
+ ATOM_TITLE = 3;
+ ATOM_CONTENT = 4;
+ ATOM_SUMMARY = 5;
+ ATOM_AUTHOR = 6;
+
+ GD_WHEN = 7;
+ GD_EMAIL = 8;
+ GEORSS_POINT = 9;
+ GD_IM = 10;
+
+ GD_PHONENUMBER = 11;
+ GD_POSTALADDRESS = 12;
+
+ GD_RATING = 13;
+
+ BLOBKEY = 17;
+ ENTITY_PROTO = 19;
+
+ INDEX_VALUE = 18;
+ };
+
+ optional Meaning meaning = 1 [default = NO_MEANING];
+ optional string meaning_uri = 2;
+
+ required string name = 3;
+
+ required PropertyValue value = 5;
+
+ required bool multiple = 4;
+
+ optional bool searchable = 6 [default=false];
+
+ enum FtsTokenizationOption {
+ HTML = 1;
+ ATOM = 2;
+ }
+
+ optional FtsTokenizationOption fts_tokenization_option = 8;
+
+ optional string locale = 9 [default = "en"];
+}
+
+message Path {
+ repeated group Element = 1 {
+ required string type = 2;
+ optional int64 id = 3;
+ optional string name = 4;
+ }
+}
+
+message Reference {
+ required string app = 13;
+ optional string name_space = 20;
+ required Path path = 14;
+}
+
+message User {
+ required string email = 1;
+ required string auth_domain = 2;
+ optional string nickname = 3;
+ optional string federated_identity = 6;
+ optional string federated_provider = 7;
+}
+
+message EntityProto {
+ required Reference key = 13;
+ required Path entity_group = 16;
+ optional User owner = 17;
+
+ enum Kind {
+ GD_CONTACT = 1;
+ GD_EVENT = 2;
+ GD_MESSAGE = 3;
+ }
+ optional Kind kind = 4;
+ optional string kind_uri = 5;
+
+ repeated Property property = 14;
+ repeated Property raw_property = 15;
+
+ optional int32 rank = 18;
+}
+
+message CompositeProperty {
+ required int64 index_id = 1;
+ repeated string value = 2;
+}
+
+message Index {
+ required string entity_type = 1;
+ required bool ancestor = 5;
+ repeated group Property = 2 {
+ required string name = 3;
+ enum Direction {
+ ASCENDING = 1;
+ DESCENDING = 2;
+ }
+ optional Direction direction = 4 [default = ASCENDING];
+ }
+}
+
+message CompositeIndex {
+ required string app_id = 1;
+ required int64 id = 2;
+ required Index definition = 3;
+
+ enum State {
+ WRITE_ONLY = 1;
+ READ_WRITE = 2;
+ DELETED = 3;
+ ERROR = 4;
+ }
+ required State state = 4;
+
+ optional bool only_use_if_required = 6 [default = false];
+}
+
+message IndexPostfix {
+ message IndexValue {
+ required string property_name = 1;
+ required PropertyValue value = 2;
+ }
+
+ repeated IndexValue index_value = 1;
+
+ optional Reference key = 2;
+
+ optional bool before = 3 [default=true];
+}
+
+message IndexPosition {
+ optional string key = 1;
+
+ optional bool before = 2 [default=true];
+}
+
+message Snapshot {
+ enum Status {
+ INACTIVE = 0;
+ ACTIVE = 1;
+ }
+
+ required int64 ts = 1;
+}
+
+message InternalHeader {
+ optional string qos = 1;
+}
+
+message Transaction {
+ optional InternalHeader header = 4;
+ required fixed64 handle = 1;
+ required string app = 2;
+ optional bool mark_changes = 3 [default = false];
+}
+
+message Query {
+ optional InternalHeader header = 39;
+
+ required string app = 1;
+ optional string name_space = 29;
+
+ optional string kind = 3;
+ optional Reference ancestor = 17;
+
+ repeated group Filter = 4 {
+ enum Operator {
+ LESS_THAN = 1;
+ LESS_THAN_OR_EQUAL = 2;
+ GREATER_THAN = 3;
+ GREATER_THAN_OR_EQUAL = 4;
+ EQUAL = 5;
+ IN = 6;
+ EXISTS = 7;
+ }
+
+ required Operator op = 6;
+ repeated Property property = 14;
+ }
+
+ optional string search_query = 8;
+
+ repeated group Order = 9 {
+ enum Direction {
+ ASCENDING = 1;
+ DESCENDING = 2;
+ }
+
+ required string property = 10;
+ optional Direction direction = 11 [default = ASCENDING];
+ }
+
+ enum Hint {
+ ORDER_FIRST = 1;
+ ANCESTOR_FIRST = 2;
+ FILTER_FIRST = 3;
+ }
+ optional Hint hint = 18;
+
+ optional int32 count = 23;
+
+ optional int32 offset = 12 [default = 0];
+
+ optional int32 limit = 16;
+
+ optional CompiledCursor compiled_cursor = 30;
+ optional CompiledCursor end_compiled_cursor = 31;
+
+ repeated CompositeIndex composite_index = 19;
+
+ optional bool require_perfect_plan = 20 [default = false];
+
+ optional bool keys_only = 21 [default = false];
+
+ optional Transaction transaction = 22;
+
+ optional bool compile = 25 [default = false];
+
+ optional int64 failover_ms = 26;
+
+ optional bool strong = 32;
+
+ repeated string property_name = 33;
+
+ repeated string group_by_property_name = 34;
+
+ optional bool distinct = 24;
+
+ optional int64 min_safe_time_seconds = 35;
+
+ repeated string safe_replica_name = 36;
+
+ optional bool persist_offset = 37 [default=false];
+}
+
+message CompiledQuery {
+ required group PrimaryScan = 1 {
+ optional string index_name = 2;
+
+ optional string start_key = 3;
+ optional bool start_inclusive = 4;
+ optional string end_key = 5;
+ optional bool end_inclusive = 6;
+
+ repeated string start_postfix_value = 22;
+ repeated string end_postfix_value = 23;
+
+ optional int64 end_unapplied_log_timestamp_us = 19;
+ }
+
+ repeated group MergeJoinScan = 7 {
+ required string index_name = 8;
+
+ repeated string prefix_value = 9;
+
+ optional bool value_prefix = 20 [default=false];
+ }
+
+ optional Index index_def = 21;
+
+ optional int32 offset = 10 [default = 0];
+
+ optional int32 limit = 11;
+
+ required bool keys_only = 12;
+
+ repeated string property_name = 24;
+
+ optional int32 distinct_infix_size = 25;
+
+ optional group EntityFilter = 13 {
+ optional bool distinct = 14 [default=false];
+
+ optional string kind = 17;
+ optional Reference ancestor = 18;
+ }
+}
+
+message CompiledCursor {
+ optional group Position = 2 {
+ optional string start_key = 27;
+
+ repeated group IndexValue = 29 {
+ optional string property = 30;
+ required PropertyValue value = 31;
+ }
+
+ optional Reference key = 32;
+
+ optional bool start_inclusive = 28 [default=true];
+ }
+}
+
+message Cursor {
+ required fixed64 cursor = 1;
+
+ optional string app = 2;
+}
+
+message Error {
+ enum ErrorCode {
+ BAD_REQUEST = 1;
+ CONCURRENT_TRANSACTION = 2;
+ INTERNAL_ERROR = 3;
+ NEED_INDEX = 4;
+ TIMEOUT = 5;
+ PERMISSION_DENIED = 6;
+ BIGTABLE_ERROR = 7;
+ COMMITTED_BUT_STILL_APPLYING = 8;
+ CAPABILITY_DISABLED = 9;
+ TRY_ALTERNATE_BACKEND = 10;
+ SAFE_TIME_TOO_OLD = 11;
+ }
+}
+
+message Cost {
+ optional int32 index_writes = 1;
+ optional int32 index_write_bytes = 2;
+ optional int32 entity_writes = 3;
+ optional int32 entity_write_bytes = 4;
+ optional group CommitCost = 5 {
+ optional int32 requested_entity_puts = 6;
+ optional int32 requested_entity_deletes = 7;
+ };
+ optional int32 approximate_storage_delta = 8;
+ optional int32 id_sequence_updates = 9;
+}
+
+message GetRequest {
+ optional InternalHeader header = 6;
+
+ repeated Reference key = 1;
+ optional Transaction transaction = 2;
+
+ optional int64 failover_ms = 3;
+
+ optional bool strong = 4;
+
+ optional bool allow_deferred = 5 [default=false];
+}
+
+message GetResponse {
+ repeated group Entity = 1 {
+ optional EntityProto entity = 2;
+ optional Reference key = 4;
+
+ optional int64 version = 3;
+ }
+
+ repeated Reference deferred = 5;
+
+ optional bool in_order = 6 [default=true];
+}
+
+message PutRequest {
+ optional InternalHeader header = 11;
+
+ repeated EntityProto entity = 1;
+ optional Transaction transaction = 2;
+ repeated CompositeIndex composite_index = 3;
+
+ optional bool trusted = 4 [default = false];
+
+ optional bool force = 7 [default = false];
+
+ optional bool mark_changes = 8 [default = false];
+ repeated Snapshot snapshot = 9;
+
+ enum AutoIdPolicy {
+ CURRENT = 0;
+ SEQUENTIAL = 1;
+ }
+ optional AutoIdPolicy auto_id_policy = 10 [default = CURRENT];
+}
+
+message PutResponse {
+ repeated Reference key = 1;
+ optional Cost cost = 2;
+ repeated int64 version = 3;
+}
+
+message TouchRequest {
+ optional InternalHeader header = 10;
+
+ repeated Reference key = 1;
+ repeated CompositeIndex composite_index = 2;
+ optional bool force = 3 [default = false];
+ repeated Snapshot snapshot = 9;
+}
+
+message TouchResponse {
+ optional Cost cost = 1;
+}
+
+message DeleteRequest {
+ optional InternalHeader header = 10;
+
+ repeated Reference key = 6;
+ optional Transaction transaction = 5;
+
+ optional bool trusted = 4 [default = false];
+
+ optional bool force = 7 [default = false];
+
+ optional bool mark_changes = 8 [default = false];
+ repeated Snapshot snapshot = 9;
+}
+
+message DeleteResponse {
+ optional Cost cost = 1;
+ repeated int64 version = 3;
+}
+
+message NextRequest {
+ optional InternalHeader header = 5;
+
+ required Cursor cursor = 1;
+ optional int32 count = 2;
+
+ optional int32 offset = 4 [default = 0];
+
+ optional bool compile = 3 [default = false];
+}
+
+message QueryResult {
+ optional Cursor cursor = 1;
+
+ repeated EntityProto result = 2;
+
+ optional int32 skipped_results = 7;
+
+ required bool more_results = 3;
+
+ optional bool keys_only = 4;
+
+ optional bool index_only = 9;
+
+ optional bool small_ops = 10;
+
+ optional CompiledQuery compiled_query = 5;
+
+ optional CompiledCursor compiled_cursor = 6;
+
+ repeated CompositeIndex index = 8;
+
+ repeated int64 version = 11;
+}
+
+message AllocateIdsRequest {
+ optional InternalHeader header = 4;
+
+ optional Reference model_key = 1;
+
+ optional int64 size = 2;
+
+ optional int64 max = 3;
+
+ repeated Reference reserve = 5;
+}
+
+message AllocateIdsResponse {
+ required int64 start = 1;
+ required int64 end = 2;
+ optional Cost cost = 3;
+}
+
+message CompositeIndices {
+ repeated CompositeIndex index = 1;
+}
+
+message AddActionsRequest {
+ optional InternalHeader header = 3;
+
+ required Transaction transaction = 1;
+ repeated Action action = 2;
+}
+
+message AddActionsResponse {
+}
+
+message BeginTransactionRequest {
+ optional InternalHeader header = 3;
+
+ required string app = 1;
+ optional bool allow_multiple_eg = 2 [default = false];
+ optional string database_id = 4;
+
+ enum TransactionMode {
+ UNKNOWN = 0;
+ READ_ONLY = 1;
+ READ_WRITE = 2;
+ }
+ optional TransactionMode mode = 5 [default = UNKNOWN];
+
+ optional Transaction previous_transaction = 7;
+}
+
+message CommitResponse {
+ optional Cost cost = 1;
+
+ repeated group Version = 3 {
+ required Reference root_entity_key = 4;
+ required int64 version = 5;
+ }
+}
diff --git a/vendor/google.golang.org/appengine/internal/identity.go b/vendor/google.golang.org/appengine/internal/identity.go
new file mode 100644
index 0000000000000000000000000000000000000000..9b4134e425732fa069c2712305aaccd863e7d3ef
--- /dev/null
+++ b/vendor/google.golang.org/appengine/internal/identity.go
@@ -0,0 +1,55 @@
+// Copyright 2011 Google Inc. All rights reserved.
+// Use of this source code is governed by the Apache 2.0
+// license that can be found in the LICENSE file.
+
+package internal
+
+import (
+ "os"
+
+ netcontext "golang.org/x/net/context"
+)
+
+var (
+ // This is set to true in identity_classic.go, which is behind the appengine build tag.
+ // The appengine build tag is set for the first generation runtimes (<= Go 1.9) but not
+ // the second generation runtimes (>= Go 1.11), so this indicates whether we're on a
+ // first-gen runtime. See IsStandard below for the second-gen check.
+ appengineStandard bool
+
+ // This is set to true in identity_flex.go, which is behind the appenginevm build tag.
+ appengineFlex bool
+)
+
+// AppID is the implementation of the wrapper function of the same name in
+// ../identity.go. See that file for commentary.
+func AppID(c netcontext.Context) string {
+ return appID(FullyQualifiedAppID(c))
+}
+
+// IsStandard is the implementation of the wrapper function of the same name in
+// ../appengine.go. See that file for commentary.
+func IsStandard() bool {
+ // appengineStandard will be true for first-gen runtimes (<= Go 1.9) but not
+ // second-gen (>= Go 1.11).
+ return appengineStandard || IsSecondGen()
+}
+
+// IsStandard is the implementation of the wrapper function of the same name in
+// ../appengine.go. See that file for commentary.
+func IsSecondGen() bool {
+ // Second-gen runtimes set $GAE_ENV so we use that to check if we're on a second-gen runtime.
+ return os.Getenv("GAE_ENV") == "standard"
+}
+
+// IsFlex is the implementation of the wrapper function of the same name in
+// ../appengine.go. See that file for commentary.
+func IsFlex() bool {
+ return appengineFlex
+}
+
+// IsAppEngine is the implementation of the wrapper function of the same name in
+// ../appengine.go. See that file for commentary.
+func IsAppEngine() bool {
+ return IsStandard() || IsFlex()
+}
diff --git a/vendor/google.golang.org/appengine/internal/identity_classic.go b/vendor/google.golang.org/appengine/internal/identity_classic.go
new file mode 100644
index 0000000000000000000000000000000000000000..4e979f45e34d53749779597286c98a73e8cd46bd
--- /dev/null
+++ b/vendor/google.golang.org/appengine/internal/identity_classic.go
@@ -0,0 +1,61 @@
+// Copyright 2015 Google Inc. All rights reserved.
+// Use of this source code is governed by the Apache 2.0
+// license that can be found in the LICENSE file.
+
+// +build appengine
+
+package internal
+
+import (
+ "appengine"
+
+ netcontext "golang.org/x/net/context"
+)
+
+func init() {
+ appengineStandard = true
+}
+
+func DefaultVersionHostname(ctx netcontext.Context) string {
+ c := fromContext(ctx)
+ if c == nil {
+ panic(errNotAppEngineContext)
+ }
+ return appengine.DefaultVersionHostname(c)
+}
+
+func Datacenter(_ netcontext.Context) string { return appengine.Datacenter() }
+func ServerSoftware() string { return appengine.ServerSoftware() }
+func InstanceID() string { return appengine.InstanceID() }
+func IsDevAppServer() bool { return appengine.IsDevAppServer() }
+
+func RequestID(ctx netcontext.Context) string {
+ c := fromContext(ctx)
+ if c == nil {
+ panic(errNotAppEngineContext)
+ }
+ return appengine.RequestID(c)
+}
+
+func ModuleName(ctx netcontext.Context) string {
+ c := fromContext(ctx)
+ if c == nil {
+ panic(errNotAppEngineContext)
+ }
+ return appengine.ModuleName(c)
+}
+func VersionID(ctx netcontext.Context) string {
+ c := fromContext(ctx)
+ if c == nil {
+ panic(errNotAppEngineContext)
+ }
+ return appengine.VersionID(c)
+}
+
+func fullyQualifiedAppID(ctx netcontext.Context) string {
+ c := fromContext(ctx)
+ if c == nil {
+ panic(errNotAppEngineContext)
+ }
+ return c.FullyQualifiedAppID()
+}
diff --git a/vendor/google.golang.org/appengine/internal/identity_flex.go b/vendor/google.golang.org/appengine/internal/identity_flex.go
new file mode 100644
index 0000000000000000000000000000000000000000..d5e2e7b5e3f8cc10269a00fd602402708f23737a
--- /dev/null
+++ b/vendor/google.golang.org/appengine/internal/identity_flex.go
@@ -0,0 +1,11 @@
+// Copyright 2018 Google LLC. All rights reserved.
+// Use of this source code is governed by the Apache 2.0
+// license that can be found in the LICENSE file.
+
+// +build appenginevm
+
+package internal
+
+func init() {
+ appengineFlex = true
+}
diff --git a/vendor/google.golang.org/appengine/internal/identity_vm.go b/vendor/google.golang.org/appengine/internal/identity_vm.go
new file mode 100644
index 0000000000000000000000000000000000000000..5d80672635560b6456573b4090d86f904ddb7dea
--- /dev/null
+++ b/vendor/google.golang.org/appengine/internal/identity_vm.go
@@ -0,0 +1,134 @@
+// Copyright 2011 Google Inc. All rights reserved.
+// Use of this source code is governed by the Apache 2.0
+// license that can be found in the LICENSE file.
+
+// +build !appengine
+
+package internal
+
+import (
+ "log"
+ "net/http"
+ "os"
+ "strings"
+
+ netcontext "golang.org/x/net/context"
+)
+
+// These functions are implementations of the wrapper functions
+// in ../appengine/identity.go. See that file for commentary.
+
+const (
+ hDefaultVersionHostname = "X-AppEngine-Default-Version-Hostname"
+ hRequestLogId = "X-AppEngine-Request-Log-Id"
+ hDatacenter = "X-AppEngine-Datacenter"
+)
+
+func ctxHeaders(ctx netcontext.Context) http.Header {
+ c := fromContext(ctx)
+ if c == nil {
+ return nil
+ }
+ return c.Request().Header
+}
+
+func DefaultVersionHostname(ctx netcontext.Context) string {
+ return ctxHeaders(ctx).Get(hDefaultVersionHostname)
+}
+
+func RequestID(ctx netcontext.Context) string {
+ return ctxHeaders(ctx).Get(hRequestLogId)
+}
+
+func Datacenter(ctx netcontext.Context) string {
+ if dc := ctxHeaders(ctx).Get(hDatacenter); dc != "" {
+ return dc
+ }
+ // If the header isn't set, read zone from the metadata service.
+ // It has the format projects/[NUMERIC_PROJECT_ID]/zones/[ZONE]
+ zone, err := getMetadata("instance/zone")
+ if err != nil {
+ log.Printf("Datacenter: %v", err)
+ return ""
+ }
+ parts := strings.Split(string(zone), "/")
+ if len(parts) == 0 {
+ return ""
+ }
+ return parts[len(parts)-1]
+}
+
+func ServerSoftware() string {
+ // TODO(dsymonds): Remove fallback when we've verified this.
+ if s := os.Getenv("SERVER_SOFTWARE"); s != "" {
+ return s
+ }
+ if s := os.Getenv("GAE_ENV"); s != "" {
+ return s
+ }
+ return "Google App Engine/1.x.x"
+}
+
+// TODO(dsymonds): Remove the metadata fetches.
+
+func ModuleName(_ netcontext.Context) string {
+ if s := os.Getenv("GAE_MODULE_NAME"); s != "" {
+ return s
+ }
+ if s := os.Getenv("GAE_SERVICE"); s != "" {
+ return s
+ }
+ return string(mustGetMetadata("instance/attributes/gae_backend_name"))
+}
+
+func VersionID(_ netcontext.Context) string {
+ if s1, s2 := os.Getenv("GAE_MODULE_VERSION"), os.Getenv("GAE_MINOR_VERSION"); s1 != "" && s2 != "" {
+ return s1 + "." + s2
+ }
+ if s1, s2 := os.Getenv("GAE_VERSION"), os.Getenv("GAE_DEPLOYMENT_ID"); s1 != "" && s2 != "" {
+ return s1 + "." + s2
+ }
+ return string(mustGetMetadata("instance/attributes/gae_backend_version")) + "." + string(mustGetMetadata("instance/attributes/gae_backend_minor_version"))
+}
+
+func InstanceID() string {
+ if s := os.Getenv("GAE_MODULE_INSTANCE"); s != "" {
+ return s
+ }
+ if s := os.Getenv("GAE_INSTANCE"); s != "" {
+ return s
+ }
+ return string(mustGetMetadata("instance/attributes/gae_backend_instance"))
+}
+
+func partitionlessAppID() string {
+ // gae_project has everything except the partition prefix.
+ if appID := os.Getenv("GAE_LONG_APP_ID"); appID != "" {
+ return appID
+ }
+ if project := os.Getenv("GOOGLE_CLOUD_PROJECT"); project != "" {
+ return project
+ }
+ return string(mustGetMetadata("instance/attributes/gae_project"))
+}
+
+func fullyQualifiedAppID(_ netcontext.Context) string {
+ if s := os.Getenv("GAE_APPLICATION"); s != "" {
+ return s
+ }
+ appID := partitionlessAppID()
+
+ part := os.Getenv("GAE_PARTITION")
+ if part == "" {
+ part = string(mustGetMetadata("instance/attributes/gae_partition"))
+ }
+
+ if part != "" {
+ appID = part + "~" + appID
+ }
+ return appID
+}
+
+func IsDevAppServer() bool {
+ return os.Getenv("RUN_WITH_DEVAPPSERVER") != ""
+}
diff --git a/vendor/google.golang.org/appengine/internal/internal.go b/vendor/google.golang.org/appengine/internal/internal.go
new file mode 100644
index 0000000000000000000000000000000000000000..051ea3980abe4d4e189dbc1b64b1c9c80a3844f4
--- /dev/null
+++ b/vendor/google.golang.org/appengine/internal/internal.go
@@ -0,0 +1,110 @@
+// Copyright 2011 Google Inc. All rights reserved.
+// Use of this source code is governed by the Apache 2.0
+// license that can be found in the LICENSE file.
+
+// Package internal provides support for package appengine.
+//
+// Programs should not use this package directly. Its API is not stable.
+// Use packages appengine and appengine/* instead.
+package internal
+
+import (
+ "fmt"
+
+ "github.com/golang/protobuf/proto"
+
+ remotepb "google.golang.org/appengine/internal/remote_api"
+)
+
+// errorCodeMaps is a map of service name to the error code map for the service.
+var errorCodeMaps = make(map[string]map[int32]string)
+
+// RegisterErrorCodeMap is called from API implementations to register their
+// error code map. This should only be called from init functions.
+func RegisterErrorCodeMap(service string, m map[int32]string) {
+ errorCodeMaps[service] = m
+}
+
+type timeoutCodeKey struct {
+ service string
+ code int32
+}
+
+// timeoutCodes is the set of service+code pairs that represent timeouts.
+var timeoutCodes = make(map[timeoutCodeKey]bool)
+
+func RegisterTimeoutErrorCode(service string, code int32) {
+ timeoutCodes[timeoutCodeKey{service, code}] = true
+}
+
+// APIError is the type returned by appengine.Context's Call method
+// when an API call fails in an API-specific way. This may be, for instance,
+// a taskqueue API call failing with TaskQueueServiceError::UNKNOWN_QUEUE.
+type APIError struct {
+ Service string
+ Detail string
+ Code int32 // API-specific error code
+}
+
+func (e *APIError) Error() string {
+ if e.Code == 0 {
+ if e.Detail == "" {
+ return "APIError "
+ }
+ return e.Detail
+ }
+ s := fmt.Sprintf("API error %d", e.Code)
+ if m, ok := errorCodeMaps[e.Service]; ok {
+ s += " (" + e.Service + ": " + m[e.Code] + ")"
+ } else {
+ // Shouldn't happen, but provide a bit more detail if it does.
+ s = e.Service + " " + s
+ }
+ if e.Detail != "" {
+ s += ": " + e.Detail
+ }
+ return s
+}
+
+func (e *APIError) IsTimeout() bool {
+ return timeoutCodes[timeoutCodeKey{e.Service, e.Code}]
+}
+
+// CallError is the type returned by appengine.Context's Call method when an
+// API call fails in a generic way, such as RpcError::CAPABILITY_DISABLED.
+type CallError struct {
+ Detail string
+ Code int32
+ // TODO: Remove this if we get a distinguishable error code.
+ Timeout bool
+}
+
+func (e *CallError) Error() string {
+ var msg string
+ switch remotepb.RpcError_ErrorCode(e.Code) {
+ case remotepb.RpcError_UNKNOWN:
+ return e.Detail
+ case remotepb.RpcError_OVER_QUOTA:
+ msg = "Over quota"
+ case remotepb.RpcError_CAPABILITY_DISABLED:
+ msg = "Capability disabled"
+ case remotepb.RpcError_CANCELLED:
+ msg = "Canceled"
+ default:
+ msg = fmt.Sprintf("Call error %d", e.Code)
+ }
+ s := msg + ": " + e.Detail
+ if e.Timeout {
+ s += " (timeout)"
+ }
+ return s
+}
+
+func (e *CallError) IsTimeout() bool {
+ return e.Timeout
+}
+
+// NamespaceMods is a map from API service to a function that will mutate an RPC request to attach a namespace.
+// The function should be prepared to be called on the same message more than once; it should only modify the
+// RPC request the first time.
+var NamespaceMods = make(map[string]func(m proto.Message, namespace string))
diff --git a/vendor/google.golang.org/appengine/internal/log/log_service.pb.go b/vendor/google.golang.org/appengine/internal/log/log_service.pb.go
new file mode 100644
index 0000000000000000000000000000000000000000..8545ac4ad6abbbb60cfd033497e4278b28533262
--- /dev/null
+++ b/vendor/google.golang.org/appengine/internal/log/log_service.pb.go
@@ -0,0 +1,1313 @@
+// Code generated by protoc-gen-go. DO NOT EDIT.
+// source: google.golang.org/appengine/internal/log/log_service.proto
+
+package log
+
+import proto "github.com/golang/protobuf/proto"
+import fmt "fmt"
+import math "math"
+
+// Reference imports to suppress errors if they are not otherwise used.
+var _ = proto.Marshal
+var _ = fmt.Errorf
+var _ = math.Inf
+
+// This is a compile-time assertion to ensure that this generated file
+// is compatible with the proto package it is being compiled against.
+// A compilation error at this line likely means your copy of the
+// proto package needs to be updated.
+const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package
+
+type LogServiceError_ErrorCode int32
+
+const (
+ LogServiceError_OK LogServiceError_ErrorCode = 0
+ LogServiceError_INVALID_REQUEST LogServiceError_ErrorCode = 1
+ LogServiceError_STORAGE_ERROR LogServiceError_ErrorCode = 2
+)
+
+var LogServiceError_ErrorCode_name = map[int32]string{
+ 0: "OK",
+ 1: "INVALID_REQUEST",
+ 2: "STORAGE_ERROR",
+}
+var LogServiceError_ErrorCode_value = map[string]int32{
+ "OK": 0,
+ "INVALID_REQUEST": 1,
+ "STORAGE_ERROR": 2,
+}
+
+func (x LogServiceError_ErrorCode) Enum() *LogServiceError_ErrorCode {
+ p := new(LogServiceError_ErrorCode)
+ *p = x
+ return p
+}
+func (x LogServiceError_ErrorCode) String() string {
+ return proto.EnumName(LogServiceError_ErrorCode_name, int32(x))
+}
+func (x *LogServiceError_ErrorCode) UnmarshalJSON(data []byte) error {
+ value, err := proto.UnmarshalJSONEnum(LogServiceError_ErrorCode_value, data, "LogServiceError_ErrorCode")
+ if err != nil {
+ return err
+ }
+ *x = LogServiceError_ErrorCode(value)
+ return nil
+}
+func (LogServiceError_ErrorCode) EnumDescriptor() ([]byte, []int) {
+ return fileDescriptor_log_service_f054fd4b5012319d, []int{0, 0}
+}
+
+type LogServiceError struct {
+ XXX_NoUnkeyedLiteral struct{} `json:"-"`
+ XXX_unrecognized []byte `json:"-"`
+ XXX_sizecache int32 `json:"-"`
+}
+
+func (m *LogServiceError) Reset() { *m = LogServiceError{} }
+func (m *LogServiceError) String() string { return proto.CompactTextString(m) }
+func (*LogServiceError) ProtoMessage() {}
+func (*LogServiceError) Descriptor() ([]byte, []int) {
+ return fileDescriptor_log_service_f054fd4b5012319d, []int{0}
+}
+func (m *LogServiceError) XXX_Unmarshal(b []byte) error {
+ return xxx_messageInfo_LogServiceError.Unmarshal(m, b)
+}
+func (m *LogServiceError) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ return xxx_messageInfo_LogServiceError.Marshal(b, m, deterministic)
+}
+func (dst *LogServiceError) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_LogServiceError.Merge(dst, src)
+}
+func (m *LogServiceError) XXX_Size() int {
+ return xxx_messageInfo_LogServiceError.Size(m)
+}
+func (m *LogServiceError) XXX_DiscardUnknown() {
+ xxx_messageInfo_LogServiceError.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_LogServiceError proto.InternalMessageInfo
+
+type UserAppLogLine struct {
+ TimestampUsec *int64 `protobuf:"varint,1,req,name=timestamp_usec,json=timestampUsec" json:"timestamp_usec,omitempty"`
+ Level *int64 `protobuf:"varint,2,req,name=level" json:"level,omitempty"`
+ Message *string `protobuf:"bytes,3,req,name=message" json:"message,omitempty"`
+ XXX_NoUnkeyedLiteral struct{} `json:"-"`
+ XXX_unrecognized []byte `json:"-"`
+ XXX_sizecache int32 `json:"-"`
+}
+
+func (m *UserAppLogLine) Reset() { *m = UserAppLogLine{} }
+func (m *UserAppLogLine) String() string { return proto.CompactTextString(m) }
+func (*UserAppLogLine) ProtoMessage() {}
+func (*UserAppLogLine) Descriptor() ([]byte, []int) {
+ return fileDescriptor_log_service_f054fd4b5012319d, []int{1}
+}
+func (m *UserAppLogLine) XXX_Unmarshal(b []byte) error {
+ return xxx_messageInfo_UserAppLogLine.Unmarshal(m, b)
+}
+func (m *UserAppLogLine) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ return xxx_messageInfo_UserAppLogLine.Marshal(b, m, deterministic)
+}
+func (dst *UserAppLogLine) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_UserAppLogLine.Merge(dst, src)
+}
+func (m *UserAppLogLine) XXX_Size() int {
+ return xxx_messageInfo_UserAppLogLine.Size(m)
+}
+func (m *UserAppLogLine) XXX_DiscardUnknown() {
+ xxx_messageInfo_UserAppLogLine.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_UserAppLogLine proto.InternalMessageInfo
+
+func (m *UserAppLogLine) GetTimestampUsec() int64 {
+ if m != nil && m.TimestampUsec != nil {
+ return *m.TimestampUsec
+ }
+ return 0
+}
+
+func (m *UserAppLogLine) GetLevel() int64 {
+ if m != nil && m.Level != nil {
+ return *m.Level
+ }
+ return 0
+}
+
+func (m *UserAppLogLine) GetMessage() string {
+ if m != nil && m.Message != nil {
+ return *m.Message
+ }
+ return ""
+}
+
+type UserAppLogGroup struct {
+ LogLine []*UserAppLogLine `protobuf:"bytes,2,rep,name=log_line,json=logLine" json:"log_line,omitempty"`
+ XXX_NoUnkeyedLiteral struct{} `json:"-"`
+ XXX_unrecognized []byte `json:"-"`
+ XXX_sizecache int32 `json:"-"`
+}
+
+func (m *UserAppLogGroup) Reset() { *m = UserAppLogGroup{} }
+func (m *UserAppLogGroup) String() string { return proto.CompactTextString(m) }
+func (*UserAppLogGroup) ProtoMessage() {}
+func (*UserAppLogGroup) Descriptor() ([]byte, []int) {
+ return fileDescriptor_log_service_f054fd4b5012319d, []int{2}
+}
+func (m *UserAppLogGroup) XXX_Unmarshal(b []byte) error {
+ return xxx_messageInfo_UserAppLogGroup.Unmarshal(m, b)
+}
+func (m *UserAppLogGroup) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ return xxx_messageInfo_UserAppLogGroup.Marshal(b, m, deterministic)
+}
+func (dst *UserAppLogGroup) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_UserAppLogGroup.Merge(dst, src)
+}
+func (m *UserAppLogGroup) XXX_Size() int {
+ return xxx_messageInfo_UserAppLogGroup.Size(m)
+}
+func (m *UserAppLogGroup) XXX_DiscardUnknown() {
+ xxx_messageInfo_UserAppLogGroup.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_UserAppLogGroup proto.InternalMessageInfo
+
+func (m *UserAppLogGroup) GetLogLine() []*UserAppLogLine {
+ if m != nil {
+ return m.LogLine
+ }
+ return nil
+}
+
+type FlushRequest struct {
+ Logs []byte `protobuf:"bytes,1,opt,name=logs" json:"logs,omitempty"`
+ XXX_NoUnkeyedLiteral struct{} `json:"-"`
+ XXX_unrecognized []byte `json:"-"`
+ XXX_sizecache int32 `json:"-"`
+}
+
+func (m *FlushRequest) Reset() { *m = FlushRequest{} }
+func (m *FlushRequest) String() string { return proto.CompactTextString(m) }
+func (*FlushRequest) ProtoMessage() {}
+func (*FlushRequest) Descriptor() ([]byte, []int) {
+ return fileDescriptor_log_service_f054fd4b5012319d, []int{3}
+}
+func (m *FlushRequest) XXX_Unmarshal(b []byte) error {
+ return xxx_messageInfo_FlushRequest.Unmarshal(m, b)
+}
+func (m *FlushRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ return xxx_messageInfo_FlushRequest.Marshal(b, m, deterministic)
+}
+func (dst *FlushRequest) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_FlushRequest.Merge(dst, src)
+}
+func (m *FlushRequest) XXX_Size() int {
+ return xxx_messageInfo_FlushRequest.Size(m)
+}
+func (m *FlushRequest) XXX_DiscardUnknown() {
+ xxx_messageInfo_FlushRequest.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_FlushRequest proto.InternalMessageInfo
+
+func (m *FlushRequest) GetLogs() []byte {
+ if m != nil {
+ return m.Logs
+ }
+ return nil
+}
+
+type SetStatusRequest struct {
+ Status *string `protobuf:"bytes,1,req,name=status" json:"status,omitempty"`
+ XXX_NoUnkeyedLiteral struct{} `json:"-"`
+ XXX_unrecognized []byte `json:"-"`
+ XXX_sizecache int32 `json:"-"`
+}
+
+func (m *SetStatusRequest) Reset() { *m = SetStatusRequest{} }
+func (m *SetStatusRequest) String() string { return proto.CompactTextString(m) }
+func (*SetStatusRequest) ProtoMessage() {}
+func (*SetStatusRequest) Descriptor() ([]byte, []int) {
+ return fileDescriptor_log_service_f054fd4b5012319d, []int{4}
+}
+func (m *SetStatusRequest) XXX_Unmarshal(b []byte) error {
+ return xxx_messageInfo_SetStatusRequest.Unmarshal(m, b)
+}
+func (m *SetStatusRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ return xxx_messageInfo_SetStatusRequest.Marshal(b, m, deterministic)
+}
+func (dst *SetStatusRequest) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_SetStatusRequest.Merge(dst, src)
+}
+func (m *SetStatusRequest) XXX_Size() int {
+ return xxx_messageInfo_SetStatusRequest.Size(m)
+}
+func (m *SetStatusRequest) XXX_DiscardUnknown() {
+ xxx_messageInfo_SetStatusRequest.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_SetStatusRequest proto.InternalMessageInfo
+
+func (m *SetStatusRequest) GetStatus() string {
+ if m != nil && m.Status != nil {
+ return *m.Status
+ }
+ return ""
+}
+
+type LogOffset struct {
+ RequestId []byte `protobuf:"bytes,1,opt,name=request_id,json=requestId" json:"request_id,omitempty"`
+ XXX_NoUnkeyedLiteral struct{} `json:"-"`
+ XXX_unrecognized []byte `json:"-"`
+ XXX_sizecache int32 `json:"-"`
+}
+
+func (m *LogOffset) Reset() { *m = LogOffset{} }
+func (m *LogOffset) String() string { return proto.CompactTextString(m) }
+func (*LogOffset) ProtoMessage() {}
+func (*LogOffset) Descriptor() ([]byte, []int) {
+ return fileDescriptor_log_service_f054fd4b5012319d, []int{5}
+}
+func (m *LogOffset) XXX_Unmarshal(b []byte) error {
+ return xxx_messageInfo_LogOffset.Unmarshal(m, b)
+}
+func (m *LogOffset) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ return xxx_messageInfo_LogOffset.Marshal(b, m, deterministic)
+}
+func (dst *LogOffset) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_LogOffset.Merge(dst, src)
+}
+func (m *LogOffset) XXX_Size() int {
+ return xxx_messageInfo_LogOffset.Size(m)
+}
+func (m *LogOffset) XXX_DiscardUnknown() {
+ xxx_messageInfo_LogOffset.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_LogOffset proto.InternalMessageInfo
+
+func (m *LogOffset) GetRequestId() []byte {
+ if m != nil {
+ return m.RequestId
+ }
+ return nil
+}
+
+type LogLine struct {
+ Time *int64 `protobuf:"varint,1,req,name=time" json:"time,omitempty"`
+ Level *int32 `protobuf:"varint,2,req,name=level" json:"level,omitempty"`
+ LogMessage *string `protobuf:"bytes,3,req,name=log_message,json=logMessage" json:"log_message,omitempty"`
+ XXX_NoUnkeyedLiteral struct{} `json:"-"`
+ XXX_unrecognized []byte `json:"-"`
+ XXX_sizecache int32 `json:"-"`
+}
+
+func (m *LogLine) Reset() { *m = LogLine{} }
+func (m *LogLine) String() string { return proto.CompactTextString(m) }
+func (*LogLine) ProtoMessage() {}
+func (*LogLine) Descriptor() ([]byte, []int) {
+ return fileDescriptor_log_service_f054fd4b5012319d, []int{6}
+}
+func (m *LogLine) XXX_Unmarshal(b []byte) error {
+ return xxx_messageInfo_LogLine.Unmarshal(m, b)
+}
+func (m *LogLine) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ return xxx_messageInfo_LogLine.Marshal(b, m, deterministic)
+}
+func (dst *LogLine) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_LogLine.Merge(dst, src)
+}
+func (m *LogLine) XXX_Size() int {
+ return xxx_messageInfo_LogLine.Size(m)
+}
+func (m *LogLine) XXX_DiscardUnknown() {
+ xxx_messageInfo_LogLine.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_LogLine proto.InternalMessageInfo
+
+func (m *LogLine) GetTime() int64 {
+ if m != nil && m.Time != nil {
+ return *m.Time
+ }
+ return 0
+}
+
+func (m *LogLine) GetLevel() int32 {
+ if m != nil && m.Level != nil {
+ return *m.Level
+ }
+ return 0
+}
+
+func (m *LogLine) GetLogMessage() string {
+ if m != nil && m.LogMessage != nil {
+ return *m.LogMessage
+ }
+ return ""
+}
+
+type RequestLog struct {
+ AppId *string `protobuf:"bytes,1,req,name=app_id,json=appId" json:"app_id,omitempty"`
+ ModuleId *string `protobuf:"bytes,37,opt,name=module_id,json=moduleId,def=default" json:"module_id,omitempty"`
+ VersionId *string `protobuf:"bytes,2,req,name=version_id,json=versionId" json:"version_id,omitempty"`
+ RequestId []byte `protobuf:"bytes,3,req,name=request_id,json=requestId" json:"request_id,omitempty"`
+ Offset *LogOffset `protobuf:"bytes,35,opt,name=offset" json:"offset,omitempty"`
+ Ip *string `protobuf:"bytes,4,req,name=ip" json:"ip,omitempty"`
+ Nickname *string `protobuf:"bytes,5,opt,name=nickname" json:"nickname,omitempty"`
+ StartTime *int64 `protobuf:"varint,6,req,name=start_time,json=startTime" json:"start_time,omitempty"`
+ EndTime *int64 `protobuf:"varint,7,req,name=end_time,json=endTime" json:"end_time,omitempty"`
+ Latency *int64 `protobuf:"varint,8,req,name=latency" json:"latency,omitempty"`
+ Mcycles *int64 `protobuf:"varint,9,req,name=mcycles" json:"mcycles,omitempty"`
+ Method *string `protobuf:"bytes,10,req,name=method" json:"method,omitempty"`
+ Resource *string `protobuf:"bytes,11,req,name=resource" json:"resource,omitempty"`
+ HttpVersion *string `protobuf:"bytes,12,req,name=http_version,json=httpVersion" json:"http_version,omitempty"`
+ Status *int32 `protobuf:"varint,13,req,name=status" json:"status,omitempty"`
+ ResponseSize *int64 `protobuf:"varint,14,req,name=response_size,json=responseSize" json:"response_size,omitempty"`
+ Referrer *string `protobuf:"bytes,15,opt,name=referrer" json:"referrer,omitempty"`
+ UserAgent *string `protobuf:"bytes,16,opt,name=user_agent,json=userAgent" json:"user_agent,omitempty"`
+ UrlMapEntry *string `protobuf:"bytes,17,req,name=url_map_entry,json=urlMapEntry" json:"url_map_entry,omitempty"`
+ Combined *string `protobuf:"bytes,18,req,name=combined" json:"combined,omitempty"`
+ ApiMcycles *int64 `protobuf:"varint,19,opt,name=api_mcycles,json=apiMcycles" json:"api_mcycles,omitempty"`
+ Host *string `protobuf:"bytes,20,opt,name=host" json:"host,omitempty"`
+ Cost *float64 `protobuf:"fixed64,21,opt,name=cost" json:"cost,omitempty"`
+ TaskQueueName *string `protobuf:"bytes,22,opt,name=task_queue_name,json=taskQueueName" json:"task_queue_name,omitempty"`
+ TaskName *string `protobuf:"bytes,23,opt,name=task_name,json=taskName" json:"task_name,omitempty"`
+ WasLoadingRequest *bool `protobuf:"varint,24,opt,name=was_loading_request,json=wasLoadingRequest" json:"was_loading_request,omitempty"`
+ PendingTime *int64 `protobuf:"varint,25,opt,name=pending_time,json=pendingTime" json:"pending_time,omitempty"`
+ ReplicaIndex *int32 `protobuf:"varint,26,opt,name=replica_index,json=replicaIndex,def=-1" json:"replica_index,omitempty"`
+ Finished *bool `protobuf:"varint,27,opt,name=finished,def=1" json:"finished,omitempty"`
+ CloneKey []byte `protobuf:"bytes,28,opt,name=clone_key,json=cloneKey" json:"clone_key,omitempty"`
+ Line []*LogLine `protobuf:"bytes,29,rep,name=line" json:"line,omitempty"`
+ LinesIncomplete *bool `protobuf:"varint,36,opt,name=lines_incomplete,json=linesIncomplete" json:"lines_incomplete,omitempty"`
+ AppEngineRelease []byte `protobuf:"bytes,38,opt,name=app_engine_release,json=appEngineRelease" json:"app_engine_release,omitempty"`
+ ExitReason *int32 `protobuf:"varint,30,opt,name=exit_reason,json=exitReason" json:"exit_reason,omitempty"`
+ WasThrottledForTime *bool `protobuf:"varint,31,opt,name=was_throttled_for_time,json=wasThrottledForTime" json:"was_throttled_for_time,omitempty"`
+ WasThrottledForRequests *bool `protobuf:"varint,32,opt,name=was_throttled_for_requests,json=wasThrottledForRequests" json:"was_throttled_for_requests,omitempty"`
+ ThrottledTime *int64 `protobuf:"varint,33,opt,name=throttled_time,json=throttledTime" json:"throttled_time,omitempty"`
+ ServerName []byte `protobuf:"bytes,34,opt,name=server_name,json=serverName" json:"server_name,omitempty"`
+ XXX_NoUnkeyedLiteral struct{} `json:"-"`
+ XXX_unrecognized []byte `json:"-"`
+ XXX_sizecache int32 `json:"-"`
+}
+
+func (m *RequestLog) Reset() { *m = RequestLog{} }
+func (m *RequestLog) String() string { return proto.CompactTextString(m) }
+func (*RequestLog) ProtoMessage() {}
+func (*RequestLog) Descriptor() ([]byte, []int) {
+ return fileDescriptor_log_service_f054fd4b5012319d, []int{7}
+}
+func (m *RequestLog) XXX_Unmarshal(b []byte) error {
+ return xxx_messageInfo_RequestLog.Unmarshal(m, b)
+}
+func (m *RequestLog) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ return xxx_messageInfo_RequestLog.Marshal(b, m, deterministic)
+}
+func (dst *RequestLog) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_RequestLog.Merge(dst, src)
+}
+func (m *RequestLog) XXX_Size() int {
+ return xxx_messageInfo_RequestLog.Size(m)
+}
+func (m *RequestLog) XXX_DiscardUnknown() {
+ xxx_messageInfo_RequestLog.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_RequestLog proto.InternalMessageInfo
+
+const Default_RequestLog_ModuleId string = "default"
+const Default_RequestLog_ReplicaIndex int32 = -1
+const Default_RequestLog_Finished bool = true
+
+func (m *RequestLog) GetAppId() string {
+ if m != nil && m.AppId != nil {
+ return *m.AppId
+ }
+ return ""
+}
+
+func (m *RequestLog) GetModuleId() string {
+ if m != nil && m.ModuleId != nil {
+ return *m.ModuleId
+ }
+ return Default_RequestLog_ModuleId
+}
+
+func (m *RequestLog) GetVersionId() string {
+ if m != nil && m.VersionId != nil {
+ return *m.VersionId
+ }
+ return ""
+}
+
+func (m *RequestLog) GetRequestId() []byte {
+ if m != nil {
+ return m.RequestId
+ }
+ return nil
+}
+
+func (m *RequestLog) GetOffset() *LogOffset {
+ if m != nil {
+ return m.Offset
+ }
+ return nil
+}
+
+func (m *RequestLog) GetIp() string {
+ if m != nil && m.Ip != nil {
+ return *m.Ip
+ }
+ return ""
+}
+
+func (m *RequestLog) GetNickname() string {
+ if m != nil && m.Nickname != nil {
+ return *m.Nickname
+ }
+ return ""
+}
+
+func (m *RequestLog) GetStartTime() int64 {
+ if m != nil && m.StartTime != nil {
+ return *m.StartTime
+ }
+ return 0
+}
+
+func (m *RequestLog) GetEndTime() int64 {
+ if m != nil && m.EndTime != nil {
+ return *m.EndTime
+ }
+ return 0
+}
+
+func (m *RequestLog) GetLatency() int64 {
+ if m != nil && m.Latency != nil {
+ return *m.Latency
+ }
+ return 0
+}
+
+func (m *RequestLog) GetMcycles() int64 {
+ if m != nil && m.Mcycles != nil {
+ return *m.Mcycles
+ }
+ return 0
+}
+
+func (m *RequestLog) GetMethod() string {
+ if m != nil && m.Method != nil {
+ return *m.Method
+ }
+ return ""
+}
+
+func (m *RequestLog) GetResource() string {
+ if m != nil && m.Resource != nil {
+ return *m.Resource
+ }
+ return ""
+}
+
+func (m *RequestLog) GetHttpVersion() string {
+ if m != nil && m.HttpVersion != nil {
+ return *m.HttpVersion
+ }
+ return ""
+}
+
+func (m *RequestLog) GetStatus() int32 {
+ if m != nil && m.Status != nil {
+ return *m.Status
+ }
+ return 0
+}
+
+func (m *RequestLog) GetResponseSize() int64 {
+ if m != nil && m.ResponseSize != nil {
+ return *m.ResponseSize
+ }
+ return 0
+}
+
+func (m *RequestLog) GetReferrer() string {
+ if m != nil && m.Referrer != nil {
+ return *m.Referrer
+ }
+ return ""
+}
+
+func (m *RequestLog) GetUserAgent() string {
+ if m != nil && m.UserAgent != nil {
+ return *m.UserAgent
+ }
+ return ""
+}
+
+func (m *RequestLog) GetUrlMapEntry() string {
+ if m != nil && m.UrlMapEntry != nil {
+ return *m.UrlMapEntry
+ }
+ return ""
+}
+
+func (m *RequestLog) GetCombined() string {
+ if m != nil && m.Combined != nil {
+ return *m.Combined
+ }
+ return ""
+}
+
+func (m *RequestLog) GetApiMcycles() int64 {
+ if m != nil && m.ApiMcycles != nil {
+ return *m.ApiMcycles
+ }
+ return 0
+}
+
+func (m *RequestLog) GetHost() string {
+ if m != nil && m.Host != nil {
+ return *m.Host
+ }
+ return ""
+}
+
+func (m *RequestLog) GetCost() float64 {
+ if m != nil && m.Cost != nil {
+ return *m.Cost
+ }
+ return 0
+}
+
+func (m *RequestLog) GetTaskQueueName() string {
+ if m != nil && m.TaskQueueName != nil {
+ return *m.TaskQueueName
+ }
+ return ""
+}
+
+func (m *RequestLog) GetTaskName() string {
+ if m != nil && m.TaskName != nil {
+ return *m.TaskName
+ }
+ return ""
+}
+
+func (m *RequestLog) GetWasLoadingRequest() bool {
+ if m != nil && m.WasLoadingRequest != nil {
+ return *m.WasLoadingRequest
+ }
+ return false
+}
+
+func (m *RequestLog) GetPendingTime() int64 {
+ if m != nil && m.PendingTime != nil {
+ return *m.PendingTime
+ }
+ return 0
+}
+
+func (m *RequestLog) GetReplicaIndex() int32 {
+ if m != nil && m.ReplicaIndex != nil {
+ return *m.ReplicaIndex
+ }
+ return Default_RequestLog_ReplicaIndex
+}
+
+func (m *RequestLog) GetFinished() bool {
+ if m != nil && m.Finished != nil {
+ return *m.Finished
+ }
+ return Default_RequestLog_Finished
+}
+
+func (m *RequestLog) GetCloneKey() []byte {
+ if m != nil {
+ return m.CloneKey
+ }
+ return nil
+}
+
+func (m *RequestLog) GetLine() []*LogLine {
+ if m != nil {
+ return m.Line
+ }
+ return nil
+}
+
+func (m *RequestLog) GetLinesIncomplete() bool {
+ if m != nil && m.LinesIncomplete != nil {
+ return *m.LinesIncomplete
+ }
+ return false
+}
+
+func (m *RequestLog) GetAppEngineRelease() []byte {
+ if m != nil {
+ return m.AppEngineRelease
+ }
+ return nil
+}
+
+func (m *RequestLog) GetExitReason() int32 {
+ if m != nil && m.ExitReason != nil {
+ return *m.ExitReason
+ }
+ return 0
+}
+
+func (m *RequestLog) GetWasThrottledForTime() bool {
+ if m != nil && m.WasThrottledForTime != nil {
+ return *m.WasThrottledForTime
+ }
+ return false
+}
+
+func (m *RequestLog) GetWasThrottledForRequests() bool {
+ if m != nil && m.WasThrottledForRequests != nil {
+ return *m.WasThrottledForRequests
+ }
+ return false
+}
+
+func (m *RequestLog) GetThrottledTime() int64 {
+ if m != nil && m.ThrottledTime != nil {
+ return *m.ThrottledTime
+ }
+ return 0
+}
+
+func (m *RequestLog) GetServerName() []byte {
+ if m != nil {
+ return m.ServerName
+ }
+ return nil
+}
+
+type LogModuleVersion struct {
+ ModuleId *string `protobuf:"bytes,1,opt,name=module_id,json=moduleId,def=default" json:"module_id,omitempty"`
+ VersionId *string `protobuf:"bytes,2,opt,name=version_id,json=versionId" json:"version_id,omitempty"`
+ XXX_NoUnkeyedLiteral struct{} `json:"-"`
+ XXX_unrecognized []byte `json:"-"`
+ XXX_sizecache int32 `json:"-"`
+}
+
+func (m *LogModuleVersion) Reset() { *m = LogModuleVersion{} }
+func (m *LogModuleVersion) String() string { return proto.CompactTextString(m) }
+func (*LogModuleVersion) ProtoMessage() {}
+func (*LogModuleVersion) Descriptor() ([]byte, []int) {
+ return fileDescriptor_log_service_f054fd4b5012319d, []int{8}
+}
+func (m *LogModuleVersion) XXX_Unmarshal(b []byte) error {
+ return xxx_messageInfo_LogModuleVersion.Unmarshal(m, b)
+}
+func (m *LogModuleVersion) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ return xxx_messageInfo_LogModuleVersion.Marshal(b, m, deterministic)
+}
+func (dst *LogModuleVersion) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_LogModuleVersion.Merge(dst, src)
+}
+func (m *LogModuleVersion) XXX_Size() int {
+ return xxx_messageInfo_LogModuleVersion.Size(m)
+}
+func (m *LogModuleVersion) XXX_DiscardUnknown() {
+ xxx_messageInfo_LogModuleVersion.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_LogModuleVersion proto.InternalMessageInfo
+
+const Default_LogModuleVersion_ModuleId string = "default"
+
+func (m *LogModuleVersion) GetModuleId() string {
+ if m != nil && m.ModuleId != nil {
+ return *m.ModuleId
+ }
+ return Default_LogModuleVersion_ModuleId
+}
+
+func (m *LogModuleVersion) GetVersionId() string {
+ if m != nil && m.VersionId != nil {
+ return *m.VersionId
+ }
+ return ""
+}
+
+type LogReadRequest struct {
+ AppId *string `protobuf:"bytes,1,req,name=app_id,json=appId" json:"app_id,omitempty"`
+ VersionId []string `protobuf:"bytes,2,rep,name=version_id,json=versionId" json:"version_id,omitempty"`
+ ModuleVersion []*LogModuleVersion `protobuf:"bytes,19,rep,name=module_version,json=moduleVersion" json:"module_version,omitempty"`
+ StartTime *int64 `protobuf:"varint,3,opt,name=start_time,json=startTime" json:"start_time,omitempty"`
+ EndTime *int64 `protobuf:"varint,4,opt,name=end_time,json=endTime" json:"end_time,omitempty"`
+ Offset *LogOffset `protobuf:"bytes,5,opt,name=offset" json:"offset,omitempty"`
+ RequestId [][]byte `protobuf:"bytes,6,rep,name=request_id,json=requestId" json:"request_id,omitempty"`
+ MinimumLogLevel *int32 `protobuf:"varint,7,opt,name=minimum_log_level,json=minimumLogLevel" json:"minimum_log_level,omitempty"`
+ IncludeIncomplete *bool `protobuf:"varint,8,opt,name=include_incomplete,json=includeIncomplete" json:"include_incomplete,omitempty"`
+ Count *int64 `protobuf:"varint,9,opt,name=count" json:"count,omitempty"`
+ CombinedLogRegex *string `protobuf:"bytes,14,opt,name=combined_log_regex,json=combinedLogRegex" json:"combined_log_regex,omitempty"`
+ HostRegex *string `protobuf:"bytes,15,opt,name=host_regex,json=hostRegex" json:"host_regex,omitempty"`
+ ReplicaIndex *int32 `protobuf:"varint,16,opt,name=replica_index,json=replicaIndex" json:"replica_index,omitempty"`
+ IncludeAppLogs *bool `protobuf:"varint,10,opt,name=include_app_logs,json=includeAppLogs" json:"include_app_logs,omitempty"`
+ AppLogsPerRequest *int32 `protobuf:"varint,17,opt,name=app_logs_per_request,json=appLogsPerRequest" json:"app_logs_per_request,omitempty"`
+ IncludeHost *bool `protobuf:"varint,11,opt,name=include_host,json=includeHost" json:"include_host,omitempty"`
+ IncludeAll *bool `protobuf:"varint,12,opt,name=include_all,json=includeAll" json:"include_all,omitempty"`
+ CacheIterator *bool `protobuf:"varint,13,opt,name=cache_iterator,json=cacheIterator" json:"cache_iterator,omitempty"`
+ NumShards *int32 `protobuf:"varint,18,opt,name=num_shards,json=numShards" json:"num_shards,omitempty"`
+ XXX_NoUnkeyedLiteral struct{} `json:"-"`
+ XXX_unrecognized []byte `json:"-"`
+ XXX_sizecache int32 `json:"-"`
+}
+
+func (m *LogReadRequest) Reset() { *m = LogReadRequest{} }
+func (m *LogReadRequest) String() string { return proto.CompactTextString(m) }
+func (*LogReadRequest) ProtoMessage() {}
+func (*LogReadRequest) Descriptor() ([]byte, []int) {
+ return fileDescriptor_log_service_f054fd4b5012319d, []int{9}
+}
+func (m *LogReadRequest) XXX_Unmarshal(b []byte) error {
+ return xxx_messageInfo_LogReadRequest.Unmarshal(m, b)
+}
+func (m *LogReadRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ return xxx_messageInfo_LogReadRequest.Marshal(b, m, deterministic)
+}
+func (dst *LogReadRequest) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_LogReadRequest.Merge(dst, src)
+}
+func (m *LogReadRequest) XXX_Size() int {
+ return xxx_messageInfo_LogReadRequest.Size(m)
+}
+func (m *LogReadRequest) XXX_DiscardUnknown() {
+ xxx_messageInfo_LogReadRequest.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_LogReadRequest proto.InternalMessageInfo
+
+func (m *LogReadRequest) GetAppId() string {
+ if m != nil && m.AppId != nil {
+ return *m.AppId
+ }
+ return ""
+}
+
+func (m *LogReadRequest) GetVersionId() []string {
+ if m != nil {
+ return m.VersionId
+ }
+ return nil
+}
+
+func (m *LogReadRequest) GetModuleVersion() []*LogModuleVersion {
+ if m != nil {
+ return m.ModuleVersion
+ }
+ return nil
+}
+
+func (m *LogReadRequest) GetStartTime() int64 {
+ if m != nil && m.StartTime != nil {
+ return *m.StartTime
+ }
+ return 0
+}
+
+func (m *LogReadRequest) GetEndTime() int64 {
+ if m != nil && m.EndTime != nil {
+ return *m.EndTime
+ }
+ return 0
+}
+
+func (m *LogReadRequest) GetOffset() *LogOffset {
+ if m != nil {
+ return m.Offset
+ }
+ return nil
+}
+
+func (m *LogReadRequest) GetRequestId() [][]byte {
+ if m != nil {
+ return m.RequestId
+ }
+ return nil
+}
+
+func (m *LogReadRequest) GetMinimumLogLevel() int32 {
+ if m != nil && m.MinimumLogLevel != nil {
+ return *m.MinimumLogLevel
+ }
+ return 0
+}
+
+func (m *LogReadRequest) GetIncludeIncomplete() bool {
+ if m != nil && m.IncludeIncomplete != nil {
+ return *m.IncludeIncomplete
+ }
+ return false
+}
+
+func (m *LogReadRequest) GetCount() int64 {
+ if m != nil && m.Count != nil {
+ return *m.Count
+ }
+ return 0
+}
+
+func (m *LogReadRequest) GetCombinedLogRegex() string {
+ if m != nil && m.CombinedLogRegex != nil {
+ return *m.CombinedLogRegex
+ }
+ return ""
+}
+
+func (m *LogReadRequest) GetHostRegex() string {
+ if m != nil && m.HostRegex != nil {
+ return *m.HostRegex
+ }
+ return ""
+}
+
+func (m *LogReadRequest) GetReplicaIndex() int32 {
+ if m != nil && m.ReplicaIndex != nil {
+ return *m.ReplicaIndex
+ }
+ return 0
+}
+
+func (m *LogReadRequest) GetIncludeAppLogs() bool {
+ if m != nil && m.IncludeAppLogs != nil {
+ return *m.IncludeAppLogs
+ }
+ return false
+}
+
+func (m *LogReadRequest) GetAppLogsPerRequest() int32 {
+ if m != nil && m.AppLogsPerRequest != nil {
+ return *m.AppLogsPerRequest
+ }
+ return 0
+}
+
+func (m *LogReadRequest) GetIncludeHost() bool {
+ if m != nil && m.IncludeHost != nil {
+ return *m.IncludeHost
+ }
+ return false
+}
+
+func (m *LogReadRequest) GetIncludeAll() bool {
+ if m != nil && m.IncludeAll != nil {
+ return *m.IncludeAll
+ }
+ return false
+}
+
+func (m *LogReadRequest) GetCacheIterator() bool {
+ if m != nil && m.CacheIterator != nil {
+ return *m.CacheIterator
+ }
+ return false
+}
+
+func (m *LogReadRequest) GetNumShards() int32 {
+ if m != nil && m.NumShards != nil {
+ return *m.NumShards
+ }
+ return 0
+}
+
+type LogReadResponse struct {
+ Log []*RequestLog `protobuf:"bytes,1,rep,name=log" json:"log,omitempty"`
+ Offset *LogOffset `protobuf:"bytes,2,opt,name=offset" json:"offset,omitempty"`
+ LastEndTime *int64 `protobuf:"varint,3,opt,name=last_end_time,json=lastEndTime" json:"last_end_time,omitempty"`
+ XXX_NoUnkeyedLiteral struct{} `json:"-"`
+ XXX_unrecognized []byte `json:"-"`
+ XXX_sizecache int32 `json:"-"`
+}
+
+func (m *LogReadResponse) Reset() { *m = LogReadResponse{} }
+func (m *LogReadResponse) String() string { return proto.CompactTextString(m) }
+func (*LogReadResponse) ProtoMessage() {}
+func (*LogReadResponse) Descriptor() ([]byte, []int) {
+ return fileDescriptor_log_service_f054fd4b5012319d, []int{10}
+}
+func (m *LogReadResponse) XXX_Unmarshal(b []byte) error {
+ return xxx_messageInfo_LogReadResponse.Unmarshal(m, b)
+}
+func (m *LogReadResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ return xxx_messageInfo_LogReadResponse.Marshal(b, m, deterministic)
+}
+func (dst *LogReadResponse) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_LogReadResponse.Merge(dst, src)
+}
+func (m *LogReadResponse) XXX_Size() int {
+ return xxx_messageInfo_LogReadResponse.Size(m)
+}
+func (m *LogReadResponse) XXX_DiscardUnknown() {
+ xxx_messageInfo_LogReadResponse.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_LogReadResponse proto.InternalMessageInfo
+
+func (m *LogReadResponse) GetLog() []*RequestLog {
+ if m != nil {
+ return m.Log
+ }
+ return nil
+}
+
+func (m *LogReadResponse) GetOffset() *LogOffset {
+ if m != nil {
+ return m.Offset
+ }
+ return nil
+}
+
+func (m *LogReadResponse) GetLastEndTime() int64 {
+ if m != nil && m.LastEndTime != nil {
+ return *m.LastEndTime
+ }
+ return 0
+}
+
+type LogUsageRecord struct {
+ VersionId *string `protobuf:"bytes,1,opt,name=version_id,json=versionId" json:"version_id,omitempty"`
+ StartTime *int32 `protobuf:"varint,2,opt,name=start_time,json=startTime" json:"start_time,omitempty"`
+ EndTime *int32 `protobuf:"varint,3,opt,name=end_time,json=endTime" json:"end_time,omitempty"`
+ Count *int64 `protobuf:"varint,4,opt,name=count" json:"count,omitempty"`
+ TotalSize *int64 `protobuf:"varint,5,opt,name=total_size,json=totalSize" json:"total_size,omitempty"`
+ Records *int32 `protobuf:"varint,6,opt,name=records" json:"records,omitempty"`
+ XXX_NoUnkeyedLiteral struct{} `json:"-"`
+ XXX_unrecognized []byte `json:"-"`
+ XXX_sizecache int32 `json:"-"`
+}
+
+func (m *LogUsageRecord) Reset() { *m = LogUsageRecord{} }
+func (m *LogUsageRecord) String() string { return proto.CompactTextString(m) }
+func (*LogUsageRecord) ProtoMessage() {}
+func (*LogUsageRecord) Descriptor() ([]byte, []int) {
+ return fileDescriptor_log_service_f054fd4b5012319d, []int{11}
+}
+func (m *LogUsageRecord) XXX_Unmarshal(b []byte) error {
+ return xxx_messageInfo_LogUsageRecord.Unmarshal(m, b)
+}
+func (m *LogUsageRecord) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ return xxx_messageInfo_LogUsageRecord.Marshal(b, m, deterministic)
+}
+func (dst *LogUsageRecord) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_LogUsageRecord.Merge(dst, src)
+}
+func (m *LogUsageRecord) XXX_Size() int {
+ return xxx_messageInfo_LogUsageRecord.Size(m)
+}
+func (m *LogUsageRecord) XXX_DiscardUnknown() {
+ xxx_messageInfo_LogUsageRecord.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_LogUsageRecord proto.InternalMessageInfo
+
+func (m *LogUsageRecord) GetVersionId() string {
+ if m != nil && m.VersionId != nil {
+ return *m.VersionId
+ }
+ return ""
+}
+
+func (m *LogUsageRecord) GetStartTime() int32 {
+ if m != nil && m.StartTime != nil {
+ return *m.StartTime
+ }
+ return 0
+}
+
+func (m *LogUsageRecord) GetEndTime() int32 {
+ if m != nil && m.EndTime != nil {
+ return *m.EndTime
+ }
+ return 0
+}
+
+func (m *LogUsageRecord) GetCount() int64 {
+ if m != nil && m.Count != nil {
+ return *m.Count
+ }
+ return 0
+}
+
+func (m *LogUsageRecord) GetTotalSize() int64 {
+ if m != nil && m.TotalSize != nil {
+ return *m.TotalSize
+ }
+ return 0
+}
+
+func (m *LogUsageRecord) GetRecords() int32 {
+ if m != nil && m.Records != nil {
+ return *m.Records
+ }
+ return 0
+}
+
+type LogUsageRequest struct {
+ AppId *string `protobuf:"bytes,1,req,name=app_id,json=appId" json:"app_id,omitempty"`
+ VersionId []string `protobuf:"bytes,2,rep,name=version_id,json=versionId" json:"version_id,omitempty"`
+ StartTime *int32 `protobuf:"varint,3,opt,name=start_time,json=startTime" json:"start_time,omitempty"`
+ EndTime *int32 `protobuf:"varint,4,opt,name=end_time,json=endTime" json:"end_time,omitempty"`
+ ResolutionHours *uint32 `protobuf:"varint,5,opt,name=resolution_hours,json=resolutionHours,def=1" json:"resolution_hours,omitempty"`
+ CombineVersions *bool `protobuf:"varint,6,opt,name=combine_versions,json=combineVersions" json:"combine_versions,omitempty"`
+ UsageVersion *int32 `protobuf:"varint,7,opt,name=usage_version,json=usageVersion" json:"usage_version,omitempty"`
+ VersionsOnly *bool `protobuf:"varint,8,opt,name=versions_only,json=versionsOnly" json:"versions_only,omitempty"`
+ XXX_NoUnkeyedLiteral struct{} `json:"-"`
+ XXX_unrecognized []byte `json:"-"`
+ XXX_sizecache int32 `json:"-"`
+}
+
+func (m *LogUsageRequest) Reset() { *m = LogUsageRequest{} }
+func (m *LogUsageRequest) String() string { return proto.CompactTextString(m) }
+func (*LogUsageRequest) ProtoMessage() {}
+func (*LogUsageRequest) Descriptor() ([]byte, []int) {
+ return fileDescriptor_log_service_f054fd4b5012319d, []int{12}
+}
+func (m *LogUsageRequest) XXX_Unmarshal(b []byte) error {
+ return xxx_messageInfo_LogUsageRequest.Unmarshal(m, b)
+}
+func (m *LogUsageRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ return xxx_messageInfo_LogUsageRequest.Marshal(b, m, deterministic)
+}
+func (dst *LogUsageRequest) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_LogUsageRequest.Merge(dst, src)
+}
+func (m *LogUsageRequest) XXX_Size() int {
+ return xxx_messageInfo_LogUsageRequest.Size(m)
+}
+func (m *LogUsageRequest) XXX_DiscardUnknown() {
+ xxx_messageInfo_LogUsageRequest.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_LogUsageRequest proto.InternalMessageInfo
+
+const Default_LogUsageRequest_ResolutionHours uint32 = 1
+
+func (m *LogUsageRequest) GetAppId() string {
+ if m != nil && m.AppId != nil {
+ return *m.AppId
+ }
+ return ""
+}
+
+func (m *LogUsageRequest) GetVersionId() []string {
+ if m != nil {
+ return m.VersionId
+ }
+ return nil
+}
+
+func (m *LogUsageRequest) GetStartTime() int32 {
+ if m != nil && m.StartTime != nil {
+ return *m.StartTime
+ }
+ return 0
+}
+
+func (m *LogUsageRequest) GetEndTime() int32 {
+ if m != nil && m.EndTime != nil {
+ return *m.EndTime
+ }
+ return 0
+}
+
+func (m *LogUsageRequest) GetResolutionHours() uint32 {
+ if m != nil && m.ResolutionHours != nil {
+ return *m.ResolutionHours
+ }
+ return Default_LogUsageRequest_ResolutionHours
+}
+
+func (m *LogUsageRequest) GetCombineVersions() bool {
+ if m != nil && m.CombineVersions != nil {
+ return *m.CombineVersions
+ }
+ return false
+}
+
+func (m *LogUsageRequest) GetUsageVersion() int32 {
+ if m != nil && m.UsageVersion != nil {
+ return *m.UsageVersion
+ }
+ return 0
+}
+
+func (m *LogUsageRequest) GetVersionsOnly() bool {
+ if m != nil && m.VersionsOnly != nil {
+ return *m.VersionsOnly
+ }
+ return false
+}
+
+type LogUsageResponse struct {
+ Usage []*LogUsageRecord `protobuf:"bytes,1,rep,name=usage" json:"usage,omitempty"`
+ Summary *LogUsageRecord `protobuf:"bytes,2,opt,name=summary" json:"summary,omitempty"`
+ XXX_NoUnkeyedLiteral struct{} `json:"-"`
+ XXX_unrecognized []byte `json:"-"`
+ XXX_sizecache int32 `json:"-"`
+}
+
+func (m *LogUsageResponse) Reset() { *m = LogUsageResponse{} }
+func (m *LogUsageResponse) String() string { return proto.CompactTextString(m) }
+func (*LogUsageResponse) ProtoMessage() {}
+func (*LogUsageResponse) Descriptor() ([]byte, []int) {
+ return fileDescriptor_log_service_f054fd4b5012319d, []int{13}
+}
+func (m *LogUsageResponse) XXX_Unmarshal(b []byte) error {
+ return xxx_messageInfo_LogUsageResponse.Unmarshal(m, b)
+}
+func (m *LogUsageResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ return xxx_messageInfo_LogUsageResponse.Marshal(b, m, deterministic)
+}
+func (dst *LogUsageResponse) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_LogUsageResponse.Merge(dst, src)
+}
+func (m *LogUsageResponse) XXX_Size() int {
+ return xxx_messageInfo_LogUsageResponse.Size(m)
+}
+func (m *LogUsageResponse) XXX_DiscardUnknown() {
+ xxx_messageInfo_LogUsageResponse.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_LogUsageResponse proto.InternalMessageInfo
+
+func (m *LogUsageResponse) GetUsage() []*LogUsageRecord {
+ if m != nil {
+ return m.Usage
+ }
+ return nil
+}
+
+func (m *LogUsageResponse) GetSummary() *LogUsageRecord {
+ if m != nil {
+ return m.Summary
+ }
+ return nil
+}
+
+func init() {
+ proto.RegisterType((*LogServiceError)(nil), "appengine.LogServiceError")
+ proto.RegisterType((*UserAppLogLine)(nil), "appengine.UserAppLogLine")
+ proto.RegisterType((*UserAppLogGroup)(nil), "appengine.UserAppLogGroup")
+ proto.RegisterType((*FlushRequest)(nil), "appengine.FlushRequest")
+ proto.RegisterType((*SetStatusRequest)(nil), "appengine.SetStatusRequest")
+ proto.RegisterType((*LogOffset)(nil), "appengine.LogOffset")
+ proto.RegisterType((*LogLine)(nil), "appengine.LogLine")
+ proto.RegisterType((*RequestLog)(nil), "appengine.RequestLog")
+ proto.RegisterType((*LogModuleVersion)(nil), "appengine.LogModuleVersion")
+ proto.RegisterType((*LogReadRequest)(nil), "appengine.LogReadRequest")
+ proto.RegisterType((*LogReadResponse)(nil), "appengine.LogReadResponse")
+ proto.RegisterType((*LogUsageRecord)(nil), "appengine.LogUsageRecord")
+ proto.RegisterType((*LogUsageRequest)(nil), "appengine.LogUsageRequest")
+ proto.RegisterType((*LogUsageResponse)(nil), "appengine.LogUsageResponse")
+}
+
+func init() {
+ proto.RegisterFile("google.golang.org/appengine/internal/log/log_service.proto", fileDescriptor_log_service_f054fd4b5012319d)
+}
+
+var fileDescriptor_log_service_f054fd4b5012319d = []byte{
+ // 1553 bytes of a gzipped FileDescriptorProto
+ 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x56, 0xdd, 0x72, 0xdb, 0xc6,
+ 0x15, 0x2e, 0x48, 0x51, 0x24, 0x0f, 0x49, 0x91, 0x5a, 0xcb, 0xce, 0xda, 0xae, 0x6b, 0x1a, 0x4e,
+ 0x1c, 0xd6, 0x93, 0x48, 0x93, 0xa4, 0x57, 0xca, 0x95, 0xd3, 0x2a, 0x8e, 0x26, 0xb4, 0xd5, 0x40,
+ 0x72, 0x3a, 0xd3, 0x1b, 0x0c, 0x0a, 0x1c, 0x81, 0x18, 0x2f, 0xb1, 0xc8, 0xee, 0xc2, 0x91, 0x72,
+ 0xdb, 0xdb, 0x3e, 0x46, 0x1f, 0xa2, 0xaf, 0xd2, 0xb7, 0xe9, 0xec, 0xd9, 0x05, 0x44, 0x2a, 0x4d,
+ 0xc6, 0x33, 0xb9, 0xe0, 0x10, 0xfb, 0x9d, 0x83, 0xdd, 0xf3, 0xf3, 0x9d, 0x6f, 0x01, 0xc7, 0xb9,
+ 0x94, 0xb9, 0xc0, 0xc3, 0x5c, 0x8a, 0xa4, 0xcc, 0x0f, 0xa5, 0xca, 0x8f, 0x92, 0xaa, 0xc2, 0x32,
+ 0x2f, 0x4a, 0x3c, 0x2a, 0x4a, 0x83, 0xaa, 0x4c, 0xc4, 0x91, 0x90, 0xb9, 0xfd, 0xc5, 0x1a, 0xd5,
+ 0xbb, 0x22, 0xc5, 0xc3, 0x4a, 0x49, 0x23, 0xd9, 0xb0, 0xf5, 0x0c, 0x5f, 0xc3, 0x74, 0x29, 0xf3,
+ 0x73, 0x67, 0x3e, 0x51, 0x4a, 0xaa, 0xf0, 0x4b, 0x18, 0xd2, 0xc3, 0x9f, 0x65, 0x86, 0x6c, 0x17,
+ 0x3a, 0x67, 0xdf, 0xce, 0x7e, 0xc7, 0xee, 0xc0, 0xf4, 0xf4, 0xf5, 0xf7, 0x2f, 0x96, 0xa7, 0x7f,
+ 0x89, 0xa3, 0x93, 0xef, 0xde, 0x9c, 0x9c, 0x5f, 0xcc, 0x02, 0xb6, 0x0f, 0x93, 0xf3, 0x8b, 0xb3,
+ 0xe8, 0xc5, 0xcb, 0x93, 0xf8, 0x24, 0x8a, 0xce, 0xa2, 0x59, 0x27, 0xcc, 0x61, 0xef, 0x8d, 0x46,
+ 0xf5, 0xa2, 0xaa, 0x96, 0x32, 0x5f, 0x16, 0x25, 0xb2, 0x8f, 0x60, 0xcf, 0x14, 0x6b, 0xd4, 0x26,
+ 0x59, 0x57, 0x71, 0xad, 0x31, 0xe5, 0xc1, 0xbc, 0xb3, 0xe8, 0x46, 0x93, 0x16, 0x7d, 0xa3, 0x31,
+ 0x65, 0x07, 0xd0, 0x13, 0xf8, 0x0e, 0x05, 0xef, 0x90, 0xd5, 0x2d, 0x18, 0x87, 0xfe, 0x1a, 0xb5,
+ 0x4e, 0x72, 0xe4, 0xdd, 0x79, 0x67, 0x31, 0x8c, 0x9a, 0x65, 0xf8, 0x12, 0xa6, 0x37, 0x07, 0xbd,
+ 0x54, 0xb2, 0xae, 0xd8, 0x9f, 0x60, 0x60, 0x73, 0x15, 0x45, 0x89, 0xbc, 0x33, 0xef, 0x2e, 0x46,
+ 0x9f, 0xdf, 0x3f, 0x6c, 0x33, 0x3d, 0xdc, 0x0e, 0x2b, 0xea, 0x0b, 0xf7, 0x10, 0x86, 0x30, 0xfe,
+ 0x5a, 0xd4, 0x7a, 0x15, 0xe1, 0x0f, 0x35, 0x6a, 0xc3, 0x18, 0xec, 0x08, 0x99, 0x6b, 0x1e, 0xcc,
+ 0x83, 0xc5, 0x38, 0xa2, 0xe7, 0xf0, 0x39, 0xcc, 0xce, 0xd1, 0x9c, 0x9b, 0xc4, 0xd4, 0xba, 0xf1,
+ 0xbb, 0x07, 0xbb, 0x9a, 0x00, 0xca, 0x67, 0x18, 0xf9, 0x55, 0xf8, 0x1c, 0x86, 0x4b, 0x99, 0x9f,
+ 0x5d, 0x5e, 0x6a, 0x34, 0xec, 0x11, 0x80, 0x72, 0xfe, 0x71, 0x91, 0xf9, 0x2d, 0x87, 0x1e, 0x39,
+ 0xcd, 0xc2, 0x0b, 0xe8, 0x37, 0x65, 0x62, 0xb0, 0x63, 0x0b, 0xe2, 0x8b, 0x43, 0xcf, 0xdb, 0x35,
+ 0xe9, 0x35, 0x35, 0x79, 0x0c, 0x23, 0x9b, 0xe6, 0x76, 0x5d, 0x40, 0xc8, 0xfc, 0x95, 0x2f, 0xcd,
+ 0x3f, 0x01, 0xc0, 0x47, 0xb9, 0x94, 0x39, 0xbb, 0x0b, 0xbb, 0x49, 0x55, 0xb9, 0xf3, 0xad, 0x6b,
+ 0x2f, 0xa9, 0xaa, 0xd3, 0x8c, 0x7d, 0x08, 0xc3, 0xb5, 0xcc, 0x6a, 0x81, 0xd6, 0xf2, 0xd1, 0x3c,
+ 0x58, 0x0c, 0x8f, 0xfb, 0x19, 0x5e, 0x26, 0xb5, 0x30, 0xd1, 0xc0, 0x59, 0x4e, 0x33, 0x9b, 0xc0,
+ 0x3b, 0x54, 0xba, 0x90, 0xa5, 0x75, 0xeb, 0xd0, 0x06, 0x43, 0x8f, 0x38, 0xf3, 0x46, 0x7e, 0x36,
+ 0x94, 0xcd, 0xfc, 0xd8, 0x27, 0xb0, 0x2b, 0xa9, 0x10, 0xfc, 0xe9, 0x3c, 0x58, 0x8c, 0x3e, 0x3f,
+ 0xd8, 0xe8, 0x47, 0x5b, 0xa4, 0xc8, 0xfb, 0xb0, 0x3d, 0xe8, 0x14, 0x15, 0xdf, 0xa1, 0x33, 0x3a,
+ 0x45, 0xc5, 0x1e, 0xc0, 0xa0, 0x2c, 0xd2, 0xb7, 0x65, 0xb2, 0x46, 0xde, 0xb3, 0x01, 0x46, 0xed,
+ 0xda, 0x1e, 0xac, 0x4d, 0xa2, 0x4c, 0x4c, 0x45, 0xdb, 0xa5, 0xa2, 0x0d, 0x09, 0xb9, 0xb0, 0x95,
+ 0xbb, 0x0f, 0x03, 0x2c, 0x33, 0x67, 0xec, 0x93, 0xb1, 0x8f, 0x65, 0x46, 0x26, 0x0e, 0x7d, 0x91,
+ 0x18, 0x2c, 0xd3, 0x6b, 0x3e, 0x70, 0x16, 0xbf, 0x24, 0xb2, 0xa5, 0xd7, 0xa9, 0x40, 0xcd, 0x87,
+ 0xce, 0xe2, 0x97, 0xb6, 0xd7, 0x6b, 0x34, 0x2b, 0x99, 0x71, 0x70, 0xbd, 0x76, 0x2b, 0x1b, 0xa1,
+ 0x42, 0x2d, 0x6b, 0x95, 0x22, 0x1f, 0x91, 0xa5, 0x5d, 0xb3, 0x27, 0x30, 0x5e, 0x19, 0x53, 0xc5,
+ 0xbe, 0x58, 0x7c, 0x4c, 0xf6, 0x91, 0xc5, 0xbe, 0x77, 0xd0, 0x06, 0x85, 0x26, 0xd4, 0x60, 0xbf,
+ 0x62, 0x4f, 0x61, 0xa2, 0x50, 0x57, 0xb2, 0xd4, 0x18, 0xeb, 0xe2, 0x27, 0xe4, 0x7b, 0x14, 0xce,
+ 0xb8, 0x01, 0xcf, 0x8b, 0x9f, 0xd0, 0x9d, 0x7d, 0x89, 0x4a, 0xa1, 0xe2, 0x53, 0x57, 0x9d, 0x66,
+ 0x6d, 0xab, 0x53, 0x6b, 0x54, 0x71, 0x92, 0x63, 0x69, 0xf8, 0x8c, 0xac, 0x43, 0x8b, 0xbc, 0xb0,
+ 0x00, 0x0b, 0x61, 0x52, 0x2b, 0x11, 0xaf, 0x93, 0x2a, 0xc6, 0xd2, 0xa8, 0x6b, 0xbe, 0xef, 0x62,
+ 0xab, 0x95, 0x78, 0x95, 0x54, 0x27, 0x16, 0xb2, 0xdb, 0xa7, 0x72, 0xfd, 0x8f, 0xa2, 0xc4, 0x8c,
+ 0x33, 0x97, 0x5a, 0xb3, 0xb6, 0x0c, 0x4c, 0xaa, 0x22, 0x6e, 0x8a, 0x75, 0x67, 0x1e, 0x2c, 0xba,
+ 0x11, 0x24, 0x55, 0xf1, 0xca, 0xd7, 0x8b, 0xc1, 0xce, 0x4a, 0x6a, 0xc3, 0x0f, 0xe8, 0x64, 0x7a,
+ 0xb6, 0x58, 0x6a, 0xb1, 0xbb, 0xf3, 0x60, 0x11, 0x44, 0xf4, 0xcc, 0x9e, 0xc1, 0xd4, 0x24, 0xfa,
+ 0x6d, 0xfc, 0x43, 0x8d, 0x35, 0xc6, 0xd4, 0xe8, 0x7b, 0xf4, 0xca, 0xc4, 0xc2, 0xdf, 0x59, 0xf4,
+ 0xb5, 0xed, 0xf6, 0x43, 0x18, 0x92, 0x1f, 0x79, 0x7c, 0xe0, 0x92, 0xb5, 0x00, 0x19, 0x0f, 0xe1,
+ 0xce, 0x8f, 0x89, 0x8e, 0x85, 0x4c, 0xb2, 0xa2, 0xcc, 0x63, 0xcf, 0x3e, 0xce, 0xe7, 0xc1, 0x62,
+ 0x10, 0xed, 0xff, 0x98, 0xe8, 0xa5, 0xb3, 0x34, 0x83, 0xfb, 0x04, 0xc6, 0x15, 0x96, 0xe4, 0x4b,
+ 0xfc, 0xb8, 0x4f, 0xe1, 0x8f, 0x3c, 0x46, 0x1c, 0xf9, 0xd8, 0x36, 0xa0, 0x12, 0x45, 0x9a, 0xc4,
+ 0x45, 0x99, 0xe1, 0x15, 0x7f, 0x30, 0x0f, 0x16, 0xbd, 0xe3, 0xce, 0xa7, 0x9f, 0xd9, 0x26, 0x90,
+ 0xe1, 0xd4, 0xe2, 0x6c, 0x0e, 0x83, 0xcb, 0xa2, 0x2c, 0xf4, 0x0a, 0x33, 0xfe, 0xd0, 0x1e, 0x78,
+ 0xbc, 0x63, 0x54, 0x8d, 0x51, 0x8b, 0xda, 0xd0, 0x53, 0x21, 0x4b, 0x8c, 0xdf, 0xe2, 0x35, 0xff,
+ 0x3d, 0x09, 0xc0, 0x80, 0x80, 0x6f, 0xf1, 0x9a, 0x3d, 0x83, 0x1d, 0x52, 0xab, 0x47, 0xa4, 0x56,
+ 0x6c, 0x7b, 0x3a, 0x48, 0xa6, 0xc8, 0xce, 0xfe, 0x08, 0x33, 0xfb, 0xaf, 0xe3, 0xa2, 0x4c, 0xe5,
+ 0xba, 0x12, 0x68, 0x90, 0x7f, 0x48, 0xf9, 0x4d, 0x09, 0x3f, 0x6d, 0x61, 0xf6, 0x09, 0x30, 0x3b,
+ 0xed, 0x6e, 0x9b, 0x58, 0xa1, 0xc0, 0x44, 0x23, 0x7f, 0x46, 0x07, 0xcf, 0x92, 0xaa, 0x3a, 0x21,
+ 0x43, 0xe4, 0x70, 0xdb, 0x49, 0xbc, 0x2a, 0x4c, 0xac, 0x30, 0xd1, 0xb2, 0xe4, 0x7f, 0xb0, 0x69,
+ 0x46, 0x60, 0xa1, 0x88, 0x10, 0xf6, 0x05, 0xdc, 0xb3, 0xc5, 0x35, 0x2b, 0x25, 0x8d, 0x11, 0x98,
+ 0xc5, 0x97, 0x52, 0xb9, 0xb2, 0x3d, 0xa6, 0xf3, 0x6d, 0xe9, 0x2f, 0x1a, 0xe3, 0xd7, 0x52, 0x51,
+ 0xf9, 0xbe, 0x84, 0x07, 0x3f, 0x7f, 0xc9, 0xf7, 0x45, 0xf3, 0x39, 0xbd, 0xf8, 0xc1, 0xad, 0x17,
+ 0x7d, 0x77, 0x34, 0xdd, 0x17, 0xed, 0x8b, 0x74, 0xd2, 0x13, 0x6a, 0xd0, 0xa4, 0x45, 0xe9, 0x8c,
+ 0xc7, 0x30, 0xb2, 0x97, 0x1a, 0x2a, 0x47, 0x8a, 0x90, 0x12, 0x04, 0x07, 0x59, 0x5a, 0x84, 0x7f,
+ 0x83, 0xd9, 0x52, 0xe6, 0xaf, 0x48, 0xc8, 0x9a, 0x81, 0xdb, 0xd2, 0xbc, 0xe0, 0x7d, 0x35, 0x2f,
+ 0xd8, 0xd2, 0xbc, 0xf0, 0xbf, 0x3d, 0xd8, 0x5b, 0xca, 0x3c, 0xc2, 0x24, 0x6b, 0x28, 0xf5, 0x0b,
+ 0x12, 0x7b, 0x7b, 0xa3, 0xee, 0xb6, 0x78, 0x7e, 0x05, 0x7b, 0x3e, 0x9a, 0x46, 0x23, 0xee, 0x10,
+ 0x0f, 0x1e, 0x6e, 0xf3, 0x60, 0x2b, 0x85, 0x68, 0xb2, 0xde, 0xca, 0x68, 0x5b, 0x07, 0xbb, 0x54,
+ 0xa9, 0x5f, 0xd0, 0xc1, 0x1d, 0x32, 0xb6, 0x3a, 0x78, 0xa3, 0xcd, 0xbd, 0xf7, 0xd0, 0xe6, 0x6d,
+ 0xa1, 0xdf, 0x9d, 0x77, 0xb7, 0x85, 0xfe, 0x39, 0xec, 0xaf, 0x8b, 0xb2, 0x58, 0xd7, 0xeb, 0x98,
+ 0xae, 0x60, 0xba, 0xb5, 0xfa, 0xc4, 0xa6, 0xa9, 0x37, 0x58, 0x46, 0xd3, 0xfd, 0xf5, 0x29, 0xb0,
+ 0xa2, 0x4c, 0x45, 0x9d, 0xe1, 0x26, 0x9d, 0x07, 0x6e, 0x5c, 0xbd, 0x65, 0x83, 0xd0, 0x07, 0xd0,
+ 0x4b, 0x65, 0x5d, 0x1a, 0x3e, 0xa4, 0xf8, 0xdd, 0xc2, 0xd2, 0xbc, 0x91, 0x23, 0x3a, 0x51, 0x61,
+ 0x8e, 0x57, 0x7c, 0x8f, 0x7a, 0x35, 0x6b, 0x2c, 0xd4, 0xa5, 0x1c, 0xaf, 0x6c, 0xf4, 0x56, 0x83,
+ 0xbc, 0x97, 0x53, 0xcb, 0xa1, 0x45, 0x9c, 0xf9, 0xe9, 0xed, 0x71, 0x9f, 0x51, 0xe4, 0xdb, 0xa3,
+ 0xbe, 0x80, 0x59, 0x13, 0xb6, 0xed, 0x35, 0x7d, 0x23, 0x00, 0x05, 0xbd, 0xe7, 0x71, 0xf7, 0x75,
+ 0xa1, 0xd9, 0x11, 0x1c, 0x34, 0x1e, 0x71, 0x85, 0x2d, 0xf3, 0xf9, 0x3e, 0xed, 0xba, 0x9f, 0x38,
+ 0xb7, 0xbf, 0xa2, 0xda, 0x50, 0xa4, 0x66, 0x6b, 0x92, 0xcd, 0x11, 0x6d, 0x3b, 0xf2, 0xd8, 0x37,
+ 0x56, 0x29, 0x1f, 0xc3, 0xa8, 0x3d, 0x5d, 0x08, 0x3e, 0x26, 0x0f, 0x68, 0x0e, 0x16, 0xc2, 0x8e,
+ 0x4d, 0x9a, 0xa4, 0x2b, 0x8c, 0x0b, 0x83, 0x2a, 0x31, 0x52, 0xf1, 0x09, 0xf9, 0x4c, 0x08, 0x3d,
+ 0xf5, 0xa0, 0xad, 0x44, 0x59, 0xaf, 0x63, 0xbd, 0x4a, 0x54, 0xa6, 0x39, 0xa3, 0x88, 0x86, 0x65,
+ 0xbd, 0x3e, 0x27, 0x20, 0xfc, 0x57, 0x40, 0xdf, 0x83, 0x8e, 0xdb, 0xee, 0xb2, 0x61, 0x1f, 0x43,
+ 0x57, 0xc8, 0x9c, 0x07, 0xc4, 0xcd, 0xbb, 0x1b, 0x2c, 0xb9, 0xf9, 0xc6, 0x88, 0xac, 0xc7, 0x06,
+ 0xa3, 0x3a, 0xef, 0xc1, 0xa8, 0x10, 0x26, 0x22, 0xd1, 0x26, 0x6e, 0xf9, 0xe9, 0xc8, 0x3b, 0xb2,
+ 0xe0, 0x89, 0xe3, 0x68, 0xf8, 0x9f, 0x80, 0x46, 0xed, 0x8d, 0xfd, 0xac, 0x89, 0x30, 0x95, 0xea,
+ 0xf6, 0x4c, 0x05, 0xb7, 0x86, 0xf3, 0xd6, 0x3c, 0x74, 0x5c, 0x7e, 0xff, 0x7f, 0x1e, 0xba, 0x64,
+ 0x6c, 0xe7, 0xa1, 0xe5, 0xd9, 0xce, 0x26, 0xcf, 0x1e, 0x01, 0x18, 0x69, 0x12, 0xe1, 0xee, 0xe1,
+ 0x9e, 0x9b, 0x2f, 0x42, 0xe8, 0x12, 0xe6, 0xd0, 0x57, 0x14, 0x97, 0xe6, 0xbb, 0x6e, 0x3b, 0xbf,
+ 0x0c, 0xff, 0xdd, 0xa1, 0x4a, 0xfa, 0xd0, 0x7f, 0x8b, 0x4c, 0xfc, 0x7c, 0xc4, 0x7b, 0xbf, 0x36,
+ 0xe2, 0xbd, 0xcd, 0x11, 0x9f, 0xd9, 0xcf, 0x11, 0x51, 0x1b, 0xbb, 0xf7, 0x4a, 0xd6, 0x4a, 0x53,
+ 0x0a, 0x93, 0xe3, 0xe0, 0xb3, 0x68, 0x7a, 0x63, 0xfa, 0xc6, 0x5a, 0xec, 0x25, 0xe3, 0x07, 0xa7,
+ 0xd1, 0x23, 0x97, 0xd4, 0x20, 0x9a, 0x7a, 0xdc, 0x8b, 0x0e, 0x7d, 0xa0, 0xd4, 0x36, 0xb1, 0x56,
+ 0xb8, 0xdc, 0xa8, 0x8f, 0x09, 0x6c, 0xa4, 0xe9, 0x29, 0x4c, 0x9a, 0x7d, 0x62, 0x59, 0x8a, 0x6b,
+ 0x3f, 0xe2, 0xe3, 0x06, 0x3c, 0x2b, 0xc5, 0x75, 0x78, 0x45, 0x2a, 0xed, 0xab, 0xe4, 0x09, 0x77,
+ 0x04, 0x3d, 0xda, 0xc8, 0x53, 0xee, 0xfe, 0x36, 0x8d, 0x36, 0xc8, 0x10, 0x39, 0x3f, 0xf6, 0x05,
+ 0xf4, 0x75, 0xbd, 0x5e, 0x27, 0xea, 0xda, 0x33, 0xef, 0x57, 0x5e, 0x69, 0x3c, 0xbf, 0xea, 0xfd,
+ 0xdd, 0x92, 0xf6, 0x7f, 0x01, 0x00, 0x00, 0xff, 0xff, 0x70, 0xd9, 0xa0, 0xf8, 0x48, 0x0d, 0x00,
+ 0x00,
+}
diff --git a/vendor/google.golang.org/appengine/internal/log/log_service.proto b/vendor/google.golang.org/appengine/internal/log/log_service.proto
new file mode 100644
index 0000000000000000000000000000000000000000..8981dc47577cedcbd5ac1fe11d698c3db24b5d45
--- /dev/null
+++ b/vendor/google.golang.org/appengine/internal/log/log_service.proto
@@ -0,0 +1,150 @@
+syntax = "proto2";
+option go_package = "log";
+
+package appengine;
+
+message LogServiceError {
+ enum ErrorCode {
+ OK = 0;
+ INVALID_REQUEST = 1;
+ STORAGE_ERROR = 2;
+ }
+}
+
+message UserAppLogLine {
+ required int64 timestamp_usec = 1;
+ required int64 level = 2;
+ required string message = 3;
+}
+
+message UserAppLogGroup {
+ repeated UserAppLogLine log_line = 2;
+}
+
+message FlushRequest {
+ optional bytes logs = 1;
+}
+
+message SetStatusRequest {
+ required string status = 1;
+}
+
+
+message LogOffset {
+ optional bytes request_id = 1;
+}
+
+message LogLine {
+ required int64 time = 1;
+ required int32 level = 2;
+ required string log_message = 3;
+}
+
+message RequestLog {
+ required string app_id = 1;
+ optional string module_id = 37 [default="default"];
+ required string version_id = 2;
+ required bytes request_id = 3;
+ optional LogOffset offset = 35;
+ required string ip = 4;
+ optional string nickname = 5;
+ required int64 start_time = 6;
+ required int64 end_time = 7;
+ required int64 latency = 8;
+ required int64 mcycles = 9;
+ required string method = 10;
+ required string resource = 11;
+ required string http_version = 12;
+ required int32 status = 13;
+ required int64 response_size = 14;
+ optional string referrer = 15;
+ optional string user_agent = 16;
+ required string url_map_entry = 17;
+ required string combined = 18;
+ optional int64 api_mcycles = 19;
+ optional string host = 20;
+ optional double cost = 21;
+
+ optional string task_queue_name = 22;
+ optional string task_name = 23;
+
+ optional bool was_loading_request = 24;
+ optional int64 pending_time = 25;
+ optional int32 replica_index = 26 [default = -1];
+ optional bool finished = 27 [default = true];
+ optional bytes clone_key = 28;
+
+ repeated LogLine line = 29;
+
+ optional bool lines_incomplete = 36;
+ optional bytes app_engine_release = 38;
+
+ optional int32 exit_reason = 30;
+ optional bool was_throttled_for_time = 31;
+ optional bool was_throttled_for_requests = 32;
+ optional int64 throttled_time = 33;
+
+ optional bytes server_name = 34;
+}
+
+message LogModuleVersion {
+ optional string module_id = 1 [default="default"];
+ optional string version_id = 2;
+}
+
+message LogReadRequest {
+ required string app_id = 1;
+ repeated string version_id = 2;
+ repeated LogModuleVersion module_version = 19;
+
+ optional int64 start_time = 3;
+ optional int64 end_time = 4;
+ optional LogOffset offset = 5;
+ repeated bytes request_id = 6;
+
+ optional int32 minimum_log_level = 7;
+ optional bool include_incomplete = 8;
+ optional int64 count = 9;
+
+ optional string combined_log_regex = 14;
+ optional string host_regex = 15;
+ optional int32 replica_index = 16;
+
+ optional bool include_app_logs = 10;
+ optional int32 app_logs_per_request = 17;
+ optional bool include_host = 11;
+ optional bool include_all = 12;
+ optional bool cache_iterator = 13;
+ optional int32 num_shards = 18;
+}
+
+message LogReadResponse {
+ repeated RequestLog log = 1;
+ optional LogOffset offset = 2;
+ optional int64 last_end_time = 3;
+}
+
+message LogUsageRecord {
+ optional string version_id = 1;
+ optional int32 start_time = 2;
+ optional int32 end_time = 3;
+ optional int64 count = 4;
+ optional int64 total_size = 5;
+ optional int32 records = 6;
+}
+
+message LogUsageRequest {
+ required string app_id = 1;
+ repeated string version_id = 2;
+ optional int32 start_time = 3;
+ optional int32 end_time = 4;
+ optional uint32 resolution_hours = 5 [default = 1];
+ optional bool combine_versions = 6;
+ optional int32 usage_version = 7;
+ optional bool versions_only = 8;
+}
+
+message LogUsageResponse {
+ repeated LogUsageRecord usage = 1;
+ optional LogUsageRecord summary = 2;
+}
diff --git a/vendor/google.golang.org/appengine/internal/main.go b/vendor/google.golang.org/appengine/internal/main.go
new file mode 100644
index 0000000000000000000000000000000000000000..1e765312fd180f0be563c16c437ee0296104804a
--- /dev/null
+++ b/vendor/google.golang.org/appengine/internal/main.go
@@ -0,0 +1,16 @@
+// Copyright 2011 Google Inc. All rights reserved.
+// Use of this source code is governed by the Apache 2.0
+// license that can be found in the LICENSE file.
+
+// +build appengine
+
+package internal
+
+import (
+ "appengine_internal"
+)
+
+func Main() {
+ MainPath = ""
+ appengine_internal.Main()
+}
diff --git a/vendor/google.golang.org/appengine/internal/main_common.go b/vendor/google.golang.org/appengine/internal/main_common.go
new file mode 100644
index 0000000000000000000000000000000000000000..357dce4dd01298c4f10ff9856cc2469dc4f8831e
--- /dev/null
+++ b/vendor/google.golang.org/appengine/internal/main_common.go
@@ -0,0 +1,7 @@
+package internal
+
+// MainPath stores the file path of the main package. On App Engine Standard
+// using Go version 1.9 and below, this will be unset. On App Engine Flex and
+// App Engine Standard second-gen (Go 1.11 and above), this will be the
+// filepath to package main.
+var MainPath string
diff --git a/vendor/google.golang.org/appengine/internal/main_vm.go b/vendor/google.golang.org/appengine/internal/main_vm.go
new file mode 100644
index 0000000000000000000000000000000000000000..ddb79a333879a4e45284eb971761fd504b0056f3
--- /dev/null
+++ b/vendor/google.golang.org/appengine/internal/main_vm.go
@@ -0,0 +1,69 @@
+// Copyright 2011 Google Inc. All rights reserved.
+// Use of this source code is governed by the Apache 2.0
+// license that can be found in the LICENSE file.
+
+// +build !appengine
+
+package internal
+
+import (
+ "io"
+ "log"
+ "net/http"
+ "net/url"
+ "os"
+ "path/filepath"
+ "runtime"
+)
+
+func Main() {
+ MainPath = filepath.Dir(findMainPath())
+ installHealthChecker(http.DefaultServeMux)
+
+ port := "8080"
+ if s := os.Getenv("PORT"); s != "" {
+ port = s
+ }
+
+ host := ""
+ if IsDevAppServer() {
+ host = "127.0.0.1"
+ }
+ if err := http.ListenAndServe(host+":"+port, http.HandlerFunc(handleHTTP)); err != nil {
+ log.Fatalf("http.ListenAndServe: %v", err)
+ }
+}
+
+// Find the path to package main by looking at the root Caller.
+func findMainPath() string {
+ pc := make([]uintptr, 100)
+ n := runtime.Callers(2, pc)
+ frames := runtime.CallersFrames(pc[:n])
+ for {
+ frame, more := frames.Next()
+ // Tests won't have package main, instead they have testing.tRunner
+ if frame.Function == "main.main" || frame.Function == "testing.tRunner" {
+ return frame.File
+ }
+ if !more {
+ break
+ }
+ }
+ return ""
+}
+
+func installHealthChecker(mux *http.ServeMux) {
+ // If no health check handler has been installed by this point, add a trivial one.
+ const healthPath = "/_ah/health"
+ hreq := &http.Request{
+ Method: "GET",
+ URL: &url.URL{
+ Path: healthPath,
+ },
+ }
+ if _, pat := mux.Handler(hreq); pat != healthPath {
+ mux.HandleFunc(healthPath, func(w http.ResponseWriter, r *http.Request) {
+ io.WriteString(w, "ok")
+ })
+ }
+}
diff --git a/vendor/google.golang.org/appengine/internal/metadata.go b/vendor/google.golang.org/appengine/internal/metadata.go
new file mode 100644
index 0000000000000000000000000000000000000000..c4ba63bb4819f4b865805beb1bfa6d29ac88d732
--- /dev/null
+++ b/vendor/google.golang.org/appengine/internal/metadata.go
@@ -0,0 +1,60 @@
+// Copyright 2014 Google Inc. All rights reserved.
+// Use of this source code is governed by the Apache 2.0
+// license that can be found in the LICENSE file.
+
+package internal
+
+// This file has code for accessing metadata.
+//
+// References:
+// https://cloud.google.com/compute/docs/metadata
+
+import (
+ "fmt"
+ "io/ioutil"
+ "net/http"
+ "net/url"
+)
+
+const (
+ metadataHost = "metadata"
+ metadataPath = "/computeMetadata/v1/"
+)
+
+var (
+ metadataRequestHeaders = http.Header{
+ "Metadata-Flavor": []string{"Google"},
+ }
+)
+
+// TODO(dsymonds): Do we need to support default values, like Python?
+func mustGetMetadata(key string) []byte {
+ b, err := getMetadata(key)
+ if err != nil {
+ panic(fmt.Sprintf("Metadata fetch failed for '%s': %v", key, err))
+ }
+ return b
+}
+
+func getMetadata(key string) ([]byte, error) {
+ // TODO(dsymonds): May need to use url.Parse to support keys with query args.
+ req := &http.Request{
+ Method: "GET",
+ URL: &url.URL{
+ Scheme: "http",
+ Host: metadataHost,
+ Path: metadataPath + key,
+ },
+ Header: metadataRequestHeaders,
+ Host: metadataHost,
+ }
+ resp, err := http.DefaultClient.Do(req)
+ if err != nil {
+ return nil, err
+ }
+ defer resp.Body.Close()
+ if resp.StatusCode != 200 {
+ return nil, fmt.Errorf("metadata server returned HTTP %d", resp.StatusCode)
+ }
+ return ioutil.ReadAll(resp.Body)
+}
diff --git a/vendor/google.golang.org/appengine/internal/net.go b/vendor/google.golang.org/appengine/internal/net.go
new file mode 100644
index 0000000000000000000000000000000000000000..fe429720e1f25d9e65982c3a4f0cd605913225ed
--- /dev/null
+++ b/vendor/google.golang.org/appengine/internal/net.go
@@ -0,0 +1,56 @@
+// Copyright 2014 Google Inc. All rights reserved.
+// Use of this source code is governed by the Apache 2.0
+// license that can be found in the LICENSE file.
+
+package internal
+
+// This file implements a network dialer that limits the number of concurrent connections.
+// It is only used for API calls.
+
+import (
+ "log"
+ "net"
+ "runtime"
+ "sync"
+ "time"
+)
+
+var limitSem = make(chan int, 100) // TODO(dsymonds): Use environment variable.
+
+func limitRelease() {
+ // non-blocking
+ select {
+ case <-limitSem:
+ default:
+ // This should not normally happen.
+ log.Print("appengine: unbalanced limitSem release!")
+ }
+}
+
+func limitDial(network, addr string) (net.Conn, error) {
+ limitSem <- 1
+
+ // Dial with a timeout in case the API host is MIA.
+ // The connection should normally be very fast.
+ conn, err := net.DialTimeout(network, addr, 10*time.Second)
+ if err != nil {
+ limitRelease()
+ return nil, err
+ }
+ lc := &limitConn{Conn: conn}
+ runtime.SetFinalizer(lc, (*limitConn).Close) // shouldn't usually be required
+ return lc, nil
+}
+
+type limitConn struct {
+ close sync.Once
+ net.Conn
+}
+
+func (lc *limitConn) Close() error {
+ defer lc.close.Do(func() {
+ limitRelease()
+ runtime.SetFinalizer(lc, nil)
+ })
+ return lc.Conn.Close()
+}
diff --git a/vendor/google.golang.org/appengine/internal/regen.sh b/vendor/google.golang.org/appengine/internal/regen.sh
new file mode 100644
index 0000000000000000000000000000000000000000..2fdb546a63335a08a0c82688066c80291a02a112
--- /dev/null
+++ b/vendor/google.golang.org/appengine/internal/regen.sh
@@ -0,0 +1,40 @@
+#!/bin/bash -e
+#
+# This script rebuilds the generated code for the protocol buffers.
+# To run this you will need protoc and goprotobuf installed;
+# see https://github.com/golang/protobuf for instructions.
+
+PKG=google.golang.org/appengine
+
+function die() {
+ echo 1>&2 $*
+ exit 1
+}
+
+# Sanity check that the right tools are accessible.
+for tool in go protoc protoc-gen-go; do
+ q=$(which $tool) || die "didn't find $tool"
+ echo 1>&2 "$tool: $q"
+done
+
+echo -n 1>&2 "finding package dir... "
+pkgdir=$(go list -f '{{.Dir}}' $PKG)
+echo 1>&2 $pkgdir
+base=$(echo $pkgdir | sed "s,/$PKG\$,,")
+echo 1>&2 "base: $base"
+cd $base
+
+# Run protoc once per package.
+for dir in $(find $PKG/internal -name '*.proto' | xargs dirname | sort | uniq); do
+ echo 1>&2 "* $dir"
+ protoc --go_out=. $dir/*.proto
+done
+
+for f in $(find $PKG/internal -name '*.pb.go'); do
+ # Remove proto.RegisterEnum calls.
+ # These cause duplicate registration panics when these packages
+ # are used on classic App Engine. proto.RegisterEnum only affects
+ # parsing the text format; we don't care about that.
+ # https://code.google.com/p/googleappengine/issues/detail?id=11670#c17
+ sed -i '/proto.RegisterEnum/d' $f
+done
diff --git a/vendor/google.golang.org/appengine/internal/remote_api/remote_api.pb.go b/vendor/google.golang.org/appengine/internal/remote_api/remote_api.pb.go
new file mode 100644
index 0000000000000000000000000000000000000000..8d782a38e172d9fed7b26716ab699f69d33d572b
--- /dev/null
+++ b/vendor/google.golang.org/appengine/internal/remote_api/remote_api.pb.go
@@ -0,0 +1,361 @@
+// Code generated by protoc-gen-go. DO NOT EDIT.
+// source: google.golang.org/appengine/internal/remote_api/remote_api.proto
+
+package remote_api
+
+import proto "github.com/golang/protobuf/proto"
+import fmt "fmt"
+import math "math"
+
+// Reference imports to suppress errors if they are not otherwise used.
+var _ = proto.Marshal
+var _ = fmt.Errorf
+var _ = math.Inf
+
+// This is a compile-time assertion to ensure that this generated file
+// is compatible with the proto package it is being compiled against.
+// A compilation error at this line likely means your copy of the
+// proto package needs to be updated.
+const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package
+
+type RpcError_ErrorCode int32
+
+const (
+ RpcError_UNKNOWN RpcError_ErrorCode = 0
+ RpcError_CALL_NOT_FOUND RpcError_ErrorCode = 1
+ RpcError_PARSE_ERROR RpcError_ErrorCode = 2
+ RpcError_SECURITY_VIOLATION RpcError_ErrorCode = 3
+ RpcError_OVER_QUOTA RpcError_ErrorCode = 4
+ RpcError_REQUEST_TOO_LARGE RpcError_ErrorCode = 5
+ RpcError_CAPABILITY_DISABLED RpcError_ErrorCode = 6
+ RpcError_FEATURE_DISABLED RpcError_ErrorCode = 7
+ RpcError_BAD_REQUEST RpcError_ErrorCode = 8
+ RpcError_RESPONSE_TOO_LARGE RpcError_ErrorCode = 9
+ RpcError_CANCELLED RpcError_ErrorCode = 10
+ RpcError_REPLAY_ERROR RpcError_ErrorCode = 11
+ RpcError_DEADLINE_EXCEEDED RpcError_ErrorCode = 12
+)
+
+var RpcError_ErrorCode_name = map[int32]string{
+ 0: "UNKNOWN",
+ 1: "CALL_NOT_FOUND",
+ 2: "PARSE_ERROR",
+ 3: "SECURITY_VIOLATION",
+ 4: "OVER_QUOTA",
+ 5: "REQUEST_TOO_LARGE",
+ 6: "CAPABILITY_DISABLED",
+ 7: "FEATURE_DISABLED",
+ 8: "BAD_REQUEST",
+ 9: "RESPONSE_TOO_LARGE",
+ 10: "CANCELLED",
+ 11: "REPLAY_ERROR",
+ 12: "DEADLINE_EXCEEDED",
+}
+var RpcError_ErrorCode_value = map[string]int32{
+ "UNKNOWN": 0,
+ "CALL_NOT_FOUND": 1,
+ "PARSE_ERROR": 2,
+ "SECURITY_VIOLATION": 3,
+ "OVER_QUOTA": 4,
+ "REQUEST_TOO_LARGE": 5,
+ "CAPABILITY_DISABLED": 6,
+ "FEATURE_DISABLED": 7,
+ "BAD_REQUEST": 8,
+ "RESPONSE_TOO_LARGE": 9,
+ "CANCELLED": 10,
+ "REPLAY_ERROR": 11,
+ "DEADLINE_EXCEEDED": 12,
+}
+
+func (x RpcError_ErrorCode) Enum() *RpcError_ErrorCode {
+ p := new(RpcError_ErrorCode)
+ *p = x
+ return p
+}
+func (x RpcError_ErrorCode) String() string {
+ return proto.EnumName(RpcError_ErrorCode_name, int32(x))
+}
+func (x *RpcError_ErrorCode) UnmarshalJSON(data []byte) error {
+ value, err := proto.UnmarshalJSONEnum(RpcError_ErrorCode_value, data, "RpcError_ErrorCode")
+ if err != nil {
+ return err
+ }
+ *x = RpcError_ErrorCode(value)
+ return nil
+}
+func (RpcError_ErrorCode) EnumDescriptor() ([]byte, []int) {
+ return fileDescriptor_remote_api_1978114ec33a273d, []int{2, 0}
+}
+
+type Request struct {
+ ServiceName *string `protobuf:"bytes,2,req,name=service_name,json=serviceName" json:"service_name,omitempty"`
+ Method *string `protobuf:"bytes,3,req,name=method" json:"method,omitempty"`
+ Request []byte `protobuf:"bytes,4,req,name=request" json:"request,omitempty"`
+ RequestId *string `protobuf:"bytes,5,opt,name=request_id,json=requestId" json:"request_id,omitempty"`
+ XXX_NoUnkeyedLiteral struct{} `json:"-"`
+ XXX_unrecognized []byte `json:"-"`
+ XXX_sizecache int32 `json:"-"`
+}
+
+func (m *Request) Reset() { *m = Request{} }
+func (m *Request) String() string { return proto.CompactTextString(m) }
+func (*Request) ProtoMessage() {}
+func (*Request) Descriptor() ([]byte, []int) {
+ return fileDescriptor_remote_api_1978114ec33a273d, []int{0}
+}
+func (m *Request) XXX_Unmarshal(b []byte) error {
+ return xxx_messageInfo_Request.Unmarshal(m, b)
+}
+func (m *Request) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ return xxx_messageInfo_Request.Marshal(b, m, deterministic)
+}
+func (dst *Request) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_Request.Merge(dst, src)
+}
+func (m *Request) XXX_Size() int {
+ return xxx_messageInfo_Request.Size(m)
+}
+func (m *Request) XXX_DiscardUnknown() {
+ xxx_messageInfo_Request.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_Request proto.InternalMessageInfo
+
+func (m *Request) GetServiceName() string {
+ if m != nil && m.ServiceName != nil {
+ return *m.ServiceName
+ }
+ return ""
+}
+
+func (m *Request) GetMethod() string {
+ if m != nil && m.Method != nil {
+ return *m.Method
+ }
+ return ""
+}
+
+func (m *Request) GetRequest() []byte {
+ if m != nil {
+ return m.Request
+ }
+ return nil
+}
+
+func (m *Request) GetRequestId() string {
+ if m != nil && m.RequestId != nil {
+ return *m.RequestId
+ }
+ return ""
+}
+
+type ApplicationError struct {
+ Code *int32 `protobuf:"varint,1,req,name=code" json:"code,omitempty"`
+ Detail *string `protobuf:"bytes,2,req,name=detail" json:"detail,omitempty"`
+ XXX_NoUnkeyedLiteral struct{} `json:"-"`
+ XXX_unrecognized []byte `json:"-"`
+ XXX_sizecache int32 `json:"-"`
+}
+
+func (m *ApplicationError) Reset() { *m = ApplicationError{} }
+func (m *ApplicationError) String() string { return proto.CompactTextString(m) }
+func (*ApplicationError) ProtoMessage() {}
+func (*ApplicationError) Descriptor() ([]byte, []int) {
+ return fileDescriptor_remote_api_1978114ec33a273d, []int{1}
+}
+func (m *ApplicationError) XXX_Unmarshal(b []byte) error {
+ return xxx_messageInfo_ApplicationError.Unmarshal(m, b)
+}
+func (m *ApplicationError) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ return xxx_messageInfo_ApplicationError.Marshal(b, m, deterministic)
+}
+func (dst *ApplicationError) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_ApplicationError.Merge(dst, src)
+}
+func (m *ApplicationError) XXX_Size() int {
+ return xxx_messageInfo_ApplicationError.Size(m)
+}
+func (m *ApplicationError) XXX_DiscardUnknown() {
+ xxx_messageInfo_ApplicationError.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_ApplicationError proto.InternalMessageInfo
+
+func (m *ApplicationError) GetCode() int32 {
+ if m != nil && m.Code != nil {
+ return *m.Code
+ }
+ return 0
+}
+
+func (m *ApplicationError) GetDetail() string {
+ if m != nil && m.Detail != nil {
+ return *m.Detail
+ }
+ return ""
+}
+
+type RpcError struct {
+ Code *int32 `protobuf:"varint,1,req,name=code" json:"code,omitempty"`
+ Detail *string `protobuf:"bytes,2,opt,name=detail" json:"detail,omitempty"`
+ XXX_NoUnkeyedLiteral struct{} `json:"-"`
+ XXX_unrecognized []byte `json:"-"`
+ XXX_sizecache int32 `json:"-"`
+}
+
+func (m *RpcError) Reset() { *m = RpcError{} }
+func (m *RpcError) String() string { return proto.CompactTextString(m) }
+func (*RpcError) ProtoMessage() {}
+func (*RpcError) Descriptor() ([]byte, []int) {
+ return fileDescriptor_remote_api_1978114ec33a273d, []int{2}
+}
+func (m *RpcError) XXX_Unmarshal(b []byte) error {
+ return xxx_messageInfo_RpcError.Unmarshal(m, b)
+}
+func (m *RpcError) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ return xxx_messageInfo_RpcError.Marshal(b, m, deterministic)
+}
+func (dst *RpcError) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_RpcError.Merge(dst, src)
+}
+func (m *RpcError) XXX_Size() int {
+ return xxx_messageInfo_RpcError.Size(m)
+}
+func (m *RpcError) XXX_DiscardUnknown() {
+ xxx_messageInfo_RpcError.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_RpcError proto.InternalMessageInfo
+
+func (m *RpcError) GetCode() int32 {
+ if m != nil && m.Code != nil {
+ return *m.Code
+ }
+ return 0
+}
+
+func (m *RpcError) GetDetail() string {
+ if m != nil && m.Detail != nil {
+ return *m.Detail
+ }
+ return ""
+}
+
+type Response struct {
+ Response []byte `protobuf:"bytes,1,opt,name=response" json:"response,omitempty"`
+ Exception []byte `protobuf:"bytes,2,opt,name=exception" json:"exception,omitempty"`
+ ApplicationError *ApplicationError `protobuf:"bytes,3,opt,name=application_error,json=applicationError" json:"application_error,omitempty"`
+ JavaException []byte `protobuf:"bytes,4,opt,name=java_exception,json=javaException" json:"java_exception,omitempty"`
+ RpcError *RpcError `protobuf:"bytes,5,opt,name=rpc_error,json=rpcError" json:"rpc_error,omitempty"`
+ XXX_NoUnkeyedLiteral struct{} `json:"-"`
+ XXX_unrecognized []byte `json:"-"`
+ XXX_sizecache int32 `json:"-"`
+}
+
+func (m *Response) Reset() { *m = Response{} }
+func (m *Response) String() string { return proto.CompactTextString(m) }
+func (*Response) ProtoMessage() {}
+func (*Response) Descriptor() ([]byte, []int) {
+ return fileDescriptor_remote_api_1978114ec33a273d, []int{3}
+}
+func (m *Response) XXX_Unmarshal(b []byte) error {
+ return xxx_messageInfo_Response.Unmarshal(m, b)
+}
+func (m *Response) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ return xxx_messageInfo_Response.Marshal(b, m, deterministic)
+}
+func (dst *Response) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_Response.Merge(dst, src)
+}
+func (m *Response) XXX_Size() int {
+ return xxx_messageInfo_Response.Size(m)
+}
+func (m *Response) XXX_DiscardUnknown() {
+ xxx_messageInfo_Response.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_Response proto.InternalMessageInfo
+
+func (m *Response) GetResponse() []byte {
+ if m != nil {
+ return m.Response
+ }
+ return nil
+}
+
+func (m *Response) GetException() []byte {
+ if m != nil {
+ return m.Exception
+ }
+ return nil
+}
+
+func (m *Response) GetApplicationError() *ApplicationError {
+ if m != nil {
+ return m.ApplicationError
+ }
+ return nil
+}
+
+func (m *Response) GetJavaException() []byte {
+ if m != nil {
+ return m.JavaException
+ }
+ return nil
+}
+
+func (m *Response) GetRpcError() *RpcError {
+ if m != nil {
+ return m.RpcError
+ }
+ return nil
+}
+
+func init() {
+ proto.RegisterType((*Request)(nil), "remote_api.Request")
+ proto.RegisterType((*ApplicationError)(nil), "remote_api.ApplicationError")
+ proto.RegisterType((*RpcError)(nil), "remote_api.RpcError")
+ proto.RegisterType((*Response)(nil), "remote_api.Response")
+}
+
+func init() {
+ proto.RegisterFile("google.golang.org/appengine/internal/remote_api/remote_api.proto", fileDescriptor_remote_api_1978114ec33a273d)
+}
+
+var fileDescriptor_remote_api_1978114ec33a273d = []byte{
+ // 531 bytes of a gzipped FileDescriptorProto
+ 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x93, 0x51, 0x6e, 0xd3, 0x40,
+ 0x10, 0x86, 0xb1, 0x9b, 0x34, 0xf1, 0xc4, 0x2d, 0xdb, 0xa5, 0x14, 0x0b, 0x15, 0x29, 0x44, 0x42,
+ 0xca, 0x53, 0x2a, 0x38, 0x00, 0x62, 0x63, 0x6f, 0x91, 0x85, 0x65, 0xa7, 0x6b, 0xbb, 0x50, 0x5e,
+ 0x56, 0x2b, 0x67, 0x65, 0x8c, 0x12, 0xaf, 0xd9, 0x98, 0x8a, 0x17, 0x6e, 0xc0, 0xb5, 0x38, 0x0c,
+ 0xb7, 0x40, 0x36, 0x6e, 0x63, 0xf5, 0x89, 0xb7, 0x7f, 0x7e, 0x7b, 0xe6, 0x1b, 0xcd, 0xcc, 0xc2,
+ 0xbb, 0x5c, 0xa9, 0x7c, 0x23, 0x17, 0xb9, 0xda, 0x88, 0x32, 0x5f, 0x28, 0x9d, 0x5f, 0x88, 0xaa,
+ 0x92, 0x65, 0x5e, 0x94, 0xf2, 0xa2, 0x28, 0x6b, 0xa9, 0x4b, 0xb1, 0xb9, 0xd0, 0x72, 0xab, 0x6a,
+ 0xc9, 0x45, 0x55, 0xf4, 0xe4, 0xa2, 0xd2, 0xaa, 0x56, 0x18, 0xf6, 0xce, 0xec, 0x27, 0x8c, 0x98,
+ 0xfc, 0xf6, 0x5d, 0xee, 0x6a, 0xfc, 0x12, 0xec, 0x9d, 0xd4, 0xb7, 0x45, 0x26, 0x79, 0x29, 0xb6,
+ 0xd2, 0x31, 0xa7, 0xe6, 0xdc, 0x62, 0x93, 0xce, 0x0b, 0xc5, 0x56, 0xe2, 0x33, 0x38, 0xdc, 0xca,
+ 0xfa, 0x8b, 0x5a, 0x3b, 0x07, 0xed, 0xc7, 0x2e, 0xc2, 0x0e, 0x8c, 0xf4, 0xbf, 0x2a, 0xce, 0x60,
+ 0x6a, 0xce, 0x6d, 0x76, 0x17, 0xe2, 0x17, 0x00, 0x9d, 0xe4, 0xc5, 0xda, 0x19, 0x4e, 0x8d, 0xb9,
+ 0xc5, 0xac, 0xce, 0xf1, 0xd7, 0xb3, 0xb7, 0x80, 0x48, 0x55, 0x6d, 0x8a, 0x4c, 0xd4, 0x85, 0x2a,
+ 0xa9, 0xd6, 0x4a, 0x63, 0x0c, 0x83, 0x4c, 0xad, 0xa5, 0x63, 0x4c, 0xcd, 0xf9, 0x90, 0xb5, 0xba,
+ 0x01, 0xaf, 0x65, 0x2d, 0x8a, 0x4d, 0xd7, 0x55, 0x17, 0xcd, 0x7e, 0x9b, 0x30, 0x66, 0x55, 0xf6,
+ 0x7f, 0x89, 0x46, 0x2f, 0xf1, 0x97, 0x09, 0x56, 0x9b, 0xe5, 0x36, 0x7f, 0x4d, 0x60, 0x94, 0x86,
+ 0x1f, 0xc2, 0xe8, 0x63, 0x88, 0x1e, 0x61, 0x0c, 0xc7, 0x2e, 0x09, 0x02, 0x1e, 0x46, 0x09, 0xbf,
+ 0x8c, 0xd2, 0xd0, 0x43, 0x06, 0x7e, 0x0c, 0x93, 0x15, 0x61, 0x31, 0xe5, 0x94, 0xb1, 0x88, 0x21,
+ 0x13, 0x9f, 0x01, 0x8e, 0xa9, 0x9b, 0x32, 0x3f, 0xb9, 0xe1, 0xd7, 0x7e, 0x14, 0x90, 0xc4, 0x8f,
+ 0x42, 0x74, 0x80, 0x8f, 0x01, 0xa2, 0x6b, 0xca, 0xf8, 0x55, 0x1a, 0x25, 0x04, 0x0d, 0xf0, 0x53,
+ 0x38, 0x61, 0xf4, 0x2a, 0xa5, 0x71, 0xc2, 0x93, 0x28, 0xe2, 0x01, 0x61, 0xef, 0x29, 0x1a, 0xe2,
+ 0x67, 0xf0, 0xc4, 0x25, 0x2b, 0xb2, 0xf4, 0x83, 0xa6, 0x80, 0xe7, 0xc7, 0x64, 0x19, 0x50, 0x0f,
+ 0x1d, 0xe2, 0x53, 0x40, 0x97, 0x94, 0x24, 0x29, 0xa3, 0x7b, 0x77, 0xd4, 0xe0, 0x97, 0xc4, 0xe3,
+ 0x5d, 0x25, 0x34, 0x6e, 0xf0, 0x8c, 0xc6, 0xab, 0x28, 0x8c, 0x69, 0xaf, 0xae, 0x85, 0x8f, 0xc0,
+ 0x72, 0x49, 0xe8, 0xd2, 0xa0, 0xc9, 0x03, 0x8c, 0xc0, 0x66, 0x74, 0x15, 0x90, 0x9b, 0xae, 0xef,
+ 0x49, 0xd3, 0x8f, 0x47, 0x89, 0x17, 0xf8, 0x21, 0xe5, 0xf4, 0x93, 0x4b, 0xa9, 0x47, 0x3d, 0x64,
+ 0xcf, 0xfe, 0x18, 0x30, 0x66, 0x72, 0x57, 0xa9, 0x72, 0x27, 0xf1, 0x73, 0x18, 0xeb, 0x4e, 0x3b,
+ 0xc6, 0xd4, 0x98, 0xdb, 0xec, 0x3e, 0xc6, 0xe7, 0x60, 0xc9, 0x1f, 0x99, 0xac, 0x9a, 0x75, 0xb5,
+ 0x23, 0xb5, 0xd9, 0xde, 0xc0, 0x3e, 0x9c, 0x88, 0xfd, 0x3a, 0xb9, 0x6c, 0x06, 0xec, 0x1c, 0x4c,
+ 0x8d, 0xf9, 0xe4, 0xcd, 0xf9, 0xa2, 0x77, 0x87, 0x0f, 0x77, 0xce, 0x90, 0x78, 0x78, 0x05, 0xaf,
+ 0xe0, 0xf8, 0xab, 0xb8, 0x15, 0x7c, 0x4f, 0x1b, 0xb4, 0xb4, 0xa3, 0xc6, 0xa5, 0xf7, 0xc4, 0xd7,
+ 0x60, 0xe9, 0x2a, 0xeb, 0x48, 0xc3, 0x96, 0x74, 0xda, 0x27, 0xdd, 0x1d, 0x07, 0x1b, 0xeb, 0x4e,
+ 0x2d, 0xed, 0xcf, 0xbd, 0x07, 0xf0, 0x37, 0x00, 0x00, 0xff, 0xff, 0x38, 0xd1, 0x0f, 0x22, 0x4f,
+ 0x03, 0x00, 0x00,
+}
diff --git a/vendor/google.golang.org/appengine/internal/remote_api/remote_api.proto b/vendor/google.golang.org/appengine/internal/remote_api/remote_api.proto
new file mode 100644
index 0000000000000000000000000000000000000000..f21763a4e239ad1ef2daf053725b521d7989e71a
--- /dev/null
+++ b/vendor/google.golang.org/appengine/internal/remote_api/remote_api.proto
@@ -0,0 +1,44 @@
+syntax = "proto2";
+option go_package = "remote_api";
+
+package remote_api;
+
+message Request {
+ required string service_name = 2;
+ required string method = 3;
+ required bytes request = 4;
+ optional string request_id = 5;
+}
+
+message ApplicationError {
+ required int32 code = 1;
+ required string detail = 2;
+}
+
+message RpcError {
+ enum ErrorCode {
+ UNKNOWN = 0;
+ CALL_NOT_FOUND = 1;
+ PARSE_ERROR = 2;
+ SECURITY_VIOLATION = 3;
+ OVER_QUOTA = 4;
+ REQUEST_TOO_LARGE = 5;
+ CAPABILITY_DISABLED = 6;
+ FEATURE_DISABLED = 7;
+ BAD_REQUEST = 8;
+ RESPONSE_TOO_LARGE = 9;
+ CANCELLED = 10;
+ REPLAY_ERROR = 11;
+ DEADLINE_EXCEEDED = 12;
+ }
+ required int32 code = 1;
+ optional string detail = 2;
+}
+
+message Response {
+ optional bytes response = 1;
+ optional bytes exception = 2;
+ optional ApplicationError application_error = 3;
+ optional bytes java_exception = 4;
+ optional RpcError rpc_error = 5;
+}
diff --git a/vendor/google.golang.org/appengine/internal/transaction.go b/vendor/google.golang.org/appengine/internal/transaction.go
new file mode 100644
index 0000000000000000000000000000000000000000..9006ae65380a7629ff1f6828b381138711ded2c2
--- /dev/null
+++ b/vendor/google.golang.org/appengine/internal/transaction.go
@@ -0,0 +1,115 @@
+// Copyright 2014 Google Inc. All rights reserved.
+// Use of this source code is governed by the Apache 2.0
+// license that can be found in the LICENSE file.
+
+package internal
+
+// This file implements hooks for applying datastore transactions.
+
+import (
+ "errors"
+ "reflect"
+
+ "github.com/golang/protobuf/proto"
+ netcontext "golang.org/x/net/context"
+
+ basepb "google.golang.org/appengine/internal/base"
+ pb "google.golang.org/appengine/internal/datastore"
+)
+
+var transactionSetters = make(map[reflect.Type]reflect.Value)
+
+// RegisterTransactionSetter registers a function that sets transaction information
+// in a protocol buffer message. f should be a function with two arguments,
+// the first being a protocol buffer type, and the second being *datastore.Transaction.
+func RegisterTransactionSetter(f interface{}) {
+ v := reflect.ValueOf(f)
+ transactionSetters[v.Type().In(0)] = v
+}
+
+// applyTransaction applies the transaction t to message pb
+// by using the relevant setter passed to RegisterTransactionSetter.
+func applyTransaction(pb proto.Message, t *pb.Transaction) {
+ v := reflect.ValueOf(pb)
+ if f, ok := transactionSetters[v.Type()]; ok {
+ f.Call([]reflect.Value{v, reflect.ValueOf(t)})
+ }
+}
+
+var transactionKey = "used for *Transaction"
+
+func transactionFromContext(ctx netcontext.Context) *transaction {
+ t, _ := ctx.Value(&transactionKey).(*transaction)
+ return t
+}
+
+func withTransaction(ctx netcontext.Context, t *transaction) netcontext.Context {
+ return netcontext.WithValue(ctx, &transactionKey, t)
+}
+
+type transaction struct {
+ transaction pb.Transaction
+ finished bool
+}
+
+var ErrConcurrentTransaction = errors.New("internal: concurrent transaction")
+
+func RunTransactionOnce(c netcontext.Context, f func(netcontext.Context) error, xg bool, readOnly bool, previousTransaction *pb.Transaction) (*pb.Transaction, error) {
+ if transactionFromContext(c) != nil {
+ return nil, errors.New("nested transactions are not supported")
+ }
+
+ // Begin the transaction.
+ t := &transaction{}
+ req := &pb.BeginTransactionRequest{
+ App: proto.String(FullyQualifiedAppID(c)),
+ }
+ if xg {
+ req.AllowMultipleEg = proto.Bool(true)
+ }
+ if previousTransaction != nil {
+ req.PreviousTransaction = previousTransaction
+ }
+ if readOnly {
+ req.Mode = pb.BeginTransactionRequest_READ_ONLY.Enum()
+ } else {
+ req.Mode = pb.BeginTransactionRequest_READ_WRITE.Enum()
+ }
+ if err := Call(c, "datastore_v3", "BeginTransaction", req, &t.transaction); err != nil {
+ return nil, err
+ }
+
+ // Call f, rolling back the transaction if f returns a non-nil error, or panics.
+ // The panic is not recovered.
+ defer func() {
+ if t.finished {
+ return
+ }
+ t.finished = true
+ // Ignore the error return value, since we are already returning a non-nil
+ // error (or we're panicking).
+ Call(c, "datastore_v3", "Rollback", &t.transaction, &basepb.VoidProto{})
+ }()
+ if err := f(withTransaction(c, t)); err != nil {
+ return &t.transaction, err
+ }
+ t.finished = true
+
+ // Commit the transaction.
+ res := &pb.CommitResponse{}
+ err := Call(c, "datastore_v3", "Commit", &t.transaction, res)
+ if ae, ok := err.(*APIError); ok {
+ /* TODO: restore this conditional
+ if appengine.IsDevAppServer() {
+ */
+ // The Python Dev AppServer raises an ApplicationError with error code 2 (which is
+ // Error.CONCURRENT_TRANSACTION) and message "Concurrency exception.".
+ if ae.Code == int32(pb.Error_BAD_REQUEST) && ae.Detail == "ApplicationError: 2 Concurrency exception." {
+ return &t.transaction, ErrConcurrentTransaction
+ }
+ if ae.Code == int32(pb.Error_CONCURRENT_TRANSACTION) {
+ return &t.transaction, ErrConcurrentTransaction
+ }
+ }
+ return &t.transaction, err
+}
diff --git a/vendor/google.golang.org/appengine/internal/urlfetch/urlfetch_service.pb.go b/vendor/google.golang.org/appengine/internal/urlfetch/urlfetch_service.pb.go
new file mode 100644
index 0000000000000000000000000000000000000000..5f727750adc7c8b82f6b92298ec5f1c1b5afe3a1
--- /dev/null
+++ b/vendor/google.golang.org/appengine/internal/urlfetch/urlfetch_service.pb.go
@@ -0,0 +1,527 @@
+// Code generated by protoc-gen-go. DO NOT EDIT.
+// source: google.golang.org/appengine/internal/urlfetch/urlfetch_service.proto
+
+package urlfetch
+
+import proto "github.com/golang/protobuf/proto"
+import fmt "fmt"
+import math "math"
+
+// Reference imports to suppress errors if they are not otherwise used.
+var _ = proto.Marshal
+var _ = fmt.Errorf
+var _ = math.Inf
+
+// This is a compile-time assertion to ensure that this generated file
+// is compatible with the proto package it is being compiled against.
+// A compilation error at this line likely means your copy of the
+// proto package needs to be updated.
+const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package
+
+type URLFetchServiceError_ErrorCode int32
+
+const (
+ URLFetchServiceError_OK URLFetchServiceError_ErrorCode = 0
+ URLFetchServiceError_INVALID_URL URLFetchServiceError_ErrorCode = 1
+ URLFetchServiceError_FETCH_ERROR URLFetchServiceError_ErrorCode = 2
+ URLFetchServiceError_UNSPECIFIED_ERROR URLFetchServiceError_ErrorCode = 3
+ URLFetchServiceError_RESPONSE_TOO_LARGE URLFetchServiceError_ErrorCode = 4
+ URLFetchServiceError_DEADLINE_EXCEEDED URLFetchServiceError_ErrorCode = 5
+ URLFetchServiceError_SSL_CERTIFICATE_ERROR URLFetchServiceError_ErrorCode = 6
+ URLFetchServiceError_DNS_ERROR URLFetchServiceError_ErrorCode = 7
+ URLFetchServiceError_CLOSED URLFetchServiceError_ErrorCode = 8
+ URLFetchServiceError_INTERNAL_TRANSIENT_ERROR URLFetchServiceError_ErrorCode = 9
+ URLFetchServiceError_TOO_MANY_REDIRECTS URLFetchServiceError_ErrorCode = 10
+ URLFetchServiceError_MALFORMED_REPLY URLFetchServiceError_ErrorCode = 11
+ URLFetchServiceError_CONNECTION_ERROR URLFetchServiceError_ErrorCode = 12
+)
+
+var URLFetchServiceError_ErrorCode_name = map[int32]string{
+ 0: "OK",
+ 1: "INVALID_URL",
+ 2: "FETCH_ERROR",
+ 3: "UNSPECIFIED_ERROR",
+ 4: "RESPONSE_TOO_LARGE",
+ 5: "DEADLINE_EXCEEDED",
+ 6: "SSL_CERTIFICATE_ERROR",
+ 7: "DNS_ERROR",
+ 8: "CLOSED",
+ 9: "INTERNAL_TRANSIENT_ERROR",
+ 10: "TOO_MANY_REDIRECTS",
+ 11: "MALFORMED_REPLY",
+ 12: "CONNECTION_ERROR",
+}
+var URLFetchServiceError_ErrorCode_value = map[string]int32{
+ "OK": 0,
+ "INVALID_URL": 1,
+ "FETCH_ERROR": 2,
+ "UNSPECIFIED_ERROR": 3,
+ "RESPONSE_TOO_LARGE": 4,
+ "DEADLINE_EXCEEDED": 5,
+ "SSL_CERTIFICATE_ERROR": 6,
+ "DNS_ERROR": 7,
+ "CLOSED": 8,
+ "INTERNAL_TRANSIENT_ERROR": 9,
+ "TOO_MANY_REDIRECTS": 10,
+ "MALFORMED_REPLY": 11,
+ "CONNECTION_ERROR": 12,
+}
+
+func (x URLFetchServiceError_ErrorCode) Enum() *URLFetchServiceError_ErrorCode {
+ p := new(URLFetchServiceError_ErrorCode)
+ *p = x
+ return p
+}
+func (x URLFetchServiceError_ErrorCode) String() string {
+ return proto.EnumName(URLFetchServiceError_ErrorCode_name, int32(x))
+}
+func (x *URLFetchServiceError_ErrorCode) UnmarshalJSON(data []byte) error {
+ value, err := proto.UnmarshalJSONEnum(URLFetchServiceError_ErrorCode_value, data, "URLFetchServiceError_ErrorCode")
+ if err != nil {
+ return err
+ }
+ *x = URLFetchServiceError_ErrorCode(value)
+ return nil
+}
+func (URLFetchServiceError_ErrorCode) EnumDescriptor() ([]byte, []int) {
+ return fileDescriptor_urlfetch_service_b245a7065f33bced, []int{0, 0}
+}
+
+type URLFetchRequest_RequestMethod int32
+
+const (
+ URLFetchRequest_GET URLFetchRequest_RequestMethod = 1
+ URLFetchRequest_POST URLFetchRequest_RequestMethod = 2
+ URLFetchRequest_HEAD URLFetchRequest_RequestMethod = 3
+ URLFetchRequest_PUT URLFetchRequest_RequestMethod = 4
+ URLFetchRequest_DELETE URLFetchRequest_RequestMethod = 5
+ URLFetchRequest_PATCH URLFetchRequest_RequestMethod = 6
+)
+
+var URLFetchRequest_RequestMethod_name = map[int32]string{
+ 1: "GET",
+ 2: "POST",
+ 3: "HEAD",
+ 4: "PUT",
+ 5: "DELETE",
+ 6: "PATCH",
+}
+var URLFetchRequest_RequestMethod_value = map[string]int32{
+ "GET": 1,
+ "POST": 2,
+ "HEAD": 3,
+ "PUT": 4,
+ "DELETE": 5,
+ "PATCH": 6,
+}
+
+func (x URLFetchRequest_RequestMethod) Enum() *URLFetchRequest_RequestMethod {
+ p := new(URLFetchRequest_RequestMethod)
+ *p = x
+ return p
+}
+func (x URLFetchRequest_RequestMethod) String() string {
+ return proto.EnumName(URLFetchRequest_RequestMethod_name, int32(x))
+}
+func (x *URLFetchRequest_RequestMethod) UnmarshalJSON(data []byte) error {
+ value, err := proto.UnmarshalJSONEnum(URLFetchRequest_RequestMethod_value, data, "URLFetchRequest_RequestMethod")
+ if err != nil {
+ return err
+ }
+ *x = URLFetchRequest_RequestMethod(value)
+ return nil
+}
+func (URLFetchRequest_RequestMethod) EnumDescriptor() ([]byte, []int) {
+ return fileDescriptor_urlfetch_service_b245a7065f33bced, []int{1, 0}
+}
+
+type URLFetchServiceError struct {
+ XXX_NoUnkeyedLiteral struct{} `json:"-"`
+ XXX_unrecognized []byte `json:"-"`
+ XXX_sizecache int32 `json:"-"`
+}
+
+func (m *URLFetchServiceError) Reset() { *m = URLFetchServiceError{} }
+func (m *URLFetchServiceError) String() string { return proto.CompactTextString(m) }
+func (*URLFetchServiceError) ProtoMessage() {}
+func (*URLFetchServiceError) Descriptor() ([]byte, []int) {
+ return fileDescriptor_urlfetch_service_b245a7065f33bced, []int{0}
+}
+func (m *URLFetchServiceError) XXX_Unmarshal(b []byte) error {
+ return xxx_messageInfo_URLFetchServiceError.Unmarshal(m, b)
+}
+func (m *URLFetchServiceError) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ return xxx_messageInfo_URLFetchServiceError.Marshal(b, m, deterministic)
+}
+func (dst *URLFetchServiceError) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_URLFetchServiceError.Merge(dst, src)
+}
+func (m *URLFetchServiceError) XXX_Size() int {
+ return xxx_messageInfo_URLFetchServiceError.Size(m)
+}
+func (m *URLFetchServiceError) XXX_DiscardUnknown() {
+ xxx_messageInfo_URLFetchServiceError.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_URLFetchServiceError proto.InternalMessageInfo
+
+type URLFetchRequest struct {
+ Method *URLFetchRequest_RequestMethod `protobuf:"varint,1,req,name=Method,enum=appengine.URLFetchRequest_RequestMethod" json:"Method,omitempty"`
+ Url *string `protobuf:"bytes,2,req,name=Url" json:"Url,omitempty"`
+ Header []*URLFetchRequest_Header `protobuf:"group,3,rep,name=Header,json=header" json:"header,omitempty"`
+ Payload []byte `protobuf:"bytes,6,opt,name=Payload" json:"Payload,omitempty"`
+ FollowRedirects *bool `protobuf:"varint,7,opt,name=FollowRedirects,def=1" json:"FollowRedirects,omitempty"`
+ Deadline *float64 `protobuf:"fixed64,8,opt,name=Deadline" json:"Deadline,omitempty"`
+ MustValidateServerCertificate *bool `protobuf:"varint,9,opt,name=MustValidateServerCertificate,def=1" json:"MustValidateServerCertificate,omitempty"`
+ XXX_NoUnkeyedLiteral struct{} `json:"-"`
+ XXX_unrecognized []byte `json:"-"`
+ XXX_sizecache int32 `json:"-"`
+}
+
+func (m *URLFetchRequest) Reset() { *m = URLFetchRequest{} }
+func (m *URLFetchRequest) String() string { return proto.CompactTextString(m) }
+func (*URLFetchRequest) ProtoMessage() {}
+func (*URLFetchRequest) Descriptor() ([]byte, []int) {
+ return fileDescriptor_urlfetch_service_b245a7065f33bced, []int{1}
+}
+func (m *URLFetchRequest) XXX_Unmarshal(b []byte) error {
+ return xxx_messageInfo_URLFetchRequest.Unmarshal(m, b)
+}
+func (m *URLFetchRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ return xxx_messageInfo_URLFetchRequest.Marshal(b, m, deterministic)
+}
+func (dst *URLFetchRequest) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_URLFetchRequest.Merge(dst, src)
+}
+func (m *URLFetchRequest) XXX_Size() int {
+ return xxx_messageInfo_URLFetchRequest.Size(m)
+}
+func (m *URLFetchRequest) XXX_DiscardUnknown() {
+ xxx_messageInfo_URLFetchRequest.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_URLFetchRequest proto.InternalMessageInfo
+
+const Default_URLFetchRequest_FollowRedirects bool = true
+const Default_URLFetchRequest_MustValidateServerCertificate bool = true
+
+func (m *URLFetchRequest) GetMethod() URLFetchRequest_RequestMethod {
+ if m != nil && m.Method != nil {
+ return *m.Method
+ }
+ return URLFetchRequest_GET
+}
+
+func (m *URLFetchRequest) GetUrl() string {
+ if m != nil && m.Url != nil {
+ return *m.Url
+ }
+ return ""
+}
+
+func (m *URLFetchRequest) GetHeader() []*URLFetchRequest_Header {
+ if m != nil {
+ return m.Header
+ }
+ return nil
+}
+
+func (m *URLFetchRequest) GetPayload() []byte {
+ if m != nil {
+ return m.Payload
+ }
+ return nil
+}
+
+func (m *URLFetchRequest) GetFollowRedirects() bool {
+ if m != nil && m.FollowRedirects != nil {
+ return *m.FollowRedirects
+ }
+ return Default_URLFetchRequest_FollowRedirects
+}
+
+func (m *URLFetchRequest) GetDeadline() float64 {
+ if m != nil && m.Deadline != nil {
+ return *m.Deadline
+ }
+ return 0
+}
+
+func (m *URLFetchRequest) GetMustValidateServerCertificate() bool {
+ if m != nil && m.MustValidateServerCertificate != nil {
+ return *m.MustValidateServerCertificate
+ }
+ return Default_URLFetchRequest_MustValidateServerCertificate
+}
+
+type URLFetchRequest_Header struct {
+ Key *string `protobuf:"bytes,4,req,name=Key" json:"Key,omitempty"`
+ Value *string `protobuf:"bytes,5,req,name=Value" json:"Value,omitempty"`
+ XXX_NoUnkeyedLiteral struct{} `json:"-"`
+ XXX_unrecognized []byte `json:"-"`
+ XXX_sizecache int32 `json:"-"`
+}
+
+func (m *URLFetchRequest_Header) Reset() { *m = URLFetchRequest_Header{} }
+func (m *URLFetchRequest_Header) String() string { return proto.CompactTextString(m) }
+func (*URLFetchRequest_Header) ProtoMessage() {}
+func (*URLFetchRequest_Header) Descriptor() ([]byte, []int) {
+ return fileDescriptor_urlfetch_service_b245a7065f33bced, []int{1, 0}
+}
+func (m *URLFetchRequest_Header) XXX_Unmarshal(b []byte) error {
+ return xxx_messageInfo_URLFetchRequest_Header.Unmarshal(m, b)
+}
+func (m *URLFetchRequest_Header) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ return xxx_messageInfo_URLFetchRequest_Header.Marshal(b, m, deterministic)
+}
+func (dst *URLFetchRequest_Header) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_URLFetchRequest_Header.Merge(dst, src)
+}
+func (m *URLFetchRequest_Header) XXX_Size() int {
+ return xxx_messageInfo_URLFetchRequest_Header.Size(m)
+}
+func (m *URLFetchRequest_Header) XXX_DiscardUnknown() {
+ xxx_messageInfo_URLFetchRequest_Header.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_URLFetchRequest_Header proto.InternalMessageInfo
+
+func (m *URLFetchRequest_Header) GetKey() string {
+ if m != nil && m.Key != nil {
+ return *m.Key
+ }
+ return ""
+}
+
+func (m *URLFetchRequest_Header) GetValue() string {
+ if m != nil && m.Value != nil {
+ return *m.Value
+ }
+ return ""
+}
+
+type URLFetchResponse struct {
+ Content []byte `protobuf:"bytes,1,opt,name=Content" json:"Content,omitempty"`
+ StatusCode *int32 `protobuf:"varint,2,req,name=StatusCode" json:"StatusCode,omitempty"`
+ Header []*URLFetchResponse_Header `protobuf:"group,3,rep,name=Header,json=header" json:"header,omitempty"`
+ ContentWasTruncated *bool `protobuf:"varint,6,opt,name=ContentWasTruncated,def=0" json:"ContentWasTruncated,omitempty"`
+ ExternalBytesSent *int64 `protobuf:"varint,7,opt,name=ExternalBytesSent" json:"ExternalBytesSent,omitempty"`
+ ExternalBytesReceived *int64 `protobuf:"varint,8,opt,name=ExternalBytesReceived" json:"ExternalBytesReceived,omitempty"`
+ FinalUrl *string `protobuf:"bytes,9,opt,name=FinalUrl" json:"FinalUrl,omitempty"`
+ ApiCpuMilliseconds *int64 `protobuf:"varint,10,opt,name=ApiCpuMilliseconds,def=0" json:"ApiCpuMilliseconds,omitempty"`
+ ApiBytesSent *int64 `protobuf:"varint,11,opt,name=ApiBytesSent,def=0" json:"ApiBytesSent,omitempty"`
+ ApiBytesReceived *int64 `protobuf:"varint,12,opt,name=ApiBytesReceived,def=0" json:"ApiBytesReceived,omitempty"`
+ XXX_NoUnkeyedLiteral struct{} `json:"-"`
+ XXX_unrecognized []byte `json:"-"`
+ XXX_sizecache int32 `json:"-"`
+}
+
+func (m *URLFetchResponse) Reset() { *m = URLFetchResponse{} }
+func (m *URLFetchResponse) String() string { return proto.CompactTextString(m) }
+func (*URLFetchResponse) ProtoMessage() {}
+func (*URLFetchResponse) Descriptor() ([]byte, []int) {
+ return fileDescriptor_urlfetch_service_b245a7065f33bced, []int{2}
+}
+func (m *URLFetchResponse) XXX_Unmarshal(b []byte) error {
+ return xxx_messageInfo_URLFetchResponse.Unmarshal(m, b)
+}
+func (m *URLFetchResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ return xxx_messageInfo_URLFetchResponse.Marshal(b, m, deterministic)
+}
+func (dst *URLFetchResponse) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_URLFetchResponse.Merge(dst, src)
+}
+func (m *URLFetchResponse) XXX_Size() int {
+ return xxx_messageInfo_URLFetchResponse.Size(m)
+}
+func (m *URLFetchResponse) XXX_DiscardUnknown() {
+ xxx_messageInfo_URLFetchResponse.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_URLFetchResponse proto.InternalMessageInfo
+
+const Default_URLFetchResponse_ContentWasTruncated bool = false
+const Default_URLFetchResponse_ApiCpuMilliseconds int64 = 0
+const Default_URLFetchResponse_ApiBytesSent int64 = 0
+const Default_URLFetchResponse_ApiBytesReceived int64 = 0
+
+func (m *URLFetchResponse) GetContent() []byte {
+ if m != nil {
+ return m.Content
+ }
+ return nil
+}
+
+func (m *URLFetchResponse) GetStatusCode() int32 {
+ if m != nil && m.StatusCode != nil {
+ return *m.StatusCode
+ }
+ return 0
+}
+
+func (m *URLFetchResponse) GetHeader() []*URLFetchResponse_Header {
+ if m != nil {
+ return m.Header
+ }
+ return nil
+}
+
+func (m *URLFetchResponse) GetContentWasTruncated() bool {
+ if m != nil && m.ContentWasTruncated != nil {
+ return *m.ContentWasTruncated
+ }
+ return Default_URLFetchResponse_ContentWasTruncated
+}
+
+func (m *URLFetchResponse) GetExternalBytesSent() int64 {
+ if m != nil && m.ExternalBytesSent != nil {
+ return *m.ExternalBytesSent
+ }
+ return 0
+}
+
+func (m *URLFetchResponse) GetExternalBytesReceived() int64 {
+ if m != nil && m.ExternalBytesReceived != nil {
+ return *m.ExternalBytesReceived
+ }
+ return 0
+}
+
+func (m *URLFetchResponse) GetFinalUrl() string {
+ if m != nil && m.FinalUrl != nil {
+ return *m.FinalUrl
+ }
+ return ""
+}
+
+func (m *URLFetchResponse) GetApiCpuMilliseconds() int64 {
+ if m != nil && m.ApiCpuMilliseconds != nil {
+ return *m.ApiCpuMilliseconds
+ }
+ return Default_URLFetchResponse_ApiCpuMilliseconds
+}
+
+func (m *URLFetchResponse) GetApiBytesSent() int64 {
+ if m != nil && m.ApiBytesSent != nil {
+ return *m.ApiBytesSent
+ }
+ return Default_URLFetchResponse_ApiBytesSent
+}
+
+func (m *URLFetchResponse) GetApiBytesReceived() int64 {
+ if m != nil && m.ApiBytesReceived != nil {
+ return *m.ApiBytesReceived
+ }
+ return Default_URLFetchResponse_ApiBytesReceived
+}
+
+type URLFetchResponse_Header struct {
+ Key *string `protobuf:"bytes,4,req,name=Key" json:"Key,omitempty"`
+ Value *string `protobuf:"bytes,5,req,name=Value" json:"Value,omitempty"`
+ XXX_NoUnkeyedLiteral struct{} `json:"-"`
+ XXX_unrecognized []byte `json:"-"`
+ XXX_sizecache int32 `json:"-"`
+}
+
+func (m *URLFetchResponse_Header) Reset() { *m = URLFetchResponse_Header{} }
+func (m *URLFetchResponse_Header) String() string { return proto.CompactTextString(m) }
+func (*URLFetchResponse_Header) ProtoMessage() {}
+func (*URLFetchResponse_Header) Descriptor() ([]byte, []int) {
+ return fileDescriptor_urlfetch_service_b245a7065f33bced, []int{2, 0}
+}
+func (m *URLFetchResponse_Header) XXX_Unmarshal(b []byte) error {
+ return xxx_messageInfo_URLFetchResponse_Header.Unmarshal(m, b)
+}
+func (m *URLFetchResponse_Header) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ return xxx_messageInfo_URLFetchResponse_Header.Marshal(b, m, deterministic)
+}
+func (dst *URLFetchResponse_Header) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_URLFetchResponse_Header.Merge(dst, src)
+}
+func (m *URLFetchResponse_Header) XXX_Size() int {
+ return xxx_messageInfo_URLFetchResponse_Header.Size(m)
+}
+func (m *URLFetchResponse_Header) XXX_DiscardUnknown() {
+ xxx_messageInfo_URLFetchResponse_Header.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_URLFetchResponse_Header proto.InternalMessageInfo
+
+func (m *URLFetchResponse_Header) GetKey() string {
+ if m != nil && m.Key != nil {
+ return *m.Key
+ }
+ return ""
+}
+
+func (m *URLFetchResponse_Header) GetValue() string {
+ if m != nil && m.Value != nil {
+ return *m.Value
+ }
+ return ""
+}
+
+func init() {
+ proto.RegisterType((*URLFetchServiceError)(nil), "appengine.URLFetchServiceError")
+ proto.RegisterType((*URLFetchRequest)(nil), "appengine.URLFetchRequest")
+ proto.RegisterType((*URLFetchRequest_Header)(nil), "appengine.URLFetchRequest.Header")
+ proto.RegisterType((*URLFetchResponse)(nil), "appengine.URLFetchResponse")
+ proto.RegisterType((*URLFetchResponse_Header)(nil), "appengine.URLFetchResponse.Header")
+}
+
+func init() {
+ proto.RegisterFile("google.golang.org/appengine/internal/urlfetch/urlfetch_service.proto", fileDescriptor_urlfetch_service_b245a7065f33bced)
+}
+
+var fileDescriptor_urlfetch_service_b245a7065f33bced = []byte{
+ // 770 bytes of a gzipped FileDescriptorProto
+ 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x54, 0xdd, 0x6e, 0xe3, 0x54,
+ 0x10, 0xc6, 0x76, 0x7e, 0xa7, 0x5d, 0x7a, 0x76, 0xb6, 0x45, 0x66, 0xb5, 0xa0, 0x10, 0x09, 0x29,
+ 0x17, 0x90, 0x2e, 0x2b, 0x24, 0x44, 0xaf, 0x70, 0xed, 0x93, 0xad, 0xa9, 0x63, 0x47, 0xc7, 0x4e,
+ 0x61, 0xb9, 0xb1, 0xac, 0x78, 0x9a, 0x5a, 0xb2, 0xec, 0x60, 0x9f, 0x2c, 0xf4, 0x35, 0x78, 0x0d,
+ 0xde, 0x87, 0xa7, 0xe1, 0x02, 0x9d, 0xc4, 0xc9, 0x6e, 0xbb, 0xd1, 0x4a, 0x5c, 0x65, 0xe6, 0x9b,
+ 0xef, 0xcc, 0x99, 0x7c, 0xdf, 0xf8, 0x80, 0xb3, 0x2c, 0xcb, 0x65, 0x4e, 0xe3, 0x65, 0x99, 0x27,
+ 0xc5, 0x72, 0x5c, 0x56, 0xcb, 0xf3, 0x64, 0xb5, 0xa2, 0x62, 0x99, 0x15, 0x74, 0x9e, 0x15, 0x92,
+ 0xaa, 0x22, 0xc9, 0xcf, 0xd7, 0x55, 0x7e, 0x4b, 0x72, 0x71, 0xb7, 0x0f, 0xe2, 0x9a, 0xaa, 0xb7,
+ 0xd9, 0x82, 0xc6, 0xab, 0xaa, 0x94, 0x25, 0xf6, 0xf7, 0x67, 0x86, 0x7f, 0xeb, 0x70, 0x3a, 0x17,
+ 0xde, 0x44, 0xb1, 0xc2, 0x2d, 0x89, 0x57, 0x55, 0x59, 0x0d, 0xff, 0xd2, 0xa1, 0xbf, 0x89, 0xec,
+ 0x32, 0x25, 0xec, 0x80, 0x1e, 0x5c, 0xb3, 0x4f, 0xf0, 0x04, 0x8e, 0x5c, 0xff, 0xc6, 0xf2, 0x5c,
+ 0x27, 0x9e, 0x0b, 0x8f, 0x69, 0x0a, 0x98, 0xf0, 0xc8, 0xbe, 0x8a, 0xb9, 0x10, 0x81, 0x60, 0x3a,
+ 0x9e, 0xc1, 0xd3, 0xb9, 0x1f, 0xce, 0xb8, 0xed, 0x4e, 0x5c, 0xee, 0x34, 0xb0, 0x81, 0x9f, 0x01,
+ 0x0a, 0x1e, 0xce, 0x02, 0x3f, 0xe4, 0x71, 0x14, 0x04, 0xb1, 0x67, 0x89, 0xd7, 0x9c, 0xb5, 0x14,
+ 0xdd, 0xe1, 0x96, 0xe3, 0xb9, 0x3e, 0x8f, 0xf9, 0xaf, 0x36, 0xe7, 0x0e, 0x77, 0x58, 0x1b, 0x3f,
+ 0x87, 0xb3, 0x30, 0xf4, 0x62, 0x9b, 0x8b, 0xc8, 0x9d, 0xb8, 0xb6, 0x15, 0xf1, 0xa6, 0x53, 0x07,
+ 0x9f, 0x40, 0xdf, 0xf1, 0xc3, 0x26, 0xed, 0x22, 0x40, 0xc7, 0xf6, 0x82, 0x90, 0x3b, 0xac, 0x87,
+ 0x2f, 0xc0, 0x74, 0xfd, 0x88, 0x0b, 0xdf, 0xf2, 0xe2, 0x48, 0x58, 0x7e, 0xe8, 0x72, 0x3f, 0x6a,
+ 0x98, 0x7d, 0x35, 0x82, 0xba, 0x79, 0x6a, 0xf9, 0x6f, 0x62, 0xc1, 0x1d, 0x57, 0x70, 0x3b, 0x0a,
+ 0x19, 0xe0, 0x33, 0x38, 0x99, 0x5a, 0xde, 0x24, 0x10, 0x53, 0xee, 0xc4, 0x82, 0xcf, 0xbc, 0x37,
+ 0xec, 0x08, 0x4f, 0x81, 0xd9, 0x81, 0xef, 0x73, 0x3b, 0x72, 0x03, 0xbf, 0x69, 0x71, 0x3c, 0xfc,
+ 0xc7, 0x80, 0x93, 0x9d, 0x5a, 0x82, 0x7e, 0x5f, 0x53, 0x2d, 0xf1, 0x27, 0xe8, 0x4c, 0x49, 0xde,
+ 0x95, 0xa9, 0xa9, 0x0d, 0xf4, 0xd1, 0xa7, 0xaf, 0x46, 0xe3, 0xbd, 0xba, 0xe3, 0x47, 0xdc, 0x71,
+ 0xf3, 0xbb, 0xe5, 0x8b, 0xe6, 0x1c, 0x32, 0x30, 0xe6, 0x55, 0x6e, 0xea, 0x03, 0x7d, 0xd4, 0x17,
+ 0x2a, 0xc4, 0x1f, 0xa1, 0x73, 0x47, 0x49, 0x4a, 0x95, 0x69, 0x0c, 0x8c, 0x11, 0xbc, 0xfa, 0xea,
+ 0x23, 0x3d, 0xaf, 0x36, 0x44, 0xd1, 0x1c, 0xc0, 0x17, 0xd0, 0x9d, 0x25, 0xf7, 0x79, 0x99, 0xa4,
+ 0x66, 0x67, 0xa0, 0x8d, 0x8e, 0x2f, 0xf5, 0x9e, 0x26, 0x76, 0x10, 0x8e, 0xe1, 0x64, 0x52, 0xe6,
+ 0x79, 0xf9, 0x87, 0xa0, 0x34, 0xab, 0x68, 0x21, 0x6b, 0xb3, 0x3b, 0xd0, 0x46, 0xbd, 0x8b, 0x96,
+ 0xac, 0xd6, 0x24, 0x1e, 0x17, 0xf1, 0x39, 0xf4, 0x1c, 0x4a, 0xd2, 0x3c, 0x2b, 0xc8, 0xec, 0x0d,
+ 0xb4, 0x91, 0x26, 0xf6, 0x39, 0xfe, 0x0c, 0x5f, 0x4c, 0xd7, 0xb5, 0xbc, 0x49, 0xf2, 0x2c, 0x4d,
+ 0x24, 0xa9, 0xed, 0xa1, 0xca, 0xa6, 0x4a, 0x66, 0xb7, 0xd9, 0x22, 0x91, 0x64, 0xf6, 0xdf, 0xeb,
+ 0xfc, 0x71, 0xea, 0xf3, 0x97, 0xd0, 0xd9, 0xfe, 0x0f, 0x25, 0xc6, 0x35, 0xdd, 0x9b, 0xad, 0xad,
+ 0x18, 0xd7, 0x74, 0x8f, 0xa7, 0xd0, 0xbe, 0x49, 0xf2, 0x35, 0x99, 0xed, 0x0d, 0xb6, 0x4d, 0x86,
+ 0x1e, 0x3c, 0x79, 0xa0, 0x26, 0x76, 0xc1, 0x78, 0xcd, 0x23, 0xa6, 0x61, 0x0f, 0x5a, 0xb3, 0x20,
+ 0x8c, 0x98, 0xae, 0xa2, 0x2b, 0x6e, 0x39, 0xcc, 0x50, 0xc5, 0xd9, 0x3c, 0x62, 0x2d, 0xb5, 0x2e,
+ 0x0e, 0xf7, 0x78, 0xc4, 0x59, 0x1b, 0xfb, 0xd0, 0x9e, 0x59, 0x91, 0x7d, 0xc5, 0x3a, 0xc3, 0x7f,
+ 0x0d, 0x60, 0xef, 0x84, 0xad, 0x57, 0x65, 0x51, 0x13, 0x9a, 0xd0, 0xb5, 0xcb, 0x42, 0x52, 0x21,
+ 0x4d, 0x4d, 0x49, 0x29, 0x76, 0x29, 0x7e, 0x09, 0x10, 0xca, 0x44, 0xae, 0x6b, 0xf5, 0x71, 0x6c,
+ 0x8c, 0x6b, 0x8b, 0xf7, 0x10, 0xbc, 0x78, 0xe4, 0xdf, 0xf0, 0xa0, 0x7f, 0xdb, 0x6b, 0x1e, 0x1b,
+ 0xf8, 0x03, 0x3c, 0x6b, 0xae, 0xf9, 0x25, 0xa9, 0xa3, 0x6a, 0x5d, 0x28, 0x81, 0xb6, 0x66, 0xf6,
+ 0x2e, 0xda, 0xb7, 0x49, 0x5e, 0x93, 0x38, 0xc4, 0xc0, 0x6f, 0xe0, 0x29, 0xff, 0x73, 0xfb, 0x02,
+ 0x5c, 0xde, 0x4b, 0xaa, 0x43, 0x35, 0xb8, 0x72, 0xd7, 0x10, 0x1f, 0x16, 0xf0, 0x7b, 0x38, 0x7b,
+ 0x00, 0x0a, 0x5a, 0x50, 0xf6, 0x96, 0xd2, 0x8d, 0xcd, 0x86, 0x38, 0x5c, 0x54, 0xfb, 0x30, 0xc9,
+ 0x8a, 0x24, 0x57, 0xfb, 0xaa, 0xec, 0xed, 0x8b, 0x7d, 0x8e, 0xdf, 0x01, 0x5a, 0xab, 0xcc, 0x5e,
+ 0xad, 0xa7, 0x59, 0x9e, 0x67, 0x35, 0x2d, 0xca, 0x22, 0xad, 0x4d, 0x50, 0xed, 0x2e, 0xb4, 0x97,
+ 0xe2, 0x40, 0x11, 0xbf, 0x86, 0x63, 0x6b, 0x95, 0xbd, 0x9b, 0xf6, 0x68, 0x47, 0x7e, 0x00, 0xe3,
+ 0xb7, 0xc0, 0x76, 0xf9, 0x7e, 0xcc, 0xe3, 0x1d, 0xf5, 0x83, 0xd2, 0xff, 0x5f, 0xa6, 0x4b, 0xf8,
+ 0xad, 0xb7, 0x7b, 0x2a, 0xff, 0x0b, 0x00, 0x00, 0xff, 0xff, 0x1d, 0x9f, 0x6d, 0x24, 0x63, 0x05,
+ 0x00, 0x00,
+}
diff --git a/vendor/google.golang.org/appengine/internal/urlfetch/urlfetch_service.proto b/vendor/google.golang.org/appengine/internal/urlfetch/urlfetch_service.proto
new file mode 100644
index 0000000000000000000000000000000000000000..f695edf6a9071962db5f1297c5df0459b1431baa
--- /dev/null
+++ b/vendor/google.golang.org/appengine/internal/urlfetch/urlfetch_service.proto
@@ -0,0 +1,64 @@
+syntax = "proto2";
+option go_package = "urlfetch";
+
+package appengine;
+
+message URLFetchServiceError {
+ enum ErrorCode {
+ OK = 0;
+ INVALID_URL = 1;
+ FETCH_ERROR = 2;
+ UNSPECIFIED_ERROR = 3;
+ RESPONSE_TOO_LARGE = 4;
+ DEADLINE_EXCEEDED = 5;
+ SSL_CERTIFICATE_ERROR = 6;
+ DNS_ERROR = 7;
+ CLOSED = 8;
+ INTERNAL_TRANSIENT_ERROR = 9;
+ TOO_MANY_REDIRECTS = 10;
+ MALFORMED_REPLY = 11;
+ CONNECTION_ERROR = 12;
+ }
+}
+
+message URLFetchRequest {
+ enum RequestMethod {
+ GET = 1;
+ POST = 2;
+ HEAD = 3;
+ PUT = 4;
+ DELETE = 5;
+ PATCH = 6;
+ }
+ required RequestMethod Method = 1;
+ required string Url = 2;
+ repeated group Header = 3 {
+ required string Key = 4;
+ required string Value = 5;
+ }
+ optional bytes Payload = 6 [ctype=CORD];
+
+ optional bool FollowRedirects = 7 [default=true];
+
+ optional double Deadline = 8;
+
+ optional bool MustValidateServerCertificate = 9 [default=true];
+}
+
+message URLFetchResponse {
+ optional bytes Content = 1;
+ required int32 StatusCode = 2;
+ repeated group Header = 3 {
+ required string Key = 4;
+ required string Value = 5;
+ }
+ optional bool ContentWasTruncated = 6 [default=false];
+ optional int64 ExternalBytesSent = 7;
+ optional int64 ExternalBytesReceived = 8;
+
+ optional string FinalUrl = 9;
+
+ optional int64 ApiCpuMilliseconds = 10 [default=0];
+ optional int64 ApiBytesSent = 11 [default=0];
+ optional int64 ApiBytesReceived = 12 [default=0];
+}
diff --git a/vendor/google.golang.org/appengine/urlfetch/urlfetch.go b/vendor/google.golang.org/appengine/urlfetch/urlfetch.go
new file mode 100644
index 0000000000000000000000000000000000000000..6ffe1e6d901affc4656213788bbce02210c74828
--- /dev/null
+++ b/vendor/google.golang.org/appengine/urlfetch/urlfetch.go
@@ -0,0 +1,210 @@
+// Copyright 2011 Google Inc. All rights reserved.
+// Use of this source code is governed by the Apache 2.0
+// license that can be found in the LICENSE file.
+
+// Package urlfetch provides an http.RoundTripper implementation
+// for fetching URLs via App Engine's urlfetch service.
+package urlfetch // import "google.golang.org/appengine/urlfetch"
+
+import (
+ "errors"
+ "fmt"
+ "io"
+ "io/ioutil"
+ "net/http"
+ "net/url"
+ "strconv"
+ "strings"
+ "time"
+
+ "github.com/golang/protobuf/proto"
+ "golang.org/x/net/context"
+
+ "google.golang.org/appengine/internal"
+ pb "google.golang.org/appengine/internal/urlfetch"
+)
+
+// Transport is an implementation of http.RoundTripper for
+// App Engine. Users should generally create an http.Client using
+// this transport and use the Client rather than using this transport
+// directly.
+type Transport struct {
+ Context context.Context
+
+ // Controls whether the application checks the validity of SSL certificates
+ // over HTTPS connections. A value of false (the default) instructs the
+ // application to send a request to the server only if the certificate is
+ // valid and signed by a trusted certificate authority (CA), and also
+ // includes a hostname that matches the certificate. A value of true
+ // instructs the application to perform no certificate validation.
+ AllowInvalidServerCertificate bool
+}
+
+// Verify statically that *Transport implements http.RoundTripper.
+var _ http.RoundTripper = (*Transport)(nil)
+
+// Client returns an *http.Client using a default urlfetch Transport. This
+// client will have the default deadline of 5 seconds, and will check the
+// validity of SSL certificates.
+//
+// Any deadline of the provided context will be used for requests through this client;
+// if the client does not have a deadline then a 5 second default is used.
+func Client(ctx context.Context) *http.Client {
+ return &http.Client{
+ Transport: &Transport{
+ Context: ctx,
+ },
+ }
+}
+
+type bodyReader struct {
+ content []byte
+ truncated bool
+ closed bool
+}
+
+// ErrTruncatedBody is the error returned after the final Read() from a
+// response's Body if the body has been truncated by App Engine's proxy.
+var ErrTruncatedBody = errors.New("urlfetch: truncated body")
+
+func statusCodeToText(code int) string {
+ if t := http.StatusText(code); t != "" {
+ return t
+ }
+ return strconv.Itoa(code)
+}
+
+func (br *bodyReader) Read(p []byte) (n int, err error) {
+ if br.closed {
+ if br.truncated {
+ return 0, ErrTruncatedBody
+ }
+ return 0, io.EOF
+ }
+ n = copy(p, br.content)
+ if n > 0 {
+ br.content = br.content[n:]
+ return
+ }
+ if br.truncated {
+ br.closed = true
+ return 0, ErrTruncatedBody
+ }
+ return 0, io.EOF
+}
+
+func (br *bodyReader) Close() error {
+ br.closed = true
+ br.content = nil
+ return nil
+}
+
+// A map of the URL Fetch-accepted methods that take a request body.
+var methodAcceptsRequestBody = map[string]bool{
+ "POST": true,
+ "PUT": true,
+ "PATCH": true,
+}
+
+// urlString returns a valid string given a URL. This function is necessary because
+// the String method of URL doesn't correctly handle URLs with non-empty Opaque values.
+// See http://code.google.com/p/go/issues/detail?id=4860.
+func urlString(u *url.URL) string {
+ if u.Opaque == "" || strings.HasPrefix(u.Opaque, "//") {
+ return u.String()
+ }
+ aux := *u
+ aux.Opaque = "//" + aux.Host + aux.Opaque
+ return aux.String()
+}
+
+// RoundTrip issues a single HTTP request and returns its response. Per the
+// http.RoundTripper interface, RoundTrip only returns an error if there
+// was an unsupported request or the URL Fetch proxy fails.
+// Note that HTTP response codes such as 5xx, 403, 404, etc are not
+// errors as far as the transport is concerned and will be returned
+// with err set to nil.
+func (t *Transport) RoundTrip(req *http.Request) (res *http.Response, err error) {
+ methNum, ok := pb.URLFetchRequest_RequestMethod_value[req.Method]
+ if !ok {
+ return nil, fmt.Errorf("urlfetch: unsupported HTTP method %q", req.Method)
+ }
+
+ method := pb.URLFetchRequest_RequestMethod(methNum)
+
+ freq := &pb.URLFetchRequest{
+ Method: &method,
+ Url: proto.String(urlString(req.URL)),
+ FollowRedirects: proto.Bool(false), // http.Client's responsibility
+ MustValidateServerCertificate: proto.Bool(!t.AllowInvalidServerCertificate),
+ }
+ if deadline, ok := t.Context.Deadline(); ok {
+ freq.Deadline = proto.Float64(deadline.Sub(time.Now()).Seconds())
+ }
+
+ for k, vals := range req.Header {
+ for _, val := range vals {
+ freq.Header = append(freq.Header, &pb.URLFetchRequest_Header{
+ Key: proto.String(k),
+ Value: proto.String(val),
+ })
+ }
+ }
+ if methodAcceptsRequestBody[req.Method] && req.Body != nil {
+ // Avoid a []byte copy if req.Body has a Bytes method.
+ switch b := req.Body.(type) {
+ case interface {
+ Bytes() []byte
+ }:
+ freq.Payload = b.Bytes()
+ default:
+ freq.Payload, err = ioutil.ReadAll(req.Body)
+ if err != nil {
+ return nil, err
+ }
+ }
+ }
+
+ fres := &pb.URLFetchResponse{}
+ if err := internal.Call(t.Context, "urlfetch", "Fetch", freq, fres); err != nil {
+ return nil, err
+ }
+
+ res = &http.Response{}
+ res.StatusCode = int(*fres.StatusCode)
+ res.Status = fmt.Sprintf("%d %s", res.StatusCode, statusCodeToText(res.StatusCode))
+ res.Header = make(http.Header)
+ res.Request = req
+
+ // Faked:
+ res.ProtoMajor = 1
+ res.ProtoMinor = 1
+ res.Proto = "HTTP/1.1"
+ res.Close = true
+
+ for _, h := range fres.Header {
+ hkey := http.CanonicalHeaderKey(*h.Key)
+ hval := *h.Value
+ if hkey == "Content-Length" {
+ // Will get filled in below for all but HEAD requests.
+ if req.Method == "HEAD" {
+ res.ContentLength, _ = strconv.ParseInt(hval, 10, 64)
+ }
+ continue
+ }
+ res.Header.Add(hkey, hval)
+ }
+
+ if req.Method != "HEAD" {
+ res.ContentLength = int64(len(fres.Content))
+ }
+
+ truncated := fres.GetContentWasTruncated()
+ res.Body = &bodyReader{content: fres.Content, truncated: truncated}
+ return
+}
+
+func init() {
+ internal.RegisterErrorCodeMap("urlfetch", pb.URLFetchServiceError_ErrorCode_name)
+ internal.RegisterTimeoutErrorCode("urlfetch", int32(pb.URLFetchServiceError_DEADLINE_EXCEEDED))
+}
diff --git a/vendor/gopkg.in/yaml.v2/.travis.yml b/vendor/gopkg.in/yaml.v2/.travis.yml
new file mode 100644
index 0000000000000000000000000000000000000000..9f556934d8b91e4412de52c2331263192732d821
--- /dev/null
+++ b/vendor/gopkg.in/yaml.v2/.travis.yml
@@ -0,0 +1,12 @@
+language: go
+
+go:
+ - 1.4
+ - 1.5
+ - 1.6
+ - 1.7
+ - 1.8
+ - 1.9
+ - tip
+
+go_import_path: gopkg.in/yaml.v2
diff --git a/vendor/gopkg.in/yaml.v2/LICENSE b/vendor/gopkg.in/yaml.v2/LICENSE
new file mode 100644
index 0000000000000000000000000000000000000000..8dada3edaf50dbc082c9a125058f25def75e625a
--- /dev/null
+++ b/vendor/gopkg.in/yaml.v2/LICENSE
@@ -0,0 +1,201 @@
+ 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.
diff --git a/vendor/gopkg.in/yaml.v2/LICENSE.libyaml b/vendor/gopkg.in/yaml.v2/LICENSE.libyaml
new file mode 100644
index 0000000000000000000000000000000000000000..8da58fbf6f84a9280f8351ed3c8bfb47c9d787c2
--- /dev/null
+++ b/vendor/gopkg.in/yaml.v2/LICENSE.libyaml
@@ -0,0 +1,31 @@
+The following files were ported to Go from C files of libyaml, and thus
+are still covered by their original copyright and license:
+
+ apic.go
+ emitterc.go
+ parserc.go
+ readerc.go
+ scannerc.go
+ writerc.go
+ yamlh.go
+ yamlprivateh.go
+
+Copyright (c) 2006 Kirill Simonov
+
+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.
diff --git a/vendor/gopkg.in/yaml.v2/NOTICE b/vendor/gopkg.in/yaml.v2/NOTICE
new file mode 100644
index 0000000000000000000000000000000000000000..866d74a7ad79165312a2ce3904b4bdb53e6aedf7
--- /dev/null
+++ b/vendor/gopkg.in/yaml.v2/NOTICE
@@ -0,0 +1,13 @@
+Copyright 2011-2016 Canonical Ltd.
+
+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.
diff --git a/vendor/gopkg.in/yaml.v2/README.md b/vendor/gopkg.in/yaml.v2/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..b50c6e877559437c0075edc6da1c94e2c62bca7b
--- /dev/null
+++ b/vendor/gopkg.in/yaml.v2/README.md
@@ -0,0 +1,133 @@
+# YAML support for the Go language
+
+Introduction
+------------
+
+The yaml package enables Go programs to comfortably encode and decode YAML
+values. It was developed within [Canonical](https://www.canonical.com) as
+part of the [juju](https://juju.ubuntu.com) project, and is based on a
+pure Go port of the well-known [libyaml](http://pyyaml.org/wiki/LibYAML)
+C library to parse and generate YAML data quickly and reliably.
+
+Compatibility
+-------------
+
+The yaml package supports most of YAML 1.1 and 1.2, including support for
+anchors, tags, map merging, etc. Multi-document unmarshalling is not yet
+implemented, and base-60 floats from YAML 1.1 are purposefully not
+supported since they're a poor design and are gone in YAML 1.2.
+
+Installation and usage
+----------------------
+
+The import path for the package is *gopkg.in/yaml.v2*.
+
+To install it, run:
+
+ go get gopkg.in/yaml.v2
+
+API documentation
+-----------------
+
+If opened in a browser, the import path itself leads to the API documentation:
+
+ * [https://gopkg.in/yaml.v2](https://gopkg.in/yaml.v2)
+
+API stability
+-------------
+
+The package API for yaml v2 will remain stable as described in [gopkg.in](https://gopkg.in).
+
+
+License
+-------
+
+The yaml package is licensed under the Apache License 2.0. Please see the LICENSE file for details.
+
+
+Example
+-------
+
+```Go
+package main
+
+import (
+ "fmt"
+ "log"
+
+ "gopkg.in/yaml.v2"
+)
+
+var data = `
+a: Easy!
+b:
+ c: 2
+ d: [3, 4]
+`
+
+// Note: struct fields must be public in order for unmarshal to
+// correctly populate the data.
+type T struct {
+ A string
+ B struct {
+ RenamedC int `yaml:"c"`
+ D []int `yaml:",flow"`
+ }
+}
+
+func main() {
+ t := T{}
+
+ err := yaml.Unmarshal([]byte(data), &t)
+ if err != nil {
+ log.Fatalf("error: %v", err)
+ }
+ fmt.Printf("--- t:\n%v\n\n", t)
+
+ d, err := yaml.Marshal(&t)
+ if err != nil {
+ log.Fatalf("error: %v", err)
+ }
+ fmt.Printf("--- t dump:\n%s\n\n", string(d))
+
+ m := make(map[interface{}]interface{})
+
+ err = yaml.Unmarshal([]byte(data), &m)
+ if err != nil {
+ log.Fatalf("error: %v", err)
+ }
+ fmt.Printf("--- m:\n%v\n\n", m)
+
+ d, err = yaml.Marshal(&m)
+ if err != nil {
+ log.Fatalf("error: %v", err)
+ }
+ fmt.Printf("--- m dump:\n%s\n\n", string(d))
+}
+```
+
+This example will generate the following output:
+
+```
+--- t:
+{Easy! {2 [3 4]}}
+
+--- t dump:
+a: Easy!
+b:
+ c: 2
+ d: [3, 4]
+
+
+--- m:
+map[a:Easy! b:map[c:2 d:[3 4]]]
+
+--- m dump:
+a: Easy!
+b:
+ c: 2
+ d:
+ - 3
+ - 4
+```
+
diff --git a/vendor/gopkg.in/yaml.v2/apic.go b/vendor/gopkg.in/yaml.v2/apic.go
new file mode 100644
index 0000000000000000000000000000000000000000..1f7e87e67275af6c2767393d53b9aab2c0b51962
--- /dev/null
+++ b/vendor/gopkg.in/yaml.v2/apic.go
@@ -0,0 +1,739 @@
+package yaml
+
+import (
+ "io"
+)
+
+func yaml_insert_token(parser *yaml_parser_t, pos int, token *yaml_token_t) {
+ //fmt.Println("yaml_insert_token", "pos:", pos, "typ:", token.typ, "head:", parser.tokens_head, "len:", len(parser.tokens))
+
+ // Check if we can move the queue at the beginning of the buffer.
+ if parser.tokens_head > 0 && len(parser.tokens) == cap(parser.tokens) {
+ if parser.tokens_head != len(parser.tokens) {
+ copy(parser.tokens, parser.tokens[parser.tokens_head:])
+ }
+ parser.tokens = parser.tokens[:len(parser.tokens)-parser.tokens_head]
+ parser.tokens_head = 0
+ }
+ parser.tokens = append(parser.tokens, *token)
+ if pos < 0 {
+ return
+ }
+ copy(parser.tokens[parser.tokens_head+pos+1:], parser.tokens[parser.tokens_head+pos:])
+ parser.tokens[parser.tokens_head+pos] = *token
+}
+
+// Create a new parser object.
+func yaml_parser_initialize(parser *yaml_parser_t) bool {
+ *parser = yaml_parser_t{
+ raw_buffer: make([]byte, 0, input_raw_buffer_size),
+ buffer: make([]byte, 0, input_buffer_size),
+ }
+ return true
+}
+
+// Destroy a parser object.
+func yaml_parser_delete(parser *yaml_parser_t) {
+ *parser = yaml_parser_t{}
+}
+
+// String read handler.
+func yaml_string_read_handler(parser *yaml_parser_t, buffer []byte) (n int, err error) {
+ if parser.input_pos == len(parser.input) {
+ return 0, io.EOF
+ }
+ n = copy(buffer, parser.input[parser.input_pos:])
+ parser.input_pos += n
+ return n, nil
+}
+
+// Reader read handler.
+func yaml_reader_read_handler(parser *yaml_parser_t, buffer []byte) (n int, err error) {
+ return parser.input_reader.Read(buffer)
+}
+
+// Set a string input.
+func yaml_parser_set_input_string(parser *yaml_parser_t, input []byte) {
+ if parser.read_handler != nil {
+ panic("must set the input source only once")
+ }
+ parser.read_handler = yaml_string_read_handler
+ parser.input = input
+ parser.input_pos = 0
+}
+
+// Set a file input.
+func yaml_parser_set_input_reader(parser *yaml_parser_t, r io.Reader) {
+ if parser.read_handler != nil {
+ panic("must set the input source only once")
+ }
+ parser.read_handler = yaml_reader_read_handler
+ parser.input_reader = r
+}
+
+// Set the source encoding.
+func yaml_parser_set_encoding(parser *yaml_parser_t, encoding yaml_encoding_t) {
+ if parser.encoding != yaml_ANY_ENCODING {
+ panic("must set the encoding only once")
+ }
+ parser.encoding = encoding
+}
+
+// Create a new emitter object.
+func yaml_emitter_initialize(emitter *yaml_emitter_t) {
+ *emitter = yaml_emitter_t{
+ buffer: make([]byte, output_buffer_size),
+ raw_buffer: make([]byte, 0, output_raw_buffer_size),
+ states: make([]yaml_emitter_state_t, 0, initial_stack_size),
+ events: make([]yaml_event_t, 0, initial_queue_size),
+ }
+}
+
+// Destroy an emitter object.
+func yaml_emitter_delete(emitter *yaml_emitter_t) {
+ *emitter = yaml_emitter_t{}
+}
+
+// String write handler.
+func yaml_string_write_handler(emitter *yaml_emitter_t, buffer []byte) error {
+ *emitter.output_buffer = append(*emitter.output_buffer, buffer...)
+ return nil
+}
+
+// yaml_writer_write_handler uses emitter.output_writer to write the
+// emitted text.
+func yaml_writer_write_handler(emitter *yaml_emitter_t, buffer []byte) error {
+ _, err := emitter.output_writer.Write(buffer)
+ return err
+}
+
+// Set a string output.
+func yaml_emitter_set_output_string(emitter *yaml_emitter_t, output_buffer *[]byte) {
+ if emitter.write_handler != nil {
+ panic("must set the output target only once")
+ }
+ emitter.write_handler = yaml_string_write_handler
+ emitter.output_buffer = output_buffer
+}
+
+// Set a file output.
+func yaml_emitter_set_output_writer(emitter *yaml_emitter_t, w io.Writer) {
+ if emitter.write_handler != nil {
+ panic("must set the output target only once")
+ }
+ emitter.write_handler = yaml_writer_write_handler
+ emitter.output_writer = w
+}
+
+// Set the output encoding.
+func yaml_emitter_set_encoding(emitter *yaml_emitter_t, encoding yaml_encoding_t) {
+ if emitter.encoding != yaml_ANY_ENCODING {
+ panic("must set the output encoding only once")
+ }
+ emitter.encoding = encoding
+}
+
+// Set the canonical output style.
+func yaml_emitter_set_canonical(emitter *yaml_emitter_t, canonical bool) {
+ emitter.canonical = canonical
+}
+
+//// Set the indentation increment.
+func yaml_emitter_set_indent(emitter *yaml_emitter_t, indent int) {
+ if indent < 2 || indent > 9 {
+ indent = 2
+ }
+ emitter.best_indent = indent
+}
+
+// Set the preferred line width.
+func yaml_emitter_set_width(emitter *yaml_emitter_t, width int) {
+ if width < 0 {
+ width = -1
+ }
+ emitter.best_width = width
+}
+
+// Set if unescaped non-ASCII characters are allowed.
+func yaml_emitter_set_unicode(emitter *yaml_emitter_t, unicode bool) {
+ emitter.unicode = unicode
+}
+
+// Set the preferred line break character.
+func yaml_emitter_set_break(emitter *yaml_emitter_t, line_break yaml_break_t) {
+ emitter.line_break = line_break
+}
+
+///*
+// * Destroy a token object.
+// */
+//
+//YAML_DECLARE(void)
+//yaml_token_delete(yaml_token_t *token)
+//{
+// assert(token); // Non-NULL token object expected.
+//
+// switch (token.type)
+// {
+// case YAML_TAG_DIRECTIVE_TOKEN:
+// yaml_free(token.data.tag_directive.handle);
+// yaml_free(token.data.tag_directive.prefix);
+// break;
+//
+// case YAML_ALIAS_TOKEN:
+// yaml_free(token.data.alias.value);
+// break;
+//
+// case YAML_ANCHOR_TOKEN:
+// yaml_free(token.data.anchor.value);
+// break;
+//
+// case YAML_TAG_TOKEN:
+// yaml_free(token.data.tag.handle);
+// yaml_free(token.data.tag.suffix);
+// break;
+//
+// case YAML_SCALAR_TOKEN:
+// yaml_free(token.data.scalar.value);
+// break;
+//
+// default:
+// break;
+// }
+//
+// memset(token, 0, sizeof(yaml_token_t));
+//}
+//
+///*
+// * Check if a string is a valid UTF-8 sequence.
+// *
+// * Check 'reader.c' for more details on UTF-8 encoding.
+// */
+//
+//static int
+//yaml_check_utf8(yaml_char_t *start, size_t length)
+//{
+// yaml_char_t *end = start+length;
+// yaml_char_t *pointer = start;
+//
+// while (pointer < end) {
+// unsigned char octet;
+// unsigned int width;
+// unsigned int value;
+// size_t k;
+//
+// octet = pointer[0];
+// width = (octet & 0x80) == 0x00 ? 1 :
+// (octet & 0xE0) == 0xC0 ? 2 :
+// (octet & 0xF0) == 0xE0 ? 3 :
+// (octet & 0xF8) == 0xF0 ? 4 : 0;
+// value = (octet & 0x80) == 0x00 ? octet & 0x7F :
+// (octet & 0xE0) == 0xC0 ? octet & 0x1F :
+// (octet & 0xF0) == 0xE0 ? octet & 0x0F :
+// (octet & 0xF8) == 0xF0 ? octet & 0x07 : 0;
+// if (!width) return 0;
+// if (pointer+width > end) return 0;
+// for (k = 1; k < width; k ++) {
+// octet = pointer[k];
+// if ((octet & 0xC0) != 0x80) return 0;
+// value = (value << 6) + (octet & 0x3F);
+// }
+// if (!((width == 1) ||
+// (width == 2 && value >= 0x80) ||
+// (width == 3 && value >= 0x800) ||
+// (width == 4 && value >= 0x10000))) return 0;
+//
+// pointer += width;
+// }
+//
+// return 1;
+//}
+//
+
+// Create STREAM-START.
+func yaml_stream_start_event_initialize(event *yaml_event_t, encoding yaml_encoding_t) {
+ *event = yaml_event_t{
+ typ: yaml_STREAM_START_EVENT,
+ encoding: encoding,
+ }
+}
+
+// Create STREAM-END.
+func yaml_stream_end_event_initialize(event *yaml_event_t) {
+ *event = yaml_event_t{
+ typ: yaml_STREAM_END_EVENT,
+ }
+}
+
+// Create DOCUMENT-START.
+func yaml_document_start_event_initialize(
+ event *yaml_event_t,
+ version_directive *yaml_version_directive_t,
+ tag_directives []yaml_tag_directive_t,
+ implicit bool,
+) {
+ *event = yaml_event_t{
+ typ: yaml_DOCUMENT_START_EVENT,
+ version_directive: version_directive,
+ tag_directives: tag_directives,
+ implicit: implicit,
+ }
+}
+
+// Create DOCUMENT-END.
+func yaml_document_end_event_initialize(event *yaml_event_t, implicit bool) {
+ *event = yaml_event_t{
+ typ: yaml_DOCUMENT_END_EVENT,
+ implicit: implicit,
+ }
+}
+
+///*
+// * Create ALIAS.
+// */
+//
+//YAML_DECLARE(int)
+//yaml_alias_event_initialize(event *yaml_event_t, anchor *yaml_char_t)
+//{
+// mark yaml_mark_t = { 0, 0, 0 }
+// anchor_copy *yaml_char_t = NULL
+//
+// assert(event) // Non-NULL event object is expected.
+// assert(anchor) // Non-NULL anchor is expected.
+//
+// if (!yaml_check_utf8(anchor, strlen((char *)anchor))) return 0
+//
+// anchor_copy = yaml_strdup(anchor)
+// if (!anchor_copy)
+// return 0
+//
+// ALIAS_EVENT_INIT(*event, anchor_copy, mark, mark)
+//
+// return 1
+//}
+
+// Create SCALAR.
+func yaml_scalar_event_initialize(event *yaml_event_t, anchor, tag, value []byte, plain_implicit, quoted_implicit bool, style yaml_scalar_style_t) bool {
+ *event = yaml_event_t{
+ typ: yaml_SCALAR_EVENT,
+ anchor: anchor,
+ tag: tag,
+ value: value,
+ implicit: plain_implicit,
+ quoted_implicit: quoted_implicit,
+ style: yaml_style_t(style),
+ }
+ return true
+}
+
+// Create SEQUENCE-START.
+func yaml_sequence_start_event_initialize(event *yaml_event_t, anchor, tag []byte, implicit bool, style yaml_sequence_style_t) bool {
+ *event = yaml_event_t{
+ typ: yaml_SEQUENCE_START_EVENT,
+ anchor: anchor,
+ tag: tag,
+ implicit: implicit,
+ style: yaml_style_t(style),
+ }
+ return true
+}
+
+// Create SEQUENCE-END.
+func yaml_sequence_end_event_initialize(event *yaml_event_t) bool {
+ *event = yaml_event_t{
+ typ: yaml_SEQUENCE_END_EVENT,
+ }
+ return true
+}
+
+// Create MAPPING-START.
+func yaml_mapping_start_event_initialize(event *yaml_event_t, anchor, tag []byte, implicit bool, style yaml_mapping_style_t) {
+ *event = yaml_event_t{
+ typ: yaml_MAPPING_START_EVENT,
+ anchor: anchor,
+ tag: tag,
+ implicit: implicit,
+ style: yaml_style_t(style),
+ }
+}
+
+// Create MAPPING-END.
+func yaml_mapping_end_event_initialize(event *yaml_event_t) {
+ *event = yaml_event_t{
+ typ: yaml_MAPPING_END_EVENT,
+ }
+}
+
+// Destroy an event object.
+func yaml_event_delete(event *yaml_event_t) {
+ *event = yaml_event_t{}
+}
+
+///*
+// * Create a document object.
+// */
+//
+//YAML_DECLARE(int)
+//yaml_document_initialize(document *yaml_document_t,
+// version_directive *yaml_version_directive_t,
+// tag_directives_start *yaml_tag_directive_t,
+// tag_directives_end *yaml_tag_directive_t,
+// start_implicit int, end_implicit int)
+//{
+// struct {
+// error yaml_error_type_t
+// } context
+// struct {
+// start *yaml_node_t
+// end *yaml_node_t
+// top *yaml_node_t
+// } nodes = { NULL, NULL, NULL }
+// version_directive_copy *yaml_version_directive_t = NULL
+// struct {
+// start *yaml_tag_directive_t
+// end *yaml_tag_directive_t
+// top *yaml_tag_directive_t
+// } tag_directives_copy = { NULL, NULL, NULL }
+// value yaml_tag_directive_t = { NULL, NULL }
+// mark yaml_mark_t = { 0, 0, 0 }
+//
+// assert(document) // Non-NULL document object is expected.
+// assert((tag_directives_start && tag_directives_end) ||
+// (tag_directives_start == tag_directives_end))
+// // Valid tag directives are expected.
+//
+// if (!STACK_INIT(&context, nodes, INITIAL_STACK_SIZE)) goto error
+//
+// if (version_directive) {
+// version_directive_copy = yaml_malloc(sizeof(yaml_version_directive_t))
+// if (!version_directive_copy) goto error
+// version_directive_copy.major = version_directive.major
+// version_directive_copy.minor = version_directive.minor
+// }
+//
+// if (tag_directives_start != tag_directives_end) {
+// tag_directive *yaml_tag_directive_t
+// if (!STACK_INIT(&context, tag_directives_copy, INITIAL_STACK_SIZE))
+// goto error
+// for (tag_directive = tag_directives_start
+// tag_directive != tag_directives_end; tag_directive ++) {
+// assert(tag_directive.handle)
+// assert(tag_directive.prefix)
+// if (!yaml_check_utf8(tag_directive.handle,
+// strlen((char *)tag_directive.handle)))
+// goto error
+// if (!yaml_check_utf8(tag_directive.prefix,
+// strlen((char *)tag_directive.prefix)))
+// goto error
+// value.handle = yaml_strdup(tag_directive.handle)
+// value.prefix = yaml_strdup(tag_directive.prefix)
+// if (!value.handle || !value.prefix) goto error
+// if (!PUSH(&context, tag_directives_copy, value))
+// goto error
+// value.handle = NULL
+// value.prefix = NULL
+// }
+// }
+//
+// DOCUMENT_INIT(*document, nodes.start, nodes.end, version_directive_copy,
+// tag_directives_copy.start, tag_directives_copy.top,
+// start_implicit, end_implicit, mark, mark)
+//
+// return 1
+//
+//error:
+// STACK_DEL(&context, nodes)
+// yaml_free(version_directive_copy)
+// while (!STACK_EMPTY(&context, tag_directives_copy)) {
+// value yaml_tag_directive_t = POP(&context, tag_directives_copy)
+// yaml_free(value.handle)
+// yaml_free(value.prefix)
+// }
+// STACK_DEL(&context, tag_directives_copy)
+// yaml_free(value.handle)
+// yaml_free(value.prefix)
+//
+// return 0
+//}
+//
+///*
+// * Destroy a document object.
+// */
+//
+//YAML_DECLARE(void)
+//yaml_document_delete(document *yaml_document_t)
+//{
+// struct {
+// error yaml_error_type_t
+// } context
+// tag_directive *yaml_tag_directive_t
+//
+// context.error = YAML_NO_ERROR // Eliminate a compiler warning.
+//
+// assert(document) // Non-NULL document object is expected.
+//
+// while (!STACK_EMPTY(&context, document.nodes)) {
+// node yaml_node_t = POP(&context, document.nodes)
+// yaml_free(node.tag)
+// switch (node.type) {
+// case YAML_SCALAR_NODE:
+// yaml_free(node.data.scalar.value)
+// break
+// case YAML_SEQUENCE_NODE:
+// STACK_DEL(&context, node.data.sequence.items)
+// break
+// case YAML_MAPPING_NODE:
+// STACK_DEL(&context, node.data.mapping.pairs)
+// break
+// default:
+// assert(0) // Should not happen.
+// }
+// }
+// STACK_DEL(&context, document.nodes)
+//
+// yaml_free(document.version_directive)
+// for (tag_directive = document.tag_directives.start
+// tag_directive != document.tag_directives.end
+// tag_directive++) {
+// yaml_free(tag_directive.handle)
+// yaml_free(tag_directive.prefix)
+// }
+// yaml_free(document.tag_directives.start)
+//
+// memset(document, 0, sizeof(yaml_document_t))
+//}
+//
+///**
+// * Get a document node.
+// */
+//
+//YAML_DECLARE(yaml_node_t *)
+//yaml_document_get_node(document *yaml_document_t, index int)
+//{
+// assert(document) // Non-NULL document object is expected.
+//
+// if (index > 0 && document.nodes.start + index <= document.nodes.top) {
+// return document.nodes.start + index - 1
+// }
+// return NULL
+//}
+//
+///**
+// * Get the root object.
+// */
+//
+//YAML_DECLARE(yaml_node_t *)
+//yaml_document_get_root_node(document *yaml_document_t)
+//{
+// assert(document) // Non-NULL document object is expected.
+//
+// if (document.nodes.top != document.nodes.start) {
+// return document.nodes.start
+// }
+// return NULL
+//}
+//
+///*
+// * Add a scalar node to a document.
+// */
+//
+//YAML_DECLARE(int)
+//yaml_document_add_scalar(document *yaml_document_t,
+// tag *yaml_char_t, value *yaml_char_t, length int,
+// style yaml_scalar_style_t)
+//{
+// struct {
+// error yaml_error_type_t
+// } context
+// mark yaml_mark_t = { 0, 0, 0 }
+// tag_copy *yaml_char_t = NULL
+// value_copy *yaml_char_t = NULL
+// node yaml_node_t
+//
+// assert(document) // Non-NULL document object is expected.
+// assert(value) // Non-NULL value is expected.
+//
+// if (!tag) {
+// tag = (yaml_char_t *)YAML_DEFAULT_SCALAR_TAG
+// }
+//
+// if (!yaml_check_utf8(tag, strlen((char *)tag))) goto error
+// tag_copy = yaml_strdup(tag)
+// if (!tag_copy) goto error
+//
+// if (length < 0) {
+// length = strlen((char *)value)
+// }
+//
+// if (!yaml_check_utf8(value, length)) goto error
+// value_copy = yaml_malloc(length+1)
+// if (!value_copy) goto error
+// memcpy(value_copy, value, length)
+// value_copy[length] = '\0'
+//
+// SCALAR_NODE_INIT(node, tag_copy, value_copy, length, style, mark, mark)
+// if (!PUSH(&context, document.nodes, node)) goto error
+//
+// return document.nodes.top - document.nodes.start
+//
+//error:
+// yaml_free(tag_copy)
+// yaml_free(value_copy)
+//
+// return 0
+//}
+//
+///*
+// * Add a sequence node to a document.
+// */
+//
+//YAML_DECLARE(int)
+//yaml_document_add_sequence(document *yaml_document_t,
+// tag *yaml_char_t, style yaml_sequence_style_t)
+//{
+// struct {
+// error yaml_error_type_t
+// } context
+// mark yaml_mark_t = { 0, 0, 0 }
+// tag_copy *yaml_char_t = NULL
+// struct {
+// start *yaml_node_item_t
+// end *yaml_node_item_t
+// top *yaml_node_item_t
+// } items = { NULL, NULL, NULL }
+// node yaml_node_t
+//
+// assert(document) // Non-NULL document object is expected.
+//
+// if (!tag) {
+// tag = (yaml_char_t *)YAML_DEFAULT_SEQUENCE_TAG
+// }
+//
+// if (!yaml_check_utf8(tag, strlen((char *)tag))) goto error
+// tag_copy = yaml_strdup(tag)
+// if (!tag_copy) goto error
+//
+// if (!STACK_INIT(&context, items, INITIAL_STACK_SIZE)) goto error
+//
+// SEQUENCE_NODE_INIT(node, tag_copy, items.start, items.end,
+// style, mark, mark)
+// if (!PUSH(&context, document.nodes, node)) goto error
+//
+// return document.nodes.top - document.nodes.start
+//
+//error:
+// STACK_DEL(&context, items)
+// yaml_free(tag_copy)
+//
+// return 0
+//}
+//
+///*
+// * Add a mapping node to a document.
+// */
+//
+//YAML_DECLARE(int)
+//yaml_document_add_mapping(document *yaml_document_t,
+// tag *yaml_char_t, style yaml_mapping_style_t)
+//{
+// struct {
+// error yaml_error_type_t
+// } context
+// mark yaml_mark_t = { 0, 0, 0 }
+// tag_copy *yaml_char_t = NULL
+// struct {
+// start *yaml_node_pair_t
+// end *yaml_node_pair_t
+// top *yaml_node_pair_t
+// } pairs = { NULL, NULL, NULL }
+// node yaml_node_t
+//
+// assert(document) // Non-NULL document object is expected.
+//
+// if (!tag) {
+// tag = (yaml_char_t *)YAML_DEFAULT_MAPPING_TAG
+// }
+//
+// if (!yaml_check_utf8(tag, strlen((char *)tag))) goto error
+// tag_copy = yaml_strdup(tag)
+// if (!tag_copy) goto error
+//
+// if (!STACK_INIT(&context, pairs, INITIAL_STACK_SIZE)) goto error
+//
+// MAPPING_NODE_INIT(node, tag_copy, pairs.start, pairs.end,
+// style, mark, mark)
+// if (!PUSH(&context, document.nodes, node)) goto error
+//
+// return document.nodes.top - document.nodes.start
+//
+//error:
+// STACK_DEL(&context, pairs)
+// yaml_free(tag_copy)
+//
+// return 0
+//}
+//
+///*
+// * Append an item to a sequence node.
+// */
+//
+//YAML_DECLARE(int)
+//yaml_document_append_sequence_item(document *yaml_document_t,
+// sequence int, item int)
+//{
+// struct {
+// error yaml_error_type_t
+// } context
+//
+// assert(document) // Non-NULL document is required.
+// assert(sequence > 0
+// && document.nodes.start + sequence <= document.nodes.top)
+// // Valid sequence id is required.
+// assert(document.nodes.start[sequence-1].type == YAML_SEQUENCE_NODE)
+// // A sequence node is required.
+// assert(item > 0 && document.nodes.start + item <= document.nodes.top)
+// // Valid item id is required.
+//
+// if (!PUSH(&context,
+// document.nodes.start[sequence-1].data.sequence.items, item))
+// return 0
+//
+// return 1
+//}
+//
+///*
+// * Append a pair of a key and a value to a mapping node.
+// */
+//
+//YAML_DECLARE(int)
+//yaml_document_append_mapping_pair(document *yaml_document_t,
+// mapping int, key int, value int)
+//{
+// struct {
+// error yaml_error_type_t
+// } context
+//
+// pair yaml_node_pair_t
+//
+// assert(document) // Non-NULL document is required.
+// assert(mapping > 0
+// && document.nodes.start + mapping <= document.nodes.top)
+// // Valid mapping id is required.
+// assert(document.nodes.start[mapping-1].type == YAML_MAPPING_NODE)
+// // A mapping node is required.
+// assert(key > 0 && document.nodes.start + key <= document.nodes.top)
+// // Valid key id is required.
+// assert(value > 0 && document.nodes.start + value <= document.nodes.top)
+// // Valid value id is required.
+//
+// pair.key = key
+// pair.value = value
+//
+// if (!PUSH(&context,
+// document.nodes.start[mapping-1].data.mapping.pairs, pair))
+// return 0
+//
+// return 1
+//}
+//
+//
diff --git a/vendor/gopkg.in/yaml.v2/decode.go b/vendor/gopkg.in/yaml.v2/decode.go
new file mode 100644
index 0000000000000000000000000000000000000000..e4e56e28e0e807e84ff6828a669c7b55a3c8d06d
--- /dev/null
+++ b/vendor/gopkg.in/yaml.v2/decode.go
@@ -0,0 +1,775 @@
+package yaml
+
+import (
+ "encoding"
+ "encoding/base64"
+ "fmt"
+ "io"
+ "math"
+ "reflect"
+ "strconv"
+ "time"
+)
+
+const (
+ documentNode = 1 << iota
+ mappingNode
+ sequenceNode
+ scalarNode
+ aliasNode
+)
+
+type node struct {
+ kind int
+ line, column int
+ tag string
+ // For an alias node, alias holds the resolved alias.
+ alias *node
+ value string
+ implicit bool
+ children []*node
+ anchors map[string]*node
+}
+
+// ----------------------------------------------------------------------------
+// Parser, produces a node tree out of a libyaml event stream.
+
+type parser struct {
+ parser yaml_parser_t
+ event yaml_event_t
+ doc *node
+ doneInit bool
+}
+
+func newParser(b []byte) *parser {
+ p := parser{}
+ if !yaml_parser_initialize(&p.parser) {
+ panic("failed to initialize YAML emitter")
+ }
+ if len(b) == 0 {
+ b = []byte{'\n'}
+ }
+ yaml_parser_set_input_string(&p.parser, b)
+ return &p
+}
+
+func newParserFromReader(r io.Reader) *parser {
+ p := parser{}
+ if !yaml_parser_initialize(&p.parser) {
+ panic("failed to initialize YAML emitter")
+ }
+ yaml_parser_set_input_reader(&p.parser, r)
+ return &p
+}
+
+func (p *parser) init() {
+ if p.doneInit {
+ return
+ }
+ p.expect(yaml_STREAM_START_EVENT)
+ p.doneInit = true
+}
+
+func (p *parser) destroy() {
+ if p.event.typ != yaml_NO_EVENT {
+ yaml_event_delete(&p.event)
+ }
+ yaml_parser_delete(&p.parser)
+}
+
+// expect consumes an event from the event stream and
+// checks that it's of the expected type.
+func (p *parser) expect(e yaml_event_type_t) {
+ if p.event.typ == yaml_NO_EVENT {
+ if !yaml_parser_parse(&p.parser, &p.event) {
+ p.fail()
+ }
+ }
+ if p.event.typ == yaml_STREAM_END_EVENT {
+ failf("attempted to go past the end of stream; corrupted value?")
+ }
+ if p.event.typ != e {
+ p.parser.problem = fmt.Sprintf("expected %s event but got %s", e, p.event.typ)
+ p.fail()
+ }
+ yaml_event_delete(&p.event)
+ p.event.typ = yaml_NO_EVENT
+}
+
+// peek peeks at the next event in the event stream,
+// puts the results into p.event and returns the event type.
+func (p *parser) peek() yaml_event_type_t {
+ if p.event.typ != yaml_NO_EVENT {
+ return p.event.typ
+ }
+ if !yaml_parser_parse(&p.parser, &p.event) {
+ p.fail()
+ }
+ return p.event.typ
+}
+
+func (p *parser) fail() {
+ var where string
+ var line int
+ if p.parser.problem_mark.line != 0 {
+ line = p.parser.problem_mark.line
+ // Scanner errors don't iterate line before returning error
+ if p.parser.error == yaml_SCANNER_ERROR {
+ line++
+ }
+ } else if p.parser.context_mark.line != 0 {
+ line = p.parser.context_mark.line
+ }
+ if line != 0 {
+ where = "line " + strconv.Itoa(line) + ": "
+ }
+ var msg string
+ if len(p.parser.problem) > 0 {
+ msg = p.parser.problem
+ } else {
+ msg = "unknown problem parsing YAML content"
+ }
+ failf("%s%s", where, msg)
+}
+
+func (p *parser) anchor(n *node, anchor []byte) {
+ if anchor != nil {
+ p.doc.anchors[string(anchor)] = n
+ }
+}
+
+func (p *parser) parse() *node {
+ p.init()
+ switch p.peek() {
+ case yaml_SCALAR_EVENT:
+ return p.scalar()
+ case yaml_ALIAS_EVENT:
+ return p.alias()
+ case yaml_MAPPING_START_EVENT:
+ return p.mapping()
+ case yaml_SEQUENCE_START_EVENT:
+ return p.sequence()
+ case yaml_DOCUMENT_START_EVENT:
+ return p.document()
+ case yaml_STREAM_END_EVENT:
+ // Happens when attempting to decode an empty buffer.
+ return nil
+ default:
+ panic("attempted to parse unknown event: " + p.event.typ.String())
+ }
+}
+
+func (p *parser) node(kind int) *node {
+ return &node{
+ kind: kind,
+ line: p.event.start_mark.line,
+ column: p.event.start_mark.column,
+ }
+}
+
+func (p *parser) document() *node {
+ n := p.node(documentNode)
+ n.anchors = make(map[string]*node)
+ p.doc = n
+ p.expect(yaml_DOCUMENT_START_EVENT)
+ n.children = append(n.children, p.parse())
+ p.expect(yaml_DOCUMENT_END_EVENT)
+ return n
+}
+
+func (p *parser) alias() *node {
+ n := p.node(aliasNode)
+ n.value = string(p.event.anchor)
+ n.alias = p.doc.anchors[n.value]
+ if n.alias == nil {
+ failf("unknown anchor '%s' referenced", n.value)
+ }
+ p.expect(yaml_ALIAS_EVENT)
+ return n
+}
+
+func (p *parser) scalar() *node {
+ n := p.node(scalarNode)
+ n.value = string(p.event.value)
+ n.tag = string(p.event.tag)
+ n.implicit = p.event.implicit
+ p.anchor(n, p.event.anchor)
+ p.expect(yaml_SCALAR_EVENT)
+ return n
+}
+
+func (p *parser) sequence() *node {
+ n := p.node(sequenceNode)
+ p.anchor(n, p.event.anchor)
+ p.expect(yaml_SEQUENCE_START_EVENT)
+ for p.peek() != yaml_SEQUENCE_END_EVENT {
+ n.children = append(n.children, p.parse())
+ }
+ p.expect(yaml_SEQUENCE_END_EVENT)
+ return n
+}
+
+func (p *parser) mapping() *node {
+ n := p.node(mappingNode)
+ p.anchor(n, p.event.anchor)
+ p.expect(yaml_MAPPING_START_EVENT)
+ for p.peek() != yaml_MAPPING_END_EVENT {
+ n.children = append(n.children, p.parse(), p.parse())
+ }
+ p.expect(yaml_MAPPING_END_EVENT)
+ return n
+}
+
+// ----------------------------------------------------------------------------
+// Decoder, unmarshals a node into a provided value.
+
+type decoder struct {
+ doc *node
+ aliases map[*node]bool
+ mapType reflect.Type
+ terrors []string
+ strict bool
+}
+
+var (
+ mapItemType = reflect.TypeOf(MapItem{})
+ durationType = reflect.TypeOf(time.Duration(0))
+ defaultMapType = reflect.TypeOf(map[interface{}]interface{}{})
+ ifaceType = defaultMapType.Elem()
+ timeType = reflect.TypeOf(time.Time{})
+ ptrTimeType = reflect.TypeOf(&time.Time{})
+)
+
+func newDecoder(strict bool) *decoder {
+ d := &decoder{mapType: defaultMapType, strict: strict}
+ d.aliases = make(map[*node]bool)
+ return d
+}
+
+func (d *decoder) terror(n *node, tag string, out reflect.Value) {
+ if n.tag != "" {
+ tag = n.tag
+ }
+ value := n.value
+ if tag != yaml_SEQ_TAG && tag != yaml_MAP_TAG {
+ if len(value) > 10 {
+ value = " `" + value[:7] + "...`"
+ } else {
+ value = " `" + value + "`"
+ }
+ }
+ d.terrors = append(d.terrors, fmt.Sprintf("line %d: cannot unmarshal %s%s into %s", n.line+1, shortTag(tag), value, out.Type()))
+}
+
+func (d *decoder) callUnmarshaler(n *node, u Unmarshaler) (good bool) {
+ terrlen := len(d.terrors)
+ err := u.UnmarshalYAML(func(v interface{}) (err error) {
+ defer handleErr(&err)
+ d.unmarshal(n, reflect.ValueOf(v))
+ if len(d.terrors) > terrlen {
+ issues := d.terrors[terrlen:]
+ d.terrors = d.terrors[:terrlen]
+ return &TypeError{issues}
+ }
+ return nil
+ })
+ if e, ok := err.(*TypeError); ok {
+ d.terrors = append(d.terrors, e.Errors...)
+ return false
+ }
+ if err != nil {
+ fail(err)
+ }
+ return true
+}
+
+// d.prepare initializes and dereferences pointers and calls UnmarshalYAML
+// if a value is found to implement it.
+// It returns the initialized and dereferenced out value, whether
+// unmarshalling was already done by UnmarshalYAML, and if so whether
+// its types unmarshalled appropriately.
+//
+// If n holds a null value, prepare returns before doing anything.
+func (d *decoder) prepare(n *node, out reflect.Value) (newout reflect.Value, unmarshaled, good bool) {
+ if n.tag == yaml_NULL_TAG || n.kind == scalarNode && n.tag == "" && (n.value == "null" || n.value == "~" || n.value == "" && n.implicit) {
+ return out, false, false
+ }
+ again := true
+ for again {
+ again = false
+ if out.Kind() == reflect.Ptr {
+ if out.IsNil() {
+ out.Set(reflect.New(out.Type().Elem()))
+ }
+ out = out.Elem()
+ again = true
+ }
+ if out.CanAddr() {
+ if u, ok := out.Addr().Interface().(Unmarshaler); ok {
+ good = d.callUnmarshaler(n, u)
+ return out, true, good
+ }
+ }
+ }
+ return out, false, false
+}
+
+func (d *decoder) unmarshal(n *node, out reflect.Value) (good bool) {
+ switch n.kind {
+ case documentNode:
+ return d.document(n, out)
+ case aliasNode:
+ return d.alias(n, out)
+ }
+ out, unmarshaled, good := d.prepare(n, out)
+ if unmarshaled {
+ return good
+ }
+ switch n.kind {
+ case scalarNode:
+ good = d.scalar(n, out)
+ case mappingNode:
+ good = d.mapping(n, out)
+ case sequenceNode:
+ good = d.sequence(n, out)
+ default:
+ panic("internal error: unknown node kind: " + strconv.Itoa(n.kind))
+ }
+ return good
+}
+
+func (d *decoder) document(n *node, out reflect.Value) (good bool) {
+ if len(n.children) == 1 {
+ d.doc = n
+ d.unmarshal(n.children[0], out)
+ return true
+ }
+ return false
+}
+
+func (d *decoder) alias(n *node, out reflect.Value) (good bool) {
+ if d.aliases[n] {
+ // TODO this could actually be allowed in some circumstances.
+ failf("anchor '%s' value contains itself", n.value)
+ }
+ d.aliases[n] = true
+ good = d.unmarshal(n.alias, out)
+ delete(d.aliases, n)
+ return good
+}
+
+var zeroValue reflect.Value
+
+func resetMap(out reflect.Value) {
+ for _, k := range out.MapKeys() {
+ out.SetMapIndex(k, zeroValue)
+ }
+}
+
+func (d *decoder) scalar(n *node, out reflect.Value) bool {
+ var tag string
+ var resolved interface{}
+ if n.tag == "" && !n.implicit {
+ tag = yaml_STR_TAG
+ resolved = n.value
+ } else {
+ tag, resolved = resolve(n.tag, n.value)
+ if tag == yaml_BINARY_TAG {
+ data, err := base64.StdEncoding.DecodeString(resolved.(string))
+ if err != nil {
+ failf("!!binary value contains invalid base64 data")
+ }
+ resolved = string(data)
+ }
+ }
+ if resolved == nil {
+ if out.Kind() == reflect.Map && !out.CanAddr() {
+ resetMap(out)
+ } else {
+ out.Set(reflect.Zero(out.Type()))
+ }
+ return true
+ }
+ if resolvedv := reflect.ValueOf(resolved); out.Type() == resolvedv.Type() {
+ // We've resolved to exactly the type we want, so use that.
+ out.Set(resolvedv)
+ return true
+ }
+ // Perhaps we can use the value as a TextUnmarshaler to
+ // set its value.
+ if out.CanAddr() {
+ u, ok := out.Addr().Interface().(encoding.TextUnmarshaler)
+ if ok {
+ var text []byte
+ if tag == yaml_BINARY_TAG {
+ text = []byte(resolved.(string))
+ } else {
+ // We let any value be unmarshaled into TextUnmarshaler.
+ // That might be more lax than we'd like, but the
+ // TextUnmarshaler itself should bowl out any dubious values.
+ text = []byte(n.value)
+ }
+ err := u.UnmarshalText(text)
+ if err != nil {
+ fail(err)
+ }
+ return true
+ }
+ }
+ switch out.Kind() {
+ case reflect.String:
+ if tag == yaml_BINARY_TAG {
+ out.SetString(resolved.(string))
+ return true
+ }
+ if resolved != nil {
+ out.SetString(n.value)
+ return true
+ }
+ case reflect.Interface:
+ if resolved == nil {
+ out.Set(reflect.Zero(out.Type()))
+ } else if tag == yaml_TIMESTAMP_TAG {
+ // It looks like a timestamp but for backward compatibility
+ // reasons we set it as a string, so that code that unmarshals
+ // timestamp-like values into interface{} will continue to
+ // see a string and not a time.Time.
+ // TODO(v3) Drop this.
+ out.Set(reflect.ValueOf(n.value))
+ } else {
+ out.Set(reflect.ValueOf(resolved))
+ }
+ return true
+ case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+ switch resolved := resolved.(type) {
+ case int:
+ if !out.OverflowInt(int64(resolved)) {
+ out.SetInt(int64(resolved))
+ return true
+ }
+ case int64:
+ if !out.OverflowInt(resolved) {
+ out.SetInt(resolved)
+ return true
+ }
+ case uint64:
+ if resolved <= math.MaxInt64 && !out.OverflowInt(int64(resolved)) {
+ out.SetInt(int64(resolved))
+ return true
+ }
+ case float64:
+ if resolved <= math.MaxInt64 && !out.OverflowInt(int64(resolved)) {
+ out.SetInt(int64(resolved))
+ return true
+ }
+ case string:
+ if out.Type() == durationType {
+ d, err := time.ParseDuration(resolved)
+ if err == nil {
+ out.SetInt(int64(d))
+ return true
+ }
+ }
+ }
+ case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
+ switch resolved := resolved.(type) {
+ case int:
+ if resolved >= 0 && !out.OverflowUint(uint64(resolved)) {
+ out.SetUint(uint64(resolved))
+ return true
+ }
+ case int64:
+ if resolved >= 0 && !out.OverflowUint(uint64(resolved)) {
+ out.SetUint(uint64(resolved))
+ return true
+ }
+ case uint64:
+ if !out.OverflowUint(uint64(resolved)) {
+ out.SetUint(uint64(resolved))
+ return true
+ }
+ case float64:
+ if resolved <= math.MaxUint64 && !out.OverflowUint(uint64(resolved)) {
+ out.SetUint(uint64(resolved))
+ return true
+ }
+ }
+ case reflect.Bool:
+ switch resolved := resolved.(type) {
+ case bool:
+ out.SetBool(resolved)
+ return true
+ }
+ case reflect.Float32, reflect.Float64:
+ switch resolved := resolved.(type) {
+ case int:
+ out.SetFloat(float64(resolved))
+ return true
+ case int64:
+ out.SetFloat(float64(resolved))
+ return true
+ case uint64:
+ out.SetFloat(float64(resolved))
+ return true
+ case float64:
+ out.SetFloat(resolved)
+ return true
+ }
+ case reflect.Struct:
+ if resolvedv := reflect.ValueOf(resolved); out.Type() == resolvedv.Type() {
+ out.Set(resolvedv)
+ return true
+ }
+ case reflect.Ptr:
+ if out.Type().Elem() == reflect.TypeOf(resolved) {
+ // TODO DOes this make sense? When is out a Ptr except when decoding a nil value?
+ elem := reflect.New(out.Type().Elem())
+ elem.Elem().Set(reflect.ValueOf(resolved))
+ out.Set(elem)
+ return true
+ }
+ }
+ d.terror(n, tag, out)
+ return false
+}
+
+func settableValueOf(i interface{}) reflect.Value {
+ v := reflect.ValueOf(i)
+ sv := reflect.New(v.Type()).Elem()
+ sv.Set(v)
+ return sv
+}
+
+func (d *decoder) sequence(n *node, out reflect.Value) (good bool) {
+ l := len(n.children)
+
+ var iface reflect.Value
+ switch out.Kind() {
+ case reflect.Slice:
+ out.Set(reflect.MakeSlice(out.Type(), l, l))
+ case reflect.Array:
+ if l != out.Len() {
+ failf("invalid array: want %d elements but got %d", out.Len(), l)
+ }
+ case reflect.Interface:
+ // No type hints. Will have to use a generic sequence.
+ iface = out
+ out = settableValueOf(make([]interface{}, l))
+ default:
+ d.terror(n, yaml_SEQ_TAG, out)
+ return false
+ }
+ et := out.Type().Elem()
+
+ j := 0
+ for i := 0; i < l; i++ {
+ e := reflect.New(et).Elem()
+ if ok := d.unmarshal(n.children[i], e); ok {
+ out.Index(j).Set(e)
+ j++
+ }
+ }
+ if out.Kind() != reflect.Array {
+ out.Set(out.Slice(0, j))
+ }
+ if iface.IsValid() {
+ iface.Set(out)
+ }
+ return true
+}
+
+func (d *decoder) mapping(n *node, out reflect.Value) (good bool) {
+ switch out.Kind() {
+ case reflect.Struct:
+ return d.mappingStruct(n, out)
+ case reflect.Slice:
+ return d.mappingSlice(n, out)
+ case reflect.Map:
+ // okay
+ case reflect.Interface:
+ if d.mapType.Kind() == reflect.Map {
+ iface := out
+ out = reflect.MakeMap(d.mapType)
+ iface.Set(out)
+ } else {
+ slicev := reflect.New(d.mapType).Elem()
+ if !d.mappingSlice(n, slicev) {
+ return false
+ }
+ out.Set(slicev)
+ return true
+ }
+ default:
+ d.terror(n, yaml_MAP_TAG, out)
+ return false
+ }
+ outt := out.Type()
+ kt := outt.Key()
+ et := outt.Elem()
+
+ mapType := d.mapType
+ if outt.Key() == ifaceType && outt.Elem() == ifaceType {
+ d.mapType = outt
+ }
+
+ if out.IsNil() {
+ out.Set(reflect.MakeMap(outt))
+ }
+ l := len(n.children)
+ for i := 0; i < l; i += 2 {
+ if isMerge(n.children[i]) {
+ d.merge(n.children[i+1], out)
+ continue
+ }
+ k := reflect.New(kt).Elem()
+ if d.unmarshal(n.children[i], k) {
+ kkind := k.Kind()
+ if kkind == reflect.Interface {
+ kkind = k.Elem().Kind()
+ }
+ if kkind == reflect.Map || kkind == reflect.Slice {
+ failf("invalid map key: %#v", k.Interface())
+ }
+ e := reflect.New(et).Elem()
+ if d.unmarshal(n.children[i+1], e) {
+ d.setMapIndex(n.children[i+1], out, k, e)
+ }
+ }
+ }
+ d.mapType = mapType
+ return true
+}
+
+func (d *decoder) setMapIndex(n *node, out, k, v reflect.Value) {
+ if d.strict && out.MapIndex(k) != zeroValue {
+ d.terrors = append(d.terrors, fmt.Sprintf("line %d: key %#v already set in map", n.line+1, k.Interface()))
+ return
+ }
+ out.SetMapIndex(k, v)
+}
+
+func (d *decoder) mappingSlice(n *node, out reflect.Value) (good bool) {
+ outt := out.Type()
+ if outt.Elem() != mapItemType {
+ d.terror(n, yaml_MAP_TAG, out)
+ return false
+ }
+
+ mapType := d.mapType
+ d.mapType = outt
+
+ var slice []MapItem
+ var l = len(n.children)
+ for i := 0; i < l; i += 2 {
+ if isMerge(n.children[i]) {
+ d.merge(n.children[i+1], out)
+ continue
+ }
+ item := MapItem{}
+ k := reflect.ValueOf(&item.Key).Elem()
+ if d.unmarshal(n.children[i], k) {
+ v := reflect.ValueOf(&item.Value).Elem()
+ if d.unmarshal(n.children[i+1], v) {
+ slice = append(slice, item)
+ }
+ }
+ }
+ out.Set(reflect.ValueOf(slice))
+ d.mapType = mapType
+ return true
+}
+
+func (d *decoder) mappingStruct(n *node, out reflect.Value) (good bool) {
+ sinfo, err := getStructInfo(out.Type())
+ if err != nil {
+ panic(err)
+ }
+ name := settableValueOf("")
+ l := len(n.children)
+
+ var inlineMap reflect.Value
+ var elemType reflect.Type
+ if sinfo.InlineMap != -1 {
+ inlineMap = out.Field(sinfo.InlineMap)
+ inlineMap.Set(reflect.New(inlineMap.Type()).Elem())
+ elemType = inlineMap.Type().Elem()
+ }
+
+ var doneFields []bool
+ if d.strict {
+ doneFields = make([]bool, len(sinfo.FieldsList))
+ }
+ for i := 0; i < l; i += 2 {
+ ni := n.children[i]
+ if isMerge(ni) {
+ d.merge(n.children[i+1], out)
+ continue
+ }
+ if !d.unmarshal(ni, name) {
+ continue
+ }
+ if info, ok := sinfo.FieldsMap[name.String()]; ok {
+ if d.strict {
+ if doneFields[info.Id] {
+ d.terrors = append(d.terrors, fmt.Sprintf("line %d: field %s already set in type %s", ni.line+1, name.String(), out.Type()))
+ continue
+ }
+ doneFields[info.Id] = true
+ }
+ var field reflect.Value
+ if info.Inline == nil {
+ field = out.Field(info.Num)
+ } else {
+ field = out.FieldByIndex(info.Inline)
+ }
+ d.unmarshal(n.children[i+1], field)
+ } else if sinfo.InlineMap != -1 {
+ if inlineMap.IsNil() {
+ inlineMap.Set(reflect.MakeMap(inlineMap.Type()))
+ }
+ value := reflect.New(elemType).Elem()
+ d.unmarshal(n.children[i+1], value)
+ d.setMapIndex(n.children[i+1], inlineMap, name, value)
+ } else if d.strict {
+ d.terrors = append(d.terrors, fmt.Sprintf("line %d: field %s not found in type %s", ni.line+1, name.String(), out.Type()))
+ }
+ }
+ return true
+}
+
+func failWantMap() {
+ failf("map merge requires map or sequence of maps as the value")
+}
+
+func (d *decoder) merge(n *node, out reflect.Value) {
+ switch n.kind {
+ case mappingNode:
+ d.unmarshal(n, out)
+ case aliasNode:
+ an, ok := d.doc.anchors[n.value]
+ if ok && an.kind != mappingNode {
+ failWantMap()
+ }
+ d.unmarshal(n, out)
+ case sequenceNode:
+ // Step backwards as earlier nodes take precedence.
+ for i := len(n.children) - 1; i >= 0; i-- {
+ ni := n.children[i]
+ if ni.kind == aliasNode {
+ an, ok := d.doc.anchors[ni.value]
+ if ok && an.kind != mappingNode {
+ failWantMap()
+ }
+ } else if ni.kind != mappingNode {
+ failWantMap()
+ }
+ d.unmarshal(ni, out)
+ }
+ default:
+ failWantMap()
+ }
+}
+
+func isMerge(n *node) bool {
+ return n.kind == scalarNode && n.value == "<<" && (n.implicit == true || n.tag == yaml_MERGE_TAG)
+}
diff --git a/vendor/gopkg.in/yaml.v2/emitterc.go b/vendor/gopkg.in/yaml.v2/emitterc.go
new file mode 100644
index 0000000000000000000000000000000000000000..a1c2cc52627f0bd4be81f8d88c9e4074f33b7d45
--- /dev/null
+++ b/vendor/gopkg.in/yaml.v2/emitterc.go
@@ -0,0 +1,1685 @@
+package yaml
+
+import (
+ "bytes"
+ "fmt"
+)
+
+// Flush the buffer if needed.
+func flush(emitter *yaml_emitter_t) bool {
+ if emitter.buffer_pos+5 >= len(emitter.buffer) {
+ return yaml_emitter_flush(emitter)
+ }
+ return true
+}
+
+// Put a character to the output buffer.
+func put(emitter *yaml_emitter_t, value byte) bool {
+ if emitter.buffer_pos+5 >= len(emitter.buffer) && !yaml_emitter_flush(emitter) {
+ return false
+ }
+ emitter.buffer[emitter.buffer_pos] = value
+ emitter.buffer_pos++
+ emitter.column++
+ return true
+}
+
+// Put a line break to the output buffer.
+func put_break(emitter *yaml_emitter_t) bool {
+ if emitter.buffer_pos+5 >= len(emitter.buffer) && !yaml_emitter_flush(emitter) {
+ return false
+ }
+ switch emitter.line_break {
+ case yaml_CR_BREAK:
+ emitter.buffer[emitter.buffer_pos] = '\r'
+ emitter.buffer_pos += 1
+ case yaml_LN_BREAK:
+ emitter.buffer[emitter.buffer_pos] = '\n'
+ emitter.buffer_pos += 1
+ case yaml_CRLN_BREAK:
+ emitter.buffer[emitter.buffer_pos+0] = '\r'
+ emitter.buffer[emitter.buffer_pos+1] = '\n'
+ emitter.buffer_pos += 2
+ default:
+ panic("unknown line break setting")
+ }
+ emitter.column = 0
+ emitter.line++
+ return true
+}
+
+// Copy a character from a string into buffer.
+func write(emitter *yaml_emitter_t, s []byte, i *int) bool {
+ if emitter.buffer_pos+5 >= len(emitter.buffer) && !yaml_emitter_flush(emitter) {
+ return false
+ }
+ p := emitter.buffer_pos
+ w := width(s[*i])
+ switch w {
+ case 4:
+ emitter.buffer[p+3] = s[*i+3]
+ fallthrough
+ case 3:
+ emitter.buffer[p+2] = s[*i+2]
+ fallthrough
+ case 2:
+ emitter.buffer[p+1] = s[*i+1]
+ fallthrough
+ case 1:
+ emitter.buffer[p+0] = s[*i+0]
+ default:
+ panic("unknown character width")
+ }
+ emitter.column++
+ emitter.buffer_pos += w
+ *i += w
+ return true
+}
+
+// Write a whole string into buffer.
+func write_all(emitter *yaml_emitter_t, s []byte) bool {
+ for i := 0; i < len(s); {
+ if !write(emitter, s, &i) {
+ return false
+ }
+ }
+ return true
+}
+
+// Copy a line break character from a string into buffer.
+func write_break(emitter *yaml_emitter_t, s []byte, i *int) bool {
+ if s[*i] == '\n' {
+ if !put_break(emitter) {
+ return false
+ }
+ *i++
+ } else {
+ if !write(emitter, s, i) {
+ return false
+ }
+ emitter.column = 0
+ emitter.line++
+ }
+ return true
+}
+
+// Set an emitter error and return false.
+func yaml_emitter_set_emitter_error(emitter *yaml_emitter_t, problem string) bool {
+ emitter.error = yaml_EMITTER_ERROR
+ emitter.problem = problem
+ return false
+}
+
+// Emit an event.
+func yaml_emitter_emit(emitter *yaml_emitter_t, event *yaml_event_t) bool {
+ emitter.events = append(emitter.events, *event)
+ for !yaml_emitter_need_more_events(emitter) {
+ event := &emitter.events[emitter.events_head]
+ if !yaml_emitter_analyze_event(emitter, event) {
+ return false
+ }
+ if !yaml_emitter_state_machine(emitter, event) {
+ return false
+ }
+ yaml_event_delete(event)
+ emitter.events_head++
+ }
+ return true
+}
+
+// Check if we need to accumulate more events before emitting.
+//
+// We accumulate extra
+// - 1 event for DOCUMENT-START
+// - 2 events for SEQUENCE-START
+// - 3 events for MAPPING-START
+//
+func yaml_emitter_need_more_events(emitter *yaml_emitter_t) bool {
+ if emitter.events_head == len(emitter.events) {
+ return true
+ }
+ var accumulate int
+ switch emitter.events[emitter.events_head].typ {
+ case yaml_DOCUMENT_START_EVENT:
+ accumulate = 1
+ break
+ case yaml_SEQUENCE_START_EVENT:
+ accumulate = 2
+ break
+ case yaml_MAPPING_START_EVENT:
+ accumulate = 3
+ break
+ default:
+ return false
+ }
+ if len(emitter.events)-emitter.events_head > accumulate {
+ return false
+ }
+ var level int
+ for i := emitter.events_head; i < len(emitter.events); i++ {
+ switch emitter.events[i].typ {
+ case yaml_STREAM_START_EVENT, yaml_DOCUMENT_START_EVENT, yaml_SEQUENCE_START_EVENT, yaml_MAPPING_START_EVENT:
+ level++
+ case yaml_STREAM_END_EVENT, yaml_DOCUMENT_END_EVENT, yaml_SEQUENCE_END_EVENT, yaml_MAPPING_END_EVENT:
+ level--
+ }
+ if level == 0 {
+ return false
+ }
+ }
+ return true
+}
+
+// Append a directive to the directives stack.
+func yaml_emitter_append_tag_directive(emitter *yaml_emitter_t, value *yaml_tag_directive_t, allow_duplicates bool) bool {
+ for i := 0; i < len(emitter.tag_directives); i++ {
+ if bytes.Equal(value.handle, emitter.tag_directives[i].handle) {
+ if allow_duplicates {
+ return true
+ }
+ return yaml_emitter_set_emitter_error(emitter, "duplicate %TAG directive")
+ }
+ }
+
+ // [Go] Do we actually need to copy this given garbage collection
+ // and the lack of deallocating destructors?
+ tag_copy := yaml_tag_directive_t{
+ handle: make([]byte, len(value.handle)),
+ prefix: make([]byte, len(value.prefix)),
+ }
+ copy(tag_copy.handle, value.handle)
+ copy(tag_copy.prefix, value.prefix)
+ emitter.tag_directives = append(emitter.tag_directives, tag_copy)
+ return true
+}
+
+// Increase the indentation level.
+func yaml_emitter_increase_indent(emitter *yaml_emitter_t, flow, indentless bool) bool {
+ emitter.indents = append(emitter.indents, emitter.indent)
+ if emitter.indent < 0 {
+ if flow {
+ emitter.indent = emitter.best_indent
+ } else {
+ emitter.indent = 0
+ }
+ } else if !indentless {
+ emitter.indent += emitter.best_indent
+ }
+ return true
+}
+
+// State dispatcher.
+func yaml_emitter_state_machine(emitter *yaml_emitter_t, event *yaml_event_t) bool {
+ switch emitter.state {
+ default:
+ case yaml_EMIT_STREAM_START_STATE:
+ return yaml_emitter_emit_stream_start(emitter, event)
+
+ case yaml_EMIT_FIRST_DOCUMENT_START_STATE:
+ return yaml_emitter_emit_document_start(emitter, event, true)
+
+ case yaml_EMIT_DOCUMENT_START_STATE:
+ return yaml_emitter_emit_document_start(emitter, event, false)
+
+ case yaml_EMIT_DOCUMENT_CONTENT_STATE:
+ return yaml_emitter_emit_document_content(emitter, event)
+
+ case yaml_EMIT_DOCUMENT_END_STATE:
+ return yaml_emitter_emit_document_end(emitter, event)
+
+ case yaml_EMIT_FLOW_SEQUENCE_FIRST_ITEM_STATE:
+ return yaml_emitter_emit_flow_sequence_item(emitter, event, true)
+
+ case yaml_EMIT_FLOW_SEQUENCE_ITEM_STATE:
+ return yaml_emitter_emit_flow_sequence_item(emitter, event, false)
+
+ case yaml_EMIT_FLOW_MAPPING_FIRST_KEY_STATE:
+ return yaml_emitter_emit_flow_mapping_key(emitter, event, true)
+
+ case yaml_EMIT_FLOW_MAPPING_KEY_STATE:
+ return yaml_emitter_emit_flow_mapping_key(emitter, event, false)
+
+ case yaml_EMIT_FLOW_MAPPING_SIMPLE_VALUE_STATE:
+ return yaml_emitter_emit_flow_mapping_value(emitter, event, true)
+
+ case yaml_EMIT_FLOW_MAPPING_VALUE_STATE:
+ return yaml_emitter_emit_flow_mapping_value(emitter, event, false)
+
+ case yaml_EMIT_BLOCK_SEQUENCE_FIRST_ITEM_STATE:
+ return yaml_emitter_emit_block_sequence_item(emitter, event, true)
+
+ case yaml_EMIT_BLOCK_SEQUENCE_ITEM_STATE:
+ return yaml_emitter_emit_block_sequence_item(emitter, event, false)
+
+ case yaml_EMIT_BLOCK_MAPPING_FIRST_KEY_STATE:
+ return yaml_emitter_emit_block_mapping_key(emitter, event, true)
+
+ case yaml_EMIT_BLOCK_MAPPING_KEY_STATE:
+ return yaml_emitter_emit_block_mapping_key(emitter, event, false)
+
+ case yaml_EMIT_BLOCK_MAPPING_SIMPLE_VALUE_STATE:
+ return yaml_emitter_emit_block_mapping_value(emitter, event, true)
+
+ case yaml_EMIT_BLOCK_MAPPING_VALUE_STATE:
+ return yaml_emitter_emit_block_mapping_value(emitter, event, false)
+
+ case yaml_EMIT_END_STATE:
+ return yaml_emitter_set_emitter_error(emitter, "expected nothing after STREAM-END")
+ }
+ panic("invalid emitter state")
+}
+
+// Expect STREAM-START.
+func yaml_emitter_emit_stream_start(emitter *yaml_emitter_t, event *yaml_event_t) bool {
+ if event.typ != yaml_STREAM_START_EVENT {
+ return yaml_emitter_set_emitter_error(emitter, "expected STREAM-START")
+ }
+ if emitter.encoding == yaml_ANY_ENCODING {
+ emitter.encoding = event.encoding
+ if emitter.encoding == yaml_ANY_ENCODING {
+ emitter.encoding = yaml_UTF8_ENCODING
+ }
+ }
+ if emitter.best_indent < 2 || emitter.best_indent > 9 {
+ emitter.best_indent = 2
+ }
+ if emitter.best_width >= 0 && emitter.best_width <= emitter.best_indent*2 {
+ emitter.best_width = 80
+ }
+ if emitter.best_width < 0 {
+ emitter.best_width = 1<<31 - 1
+ }
+ if emitter.line_break == yaml_ANY_BREAK {
+ emitter.line_break = yaml_LN_BREAK
+ }
+
+ emitter.indent = -1
+ emitter.line = 0
+ emitter.column = 0
+ emitter.whitespace = true
+ emitter.indention = true
+
+ if emitter.encoding != yaml_UTF8_ENCODING {
+ if !yaml_emitter_write_bom(emitter) {
+ return false
+ }
+ }
+ emitter.state = yaml_EMIT_FIRST_DOCUMENT_START_STATE
+ return true
+}
+
+// Expect DOCUMENT-START or STREAM-END.
+func yaml_emitter_emit_document_start(emitter *yaml_emitter_t, event *yaml_event_t, first bool) bool {
+
+ if event.typ == yaml_DOCUMENT_START_EVENT {
+
+ if event.version_directive != nil {
+ if !yaml_emitter_analyze_version_directive(emitter, event.version_directive) {
+ return false
+ }
+ }
+
+ for i := 0; i < len(event.tag_directives); i++ {
+ tag_directive := &event.tag_directives[i]
+ if !yaml_emitter_analyze_tag_directive(emitter, tag_directive) {
+ return false
+ }
+ if !yaml_emitter_append_tag_directive(emitter, tag_directive, false) {
+ return false
+ }
+ }
+
+ for i := 0; i < len(default_tag_directives); i++ {
+ tag_directive := &default_tag_directives[i]
+ if !yaml_emitter_append_tag_directive(emitter, tag_directive, true) {
+ return false
+ }
+ }
+
+ implicit := event.implicit
+ if !first || emitter.canonical {
+ implicit = false
+ }
+
+ if emitter.open_ended && (event.version_directive != nil || len(event.tag_directives) > 0) {
+ if !yaml_emitter_write_indicator(emitter, []byte("..."), true, false, false) {
+ return false
+ }
+ if !yaml_emitter_write_indent(emitter) {
+ return false
+ }
+ }
+
+ if event.version_directive != nil {
+ implicit = false
+ if !yaml_emitter_write_indicator(emitter, []byte("%YAML"), true, false, false) {
+ return false
+ }
+ if !yaml_emitter_write_indicator(emitter, []byte("1.1"), true, false, false) {
+ return false
+ }
+ if !yaml_emitter_write_indent(emitter) {
+ return false
+ }
+ }
+
+ if len(event.tag_directives) > 0 {
+ implicit = false
+ for i := 0; i < len(event.tag_directives); i++ {
+ tag_directive := &event.tag_directives[i]
+ if !yaml_emitter_write_indicator(emitter, []byte("%TAG"), true, false, false) {
+ return false
+ }
+ if !yaml_emitter_write_tag_handle(emitter, tag_directive.handle) {
+ return false
+ }
+ if !yaml_emitter_write_tag_content(emitter, tag_directive.prefix, true) {
+ return false
+ }
+ if !yaml_emitter_write_indent(emitter) {
+ return false
+ }
+ }
+ }
+
+ if yaml_emitter_check_empty_document(emitter) {
+ implicit = false
+ }
+ if !implicit {
+ if !yaml_emitter_write_indent(emitter) {
+ return false
+ }
+ if !yaml_emitter_write_indicator(emitter, []byte("---"), true, false, false) {
+ return false
+ }
+ if emitter.canonical {
+ if !yaml_emitter_write_indent(emitter) {
+ return false
+ }
+ }
+ }
+
+ emitter.state = yaml_EMIT_DOCUMENT_CONTENT_STATE
+ return true
+ }
+
+ if event.typ == yaml_STREAM_END_EVENT {
+ if emitter.open_ended {
+ if !yaml_emitter_write_indicator(emitter, []byte("..."), true, false, false) {
+ return false
+ }
+ if !yaml_emitter_write_indent(emitter) {
+ return false
+ }
+ }
+ if !yaml_emitter_flush(emitter) {
+ return false
+ }
+ emitter.state = yaml_EMIT_END_STATE
+ return true
+ }
+
+ return yaml_emitter_set_emitter_error(emitter, "expected DOCUMENT-START or STREAM-END")
+}
+
+// Expect the root node.
+func yaml_emitter_emit_document_content(emitter *yaml_emitter_t, event *yaml_event_t) bool {
+ emitter.states = append(emitter.states, yaml_EMIT_DOCUMENT_END_STATE)
+ return yaml_emitter_emit_node(emitter, event, true, false, false, false)
+}
+
+// Expect DOCUMENT-END.
+func yaml_emitter_emit_document_end(emitter *yaml_emitter_t, event *yaml_event_t) bool {
+ if event.typ != yaml_DOCUMENT_END_EVENT {
+ return yaml_emitter_set_emitter_error(emitter, "expected DOCUMENT-END")
+ }
+ if !yaml_emitter_write_indent(emitter) {
+ return false
+ }
+ if !event.implicit {
+ // [Go] Allocate the slice elsewhere.
+ if !yaml_emitter_write_indicator(emitter, []byte("..."), true, false, false) {
+ return false
+ }
+ if !yaml_emitter_write_indent(emitter) {
+ return false
+ }
+ }
+ if !yaml_emitter_flush(emitter) {
+ return false
+ }
+ emitter.state = yaml_EMIT_DOCUMENT_START_STATE
+ emitter.tag_directives = emitter.tag_directives[:0]
+ return true
+}
+
+// Expect a flow item node.
+func yaml_emitter_emit_flow_sequence_item(emitter *yaml_emitter_t, event *yaml_event_t, first bool) bool {
+ if first {
+ if !yaml_emitter_write_indicator(emitter, []byte{'['}, true, true, false) {
+ return false
+ }
+ if !yaml_emitter_increase_indent(emitter, true, false) {
+ return false
+ }
+ emitter.flow_level++
+ }
+
+ if event.typ == yaml_SEQUENCE_END_EVENT {
+ emitter.flow_level--
+ emitter.indent = emitter.indents[len(emitter.indents)-1]
+ emitter.indents = emitter.indents[:len(emitter.indents)-1]
+ if emitter.canonical && !first {
+ if !yaml_emitter_write_indicator(emitter, []byte{','}, false, false, false) {
+ return false
+ }
+ if !yaml_emitter_write_indent(emitter) {
+ return false
+ }
+ }
+ if !yaml_emitter_write_indicator(emitter, []byte{']'}, false, false, false) {
+ return false
+ }
+ emitter.state = emitter.states[len(emitter.states)-1]
+ emitter.states = emitter.states[:len(emitter.states)-1]
+
+ return true
+ }
+
+ if !first {
+ if !yaml_emitter_write_indicator(emitter, []byte{','}, false, false, false) {
+ return false
+ }
+ }
+
+ if emitter.canonical || emitter.column > emitter.best_width {
+ if !yaml_emitter_write_indent(emitter) {
+ return false
+ }
+ }
+ emitter.states = append(emitter.states, yaml_EMIT_FLOW_SEQUENCE_ITEM_STATE)
+ return yaml_emitter_emit_node(emitter, event, false, true, false, false)
+}
+
+// Expect a flow key node.
+func yaml_emitter_emit_flow_mapping_key(emitter *yaml_emitter_t, event *yaml_event_t, first bool) bool {
+ if first {
+ if !yaml_emitter_write_indicator(emitter, []byte{'{'}, true, true, false) {
+ return false
+ }
+ if !yaml_emitter_increase_indent(emitter, true, false) {
+ return false
+ }
+ emitter.flow_level++
+ }
+
+ if event.typ == yaml_MAPPING_END_EVENT {
+ emitter.flow_level--
+ emitter.indent = emitter.indents[len(emitter.indents)-1]
+ emitter.indents = emitter.indents[:len(emitter.indents)-1]
+ if emitter.canonical && !first {
+ if !yaml_emitter_write_indicator(emitter, []byte{','}, false, false, false) {
+ return false
+ }
+ if !yaml_emitter_write_indent(emitter) {
+ return false
+ }
+ }
+ if !yaml_emitter_write_indicator(emitter, []byte{'}'}, false, false, false) {
+ return false
+ }
+ emitter.state = emitter.states[len(emitter.states)-1]
+ emitter.states = emitter.states[:len(emitter.states)-1]
+ return true
+ }
+
+ if !first {
+ if !yaml_emitter_write_indicator(emitter, []byte{','}, false, false, false) {
+ return false
+ }
+ }
+ if emitter.canonical || emitter.column > emitter.best_width {
+ if !yaml_emitter_write_indent(emitter) {
+ return false
+ }
+ }
+
+ if !emitter.canonical && yaml_emitter_check_simple_key(emitter) {
+ emitter.states = append(emitter.states, yaml_EMIT_FLOW_MAPPING_SIMPLE_VALUE_STATE)
+ return yaml_emitter_emit_node(emitter, event, false, false, true, true)
+ }
+ if !yaml_emitter_write_indicator(emitter, []byte{'?'}, true, false, false) {
+ return false
+ }
+ emitter.states = append(emitter.states, yaml_EMIT_FLOW_MAPPING_VALUE_STATE)
+ return yaml_emitter_emit_node(emitter, event, false, false, true, false)
+}
+
+// Expect a flow value node.
+func yaml_emitter_emit_flow_mapping_value(emitter *yaml_emitter_t, event *yaml_event_t, simple bool) bool {
+ if simple {
+ if !yaml_emitter_write_indicator(emitter, []byte{':'}, false, false, false) {
+ return false
+ }
+ } else {
+ if emitter.canonical || emitter.column > emitter.best_width {
+ if !yaml_emitter_write_indent(emitter) {
+ return false
+ }
+ }
+ if !yaml_emitter_write_indicator(emitter, []byte{':'}, true, false, false) {
+ return false
+ }
+ }
+ emitter.states = append(emitter.states, yaml_EMIT_FLOW_MAPPING_KEY_STATE)
+ return yaml_emitter_emit_node(emitter, event, false, false, true, false)
+}
+
+// Expect a block item node.
+func yaml_emitter_emit_block_sequence_item(emitter *yaml_emitter_t, event *yaml_event_t, first bool) bool {
+ if first {
+ if !yaml_emitter_increase_indent(emitter, false, emitter.mapping_context && !emitter.indention) {
+ return false
+ }
+ }
+ if event.typ == yaml_SEQUENCE_END_EVENT {
+ emitter.indent = emitter.indents[len(emitter.indents)-1]
+ emitter.indents = emitter.indents[:len(emitter.indents)-1]
+ emitter.state = emitter.states[len(emitter.states)-1]
+ emitter.states = emitter.states[:len(emitter.states)-1]
+ return true
+ }
+ if !yaml_emitter_write_indent(emitter) {
+ return false
+ }
+ if !yaml_emitter_write_indicator(emitter, []byte{'-'}, true, false, true) {
+ return false
+ }
+ emitter.states = append(emitter.states, yaml_EMIT_BLOCK_SEQUENCE_ITEM_STATE)
+ return yaml_emitter_emit_node(emitter, event, false, true, false, false)
+}
+
+// Expect a block key node.
+func yaml_emitter_emit_block_mapping_key(emitter *yaml_emitter_t, event *yaml_event_t, first bool) bool {
+ if first {
+ if !yaml_emitter_increase_indent(emitter, false, false) {
+ return false
+ }
+ }
+ if event.typ == yaml_MAPPING_END_EVENT {
+ emitter.indent = emitter.indents[len(emitter.indents)-1]
+ emitter.indents = emitter.indents[:len(emitter.indents)-1]
+ emitter.state = emitter.states[len(emitter.states)-1]
+ emitter.states = emitter.states[:len(emitter.states)-1]
+ return true
+ }
+ if !yaml_emitter_write_indent(emitter) {
+ return false
+ }
+ if yaml_emitter_check_simple_key(emitter) {
+ emitter.states = append(emitter.states, yaml_EMIT_BLOCK_MAPPING_SIMPLE_VALUE_STATE)
+ return yaml_emitter_emit_node(emitter, event, false, false, true, true)
+ }
+ if !yaml_emitter_write_indicator(emitter, []byte{'?'}, true, false, true) {
+ return false
+ }
+ emitter.states = append(emitter.states, yaml_EMIT_BLOCK_MAPPING_VALUE_STATE)
+ return yaml_emitter_emit_node(emitter, event, false, false, true, false)
+}
+
+// Expect a block value node.
+func yaml_emitter_emit_block_mapping_value(emitter *yaml_emitter_t, event *yaml_event_t, simple bool) bool {
+ if simple {
+ if !yaml_emitter_write_indicator(emitter, []byte{':'}, false, false, false) {
+ return false
+ }
+ } else {
+ if !yaml_emitter_write_indent(emitter) {
+ return false
+ }
+ if !yaml_emitter_write_indicator(emitter, []byte{':'}, true, false, true) {
+ return false
+ }
+ }
+ emitter.states = append(emitter.states, yaml_EMIT_BLOCK_MAPPING_KEY_STATE)
+ return yaml_emitter_emit_node(emitter, event, false, false, true, false)
+}
+
+// Expect a node.
+func yaml_emitter_emit_node(emitter *yaml_emitter_t, event *yaml_event_t,
+ root bool, sequence bool, mapping bool, simple_key bool) bool {
+
+ emitter.root_context = root
+ emitter.sequence_context = sequence
+ emitter.mapping_context = mapping
+ emitter.simple_key_context = simple_key
+
+ switch event.typ {
+ case yaml_ALIAS_EVENT:
+ return yaml_emitter_emit_alias(emitter, event)
+ case yaml_SCALAR_EVENT:
+ return yaml_emitter_emit_scalar(emitter, event)
+ case yaml_SEQUENCE_START_EVENT:
+ return yaml_emitter_emit_sequence_start(emitter, event)
+ case yaml_MAPPING_START_EVENT:
+ return yaml_emitter_emit_mapping_start(emitter, event)
+ default:
+ return yaml_emitter_set_emitter_error(emitter,
+ fmt.Sprintf("expected SCALAR, SEQUENCE-START, MAPPING-START, or ALIAS, but got %v", event.typ))
+ }
+}
+
+// Expect ALIAS.
+func yaml_emitter_emit_alias(emitter *yaml_emitter_t, event *yaml_event_t) bool {
+ if !yaml_emitter_process_anchor(emitter) {
+ return false
+ }
+ emitter.state = emitter.states[len(emitter.states)-1]
+ emitter.states = emitter.states[:len(emitter.states)-1]
+ return true
+}
+
+// Expect SCALAR.
+func yaml_emitter_emit_scalar(emitter *yaml_emitter_t, event *yaml_event_t) bool {
+ if !yaml_emitter_select_scalar_style(emitter, event) {
+ return false
+ }
+ if !yaml_emitter_process_anchor(emitter) {
+ return false
+ }
+ if !yaml_emitter_process_tag(emitter) {
+ return false
+ }
+ if !yaml_emitter_increase_indent(emitter, true, false) {
+ return false
+ }
+ if !yaml_emitter_process_scalar(emitter) {
+ return false
+ }
+ emitter.indent = emitter.indents[len(emitter.indents)-1]
+ emitter.indents = emitter.indents[:len(emitter.indents)-1]
+ emitter.state = emitter.states[len(emitter.states)-1]
+ emitter.states = emitter.states[:len(emitter.states)-1]
+ return true
+}
+
+// Expect SEQUENCE-START.
+func yaml_emitter_emit_sequence_start(emitter *yaml_emitter_t, event *yaml_event_t) bool {
+ if !yaml_emitter_process_anchor(emitter) {
+ return false
+ }
+ if !yaml_emitter_process_tag(emitter) {
+ return false
+ }
+ if emitter.flow_level > 0 || emitter.canonical || event.sequence_style() == yaml_FLOW_SEQUENCE_STYLE ||
+ yaml_emitter_check_empty_sequence(emitter) {
+ emitter.state = yaml_EMIT_FLOW_SEQUENCE_FIRST_ITEM_STATE
+ } else {
+ emitter.state = yaml_EMIT_BLOCK_SEQUENCE_FIRST_ITEM_STATE
+ }
+ return true
+}
+
+// Expect MAPPING-START.
+func yaml_emitter_emit_mapping_start(emitter *yaml_emitter_t, event *yaml_event_t) bool {
+ if !yaml_emitter_process_anchor(emitter) {
+ return false
+ }
+ if !yaml_emitter_process_tag(emitter) {
+ return false
+ }
+ if emitter.flow_level > 0 || emitter.canonical || event.mapping_style() == yaml_FLOW_MAPPING_STYLE ||
+ yaml_emitter_check_empty_mapping(emitter) {
+ emitter.state = yaml_EMIT_FLOW_MAPPING_FIRST_KEY_STATE
+ } else {
+ emitter.state = yaml_EMIT_BLOCK_MAPPING_FIRST_KEY_STATE
+ }
+ return true
+}
+
+// Check if the document content is an empty scalar.
+func yaml_emitter_check_empty_document(emitter *yaml_emitter_t) bool {
+ return false // [Go] Huh?
+}
+
+// Check if the next events represent an empty sequence.
+func yaml_emitter_check_empty_sequence(emitter *yaml_emitter_t) bool {
+ if len(emitter.events)-emitter.events_head < 2 {
+ return false
+ }
+ return emitter.events[emitter.events_head].typ == yaml_SEQUENCE_START_EVENT &&
+ emitter.events[emitter.events_head+1].typ == yaml_SEQUENCE_END_EVENT
+}
+
+// Check if the next events represent an empty mapping.
+func yaml_emitter_check_empty_mapping(emitter *yaml_emitter_t) bool {
+ if len(emitter.events)-emitter.events_head < 2 {
+ return false
+ }
+ return emitter.events[emitter.events_head].typ == yaml_MAPPING_START_EVENT &&
+ emitter.events[emitter.events_head+1].typ == yaml_MAPPING_END_EVENT
+}
+
+// Check if the next node can be expressed as a simple key.
+func yaml_emitter_check_simple_key(emitter *yaml_emitter_t) bool {
+ length := 0
+ switch emitter.events[emitter.events_head].typ {
+ case yaml_ALIAS_EVENT:
+ length += len(emitter.anchor_data.anchor)
+ case yaml_SCALAR_EVENT:
+ if emitter.scalar_data.multiline {
+ return false
+ }
+ length += len(emitter.anchor_data.anchor) +
+ len(emitter.tag_data.handle) +
+ len(emitter.tag_data.suffix) +
+ len(emitter.scalar_data.value)
+ case yaml_SEQUENCE_START_EVENT:
+ if !yaml_emitter_check_empty_sequence(emitter) {
+ return false
+ }
+ length += len(emitter.anchor_data.anchor) +
+ len(emitter.tag_data.handle) +
+ len(emitter.tag_data.suffix)
+ case yaml_MAPPING_START_EVENT:
+ if !yaml_emitter_check_empty_mapping(emitter) {
+ return false
+ }
+ length += len(emitter.anchor_data.anchor) +
+ len(emitter.tag_data.handle) +
+ len(emitter.tag_data.suffix)
+ default:
+ return false
+ }
+ return length <= 128
+}
+
+// Determine an acceptable scalar style.
+func yaml_emitter_select_scalar_style(emitter *yaml_emitter_t, event *yaml_event_t) bool {
+
+ no_tag := len(emitter.tag_data.handle) == 0 && len(emitter.tag_data.suffix) == 0
+ if no_tag && !event.implicit && !event.quoted_implicit {
+ return yaml_emitter_set_emitter_error(emitter, "neither tag nor implicit flags are specified")
+ }
+
+ style := event.scalar_style()
+ if style == yaml_ANY_SCALAR_STYLE {
+ style = yaml_PLAIN_SCALAR_STYLE
+ }
+ if emitter.canonical {
+ style = yaml_DOUBLE_QUOTED_SCALAR_STYLE
+ }
+ if emitter.simple_key_context && emitter.scalar_data.multiline {
+ style = yaml_DOUBLE_QUOTED_SCALAR_STYLE
+ }
+
+ if style == yaml_PLAIN_SCALAR_STYLE {
+ if emitter.flow_level > 0 && !emitter.scalar_data.flow_plain_allowed ||
+ emitter.flow_level == 0 && !emitter.scalar_data.block_plain_allowed {
+ style = yaml_SINGLE_QUOTED_SCALAR_STYLE
+ }
+ if len(emitter.scalar_data.value) == 0 && (emitter.flow_level > 0 || emitter.simple_key_context) {
+ style = yaml_SINGLE_QUOTED_SCALAR_STYLE
+ }
+ if no_tag && !event.implicit {
+ style = yaml_SINGLE_QUOTED_SCALAR_STYLE
+ }
+ }
+ if style == yaml_SINGLE_QUOTED_SCALAR_STYLE {
+ if !emitter.scalar_data.single_quoted_allowed {
+ style = yaml_DOUBLE_QUOTED_SCALAR_STYLE
+ }
+ }
+ if style == yaml_LITERAL_SCALAR_STYLE || style == yaml_FOLDED_SCALAR_STYLE {
+ if !emitter.scalar_data.block_allowed || emitter.flow_level > 0 || emitter.simple_key_context {
+ style = yaml_DOUBLE_QUOTED_SCALAR_STYLE
+ }
+ }
+
+ if no_tag && !event.quoted_implicit && style != yaml_PLAIN_SCALAR_STYLE {
+ emitter.tag_data.handle = []byte{'!'}
+ }
+ emitter.scalar_data.style = style
+ return true
+}
+
+// Write an anchor.
+func yaml_emitter_process_anchor(emitter *yaml_emitter_t) bool {
+ if emitter.anchor_data.anchor == nil {
+ return true
+ }
+ c := []byte{'&'}
+ if emitter.anchor_data.alias {
+ c[0] = '*'
+ }
+ if !yaml_emitter_write_indicator(emitter, c, true, false, false) {
+ return false
+ }
+ return yaml_emitter_write_anchor(emitter, emitter.anchor_data.anchor)
+}
+
+// Write a tag.
+func yaml_emitter_process_tag(emitter *yaml_emitter_t) bool {
+ if len(emitter.tag_data.handle) == 0 && len(emitter.tag_data.suffix) == 0 {
+ return true
+ }
+ if len(emitter.tag_data.handle) > 0 {
+ if !yaml_emitter_write_tag_handle(emitter, emitter.tag_data.handle) {
+ return false
+ }
+ if len(emitter.tag_data.suffix) > 0 {
+ if !yaml_emitter_write_tag_content(emitter, emitter.tag_data.suffix, false) {
+ return false
+ }
+ }
+ } else {
+ // [Go] Allocate these slices elsewhere.
+ if !yaml_emitter_write_indicator(emitter, []byte("!<"), true, false, false) {
+ return false
+ }
+ if !yaml_emitter_write_tag_content(emitter, emitter.tag_data.suffix, false) {
+ return false
+ }
+ if !yaml_emitter_write_indicator(emitter, []byte{'>'}, false, false, false) {
+ return false
+ }
+ }
+ return true
+}
+
+// Write a scalar.
+func yaml_emitter_process_scalar(emitter *yaml_emitter_t) bool {
+ switch emitter.scalar_data.style {
+ case yaml_PLAIN_SCALAR_STYLE:
+ return yaml_emitter_write_plain_scalar(emitter, emitter.scalar_data.value, !emitter.simple_key_context)
+
+ case yaml_SINGLE_QUOTED_SCALAR_STYLE:
+ return yaml_emitter_write_single_quoted_scalar(emitter, emitter.scalar_data.value, !emitter.simple_key_context)
+
+ case yaml_DOUBLE_QUOTED_SCALAR_STYLE:
+ return yaml_emitter_write_double_quoted_scalar(emitter, emitter.scalar_data.value, !emitter.simple_key_context)
+
+ case yaml_LITERAL_SCALAR_STYLE:
+ return yaml_emitter_write_literal_scalar(emitter, emitter.scalar_data.value)
+
+ case yaml_FOLDED_SCALAR_STYLE:
+ return yaml_emitter_write_folded_scalar(emitter, emitter.scalar_data.value)
+ }
+ panic("unknown scalar style")
+}
+
+// Check if a %YAML directive is valid.
+func yaml_emitter_analyze_version_directive(emitter *yaml_emitter_t, version_directive *yaml_version_directive_t) bool {
+ if version_directive.major != 1 || version_directive.minor != 1 {
+ return yaml_emitter_set_emitter_error(emitter, "incompatible %YAML directive")
+ }
+ return true
+}
+
+// Check if a %TAG directive is valid.
+func yaml_emitter_analyze_tag_directive(emitter *yaml_emitter_t, tag_directive *yaml_tag_directive_t) bool {
+ handle := tag_directive.handle
+ prefix := tag_directive.prefix
+ if len(handle) == 0 {
+ return yaml_emitter_set_emitter_error(emitter, "tag handle must not be empty")
+ }
+ if handle[0] != '!' {
+ return yaml_emitter_set_emitter_error(emitter, "tag handle must start with '!'")
+ }
+ if handle[len(handle)-1] != '!' {
+ return yaml_emitter_set_emitter_error(emitter, "tag handle must end with '!'")
+ }
+ for i := 1; i < len(handle)-1; i += width(handle[i]) {
+ if !is_alpha(handle, i) {
+ return yaml_emitter_set_emitter_error(emitter, "tag handle must contain alphanumerical characters only")
+ }
+ }
+ if len(prefix) == 0 {
+ return yaml_emitter_set_emitter_error(emitter, "tag prefix must not be empty")
+ }
+ return true
+}
+
+// Check if an anchor is valid.
+func yaml_emitter_analyze_anchor(emitter *yaml_emitter_t, anchor []byte, alias bool) bool {
+ if len(anchor) == 0 {
+ problem := "anchor value must not be empty"
+ if alias {
+ problem = "alias value must not be empty"
+ }
+ return yaml_emitter_set_emitter_error(emitter, problem)
+ }
+ for i := 0; i < len(anchor); i += width(anchor[i]) {
+ if !is_alpha(anchor, i) {
+ problem := "anchor value must contain alphanumerical characters only"
+ if alias {
+ problem = "alias value must contain alphanumerical characters only"
+ }
+ return yaml_emitter_set_emitter_error(emitter, problem)
+ }
+ }
+ emitter.anchor_data.anchor = anchor
+ emitter.anchor_data.alias = alias
+ return true
+}
+
+// Check if a tag is valid.
+func yaml_emitter_analyze_tag(emitter *yaml_emitter_t, tag []byte) bool {
+ if len(tag) == 0 {
+ return yaml_emitter_set_emitter_error(emitter, "tag value must not be empty")
+ }
+ for i := 0; i < len(emitter.tag_directives); i++ {
+ tag_directive := &emitter.tag_directives[i]
+ if bytes.HasPrefix(tag, tag_directive.prefix) {
+ emitter.tag_data.handle = tag_directive.handle
+ emitter.tag_data.suffix = tag[len(tag_directive.prefix):]
+ return true
+ }
+ }
+ emitter.tag_data.suffix = tag
+ return true
+}
+
+// Check if a scalar is valid.
+func yaml_emitter_analyze_scalar(emitter *yaml_emitter_t, value []byte) bool {
+ var (
+ block_indicators = false
+ flow_indicators = false
+ line_breaks = false
+ special_characters = false
+
+ leading_space = false
+ leading_break = false
+ trailing_space = false
+ trailing_break = false
+ break_space = false
+ space_break = false
+
+ preceded_by_whitespace = false
+ followed_by_whitespace = false
+ previous_space = false
+ previous_break = false
+ )
+
+ emitter.scalar_data.value = value
+
+ if len(value) == 0 {
+ emitter.scalar_data.multiline = false
+ emitter.scalar_data.flow_plain_allowed = false
+ emitter.scalar_data.block_plain_allowed = true
+ emitter.scalar_data.single_quoted_allowed = true
+ emitter.scalar_data.block_allowed = false
+ return true
+ }
+
+ if len(value) >= 3 && ((value[0] == '-' && value[1] == '-' && value[2] == '-') || (value[0] == '.' && value[1] == '.' && value[2] == '.')) {
+ block_indicators = true
+ flow_indicators = true
+ }
+
+ preceded_by_whitespace = true
+ for i, w := 0, 0; i < len(value); i += w {
+ w = width(value[i])
+ followed_by_whitespace = i+w >= len(value) || is_blank(value, i+w)
+
+ if i == 0 {
+ switch value[i] {
+ case '#', ',', '[', ']', '{', '}', '&', '*', '!', '|', '>', '\'', '"', '%', '@', '`':
+ flow_indicators = true
+ block_indicators = true
+ case '?', ':':
+ flow_indicators = true
+ if followed_by_whitespace {
+ block_indicators = true
+ }
+ case '-':
+ if followed_by_whitespace {
+ flow_indicators = true
+ block_indicators = true
+ }
+ }
+ } else {
+ switch value[i] {
+ case ',', '?', '[', ']', '{', '}':
+ flow_indicators = true
+ case ':':
+ flow_indicators = true
+ if followed_by_whitespace {
+ block_indicators = true
+ }
+ case '#':
+ if preceded_by_whitespace {
+ flow_indicators = true
+ block_indicators = true
+ }
+ }
+ }
+
+ if !is_printable(value, i) || !is_ascii(value, i) && !emitter.unicode {
+ special_characters = true
+ }
+ if is_space(value, i) {
+ if i == 0 {
+ leading_space = true
+ }
+ if i+width(value[i]) == len(value) {
+ trailing_space = true
+ }
+ if previous_break {
+ break_space = true
+ }
+ previous_space = true
+ previous_break = false
+ } else if is_break(value, i) {
+ line_breaks = true
+ if i == 0 {
+ leading_break = true
+ }
+ if i+width(value[i]) == len(value) {
+ trailing_break = true
+ }
+ if previous_space {
+ space_break = true
+ }
+ previous_space = false
+ previous_break = true
+ } else {
+ previous_space = false
+ previous_break = false
+ }
+
+ // [Go]: Why 'z'? Couldn't be the end of the string as that's the loop condition.
+ preceded_by_whitespace = is_blankz(value, i)
+ }
+
+ emitter.scalar_data.multiline = line_breaks
+ emitter.scalar_data.flow_plain_allowed = true
+ emitter.scalar_data.block_plain_allowed = true
+ emitter.scalar_data.single_quoted_allowed = true
+ emitter.scalar_data.block_allowed = true
+
+ if leading_space || leading_break || trailing_space || trailing_break {
+ emitter.scalar_data.flow_plain_allowed = false
+ emitter.scalar_data.block_plain_allowed = false
+ }
+ if trailing_space {
+ emitter.scalar_data.block_allowed = false
+ }
+ if break_space {
+ emitter.scalar_data.flow_plain_allowed = false
+ emitter.scalar_data.block_plain_allowed = false
+ emitter.scalar_data.single_quoted_allowed = false
+ }
+ if space_break || special_characters {
+ emitter.scalar_data.flow_plain_allowed = false
+ emitter.scalar_data.block_plain_allowed = false
+ emitter.scalar_data.single_quoted_allowed = false
+ emitter.scalar_data.block_allowed = false
+ }
+ if line_breaks {
+ emitter.scalar_data.flow_plain_allowed = false
+ emitter.scalar_data.block_plain_allowed = false
+ }
+ if flow_indicators {
+ emitter.scalar_data.flow_plain_allowed = false
+ }
+ if block_indicators {
+ emitter.scalar_data.block_plain_allowed = false
+ }
+ return true
+}
+
+// Check if the event data is valid.
+func yaml_emitter_analyze_event(emitter *yaml_emitter_t, event *yaml_event_t) bool {
+
+ emitter.anchor_data.anchor = nil
+ emitter.tag_data.handle = nil
+ emitter.tag_data.suffix = nil
+ emitter.scalar_data.value = nil
+
+ switch event.typ {
+ case yaml_ALIAS_EVENT:
+ if !yaml_emitter_analyze_anchor(emitter, event.anchor, true) {
+ return false
+ }
+
+ case yaml_SCALAR_EVENT:
+ if len(event.anchor) > 0 {
+ if !yaml_emitter_analyze_anchor(emitter, event.anchor, false) {
+ return false
+ }
+ }
+ if len(event.tag) > 0 && (emitter.canonical || (!event.implicit && !event.quoted_implicit)) {
+ if !yaml_emitter_analyze_tag(emitter, event.tag) {
+ return false
+ }
+ }
+ if !yaml_emitter_analyze_scalar(emitter, event.value) {
+ return false
+ }
+
+ case yaml_SEQUENCE_START_EVENT:
+ if len(event.anchor) > 0 {
+ if !yaml_emitter_analyze_anchor(emitter, event.anchor, false) {
+ return false
+ }
+ }
+ if len(event.tag) > 0 && (emitter.canonical || !event.implicit) {
+ if !yaml_emitter_analyze_tag(emitter, event.tag) {
+ return false
+ }
+ }
+
+ case yaml_MAPPING_START_EVENT:
+ if len(event.anchor) > 0 {
+ if !yaml_emitter_analyze_anchor(emitter, event.anchor, false) {
+ return false
+ }
+ }
+ if len(event.tag) > 0 && (emitter.canonical || !event.implicit) {
+ if !yaml_emitter_analyze_tag(emitter, event.tag) {
+ return false
+ }
+ }
+ }
+ return true
+}
+
+// Write the BOM character.
+func yaml_emitter_write_bom(emitter *yaml_emitter_t) bool {
+ if !flush(emitter) {
+ return false
+ }
+ pos := emitter.buffer_pos
+ emitter.buffer[pos+0] = '\xEF'
+ emitter.buffer[pos+1] = '\xBB'
+ emitter.buffer[pos+2] = '\xBF'
+ emitter.buffer_pos += 3
+ return true
+}
+
+func yaml_emitter_write_indent(emitter *yaml_emitter_t) bool {
+ indent := emitter.indent
+ if indent < 0 {
+ indent = 0
+ }
+ if !emitter.indention || emitter.column > indent || (emitter.column == indent && !emitter.whitespace) {
+ if !put_break(emitter) {
+ return false
+ }
+ }
+ for emitter.column < indent {
+ if !put(emitter, ' ') {
+ return false
+ }
+ }
+ emitter.whitespace = true
+ emitter.indention = true
+ return true
+}
+
+func yaml_emitter_write_indicator(emitter *yaml_emitter_t, indicator []byte, need_whitespace, is_whitespace, is_indention bool) bool {
+ if need_whitespace && !emitter.whitespace {
+ if !put(emitter, ' ') {
+ return false
+ }
+ }
+ if !write_all(emitter, indicator) {
+ return false
+ }
+ emitter.whitespace = is_whitespace
+ emitter.indention = (emitter.indention && is_indention)
+ emitter.open_ended = false
+ return true
+}
+
+func yaml_emitter_write_anchor(emitter *yaml_emitter_t, value []byte) bool {
+ if !write_all(emitter, value) {
+ return false
+ }
+ emitter.whitespace = false
+ emitter.indention = false
+ return true
+}
+
+func yaml_emitter_write_tag_handle(emitter *yaml_emitter_t, value []byte) bool {
+ if !emitter.whitespace {
+ if !put(emitter, ' ') {
+ return false
+ }
+ }
+ if !write_all(emitter, value) {
+ return false
+ }
+ emitter.whitespace = false
+ emitter.indention = false
+ return true
+}
+
+func yaml_emitter_write_tag_content(emitter *yaml_emitter_t, value []byte, need_whitespace bool) bool {
+ if need_whitespace && !emitter.whitespace {
+ if !put(emitter, ' ') {
+ return false
+ }
+ }
+ for i := 0; i < len(value); {
+ var must_write bool
+ switch value[i] {
+ case ';', '/', '?', ':', '@', '&', '=', '+', '$', ',', '_', '.', '~', '*', '\'', '(', ')', '[', ']':
+ must_write = true
+ default:
+ must_write = is_alpha(value, i)
+ }
+ if must_write {
+ if !write(emitter, value, &i) {
+ return false
+ }
+ } else {
+ w := width(value[i])
+ for k := 0; k < w; k++ {
+ octet := value[i]
+ i++
+ if !put(emitter, '%') {
+ return false
+ }
+
+ c := octet >> 4
+ if c < 10 {
+ c += '0'
+ } else {
+ c += 'A' - 10
+ }
+ if !put(emitter, c) {
+ return false
+ }
+
+ c = octet & 0x0f
+ if c < 10 {
+ c += '0'
+ } else {
+ c += 'A' - 10
+ }
+ if !put(emitter, c) {
+ return false
+ }
+ }
+ }
+ }
+ emitter.whitespace = false
+ emitter.indention = false
+ return true
+}
+
+func yaml_emitter_write_plain_scalar(emitter *yaml_emitter_t, value []byte, allow_breaks bool) bool {
+ if !emitter.whitespace {
+ if !put(emitter, ' ') {
+ return false
+ }
+ }
+
+ spaces := false
+ breaks := false
+ for i := 0; i < len(value); {
+ if is_space(value, i) {
+ if allow_breaks && !spaces && emitter.column > emitter.best_width && !is_space(value, i+1) {
+ if !yaml_emitter_write_indent(emitter) {
+ return false
+ }
+ i += width(value[i])
+ } else {
+ if !write(emitter, value, &i) {
+ return false
+ }
+ }
+ spaces = true
+ } else if is_break(value, i) {
+ if !breaks && value[i] == '\n' {
+ if !put_break(emitter) {
+ return false
+ }
+ }
+ if !write_break(emitter, value, &i) {
+ return false
+ }
+ emitter.indention = true
+ breaks = true
+ } else {
+ if breaks {
+ if !yaml_emitter_write_indent(emitter) {
+ return false
+ }
+ }
+ if !write(emitter, value, &i) {
+ return false
+ }
+ emitter.indention = false
+ spaces = false
+ breaks = false
+ }
+ }
+
+ emitter.whitespace = false
+ emitter.indention = false
+ if emitter.root_context {
+ emitter.open_ended = true
+ }
+
+ return true
+}
+
+func yaml_emitter_write_single_quoted_scalar(emitter *yaml_emitter_t, value []byte, allow_breaks bool) bool {
+
+ if !yaml_emitter_write_indicator(emitter, []byte{'\''}, true, false, false) {
+ return false
+ }
+
+ spaces := false
+ breaks := false
+ for i := 0; i < len(value); {
+ if is_space(value, i) {
+ if allow_breaks && !spaces && emitter.column > emitter.best_width && i > 0 && i < len(value)-1 && !is_space(value, i+1) {
+ if !yaml_emitter_write_indent(emitter) {
+ return false
+ }
+ i += width(value[i])
+ } else {
+ if !write(emitter, value, &i) {
+ return false
+ }
+ }
+ spaces = true
+ } else if is_break(value, i) {
+ if !breaks && value[i] == '\n' {
+ if !put_break(emitter) {
+ return false
+ }
+ }
+ if !write_break(emitter, value, &i) {
+ return false
+ }
+ emitter.indention = true
+ breaks = true
+ } else {
+ if breaks {
+ if !yaml_emitter_write_indent(emitter) {
+ return false
+ }
+ }
+ if value[i] == '\'' {
+ if !put(emitter, '\'') {
+ return false
+ }
+ }
+ if !write(emitter, value, &i) {
+ return false
+ }
+ emitter.indention = false
+ spaces = false
+ breaks = false
+ }
+ }
+ if !yaml_emitter_write_indicator(emitter, []byte{'\''}, false, false, false) {
+ return false
+ }
+ emitter.whitespace = false
+ emitter.indention = false
+ return true
+}
+
+func yaml_emitter_write_double_quoted_scalar(emitter *yaml_emitter_t, value []byte, allow_breaks bool) bool {
+ spaces := false
+ if !yaml_emitter_write_indicator(emitter, []byte{'"'}, true, false, false) {
+ return false
+ }
+
+ for i := 0; i < len(value); {
+ if !is_printable(value, i) || (!emitter.unicode && !is_ascii(value, i)) ||
+ is_bom(value, i) || is_break(value, i) ||
+ value[i] == '"' || value[i] == '\\' {
+
+ octet := value[i]
+
+ var w int
+ var v rune
+ switch {
+ case octet&0x80 == 0x00:
+ w, v = 1, rune(octet&0x7F)
+ case octet&0xE0 == 0xC0:
+ w, v = 2, rune(octet&0x1F)
+ case octet&0xF0 == 0xE0:
+ w, v = 3, rune(octet&0x0F)
+ case octet&0xF8 == 0xF0:
+ w, v = 4, rune(octet&0x07)
+ }
+ for k := 1; k < w; k++ {
+ octet = value[i+k]
+ v = (v << 6) + (rune(octet) & 0x3F)
+ }
+ i += w
+
+ if !put(emitter, '\\') {
+ return false
+ }
+
+ var ok bool
+ switch v {
+ case 0x00:
+ ok = put(emitter, '0')
+ case 0x07:
+ ok = put(emitter, 'a')
+ case 0x08:
+ ok = put(emitter, 'b')
+ case 0x09:
+ ok = put(emitter, 't')
+ case 0x0A:
+ ok = put(emitter, 'n')
+ case 0x0b:
+ ok = put(emitter, 'v')
+ case 0x0c:
+ ok = put(emitter, 'f')
+ case 0x0d:
+ ok = put(emitter, 'r')
+ case 0x1b:
+ ok = put(emitter, 'e')
+ case 0x22:
+ ok = put(emitter, '"')
+ case 0x5c:
+ ok = put(emitter, '\\')
+ case 0x85:
+ ok = put(emitter, 'N')
+ case 0xA0:
+ ok = put(emitter, '_')
+ case 0x2028:
+ ok = put(emitter, 'L')
+ case 0x2029:
+ ok = put(emitter, 'P')
+ default:
+ if v <= 0xFF {
+ ok = put(emitter, 'x')
+ w = 2
+ } else if v <= 0xFFFF {
+ ok = put(emitter, 'u')
+ w = 4
+ } else {
+ ok = put(emitter, 'U')
+ w = 8
+ }
+ for k := (w - 1) * 4; ok && k >= 0; k -= 4 {
+ digit := byte((v >> uint(k)) & 0x0F)
+ if digit < 10 {
+ ok = put(emitter, digit+'0')
+ } else {
+ ok = put(emitter, digit+'A'-10)
+ }
+ }
+ }
+ if !ok {
+ return false
+ }
+ spaces = false
+ } else if is_space(value, i) {
+ if allow_breaks && !spaces && emitter.column > emitter.best_width && i > 0 && i < len(value)-1 {
+ if !yaml_emitter_write_indent(emitter) {
+ return false
+ }
+ if is_space(value, i+1) {
+ if !put(emitter, '\\') {
+ return false
+ }
+ }
+ i += width(value[i])
+ } else if !write(emitter, value, &i) {
+ return false
+ }
+ spaces = true
+ } else {
+ if !write(emitter, value, &i) {
+ return false
+ }
+ spaces = false
+ }
+ }
+ if !yaml_emitter_write_indicator(emitter, []byte{'"'}, false, false, false) {
+ return false
+ }
+ emitter.whitespace = false
+ emitter.indention = false
+ return true
+}
+
+func yaml_emitter_write_block_scalar_hints(emitter *yaml_emitter_t, value []byte) bool {
+ if is_space(value, 0) || is_break(value, 0) {
+ indent_hint := []byte{'0' + byte(emitter.best_indent)}
+ if !yaml_emitter_write_indicator(emitter, indent_hint, false, false, false) {
+ return false
+ }
+ }
+
+ emitter.open_ended = false
+
+ var chomp_hint [1]byte
+ if len(value) == 0 {
+ chomp_hint[0] = '-'
+ } else {
+ i := len(value) - 1
+ for value[i]&0xC0 == 0x80 {
+ i--
+ }
+ if !is_break(value, i) {
+ chomp_hint[0] = '-'
+ } else if i == 0 {
+ chomp_hint[0] = '+'
+ emitter.open_ended = true
+ } else {
+ i--
+ for value[i]&0xC0 == 0x80 {
+ i--
+ }
+ if is_break(value, i) {
+ chomp_hint[0] = '+'
+ emitter.open_ended = true
+ }
+ }
+ }
+ if chomp_hint[0] != 0 {
+ if !yaml_emitter_write_indicator(emitter, chomp_hint[:], false, false, false) {
+ return false
+ }
+ }
+ return true
+}
+
+func yaml_emitter_write_literal_scalar(emitter *yaml_emitter_t, value []byte) bool {
+ if !yaml_emitter_write_indicator(emitter, []byte{'|'}, true, false, false) {
+ return false
+ }
+ if !yaml_emitter_write_block_scalar_hints(emitter, value) {
+ return false
+ }
+ if !put_break(emitter) {
+ return false
+ }
+ emitter.indention = true
+ emitter.whitespace = true
+ breaks := true
+ for i := 0; i < len(value); {
+ if is_break(value, i) {
+ if !write_break(emitter, value, &i) {
+ return false
+ }
+ emitter.indention = true
+ breaks = true
+ } else {
+ if breaks {
+ if !yaml_emitter_write_indent(emitter) {
+ return false
+ }
+ }
+ if !write(emitter, value, &i) {
+ return false
+ }
+ emitter.indention = false
+ breaks = false
+ }
+ }
+
+ return true
+}
+
+func yaml_emitter_write_folded_scalar(emitter *yaml_emitter_t, value []byte) bool {
+ if !yaml_emitter_write_indicator(emitter, []byte{'>'}, true, false, false) {
+ return false
+ }
+ if !yaml_emitter_write_block_scalar_hints(emitter, value) {
+ return false
+ }
+
+ if !put_break(emitter) {
+ return false
+ }
+ emitter.indention = true
+ emitter.whitespace = true
+
+ breaks := true
+ leading_spaces := true
+ for i := 0; i < len(value); {
+ if is_break(value, i) {
+ if !breaks && !leading_spaces && value[i] == '\n' {
+ k := 0
+ for is_break(value, k) {
+ k += width(value[k])
+ }
+ if !is_blankz(value, k) {
+ if !put_break(emitter) {
+ return false
+ }
+ }
+ }
+ if !write_break(emitter, value, &i) {
+ return false
+ }
+ emitter.indention = true
+ breaks = true
+ } else {
+ if breaks {
+ if !yaml_emitter_write_indent(emitter) {
+ return false
+ }
+ leading_spaces = is_blank(value, i)
+ }
+ if !breaks && is_space(value, i) && !is_space(value, i+1) && emitter.column > emitter.best_width {
+ if !yaml_emitter_write_indent(emitter) {
+ return false
+ }
+ i += width(value[i])
+ } else {
+ if !write(emitter, value, &i) {
+ return false
+ }
+ }
+ emitter.indention = false
+ breaks = false
+ }
+ }
+ return true
+}
diff --git a/vendor/gopkg.in/yaml.v2/encode.go b/vendor/gopkg.in/yaml.v2/encode.go
new file mode 100644
index 0000000000000000000000000000000000000000..0ee738e11b6738a901b552764e2ed0ef5bba7913
--- /dev/null
+++ b/vendor/gopkg.in/yaml.v2/encode.go
@@ -0,0 +1,390 @@
+package yaml
+
+import (
+ "encoding"
+ "fmt"
+ "io"
+ "reflect"
+ "regexp"
+ "sort"
+ "strconv"
+ "strings"
+ "time"
+ "unicode/utf8"
+)
+
+// jsonNumber is the interface of the encoding/json.Number datatype.
+// Repeating the interface here avoids a dependency on encoding/json, and also
+// supports other libraries like jsoniter, which use a similar datatype with
+// the same interface. Detecting this interface is useful when dealing with
+// structures containing json.Number, which is a string under the hood. The
+// encoder should prefer the use of Int64(), Float64() and string(), in that
+// order, when encoding this type.
+type jsonNumber interface {
+ Float64() (float64, error)
+ Int64() (int64, error)
+ String() string
+}
+
+type encoder struct {
+ emitter yaml_emitter_t
+ event yaml_event_t
+ out []byte
+ flow bool
+ // doneInit holds whether the initial stream_start_event has been
+ // emitted.
+ doneInit bool
+}
+
+func newEncoder() *encoder {
+ e := &encoder{}
+ yaml_emitter_initialize(&e.emitter)
+ yaml_emitter_set_output_string(&e.emitter, &e.out)
+ yaml_emitter_set_unicode(&e.emitter, true)
+ return e
+}
+
+func newEncoderWithWriter(w io.Writer) *encoder {
+ e := &encoder{}
+ yaml_emitter_initialize(&e.emitter)
+ yaml_emitter_set_output_writer(&e.emitter, w)
+ yaml_emitter_set_unicode(&e.emitter, true)
+ return e
+}
+
+func (e *encoder) init() {
+ if e.doneInit {
+ return
+ }
+ yaml_stream_start_event_initialize(&e.event, yaml_UTF8_ENCODING)
+ e.emit()
+ e.doneInit = true
+}
+
+func (e *encoder) finish() {
+ e.emitter.open_ended = false
+ yaml_stream_end_event_initialize(&e.event)
+ e.emit()
+}
+
+func (e *encoder) destroy() {
+ yaml_emitter_delete(&e.emitter)
+}
+
+func (e *encoder) emit() {
+ // This will internally delete the e.event value.
+ e.must(yaml_emitter_emit(&e.emitter, &e.event))
+}
+
+func (e *encoder) must(ok bool) {
+ if !ok {
+ msg := e.emitter.problem
+ if msg == "" {
+ msg = "unknown problem generating YAML content"
+ }
+ failf("%s", msg)
+ }
+}
+
+func (e *encoder) marshalDoc(tag string, in reflect.Value) {
+ e.init()
+ yaml_document_start_event_initialize(&e.event, nil, nil, true)
+ e.emit()
+ e.marshal(tag, in)
+ yaml_document_end_event_initialize(&e.event, true)
+ e.emit()
+}
+
+func (e *encoder) marshal(tag string, in reflect.Value) {
+ if !in.IsValid() || in.Kind() == reflect.Ptr && in.IsNil() {
+ e.nilv()
+ return
+ }
+ iface := in.Interface()
+ switch m := iface.(type) {
+ case jsonNumber:
+ integer, err := m.Int64()
+ if err == nil {
+ // In this case the json.Number is a valid int64
+ in = reflect.ValueOf(integer)
+ break
+ }
+ float, err := m.Float64()
+ if err == nil {
+ // In this case the json.Number is a valid float64
+ in = reflect.ValueOf(float)
+ break
+ }
+ // fallback case - no number could be obtained
+ in = reflect.ValueOf(m.String())
+ case time.Time, *time.Time:
+ // Although time.Time implements TextMarshaler,
+ // we don't want to treat it as a string for YAML
+ // purposes because YAML has special support for
+ // timestamps.
+ case Marshaler:
+ v, err := m.MarshalYAML()
+ if err != nil {
+ fail(err)
+ }
+ if v == nil {
+ e.nilv()
+ return
+ }
+ in = reflect.ValueOf(v)
+ case encoding.TextMarshaler:
+ text, err := m.MarshalText()
+ if err != nil {
+ fail(err)
+ }
+ in = reflect.ValueOf(string(text))
+ case nil:
+ e.nilv()
+ return
+ }
+ switch in.Kind() {
+ case reflect.Interface:
+ e.marshal(tag, in.Elem())
+ case reflect.Map:
+ e.mapv(tag, in)
+ case reflect.Ptr:
+ if in.Type() == ptrTimeType {
+ e.timev(tag, in.Elem())
+ } else {
+ e.marshal(tag, in.Elem())
+ }
+ case reflect.Struct:
+ if in.Type() == timeType {
+ e.timev(tag, in)
+ } else {
+ e.structv(tag, in)
+ }
+ case reflect.Slice, reflect.Array:
+ if in.Type().Elem() == mapItemType {
+ e.itemsv(tag, in)
+ } else {
+ e.slicev(tag, in)
+ }
+ case reflect.String:
+ e.stringv(tag, in)
+ case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+ if in.Type() == durationType {
+ e.stringv(tag, reflect.ValueOf(iface.(time.Duration).String()))
+ } else {
+ e.intv(tag, in)
+ }
+ case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
+ e.uintv(tag, in)
+ case reflect.Float32, reflect.Float64:
+ e.floatv(tag, in)
+ case reflect.Bool:
+ e.boolv(tag, in)
+ default:
+ panic("cannot marshal type: " + in.Type().String())
+ }
+}
+
+func (e *encoder) mapv(tag string, in reflect.Value) {
+ e.mappingv(tag, func() {
+ keys := keyList(in.MapKeys())
+ sort.Sort(keys)
+ for _, k := range keys {
+ e.marshal("", k)
+ e.marshal("", in.MapIndex(k))
+ }
+ })
+}
+
+func (e *encoder) itemsv(tag string, in reflect.Value) {
+ e.mappingv(tag, func() {
+ slice := in.Convert(reflect.TypeOf([]MapItem{})).Interface().([]MapItem)
+ for _, item := range slice {
+ e.marshal("", reflect.ValueOf(item.Key))
+ e.marshal("", reflect.ValueOf(item.Value))
+ }
+ })
+}
+
+func (e *encoder) structv(tag string, in reflect.Value) {
+ sinfo, err := getStructInfo(in.Type())
+ if err != nil {
+ panic(err)
+ }
+ e.mappingv(tag, func() {
+ for _, info := range sinfo.FieldsList {
+ var value reflect.Value
+ if info.Inline == nil {
+ value = in.Field(info.Num)
+ } else {
+ value = in.FieldByIndex(info.Inline)
+ }
+ if info.OmitEmpty && isZero(value) {
+ continue
+ }
+ e.marshal("", reflect.ValueOf(info.Key))
+ e.flow = info.Flow
+ e.marshal("", value)
+ }
+ if sinfo.InlineMap >= 0 {
+ m := in.Field(sinfo.InlineMap)
+ if m.Len() > 0 {
+ e.flow = false
+ keys := keyList(m.MapKeys())
+ sort.Sort(keys)
+ for _, k := range keys {
+ if _, found := sinfo.FieldsMap[k.String()]; found {
+ panic(fmt.Sprintf("Can't have key %q in inlined map; conflicts with struct field", k.String()))
+ }
+ e.marshal("", k)
+ e.flow = false
+ e.marshal("", m.MapIndex(k))
+ }
+ }
+ }
+ })
+}
+
+func (e *encoder) mappingv(tag string, f func()) {
+ implicit := tag == ""
+ style := yaml_BLOCK_MAPPING_STYLE
+ if e.flow {
+ e.flow = false
+ style = yaml_FLOW_MAPPING_STYLE
+ }
+ yaml_mapping_start_event_initialize(&e.event, nil, []byte(tag), implicit, style)
+ e.emit()
+ f()
+ yaml_mapping_end_event_initialize(&e.event)
+ e.emit()
+}
+
+func (e *encoder) slicev(tag string, in reflect.Value) {
+ implicit := tag == ""
+ style := yaml_BLOCK_SEQUENCE_STYLE
+ if e.flow {
+ e.flow = false
+ style = yaml_FLOW_SEQUENCE_STYLE
+ }
+ e.must(yaml_sequence_start_event_initialize(&e.event, nil, []byte(tag), implicit, style))
+ e.emit()
+ n := in.Len()
+ for i := 0; i < n; i++ {
+ e.marshal("", in.Index(i))
+ }
+ e.must(yaml_sequence_end_event_initialize(&e.event))
+ e.emit()
+}
+
+// isBase60 returns whether s is in base 60 notation as defined in YAML 1.1.
+//
+// The base 60 float notation in YAML 1.1 is a terrible idea and is unsupported
+// in YAML 1.2 and by this package, but these should be marshalled quoted for
+// the time being for compatibility with other parsers.
+func isBase60Float(s string) (result bool) {
+ // Fast path.
+ if s == "" {
+ return false
+ }
+ c := s[0]
+ if !(c == '+' || c == '-' || c >= '0' && c <= '9') || strings.IndexByte(s, ':') < 0 {
+ return false
+ }
+ // Do the full match.
+ return base60float.MatchString(s)
+}
+
+// From http://yaml.org/type/float.html, except the regular expression there
+// is bogus. In practice parsers do not enforce the "\.[0-9_]*" suffix.
+var base60float = regexp.MustCompile(`^[-+]?[0-9][0-9_]*(?::[0-5]?[0-9])+(?:\.[0-9_]*)?$`)
+
+func (e *encoder) stringv(tag string, in reflect.Value) {
+ var style yaml_scalar_style_t
+ s := in.String()
+ canUsePlain := true
+ switch {
+ case !utf8.ValidString(s):
+ if tag == yaml_BINARY_TAG {
+ failf("explicitly tagged !!binary data must be base64-encoded")
+ }
+ if tag != "" {
+ failf("cannot marshal invalid UTF-8 data as %s", shortTag(tag))
+ }
+ // It can't be encoded directly as YAML so use a binary tag
+ // and encode it as base64.
+ tag = yaml_BINARY_TAG
+ s = encodeBase64(s)
+ case tag == "":
+ // Check to see if it would resolve to a specific
+ // tag when encoded unquoted. If it doesn't,
+ // there's no need to quote it.
+ rtag, _ := resolve("", s)
+ canUsePlain = rtag == yaml_STR_TAG && !isBase60Float(s)
+ }
+ // Note: it's possible for user code to emit invalid YAML
+ // if they explicitly specify a tag and a string containing
+ // text that's incompatible with that tag.
+ switch {
+ case strings.Contains(s, "\n"):
+ style = yaml_LITERAL_SCALAR_STYLE
+ case canUsePlain:
+ style = yaml_PLAIN_SCALAR_STYLE
+ default:
+ style = yaml_DOUBLE_QUOTED_SCALAR_STYLE
+ }
+ e.emitScalar(s, "", tag, style)
+}
+
+func (e *encoder) boolv(tag string, in reflect.Value) {
+ var s string
+ if in.Bool() {
+ s = "true"
+ } else {
+ s = "false"
+ }
+ e.emitScalar(s, "", tag, yaml_PLAIN_SCALAR_STYLE)
+}
+
+func (e *encoder) intv(tag string, in reflect.Value) {
+ s := strconv.FormatInt(in.Int(), 10)
+ e.emitScalar(s, "", tag, yaml_PLAIN_SCALAR_STYLE)
+}
+
+func (e *encoder) uintv(tag string, in reflect.Value) {
+ s := strconv.FormatUint(in.Uint(), 10)
+ e.emitScalar(s, "", tag, yaml_PLAIN_SCALAR_STYLE)
+}
+
+func (e *encoder) timev(tag string, in reflect.Value) {
+ t := in.Interface().(time.Time)
+ s := t.Format(time.RFC3339Nano)
+ e.emitScalar(s, "", tag, yaml_PLAIN_SCALAR_STYLE)
+}
+
+func (e *encoder) floatv(tag string, in reflect.Value) {
+ // Issue #352: When formatting, use the precision of the underlying value
+ precision := 64
+ if in.Kind() == reflect.Float32 {
+ precision = 32
+ }
+
+ s := strconv.FormatFloat(in.Float(), 'g', -1, precision)
+ switch s {
+ case "+Inf":
+ s = ".inf"
+ case "-Inf":
+ s = "-.inf"
+ case "NaN":
+ s = ".nan"
+ }
+ e.emitScalar(s, "", tag, yaml_PLAIN_SCALAR_STYLE)
+}
+
+func (e *encoder) nilv() {
+ e.emitScalar("null", "", "", yaml_PLAIN_SCALAR_STYLE)
+}
+
+func (e *encoder) emitScalar(value, anchor, tag string, style yaml_scalar_style_t) {
+ implicit := tag == ""
+ e.must(yaml_scalar_event_initialize(&e.event, []byte(anchor), []byte(tag), []byte(value), implicit, implicit, style))
+ e.emit()
+}
diff --git a/vendor/gopkg.in/yaml.v2/go.mod b/vendor/gopkg.in/yaml.v2/go.mod
new file mode 100644
index 0000000000000000000000000000000000000000..1934e876945021c3ac47d0aab161477e43ae35a4
--- /dev/null
+++ b/vendor/gopkg.in/yaml.v2/go.mod
@@ -0,0 +1,5 @@
+module "gopkg.in/yaml.v2"
+
+require (
+ "gopkg.in/check.v1" v0.0.0-20161208181325-20d25e280405
+)
diff --git a/vendor/gopkg.in/yaml.v2/parserc.go b/vendor/gopkg.in/yaml.v2/parserc.go
new file mode 100644
index 0000000000000000000000000000000000000000..81d05dfe573f920d4687ddfd2a9ccb371da7ba81
--- /dev/null
+++ b/vendor/gopkg.in/yaml.v2/parserc.go
@@ -0,0 +1,1095 @@
+package yaml
+
+import (
+ "bytes"
+)
+
+// The parser implements the following grammar:
+//
+// stream ::= STREAM-START implicit_document? explicit_document* STREAM-END
+// implicit_document ::= block_node DOCUMENT-END*
+// explicit_document ::= DIRECTIVE* DOCUMENT-START block_node? DOCUMENT-END*
+// block_node_or_indentless_sequence ::=
+// ALIAS
+// | properties (block_content | indentless_block_sequence)?
+// | block_content
+// | indentless_block_sequence
+// block_node ::= ALIAS
+// | properties block_content?
+// | block_content
+// flow_node ::= ALIAS
+// | properties flow_content?
+// | flow_content
+// properties ::= TAG ANCHOR? | ANCHOR TAG?
+// block_content ::= block_collection | flow_collection | SCALAR
+// flow_content ::= flow_collection | SCALAR
+// block_collection ::= block_sequence | block_mapping
+// flow_collection ::= flow_sequence | flow_mapping
+// block_sequence ::= BLOCK-SEQUENCE-START (BLOCK-ENTRY block_node?)* BLOCK-END
+// indentless_sequence ::= (BLOCK-ENTRY block_node?)+
+// block_mapping ::= BLOCK-MAPPING_START
+// ((KEY block_node_or_indentless_sequence?)?
+// (VALUE block_node_or_indentless_sequence?)?)*
+// BLOCK-END
+// flow_sequence ::= FLOW-SEQUENCE-START
+// (flow_sequence_entry FLOW-ENTRY)*
+// flow_sequence_entry?
+// FLOW-SEQUENCE-END
+// flow_sequence_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)?
+// flow_mapping ::= FLOW-MAPPING-START
+// (flow_mapping_entry FLOW-ENTRY)*
+// flow_mapping_entry?
+// FLOW-MAPPING-END
+// flow_mapping_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)?
+
+// Peek the next token in the token queue.
+func peek_token(parser *yaml_parser_t) *yaml_token_t {
+ if parser.token_available || yaml_parser_fetch_more_tokens(parser) {
+ return &parser.tokens[parser.tokens_head]
+ }
+ return nil
+}
+
+// Remove the next token from the queue (must be called after peek_token).
+func skip_token(parser *yaml_parser_t) {
+ parser.token_available = false
+ parser.tokens_parsed++
+ parser.stream_end_produced = parser.tokens[parser.tokens_head].typ == yaml_STREAM_END_TOKEN
+ parser.tokens_head++
+}
+
+// Get the next event.
+func yaml_parser_parse(parser *yaml_parser_t, event *yaml_event_t) bool {
+ // Erase the event object.
+ *event = yaml_event_t{}
+
+ // No events after the end of the stream or error.
+ if parser.stream_end_produced || parser.error != yaml_NO_ERROR || parser.state == yaml_PARSE_END_STATE {
+ return true
+ }
+
+ // Generate the next event.
+ return yaml_parser_state_machine(parser, event)
+}
+
+// Set parser error.
+func yaml_parser_set_parser_error(parser *yaml_parser_t, problem string, problem_mark yaml_mark_t) bool {
+ parser.error = yaml_PARSER_ERROR
+ parser.problem = problem
+ parser.problem_mark = problem_mark
+ return false
+}
+
+func yaml_parser_set_parser_error_context(parser *yaml_parser_t, context string, context_mark yaml_mark_t, problem string, problem_mark yaml_mark_t) bool {
+ parser.error = yaml_PARSER_ERROR
+ parser.context = context
+ parser.context_mark = context_mark
+ parser.problem = problem
+ parser.problem_mark = problem_mark
+ return false
+}
+
+// State dispatcher.
+func yaml_parser_state_machine(parser *yaml_parser_t, event *yaml_event_t) bool {
+ //trace("yaml_parser_state_machine", "state:", parser.state.String())
+
+ switch parser.state {
+ case yaml_PARSE_STREAM_START_STATE:
+ return yaml_parser_parse_stream_start(parser, event)
+
+ case yaml_PARSE_IMPLICIT_DOCUMENT_START_STATE:
+ return yaml_parser_parse_document_start(parser, event, true)
+
+ case yaml_PARSE_DOCUMENT_START_STATE:
+ return yaml_parser_parse_document_start(parser, event, false)
+
+ case yaml_PARSE_DOCUMENT_CONTENT_STATE:
+ return yaml_parser_parse_document_content(parser, event)
+
+ case yaml_PARSE_DOCUMENT_END_STATE:
+ return yaml_parser_parse_document_end(parser, event)
+
+ case yaml_PARSE_BLOCK_NODE_STATE:
+ return yaml_parser_parse_node(parser, event, true, false)
+
+ case yaml_PARSE_BLOCK_NODE_OR_INDENTLESS_SEQUENCE_STATE:
+ return yaml_parser_parse_node(parser, event, true, true)
+
+ case yaml_PARSE_FLOW_NODE_STATE:
+ return yaml_parser_parse_node(parser, event, false, false)
+
+ case yaml_PARSE_BLOCK_SEQUENCE_FIRST_ENTRY_STATE:
+ return yaml_parser_parse_block_sequence_entry(parser, event, true)
+
+ case yaml_PARSE_BLOCK_SEQUENCE_ENTRY_STATE:
+ return yaml_parser_parse_block_sequence_entry(parser, event, false)
+
+ case yaml_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE:
+ return yaml_parser_parse_indentless_sequence_entry(parser, event)
+
+ case yaml_PARSE_BLOCK_MAPPING_FIRST_KEY_STATE:
+ return yaml_parser_parse_block_mapping_key(parser, event, true)
+
+ case yaml_PARSE_BLOCK_MAPPING_KEY_STATE:
+ return yaml_parser_parse_block_mapping_key(parser, event, false)
+
+ case yaml_PARSE_BLOCK_MAPPING_VALUE_STATE:
+ return yaml_parser_parse_block_mapping_value(parser, event)
+
+ case yaml_PARSE_FLOW_SEQUENCE_FIRST_ENTRY_STATE:
+ return yaml_parser_parse_flow_sequence_entry(parser, event, true)
+
+ case yaml_PARSE_FLOW_SEQUENCE_ENTRY_STATE:
+ return yaml_parser_parse_flow_sequence_entry(parser, event, false)
+
+ case yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_KEY_STATE:
+ return yaml_parser_parse_flow_sequence_entry_mapping_key(parser, event)
+
+ case yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_VALUE_STATE:
+ return yaml_parser_parse_flow_sequence_entry_mapping_value(parser, event)
+
+ case yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_END_STATE:
+ return yaml_parser_parse_flow_sequence_entry_mapping_end(parser, event)
+
+ case yaml_PARSE_FLOW_MAPPING_FIRST_KEY_STATE:
+ return yaml_parser_parse_flow_mapping_key(parser, event, true)
+
+ case yaml_PARSE_FLOW_MAPPING_KEY_STATE:
+ return yaml_parser_parse_flow_mapping_key(parser, event, false)
+
+ case yaml_PARSE_FLOW_MAPPING_VALUE_STATE:
+ return yaml_parser_parse_flow_mapping_value(parser, event, false)
+
+ case yaml_PARSE_FLOW_MAPPING_EMPTY_VALUE_STATE:
+ return yaml_parser_parse_flow_mapping_value(parser, event, true)
+
+ default:
+ panic("invalid parser state")
+ }
+}
+
+// Parse the production:
+// stream ::= STREAM-START implicit_document? explicit_document* STREAM-END
+// ************
+func yaml_parser_parse_stream_start(parser *yaml_parser_t, event *yaml_event_t) bool {
+ token := peek_token(parser)
+ if token == nil {
+ return false
+ }
+ if token.typ != yaml_STREAM_START_TOKEN {
+ return yaml_parser_set_parser_error(parser, "did not find expected ", token.start_mark)
+ }
+ parser.state = yaml_PARSE_IMPLICIT_DOCUMENT_START_STATE
+ *event = yaml_event_t{
+ typ: yaml_STREAM_START_EVENT,
+ start_mark: token.start_mark,
+ end_mark: token.end_mark,
+ encoding: token.encoding,
+ }
+ skip_token(parser)
+ return true
+}
+
+// Parse the productions:
+// implicit_document ::= block_node DOCUMENT-END*
+// *
+// explicit_document ::= DIRECTIVE* DOCUMENT-START block_node? DOCUMENT-END*
+// *************************
+func yaml_parser_parse_document_start(parser *yaml_parser_t, event *yaml_event_t, implicit bool) bool {
+
+ token := peek_token(parser)
+ if token == nil {
+ return false
+ }
+
+ // Parse extra document end indicators.
+ if !implicit {
+ for token.typ == yaml_DOCUMENT_END_TOKEN {
+ skip_token(parser)
+ token = peek_token(parser)
+ if token == nil {
+ return false
+ }
+ }
+ }
+
+ if implicit && token.typ != yaml_VERSION_DIRECTIVE_TOKEN &&
+ token.typ != yaml_TAG_DIRECTIVE_TOKEN &&
+ token.typ != yaml_DOCUMENT_START_TOKEN &&
+ token.typ != yaml_STREAM_END_TOKEN {
+ // Parse an implicit document.
+ if !yaml_parser_process_directives(parser, nil, nil) {
+ return false
+ }
+ parser.states = append(parser.states, yaml_PARSE_DOCUMENT_END_STATE)
+ parser.state = yaml_PARSE_BLOCK_NODE_STATE
+
+ *event = yaml_event_t{
+ typ: yaml_DOCUMENT_START_EVENT,
+ start_mark: token.start_mark,
+ end_mark: token.end_mark,
+ }
+
+ } else if token.typ != yaml_STREAM_END_TOKEN {
+ // Parse an explicit document.
+ var version_directive *yaml_version_directive_t
+ var tag_directives []yaml_tag_directive_t
+ start_mark := token.start_mark
+ if !yaml_parser_process_directives(parser, &version_directive, &tag_directives) {
+ return false
+ }
+ token = peek_token(parser)
+ if token == nil {
+ return false
+ }
+ if token.typ != yaml_DOCUMENT_START_TOKEN {
+ yaml_parser_set_parser_error(parser,
+ "did not find expected ", token.start_mark)
+ return false
+ }
+ parser.states = append(parser.states, yaml_PARSE_DOCUMENT_END_STATE)
+ parser.state = yaml_PARSE_DOCUMENT_CONTENT_STATE
+ end_mark := token.end_mark
+
+ *event = yaml_event_t{
+ typ: yaml_DOCUMENT_START_EVENT,
+ start_mark: start_mark,
+ end_mark: end_mark,
+ version_directive: version_directive,
+ tag_directives: tag_directives,
+ implicit: false,
+ }
+ skip_token(parser)
+
+ } else {
+ // Parse the stream end.
+ parser.state = yaml_PARSE_END_STATE
+ *event = yaml_event_t{
+ typ: yaml_STREAM_END_EVENT,
+ start_mark: token.start_mark,
+ end_mark: token.end_mark,
+ }
+ skip_token(parser)
+ }
+
+ return true
+}
+
+// Parse the productions:
+// explicit_document ::= DIRECTIVE* DOCUMENT-START block_node? DOCUMENT-END*
+// ***********
+//
+func yaml_parser_parse_document_content(parser *yaml_parser_t, event *yaml_event_t) bool {
+ token := peek_token(parser)
+ if token == nil {
+ return false
+ }
+ if token.typ == yaml_VERSION_DIRECTIVE_TOKEN ||
+ token.typ == yaml_TAG_DIRECTIVE_TOKEN ||
+ token.typ == yaml_DOCUMENT_START_TOKEN ||
+ token.typ == yaml_DOCUMENT_END_TOKEN ||
+ token.typ == yaml_STREAM_END_TOKEN {
+ parser.state = parser.states[len(parser.states)-1]
+ parser.states = parser.states[:len(parser.states)-1]
+ return yaml_parser_process_empty_scalar(parser, event,
+ token.start_mark)
+ }
+ return yaml_parser_parse_node(parser, event, true, false)
+}
+
+// Parse the productions:
+// implicit_document ::= block_node DOCUMENT-END*
+// *************
+// explicit_document ::= DIRECTIVE* DOCUMENT-START block_node? DOCUMENT-END*
+//
+func yaml_parser_parse_document_end(parser *yaml_parser_t, event *yaml_event_t) bool {
+ token := peek_token(parser)
+ if token == nil {
+ return false
+ }
+
+ start_mark := token.start_mark
+ end_mark := token.start_mark
+
+ implicit := true
+ if token.typ == yaml_DOCUMENT_END_TOKEN {
+ end_mark = token.end_mark
+ skip_token(parser)
+ implicit = false
+ }
+
+ parser.tag_directives = parser.tag_directives[:0]
+
+ parser.state = yaml_PARSE_DOCUMENT_START_STATE
+ *event = yaml_event_t{
+ typ: yaml_DOCUMENT_END_EVENT,
+ start_mark: start_mark,
+ end_mark: end_mark,
+ implicit: implicit,
+ }
+ return true
+}
+
+// Parse the productions:
+// block_node_or_indentless_sequence ::=
+// ALIAS
+// *****
+// | properties (block_content | indentless_block_sequence)?
+// ********** *
+// | block_content | indentless_block_sequence
+// *
+// block_node ::= ALIAS
+// *****
+// | properties block_content?
+// ********** *
+// | block_content
+// *
+// flow_node ::= ALIAS
+// *****
+// | properties flow_content?
+// ********** *
+// | flow_content
+// *
+// properties ::= TAG ANCHOR? | ANCHOR TAG?
+// *************************
+// block_content ::= block_collection | flow_collection | SCALAR
+// ******
+// flow_content ::= flow_collection | SCALAR
+// ******
+func yaml_parser_parse_node(parser *yaml_parser_t, event *yaml_event_t, block, indentless_sequence bool) bool {
+ //defer trace("yaml_parser_parse_node", "block:", block, "indentless_sequence:", indentless_sequence)()
+
+ token := peek_token(parser)
+ if token == nil {
+ return false
+ }
+
+ if token.typ == yaml_ALIAS_TOKEN {
+ parser.state = parser.states[len(parser.states)-1]
+ parser.states = parser.states[:len(parser.states)-1]
+ *event = yaml_event_t{
+ typ: yaml_ALIAS_EVENT,
+ start_mark: token.start_mark,
+ end_mark: token.end_mark,
+ anchor: token.value,
+ }
+ skip_token(parser)
+ return true
+ }
+
+ start_mark := token.start_mark
+ end_mark := token.start_mark
+
+ var tag_token bool
+ var tag_handle, tag_suffix, anchor []byte
+ var tag_mark yaml_mark_t
+ if token.typ == yaml_ANCHOR_TOKEN {
+ anchor = token.value
+ start_mark = token.start_mark
+ end_mark = token.end_mark
+ skip_token(parser)
+ token = peek_token(parser)
+ if token == nil {
+ return false
+ }
+ if token.typ == yaml_TAG_TOKEN {
+ tag_token = true
+ tag_handle = token.value
+ tag_suffix = token.suffix
+ tag_mark = token.start_mark
+ end_mark = token.end_mark
+ skip_token(parser)
+ token = peek_token(parser)
+ if token == nil {
+ return false
+ }
+ }
+ } else if token.typ == yaml_TAG_TOKEN {
+ tag_token = true
+ tag_handle = token.value
+ tag_suffix = token.suffix
+ start_mark = token.start_mark
+ tag_mark = token.start_mark
+ end_mark = token.end_mark
+ skip_token(parser)
+ token = peek_token(parser)
+ if token == nil {
+ return false
+ }
+ if token.typ == yaml_ANCHOR_TOKEN {
+ anchor = token.value
+ end_mark = token.end_mark
+ skip_token(parser)
+ token = peek_token(parser)
+ if token == nil {
+ return false
+ }
+ }
+ }
+
+ var tag []byte
+ if tag_token {
+ if len(tag_handle) == 0 {
+ tag = tag_suffix
+ tag_suffix = nil
+ } else {
+ for i := range parser.tag_directives {
+ if bytes.Equal(parser.tag_directives[i].handle, tag_handle) {
+ tag = append([]byte(nil), parser.tag_directives[i].prefix...)
+ tag = append(tag, tag_suffix...)
+ break
+ }
+ }
+ if len(tag) == 0 {
+ yaml_parser_set_parser_error_context(parser,
+ "while parsing a node", start_mark,
+ "found undefined tag handle", tag_mark)
+ return false
+ }
+ }
+ }
+
+ implicit := len(tag) == 0
+ if indentless_sequence && token.typ == yaml_BLOCK_ENTRY_TOKEN {
+ end_mark = token.end_mark
+ parser.state = yaml_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE
+ *event = yaml_event_t{
+ typ: yaml_SEQUENCE_START_EVENT,
+ start_mark: start_mark,
+ end_mark: end_mark,
+ anchor: anchor,
+ tag: tag,
+ implicit: implicit,
+ style: yaml_style_t(yaml_BLOCK_SEQUENCE_STYLE),
+ }
+ return true
+ }
+ if token.typ == yaml_SCALAR_TOKEN {
+ var plain_implicit, quoted_implicit bool
+ end_mark = token.end_mark
+ if (len(tag) == 0 && token.style == yaml_PLAIN_SCALAR_STYLE) || (len(tag) == 1 && tag[0] == '!') {
+ plain_implicit = true
+ } else if len(tag) == 0 {
+ quoted_implicit = true
+ }
+ parser.state = parser.states[len(parser.states)-1]
+ parser.states = parser.states[:len(parser.states)-1]
+
+ *event = yaml_event_t{
+ typ: yaml_SCALAR_EVENT,
+ start_mark: start_mark,
+ end_mark: end_mark,
+ anchor: anchor,
+ tag: tag,
+ value: token.value,
+ implicit: plain_implicit,
+ quoted_implicit: quoted_implicit,
+ style: yaml_style_t(token.style),
+ }
+ skip_token(parser)
+ return true
+ }
+ if token.typ == yaml_FLOW_SEQUENCE_START_TOKEN {
+ // [Go] Some of the events below can be merged as they differ only on style.
+ end_mark = token.end_mark
+ parser.state = yaml_PARSE_FLOW_SEQUENCE_FIRST_ENTRY_STATE
+ *event = yaml_event_t{
+ typ: yaml_SEQUENCE_START_EVENT,
+ start_mark: start_mark,
+ end_mark: end_mark,
+ anchor: anchor,
+ tag: tag,
+ implicit: implicit,
+ style: yaml_style_t(yaml_FLOW_SEQUENCE_STYLE),
+ }
+ return true
+ }
+ if token.typ == yaml_FLOW_MAPPING_START_TOKEN {
+ end_mark = token.end_mark
+ parser.state = yaml_PARSE_FLOW_MAPPING_FIRST_KEY_STATE
+ *event = yaml_event_t{
+ typ: yaml_MAPPING_START_EVENT,
+ start_mark: start_mark,
+ end_mark: end_mark,
+ anchor: anchor,
+ tag: tag,
+ implicit: implicit,
+ style: yaml_style_t(yaml_FLOW_MAPPING_STYLE),
+ }
+ return true
+ }
+ if block && token.typ == yaml_BLOCK_SEQUENCE_START_TOKEN {
+ end_mark = token.end_mark
+ parser.state = yaml_PARSE_BLOCK_SEQUENCE_FIRST_ENTRY_STATE
+ *event = yaml_event_t{
+ typ: yaml_SEQUENCE_START_EVENT,
+ start_mark: start_mark,
+ end_mark: end_mark,
+ anchor: anchor,
+ tag: tag,
+ implicit: implicit,
+ style: yaml_style_t(yaml_BLOCK_SEQUENCE_STYLE),
+ }
+ return true
+ }
+ if block && token.typ == yaml_BLOCK_MAPPING_START_TOKEN {
+ end_mark = token.end_mark
+ parser.state = yaml_PARSE_BLOCK_MAPPING_FIRST_KEY_STATE
+ *event = yaml_event_t{
+ typ: yaml_MAPPING_START_EVENT,
+ start_mark: start_mark,
+ end_mark: end_mark,
+ anchor: anchor,
+ tag: tag,
+ implicit: implicit,
+ style: yaml_style_t(yaml_BLOCK_MAPPING_STYLE),
+ }
+ return true
+ }
+ if len(anchor) > 0 || len(tag) > 0 {
+ parser.state = parser.states[len(parser.states)-1]
+ parser.states = parser.states[:len(parser.states)-1]
+
+ *event = yaml_event_t{
+ typ: yaml_SCALAR_EVENT,
+ start_mark: start_mark,
+ end_mark: end_mark,
+ anchor: anchor,
+ tag: tag,
+ implicit: implicit,
+ quoted_implicit: false,
+ style: yaml_style_t(yaml_PLAIN_SCALAR_STYLE),
+ }
+ return true
+ }
+
+ context := "while parsing a flow node"
+ if block {
+ context = "while parsing a block node"
+ }
+ yaml_parser_set_parser_error_context(parser, context, start_mark,
+ "did not find expected node content", token.start_mark)
+ return false
+}
+
+// Parse the productions:
+// block_sequence ::= BLOCK-SEQUENCE-START (BLOCK-ENTRY block_node?)* BLOCK-END
+// ******************** *********** * *********
+//
+func yaml_parser_parse_block_sequence_entry(parser *yaml_parser_t, event *yaml_event_t, first bool) bool {
+ if first {
+ token := peek_token(parser)
+ parser.marks = append(parser.marks, token.start_mark)
+ skip_token(parser)
+ }
+
+ token := peek_token(parser)
+ if token == nil {
+ return false
+ }
+
+ if token.typ == yaml_BLOCK_ENTRY_TOKEN {
+ mark := token.end_mark
+ skip_token(parser)
+ token = peek_token(parser)
+ if token == nil {
+ return false
+ }
+ if token.typ != yaml_BLOCK_ENTRY_TOKEN && token.typ != yaml_BLOCK_END_TOKEN {
+ parser.states = append(parser.states, yaml_PARSE_BLOCK_SEQUENCE_ENTRY_STATE)
+ return yaml_parser_parse_node(parser, event, true, false)
+ } else {
+ parser.state = yaml_PARSE_BLOCK_SEQUENCE_ENTRY_STATE
+ return yaml_parser_process_empty_scalar(parser, event, mark)
+ }
+ }
+ if token.typ == yaml_BLOCK_END_TOKEN {
+ parser.state = parser.states[len(parser.states)-1]
+ parser.states = parser.states[:len(parser.states)-1]
+ parser.marks = parser.marks[:len(parser.marks)-1]
+
+ *event = yaml_event_t{
+ typ: yaml_SEQUENCE_END_EVENT,
+ start_mark: token.start_mark,
+ end_mark: token.end_mark,
+ }
+
+ skip_token(parser)
+ return true
+ }
+
+ context_mark := parser.marks[len(parser.marks)-1]
+ parser.marks = parser.marks[:len(parser.marks)-1]
+ return yaml_parser_set_parser_error_context(parser,
+ "while parsing a block collection", context_mark,
+ "did not find expected '-' indicator", token.start_mark)
+}
+
+// Parse the productions:
+// indentless_sequence ::= (BLOCK-ENTRY block_node?)+
+// *********** *
+func yaml_parser_parse_indentless_sequence_entry(parser *yaml_parser_t, event *yaml_event_t) bool {
+ token := peek_token(parser)
+ if token == nil {
+ return false
+ }
+
+ if token.typ == yaml_BLOCK_ENTRY_TOKEN {
+ mark := token.end_mark
+ skip_token(parser)
+ token = peek_token(parser)
+ if token == nil {
+ return false
+ }
+ if token.typ != yaml_BLOCK_ENTRY_TOKEN &&
+ token.typ != yaml_KEY_TOKEN &&
+ token.typ != yaml_VALUE_TOKEN &&
+ token.typ != yaml_BLOCK_END_TOKEN {
+ parser.states = append(parser.states, yaml_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE)
+ return yaml_parser_parse_node(parser, event, true, false)
+ }
+ parser.state = yaml_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE
+ return yaml_parser_process_empty_scalar(parser, event, mark)
+ }
+ parser.state = parser.states[len(parser.states)-1]
+ parser.states = parser.states[:len(parser.states)-1]
+
+ *event = yaml_event_t{
+ typ: yaml_SEQUENCE_END_EVENT,
+ start_mark: token.start_mark,
+ end_mark: token.start_mark, // [Go] Shouldn't this be token.end_mark?
+ }
+ return true
+}
+
+// Parse the productions:
+// block_mapping ::= BLOCK-MAPPING_START
+// *******************
+// ((KEY block_node_or_indentless_sequence?)?
+// *** *
+// (VALUE block_node_or_indentless_sequence?)?)*
+//
+// BLOCK-END
+// *********
+//
+func yaml_parser_parse_block_mapping_key(parser *yaml_parser_t, event *yaml_event_t, first bool) bool {
+ if first {
+ token := peek_token(parser)
+ parser.marks = append(parser.marks, token.start_mark)
+ skip_token(parser)
+ }
+
+ token := peek_token(parser)
+ if token == nil {
+ return false
+ }
+
+ if token.typ == yaml_KEY_TOKEN {
+ mark := token.end_mark
+ skip_token(parser)
+ token = peek_token(parser)
+ if token == nil {
+ return false
+ }
+ if token.typ != yaml_KEY_TOKEN &&
+ token.typ != yaml_VALUE_TOKEN &&
+ token.typ != yaml_BLOCK_END_TOKEN {
+ parser.states = append(parser.states, yaml_PARSE_BLOCK_MAPPING_VALUE_STATE)
+ return yaml_parser_parse_node(parser, event, true, true)
+ } else {
+ parser.state = yaml_PARSE_BLOCK_MAPPING_VALUE_STATE
+ return yaml_parser_process_empty_scalar(parser, event, mark)
+ }
+ } else if token.typ == yaml_BLOCK_END_TOKEN {
+ parser.state = parser.states[len(parser.states)-1]
+ parser.states = parser.states[:len(parser.states)-1]
+ parser.marks = parser.marks[:len(parser.marks)-1]
+ *event = yaml_event_t{
+ typ: yaml_MAPPING_END_EVENT,
+ start_mark: token.start_mark,
+ end_mark: token.end_mark,
+ }
+ skip_token(parser)
+ return true
+ }
+
+ context_mark := parser.marks[len(parser.marks)-1]
+ parser.marks = parser.marks[:len(parser.marks)-1]
+ return yaml_parser_set_parser_error_context(parser,
+ "while parsing a block mapping", context_mark,
+ "did not find expected key", token.start_mark)
+}
+
+// Parse the productions:
+// block_mapping ::= BLOCK-MAPPING_START
+//
+// ((KEY block_node_or_indentless_sequence?)?
+//
+// (VALUE block_node_or_indentless_sequence?)?)*
+// ***** *
+// BLOCK-END
+//
+//
+func yaml_parser_parse_block_mapping_value(parser *yaml_parser_t, event *yaml_event_t) bool {
+ token := peek_token(parser)
+ if token == nil {
+ return false
+ }
+ if token.typ == yaml_VALUE_TOKEN {
+ mark := token.end_mark
+ skip_token(parser)
+ token = peek_token(parser)
+ if token == nil {
+ return false
+ }
+ if token.typ != yaml_KEY_TOKEN &&
+ token.typ != yaml_VALUE_TOKEN &&
+ token.typ != yaml_BLOCK_END_TOKEN {
+ parser.states = append(parser.states, yaml_PARSE_BLOCK_MAPPING_KEY_STATE)
+ return yaml_parser_parse_node(parser, event, true, true)
+ }
+ parser.state = yaml_PARSE_BLOCK_MAPPING_KEY_STATE
+ return yaml_parser_process_empty_scalar(parser, event, mark)
+ }
+ parser.state = yaml_PARSE_BLOCK_MAPPING_KEY_STATE
+ return yaml_parser_process_empty_scalar(parser, event, token.start_mark)
+}
+
+// Parse the productions:
+// flow_sequence ::= FLOW-SEQUENCE-START
+// *******************
+// (flow_sequence_entry FLOW-ENTRY)*
+// * **********
+// flow_sequence_entry?
+// *
+// FLOW-SEQUENCE-END
+// *****************
+// flow_sequence_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)?
+// *
+//
+func yaml_parser_parse_flow_sequence_entry(parser *yaml_parser_t, event *yaml_event_t, first bool) bool {
+ if first {
+ token := peek_token(parser)
+ parser.marks = append(parser.marks, token.start_mark)
+ skip_token(parser)
+ }
+ token := peek_token(parser)
+ if token == nil {
+ return false
+ }
+ if token.typ != yaml_FLOW_SEQUENCE_END_TOKEN {
+ if !first {
+ if token.typ == yaml_FLOW_ENTRY_TOKEN {
+ skip_token(parser)
+ token = peek_token(parser)
+ if token == nil {
+ return false
+ }
+ } else {
+ context_mark := parser.marks[len(parser.marks)-1]
+ parser.marks = parser.marks[:len(parser.marks)-1]
+ return yaml_parser_set_parser_error_context(parser,
+ "while parsing a flow sequence", context_mark,
+ "did not find expected ',' or ']'", token.start_mark)
+ }
+ }
+
+ if token.typ == yaml_KEY_TOKEN {
+ parser.state = yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_KEY_STATE
+ *event = yaml_event_t{
+ typ: yaml_MAPPING_START_EVENT,
+ start_mark: token.start_mark,
+ end_mark: token.end_mark,
+ implicit: true,
+ style: yaml_style_t(yaml_FLOW_MAPPING_STYLE),
+ }
+ skip_token(parser)
+ return true
+ } else if token.typ != yaml_FLOW_SEQUENCE_END_TOKEN {
+ parser.states = append(parser.states, yaml_PARSE_FLOW_SEQUENCE_ENTRY_STATE)
+ return yaml_parser_parse_node(parser, event, false, false)
+ }
+ }
+
+ parser.state = parser.states[len(parser.states)-1]
+ parser.states = parser.states[:len(parser.states)-1]
+ parser.marks = parser.marks[:len(parser.marks)-1]
+
+ *event = yaml_event_t{
+ typ: yaml_SEQUENCE_END_EVENT,
+ start_mark: token.start_mark,
+ end_mark: token.end_mark,
+ }
+
+ skip_token(parser)
+ return true
+}
+
+//
+// Parse the productions:
+// flow_sequence_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)?
+// *** *
+//
+func yaml_parser_parse_flow_sequence_entry_mapping_key(parser *yaml_parser_t, event *yaml_event_t) bool {
+ token := peek_token(parser)
+ if token == nil {
+ return false
+ }
+ if token.typ != yaml_VALUE_TOKEN &&
+ token.typ != yaml_FLOW_ENTRY_TOKEN &&
+ token.typ != yaml_FLOW_SEQUENCE_END_TOKEN {
+ parser.states = append(parser.states, yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_VALUE_STATE)
+ return yaml_parser_parse_node(parser, event, false, false)
+ }
+ mark := token.end_mark
+ skip_token(parser)
+ parser.state = yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_VALUE_STATE
+ return yaml_parser_process_empty_scalar(parser, event, mark)
+}
+
+// Parse the productions:
+// flow_sequence_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)?
+// ***** *
+//
+func yaml_parser_parse_flow_sequence_entry_mapping_value(parser *yaml_parser_t, event *yaml_event_t) bool {
+ token := peek_token(parser)
+ if token == nil {
+ return false
+ }
+ if token.typ == yaml_VALUE_TOKEN {
+ skip_token(parser)
+ token := peek_token(parser)
+ if token == nil {
+ return false
+ }
+ if token.typ != yaml_FLOW_ENTRY_TOKEN && token.typ != yaml_FLOW_SEQUENCE_END_TOKEN {
+ parser.states = append(parser.states, yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_END_STATE)
+ return yaml_parser_parse_node(parser, event, false, false)
+ }
+ }
+ parser.state = yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_END_STATE
+ return yaml_parser_process_empty_scalar(parser, event, token.start_mark)
+}
+
+// Parse the productions:
+// flow_sequence_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)?
+// *
+//
+func yaml_parser_parse_flow_sequence_entry_mapping_end(parser *yaml_parser_t, event *yaml_event_t) bool {
+ token := peek_token(parser)
+ if token == nil {
+ return false
+ }
+ parser.state = yaml_PARSE_FLOW_SEQUENCE_ENTRY_STATE
+ *event = yaml_event_t{
+ typ: yaml_MAPPING_END_EVENT,
+ start_mark: token.start_mark,
+ end_mark: token.start_mark, // [Go] Shouldn't this be end_mark?
+ }
+ return true
+}
+
+// Parse the productions:
+// flow_mapping ::= FLOW-MAPPING-START
+// ******************
+// (flow_mapping_entry FLOW-ENTRY)*
+// * **********
+// flow_mapping_entry?
+// ******************
+// FLOW-MAPPING-END
+// ****************
+// flow_mapping_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)?
+// * *** *
+//
+func yaml_parser_parse_flow_mapping_key(parser *yaml_parser_t, event *yaml_event_t, first bool) bool {
+ if first {
+ token := peek_token(parser)
+ parser.marks = append(parser.marks, token.start_mark)
+ skip_token(parser)
+ }
+
+ token := peek_token(parser)
+ if token == nil {
+ return false
+ }
+
+ if token.typ != yaml_FLOW_MAPPING_END_TOKEN {
+ if !first {
+ if token.typ == yaml_FLOW_ENTRY_TOKEN {
+ skip_token(parser)
+ token = peek_token(parser)
+ if token == nil {
+ return false
+ }
+ } else {
+ context_mark := parser.marks[len(parser.marks)-1]
+ parser.marks = parser.marks[:len(parser.marks)-1]
+ return yaml_parser_set_parser_error_context(parser,
+ "while parsing a flow mapping", context_mark,
+ "did not find expected ',' or '}'", token.start_mark)
+ }
+ }
+
+ if token.typ == yaml_KEY_TOKEN {
+ skip_token(parser)
+ token = peek_token(parser)
+ if token == nil {
+ return false
+ }
+ if token.typ != yaml_VALUE_TOKEN &&
+ token.typ != yaml_FLOW_ENTRY_TOKEN &&
+ token.typ != yaml_FLOW_MAPPING_END_TOKEN {
+ parser.states = append(parser.states, yaml_PARSE_FLOW_MAPPING_VALUE_STATE)
+ return yaml_parser_parse_node(parser, event, false, false)
+ } else {
+ parser.state = yaml_PARSE_FLOW_MAPPING_VALUE_STATE
+ return yaml_parser_process_empty_scalar(parser, event, token.start_mark)
+ }
+ } else if token.typ != yaml_FLOW_MAPPING_END_TOKEN {
+ parser.states = append(parser.states, yaml_PARSE_FLOW_MAPPING_EMPTY_VALUE_STATE)
+ return yaml_parser_parse_node(parser, event, false, false)
+ }
+ }
+
+ parser.state = parser.states[len(parser.states)-1]
+ parser.states = parser.states[:len(parser.states)-1]
+ parser.marks = parser.marks[:len(parser.marks)-1]
+ *event = yaml_event_t{
+ typ: yaml_MAPPING_END_EVENT,
+ start_mark: token.start_mark,
+ end_mark: token.end_mark,
+ }
+ skip_token(parser)
+ return true
+}
+
+// Parse the productions:
+// flow_mapping_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)?
+// * ***** *
+//
+func yaml_parser_parse_flow_mapping_value(parser *yaml_parser_t, event *yaml_event_t, empty bool) bool {
+ token := peek_token(parser)
+ if token == nil {
+ return false
+ }
+ if empty {
+ parser.state = yaml_PARSE_FLOW_MAPPING_KEY_STATE
+ return yaml_parser_process_empty_scalar(parser, event, token.start_mark)
+ }
+ if token.typ == yaml_VALUE_TOKEN {
+ skip_token(parser)
+ token = peek_token(parser)
+ if token == nil {
+ return false
+ }
+ if token.typ != yaml_FLOW_ENTRY_TOKEN && token.typ != yaml_FLOW_MAPPING_END_TOKEN {
+ parser.states = append(parser.states, yaml_PARSE_FLOW_MAPPING_KEY_STATE)
+ return yaml_parser_parse_node(parser, event, false, false)
+ }
+ }
+ parser.state = yaml_PARSE_FLOW_MAPPING_KEY_STATE
+ return yaml_parser_process_empty_scalar(parser, event, token.start_mark)
+}
+
+// Generate an empty scalar event.
+func yaml_parser_process_empty_scalar(parser *yaml_parser_t, event *yaml_event_t, mark yaml_mark_t) bool {
+ *event = yaml_event_t{
+ typ: yaml_SCALAR_EVENT,
+ start_mark: mark,
+ end_mark: mark,
+ value: nil, // Empty
+ implicit: true,
+ style: yaml_style_t(yaml_PLAIN_SCALAR_STYLE),
+ }
+ return true
+}
+
+var default_tag_directives = []yaml_tag_directive_t{
+ {[]byte("!"), []byte("!")},
+ {[]byte("!!"), []byte("tag:yaml.org,2002:")},
+}
+
+// Parse directives.
+func yaml_parser_process_directives(parser *yaml_parser_t,
+ version_directive_ref **yaml_version_directive_t,
+ tag_directives_ref *[]yaml_tag_directive_t) bool {
+
+ var version_directive *yaml_version_directive_t
+ var tag_directives []yaml_tag_directive_t
+
+ token := peek_token(parser)
+ if token == nil {
+ return false
+ }
+
+ for token.typ == yaml_VERSION_DIRECTIVE_TOKEN || token.typ == yaml_TAG_DIRECTIVE_TOKEN {
+ if token.typ == yaml_VERSION_DIRECTIVE_TOKEN {
+ if version_directive != nil {
+ yaml_parser_set_parser_error(parser,
+ "found duplicate %YAML directive", token.start_mark)
+ return false
+ }
+ if token.major != 1 || token.minor != 1 {
+ yaml_parser_set_parser_error(parser,
+ "found incompatible YAML document", token.start_mark)
+ return false
+ }
+ version_directive = &yaml_version_directive_t{
+ major: token.major,
+ minor: token.minor,
+ }
+ } else if token.typ == yaml_TAG_DIRECTIVE_TOKEN {
+ value := yaml_tag_directive_t{
+ handle: token.value,
+ prefix: token.prefix,
+ }
+ if !yaml_parser_append_tag_directive(parser, value, false, token.start_mark) {
+ return false
+ }
+ tag_directives = append(tag_directives, value)
+ }
+
+ skip_token(parser)
+ token = peek_token(parser)
+ if token == nil {
+ return false
+ }
+ }
+
+ for i := range default_tag_directives {
+ if !yaml_parser_append_tag_directive(parser, default_tag_directives[i], true, token.start_mark) {
+ return false
+ }
+ }
+
+ if version_directive_ref != nil {
+ *version_directive_ref = version_directive
+ }
+ if tag_directives_ref != nil {
+ *tag_directives_ref = tag_directives
+ }
+ return true
+}
+
+// Append a tag directive to the directives stack.
+func yaml_parser_append_tag_directive(parser *yaml_parser_t, value yaml_tag_directive_t, allow_duplicates bool, mark yaml_mark_t) bool {
+ for i := range parser.tag_directives {
+ if bytes.Equal(value.handle, parser.tag_directives[i].handle) {
+ if allow_duplicates {
+ return true
+ }
+ return yaml_parser_set_parser_error(parser, "found duplicate %TAG directive", mark)
+ }
+ }
+
+ // [Go] I suspect the copy is unnecessary. This was likely done
+ // because there was no way to track ownership of the data.
+ value_copy := yaml_tag_directive_t{
+ handle: make([]byte, len(value.handle)),
+ prefix: make([]byte, len(value.prefix)),
+ }
+ copy(value_copy.handle, value.handle)
+ copy(value_copy.prefix, value.prefix)
+ parser.tag_directives = append(parser.tag_directives, value_copy)
+ return true
+}
diff --git a/vendor/gopkg.in/yaml.v2/readerc.go b/vendor/gopkg.in/yaml.v2/readerc.go
new file mode 100644
index 0000000000000000000000000000000000000000..7c1f5fac3dbd2bf54c77814ceb64068dbdf08679
--- /dev/null
+++ b/vendor/gopkg.in/yaml.v2/readerc.go
@@ -0,0 +1,412 @@
+package yaml
+
+import (
+ "io"
+)
+
+// Set the reader error and return 0.
+func yaml_parser_set_reader_error(parser *yaml_parser_t, problem string, offset int, value int) bool {
+ parser.error = yaml_READER_ERROR
+ parser.problem = problem
+ parser.problem_offset = offset
+ parser.problem_value = value
+ return false
+}
+
+// Byte order marks.
+const (
+ bom_UTF8 = "\xef\xbb\xbf"
+ bom_UTF16LE = "\xff\xfe"
+ bom_UTF16BE = "\xfe\xff"
+)
+
+// Determine the input stream encoding by checking the BOM symbol. If no BOM is
+// found, the UTF-8 encoding is assumed. Return 1 on success, 0 on failure.
+func yaml_parser_determine_encoding(parser *yaml_parser_t) bool {
+ // Ensure that we had enough bytes in the raw buffer.
+ for !parser.eof && len(parser.raw_buffer)-parser.raw_buffer_pos < 3 {
+ if !yaml_parser_update_raw_buffer(parser) {
+ return false
+ }
+ }
+
+ // Determine the encoding.
+ buf := parser.raw_buffer
+ pos := parser.raw_buffer_pos
+ avail := len(buf) - pos
+ if avail >= 2 && buf[pos] == bom_UTF16LE[0] && buf[pos+1] == bom_UTF16LE[1] {
+ parser.encoding = yaml_UTF16LE_ENCODING
+ parser.raw_buffer_pos += 2
+ parser.offset += 2
+ } else if avail >= 2 && buf[pos] == bom_UTF16BE[0] && buf[pos+1] == bom_UTF16BE[1] {
+ parser.encoding = yaml_UTF16BE_ENCODING
+ parser.raw_buffer_pos += 2
+ parser.offset += 2
+ } else if avail >= 3 && buf[pos] == bom_UTF8[0] && buf[pos+1] == bom_UTF8[1] && buf[pos+2] == bom_UTF8[2] {
+ parser.encoding = yaml_UTF8_ENCODING
+ parser.raw_buffer_pos += 3
+ parser.offset += 3
+ } else {
+ parser.encoding = yaml_UTF8_ENCODING
+ }
+ return true
+}
+
+// Update the raw buffer.
+func yaml_parser_update_raw_buffer(parser *yaml_parser_t) bool {
+ size_read := 0
+
+ // Return if the raw buffer is full.
+ if parser.raw_buffer_pos == 0 && len(parser.raw_buffer) == cap(parser.raw_buffer) {
+ return true
+ }
+
+ // Return on EOF.
+ if parser.eof {
+ return true
+ }
+
+ // Move the remaining bytes in the raw buffer to the beginning.
+ if parser.raw_buffer_pos > 0 && parser.raw_buffer_pos < len(parser.raw_buffer) {
+ copy(parser.raw_buffer, parser.raw_buffer[parser.raw_buffer_pos:])
+ }
+ parser.raw_buffer = parser.raw_buffer[:len(parser.raw_buffer)-parser.raw_buffer_pos]
+ parser.raw_buffer_pos = 0
+
+ // Call the read handler to fill the buffer.
+ size_read, err := parser.read_handler(parser, parser.raw_buffer[len(parser.raw_buffer):cap(parser.raw_buffer)])
+ parser.raw_buffer = parser.raw_buffer[:len(parser.raw_buffer)+size_read]
+ if err == io.EOF {
+ parser.eof = true
+ } else if err != nil {
+ return yaml_parser_set_reader_error(parser, "input error: "+err.Error(), parser.offset, -1)
+ }
+ return true
+}
+
+// Ensure that the buffer contains at least `length` characters.
+// Return true on success, false on failure.
+//
+// The length is supposed to be significantly less that the buffer size.
+func yaml_parser_update_buffer(parser *yaml_parser_t, length int) bool {
+ if parser.read_handler == nil {
+ panic("read handler must be set")
+ }
+
+ // [Go] This function was changed to guarantee the requested length size at EOF.
+ // The fact we need to do this is pretty awful, but the description above implies
+ // for that to be the case, and there are tests
+
+ // If the EOF flag is set and the raw buffer is empty, do nothing.
+ if parser.eof && parser.raw_buffer_pos == len(parser.raw_buffer) {
+ // [Go] ACTUALLY! Read the documentation of this function above.
+ // This is just broken. To return true, we need to have the
+ // given length in the buffer. Not doing that means every single
+ // check that calls this function to make sure the buffer has a
+ // given length is Go) panicking; or C) accessing invalid memory.
+ //return true
+ }
+
+ // Return if the buffer contains enough characters.
+ if parser.unread >= length {
+ return true
+ }
+
+ // Determine the input encoding if it is not known yet.
+ if parser.encoding == yaml_ANY_ENCODING {
+ if !yaml_parser_determine_encoding(parser) {
+ return false
+ }
+ }
+
+ // Move the unread characters to the beginning of the buffer.
+ buffer_len := len(parser.buffer)
+ if parser.buffer_pos > 0 && parser.buffer_pos < buffer_len {
+ copy(parser.buffer, parser.buffer[parser.buffer_pos:])
+ buffer_len -= parser.buffer_pos
+ parser.buffer_pos = 0
+ } else if parser.buffer_pos == buffer_len {
+ buffer_len = 0
+ parser.buffer_pos = 0
+ }
+
+ // Open the whole buffer for writing, and cut it before returning.
+ parser.buffer = parser.buffer[:cap(parser.buffer)]
+
+ // Fill the buffer until it has enough characters.
+ first := true
+ for parser.unread < length {
+
+ // Fill the raw buffer if necessary.
+ if !first || parser.raw_buffer_pos == len(parser.raw_buffer) {
+ if !yaml_parser_update_raw_buffer(parser) {
+ parser.buffer = parser.buffer[:buffer_len]
+ return false
+ }
+ }
+ first = false
+
+ // Decode the raw buffer.
+ inner:
+ for parser.raw_buffer_pos != len(parser.raw_buffer) {
+ var value rune
+ var width int
+
+ raw_unread := len(parser.raw_buffer) - parser.raw_buffer_pos
+
+ // Decode the next character.
+ switch parser.encoding {
+ case yaml_UTF8_ENCODING:
+ // Decode a UTF-8 character. Check RFC 3629
+ // (http://www.ietf.org/rfc/rfc3629.txt) for more details.
+ //
+ // The following table (taken from the RFC) is used for
+ // decoding.
+ //
+ // Char. number range | UTF-8 octet sequence
+ // (hexadecimal) | (binary)
+ // --------------------+------------------------------------
+ // 0000 0000-0000 007F | 0xxxxxxx
+ // 0000 0080-0000 07FF | 110xxxxx 10xxxxxx
+ // 0000 0800-0000 FFFF | 1110xxxx 10xxxxxx 10xxxxxx
+ // 0001 0000-0010 FFFF | 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
+ //
+ // Additionally, the characters in the range 0xD800-0xDFFF
+ // are prohibited as they are reserved for use with UTF-16
+ // surrogate pairs.
+
+ // Determine the length of the UTF-8 sequence.
+ octet := parser.raw_buffer[parser.raw_buffer_pos]
+ switch {
+ case octet&0x80 == 0x00:
+ width = 1
+ case octet&0xE0 == 0xC0:
+ width = 2
+ case octet&0xF0 == 0xE0:
+ width = 3
+ case octet&0xF8 == 0xF0:
+ width = 4
+ default:
+ // The leading octet is invalid.
+ return yaml_parser_set_reader_error(parser,
+ "invalid leading UTF-8 octet",
+ parser.offset, int(octet))
+ }
+
+ // Check if the raw buffer contains an incomplete character.
+ if width > raw_unread {
+ if parser.eof {
+ return yaml_parser_set_reader_error(parser,
+ "incomplete UTF-8 octet sequence",
+ parser.offset, -1)
+ }
+ break inner
+ }
+
+ // Decode the leading octet.
+ switch {
+ case octet&0x80 == 0x00:
+ value = rune(octet & 0x7F)
+ case octet&0xE0 == 0xC0:
+ value = rune(octet & 0x1F)
+ case octet&0xF0 == 0xE0:
+ value = rune(octet & 0x0F)
+ case octet&0xF8 == 0xF0:
+ value = rune(octet & 0x07)
+ default:
+ value = 0
+ }
+
+ // Check and decode the trailing octets.
+ for k := 1; k < width; k++ {
+ octet = parser.raw_buffer[parser.raw_buffer_pos+k]
+
+ // Check if the octet is valid.
+ if (octet & 0xC0) != 0x80 {
+ return yaml_parser_set_reader_error(parser,
+ "invalid trailing UTF-8 octet",
+ parser.offset+k, int(octet))
+ }
+
+ // Decode the octet.
+ value = (value << 6) + rune(octet&0x3F)
+ }
+
+ // Check the length of the sequence against the value.
+ switch {
+ case width == 1:
+ case width == 2 && value >= 0x80:
+ case width == 3 && value >= 0x800:
+ case width == 4 && value >= 0x10000:
+ default:
+ return yaml_parser_set_reader_error(parser,
+ "invalid length of a UTF-8 sequence",
+ parser.offset, -1)
+ }
+
+ // Check the range of the value.
+ if value >= 0xD800 && value <= 0xDFFF || value > 0x10FFFF {
+ return yaml_parser_set_reader_error(parser,
+ "invalid Unicode character",
+ parser.offset, int(value))
+ }
+
+ case yaml_UTF16LE_ENCODING, yaml_UTF16BE_ENCODING:
+ var low, high int
+ if parser.encoding == yaml_UTF16LE_ENCODING {
+ low, high = 0, 1
+ } else {
+ low, high = 1, 0
+ }
+
+ // The UTF-16 encoding is not as simple as one might
+ // naively think. Check RFC 2781
+ // (http://www.ietf.org/rfc/rfc2781.txt).
+ //
+ // Normally, two subsequent bytes describe a Unicode
+ // character. However a special technique (called a
+ // surrogate pair) is used for specifying character
+ // values larger than 0xFFFF.
+ //
+ // A surrogate pair consists of two pseudo-characters:
+ // high surrogate area (0xD800-0xDBFF)
+ // low surrogate area (0xDC00-0xDFFF)
+ //
+ // The following formulas are used for decoding
+ // and encoding characters using surrogate pairs:
+ //
+ // U = U' + 0x10000 (0x01 00 00 <= U <= 0x10 FF FF)
+ // U' = yyyyyyyyyyxxxxxxxxxx (0 <= U' <= 0x0F FF FF)
+ // W1 = 110110yyyyyyyyyy
+ // W2 = 110111xxxxxxxxxx
+ //
+ // where U is the character value, W1 is the high surrogate
+ // area, W2 is the low surrogate area.
+
+ // Check for incomplete UTF-16 character.
+ if raw_unread < 2 {
+ if parser.eof {
+ return yaml_parser_set_reader_error(parser,
+ "incomplete UTF-16 character",
+ parser.offset, -1)
+ }
+ break inner
+ }
+
+ // Get the character.
+ value = rune(parser.raw_buffer[parser.raw_buffer_pos+low]) +
+ (rune(parser.raw_buffer[parser.raw_buffer_pos+high]) << 8)
+
+ // Check for unexpected low surrogate area.
+ if value&0xFC00 == 0xDC00 {
+ return yaml_parser_set_reader_error(parser,
+ "unexpected low surrogate area",
+ parser.offset, int(value))
+ }
+
+ // Check for a high surrogate area.
+ if value&0xFC00 == 0xD800 {
+ width = 4
+
+ // Check for incomplete surrogate pair.
+ if raw_unread < 4 {
+ if parser.eof {
+ return yaml_parser_set_reader_error(parser,
+ "incomplete UTF-16 surrogate pair",
+ parser.offset, -1)
+ }
+ break inner
+ }
+
+ // Get the next character.
+ value2 := rune(parser.raw_buffer[parser.raw_buffer_pos+low+2]) +
+ (rune(parser.raw_buffer[parser.raw_buffer_pos+high+2]) << 8)
+
+ // Check for a low surrogate area.
+ if value2&0xFC00 != 0xDC00 {
+ return yaml_parser_set_reader_error(parser,
+ "expected low surrogate area",
+ parser.offset+2, int(value2))
+ }
+
+ // Generate the value of the surrogate pair.
+ value = 0x10000 + ((value & 0x3FF) << 10) + (value2 & 0x3FF)
+ } else {
+ width = 2
+ }
+
+ default:
+ panic("impossible")
+ }
+
+ // Check if the character is in the allowed range:
+ // #x9 | #xA | #xD | [#x20-#x7E] (8 bit)
+ // | #x85 | [#xA0-#xD7FF] | [#xE000-#xFFFD] (16 bit)
+ // | [#x10000-#x10FFFF] (32 bit)
+ switch {
+ case value == 0x09:
+ case value == 0x0A:
+ case value == 0x0D:
+ case value >= 0x20 && value <= 0x7E:
+ case value == 0x85:
+ case value >= 0xA0 && value <= 0xD7FF:
+ case value >= 0xE000 && value <= 0xFFFD:
+ case value >= 0x10000 && value <= 0x10FFFF:
+ default:
+ return yaml_parser_set_reader_error(parser,
+ "control characters are not allowed",
+ parser.offset, int(value))
+ }
+
+ // Move the raw pointers.
+ parser.raw_buffer_pos += width
+ parser.offset += width
+
+ // Finally put the character into the buffer.
+ if value <= 0x7F {
+ // 0000 0000-0000 007F . 0xxxxxxx
+ parser.buffer[buffer_len+0] = byte(value)
+ buffer_len += 1
+ } else if value <= 0x7FF {
+ // 0000 0080-0000 07FF . 110xxxxx 10xxxxxx
+ parser.buffer[buffer_len+0] = byte(0xC0 + (value >> 6))
+ parser.buffer[buffer_len+1] = byte(0x80 + (value & 0x3F))
+ buffer_len += 2
+ } else if value <= 0xFFFF {
+ // 0000 0800-0000 FFFF . 1110xxxx 10xxxxxx 10xxxxxx
+ parser.buffer[buffer_len+0] = byte(0xE0 + (value >> 12))
+ parser.buffer[buffer_len+1] = byte(0x80 + ((value >> 6) & 0x3F))
+ parser.buffer[buffer_len+2] = byte(0x80 + (value & 0x3F))
+ buffer_len += 3
+ } else {
+ // 0001 0000-0010 FFFF . 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
+ parser.buffer[buffer_len+0] = byte(0xF0 + (value >> 18))
+ parser.buffer[buffer_len+1] = byte(0x80 + ((value >> 12) & 0x3F))
+ parser.buffer[buffer_len+2] = byte(0x80 + ((value >> 6) & 0x3F))
+ parser.buffer[buffer_len+3] = byte(0x80 + (value & 0x3F))
+ buffer_len += 4
+ }
+
+ parser.unread++
+ }
+
+ // On EOF, put NUL into the buffer and return.
+ if parser.eof {
+ parser.buffer[buffer_len] = 0
+ buffer_len++
+ parser.unread++
+ break
+ }
+ }
+ // [Go] Read the documentation of this function above. To return true,
+ // we need to have the given length in the buffer. Not doing that means
+ // every single check that calls this function to make sure the buffer
+ // has a given length is Go) panicking; or C) accessing invalid memory.
+ // This happens here due to the EOF above breaking early.
+ for buffer_len < length {
+ parser.buffer[buffer_len] = 0
+ buffer_len++
+ }
+ parser.buffer = parser.buffer[:buffer_len]
+ return true
+}
diff --git a/vendor/gopkg.in/yaml.v2/resolve.go b/vendor/gopkg.in/yaml.v2/resolve.go
new file mode 100644
index 0000000000000000000000000000000000000000..6c151db6fbd586bfdf9080c934df88a74c0c8b4d
--- /dev/null
+++ b/vendor/gopkg.in/yaml.v2/resolve.go
@@ -0,0 +1,258 @@
+package yaml
+
+import (
+ "encoding/base64"
+ "math"
+ "regexp"
+ "strconv"
+ "strings"
+ "time"
+)
+
+type resolveMapItem struct {
+ value interface{}
+ tag string
+}
+
+var resolveTable = make([]byte, 256)
+var resolveMap = make(map[string]resolveMapItem)
+
+func init() {
+ t := resolveTable
+ t[int('+')] = 'S' // Sign
+ t[int('-')] = 'S'
+ for _, c := range "0123456789" {
+ t[int(c)] = 'D' // Digit
+ }
+ for _, c := range "yYnNtTfFoO~" {
+ t[int(c)] = 'M' // In map
+ }
+ t[int('.')] = '.' // Float (potentially in map)
+
+ var resolveMapList = []struct {
+ v interface{}
+ tag string
+ l []string
+ }{
+ {true, yaml_BOOL_TAG, []string{"y", "Y", "yes", "Yes", "YES"}},
+ {true, yaml_BOOL_TAG, []string{"true", "True", "TRUE"}},
+ {true, yaml_BOOL_TAG, []string{"on", "On", "ON"}},
+ {false, yaml_BOOL_TAG, []string{"n", "N", "no", "No", "NO"}},
+ {false, yaml_BOOL_TAG, []string{"false", "False", "FALSE"}},
+ {false, yaml_BOOL_TAG, []string{"off", "Off", "OFF"}},
+ {nil, yaml_NULL_TAG, []string{"", "~", "null", "Null", "NULL"}},
+ {math.NaN(), yaml_FLOAT_TAG, []string{".nan", ".NaN", ".NAN"}},
+ {math.Inf(+1), yaml_FLOAT_TAG, []string{".inf", ".Inf", ".INF"}},
+ {math.Inf(+1), yaml_FLOAT_TAG, []string{"+.inf", "+.Inf", "+.INF"}},
+ {math.Inf(-1), yaml_FLOAT_TAG, []string{"-.inf", "-.Inf", "-.INF"}},
+ {"<<", yaml_MERGE_TAG, []string{"<<"}},
+ }
+
+ m := resolveMap
+ for _, item := range resolveMapList {
+ for _, s := range item.l {
+ m[s] = resolveMapItem{item.v, item.tag}
+ }
+ }
+}
+
+const longTagPrefix = "tag:yaml.org,2002:"
+
+func shortTag(tag string) string {
+ // TODO This can easily be made faster and produce less garbage.
+ if strings.HasPrefix(tag, longTagPrefix) {
+ return "!!" + tag[len(longTagPrefix):]
+ }
+ return tag
+}
+
+func longTag(tag string) string {
+ if strings.HasPrefix(tag, "!!") {
+ return longTagPrefix + tag[2:]
+ }
+ return tag
+}
+
+func resolvableTag(tag string) bool {
+ switch tag {
+ case "", yaml_STR_TAG, yaml_BOOL_TAG, yaml_INT_TAG, yaml_FLOAT_TAG, yaml_NULL_TAG, yaml_TIMESTAMP_TAG:
+ return true
+ }
+ return false
+}
+
+var yamlStyleFloat = regexp.MustCompile(`^[-+]?[0-9]*\.?[0-9]+([eE][-+][0-9]+)?$`)
+
+func resolve(tag string, in string) (rtag string, out interface{}) {
+ if !resolvableTag(tag) {
+ return tag, in
+ }
+
+ defer func() {
+ switch tag {
+ case "", rtag, yaml_STR_TAG, yaml_BINARY_TAG:
+ return
+ case yaml_FLOAT_TAG:
+ if rtag == yaml_INT_TAG {
+ switch v := out.(type) {
+ case int64:
+ rtag = yaml_FLOAT_TAG
+ out = float64(v)
+ return
+ case int:
+ rtag = yaml_FLOAT_TAG
+ out = float64(v)
+ return
+ }
+ }
+ }
+ failf("cannot decode %s `%s` as a %s", shortTag(rtag), in, shortTag(tag))
+ }()
+
+ // Any data is accepted as a !!str or !!binary.
+ // Otherwise, the prefix is enough of a hint about what it might be.
+ hint := byte('N')
+ if in != "" {
+ hint = resolveTable[in[0]]
+ }
+ if hint != 0 && tag != yaml_STR_TAG && tag != yaml_BINARY_TAG {
+ // Handle things we can lookup in a map.
+ if item, ok := resolveMap[in]; ok {
+ return item.tag, item.value
+ }
+
+ // Base 60 floats are a bad idea, were dropped in YAML 1.2, and
+ // are purposefully unsupported here. They're still quoted on
+ // the way out for compatibility with other parser, though.
+
+ switch hint {
+ case 'M':
+ // We've already checked the map above.
+
+ case '.':
+ // Not in the map, so maybe a normal float.
+ floatv, err := strconv.ParseFloat(in, 64)
+ if err == nil {
+ return yaml_FLOAT_TAG, floatv
+ }
+
+ case 'D', 'S':
+ // Int, float, or timestamp.
+ // Only try values as a timestamp if the value is unquoted or there's an explicit
+ // !!timestamp tag.
+ if tag == "" || tag == yaml_TIMESTAMP_TAG {
+ t, ok := parseTimestamp(in)
+ if ok {
+ return yaml_TIMESTAMP_TAG, t
+ }
+ }
+
+ plain := strings.Replace(in, "_", "", -1)
+ intv, err := strconv.ParseInt(plain, 0, 64)
+ if err == nil {
+ if intv == int64(int(intv)) {
+ return yaml_INT_TAG, int(intv)
+ } else {
+ return yaml_INT_TAG, intv
+ }
+ }
+ uintv, err := strconv.ParseUint(plain, 0, 64)
+ if err == nil {
+ return yaml_INT_TAG, uintv
+ }
+ if yamlStyleFloat.MatchString(plain) {
+ floatv, err := strconv.ParseFloat(plain, 64)
+ if err == nil {
+ return yaml_FLOAT_TAG, floatv
+ }
+ }
+ if strings.HasPrefix(plain, "0b") {
+ intv, err := strconv.ParseInt(plain[2:], 2, 64)
+ if err == nil {
+ if intv == int64(int(intv)) {
+ return yaml_INT_TAG, int(intv)
+ } else {
+ return yaml_INT_TAG, intv
+ }
+ }
+ uintv, err := strconv.ParseUint(plain[2:], 2, 64)
+ if err == nil {
+ return yaml_INT_TAG, uintv
+ }
+ } else if strings.HasPrefix(plain, "-0b") {
+ intv, err := strconv.ParseInt("-" + plain[3:], 2, 64)
+ if err == nil {
+ if true || intv == int64(int(intv)) {
+ return yaml_INT_TAG, int(intv)
+ } else {
+ return yaml_INT_TAG, intv
+ }
+ }
+ }
+ default:
+ panic("resolveTable item not yet handled: " + string(rune(hint)) + " (with " + in + ")")
+ }
+ }
+ return yaml_STR_TAG, in
+}
+
+// encodeBase64 encodes s as base64 that is broken up into multiple lines
+// as appropriate for the resulting length.
+func encodeBase64(s string) string {
+ const lineLen = 70
+ encLen := base64.StdEncoding.EncodedLen(len(s))
+ lines := encLen/lineLen + 1
+ buf := make([]byte, encLen*2+lines)
+ in := buf[0:encLen]
+ out := buf[encLen:]
+ base64.StdEncoding.Encode(in, []byte(s))
+ k := 0
+ for i := 0; i < len(in); i += lineLen {
+ j := i + lineLen
+ if j > len(in) {
+ j = len(in)
+ }
+ k += copy(out[k:], in[i:j])
+ if lines > 1 {
+ out[k] = '\n'
+ k++
+ }
+ }
+ return string(out[:k])
+}
+
+// This is a subset of the formats allowed by the regular expression
+// defined at http://yaml.org/type/timestamp.html.
+var allowedTimestampFormats = []string{
+ "2006-1-2T15:4:5.999999999Z07:00", // RCF3339Nano with short date fields.
+ "2006-1-2t15:4:5.999999999Z07:00", // RFC3339Nano with short date fields and lower-case "t".
+ "2006-1-2 15:4:5.999999999", // space separated with no time zone
+ "2006-1-2", // date only
+ // Notable exception: time.Parse cannot handle: "2001-12-14 21:59:43.10 -5"
+ // from the set of examples.
+}
+
+// parseTimestamp parses s as a timestamp string and
+// returns the timestamp and reports whether it succeeded.
+// Timestamp formats are defined at http://yaml.org/type/timestamp.html
+func parseTimestamp(s string) (time.Time, bool) {
+ // TODO write code to check all the formats supported by
+ // http://yaml.org/type/timestamp.html instead of using time.Parse.
+
+ // Quick check: all date formats start with YYYY-.
+ i := 0
+ for ; i < len(s); i++ {
+ if c := s[i]; c < '0' || c > '9' {
+ break
+ }
+ }
+ if i != 4 || i == len(s) || s[i] != '-' {
+ return time.Time{}, false
+ }
+ for _, format := range allowedTimestampFormats {
+ if t, err := time.Parse(format, s); err == nil {
+ return t, true
+ }
+ }
+ return time.Time{}, false
+}
diff --git a/vendor/gopkg.in/yaml.v2/scannerc.go b/vendor/gopkg.in/yaml.v2/scannerc.go
new file mode 100644
index 0000000000000000000000000000000000000000..077fd1dd2d446ddb9c000b6e4a15ac4518452334
--- /dev/null
+++ b/vendor/gopkg.in/yaml.v2/scannerc.go
@@ -0,0 +1,2696 @@
+package yaml
+
+import (
+ "bytes"
+ "fmt"
+)
+
+// Introduction
+// ************
+//
+// The following notes assume that you are familiar with the YAML specification
+// (http://yaml.org/spec/1.2/spec.html). We mostly follow it, although in
+// some cases we are less restrictive that it requires.
+//
+// The process of transforming a YAML stream into a sequence of events is
+// divided on two steps: Scanning and Parsing.
+//
+// The Scanner transforms the input stream into a sequence of tokens, while the
+// parser transform the sequence of tokens produced by the Scanner into a
+// sequence of parsing events.
+//
+// The Scanner is rather clever and complicated. The Parser, on the contrary,
+// is a straightforward implementation of a recursive-descendant parser (or,
+// LL(1) parser, as it is usually called).
+//
+// Actually there are two issues of Scanning that might be called "clever", the
+// rest is quite straightforward. The issues are "block collection start" and
+// "simple keys". Both issues are explained below in details.
+//
+// Here the Scanning step is explained and implemented. We start with the list
+// of all the tokens produced by the Scanner together with short descriptions.
+//
+// Now, tokens:
+//
+// STREAM-START(encoding) # The stream start.
+// STREAM-END # The stream end.
+// VERSION-DIRECTIVE(major,minor) # The '%YAML' directive.
+// TAG-DIRECTIVE(handle,prefix) # The '%TAG' directive.
+// DOCUMENT-START # '---'
+// DOCUMENT-END # '...'
+// BLOCK-SEQUENCE-START # Indentation increase denoting a block
+// BLOCK-MAPPING-START # sequence or a block mapping.
+// BLOCK-END # Indentation decrease.
+// FLOW-SEQUENCE-START # '['
+// FLOW-SEQUENCE-END # ']'
+// BLOCK-SEQUENCE-START # '{'
+// BLOCK-SEQUENCE-END # '}'
+// BLOCK-ENTRY # '-'
+// FLOW-ENTRY # ','
+// KEY # '?' or nothing (simple keys).
+// VALUE # ':'
+// ALIAS(anchor) # '*anchor'
+// ANCHOR(anchor) # '&anchor'
+// TAG(handle,suffix) # '!handle!suffix'
+// SCALAR(value,style) # A scalar.
+//
+// The following two tokens are "virtual" tokens denoting the beginning and the
+// end of the stream:
+//
+// STREAM-START(encoding)
+// STREAM-END
+//
+// We pass the information about the input stream encoding with the
+// STREAM-START token.
+//
+// The next two tokens are responsible for tags:
+//
+// VERSION-DIRECTIVE(major,minor)
+// TAG-DIRECTIVE(handle,prefix)
+//
+// Example:
+//
+// %YAML 1.1
+// %TAG ! !foo
+// %TAG !yaml! tag:yaml.org,2002:
+// ---
+//
+// The correspoding sequence of tokens:
+//
+// STREAM-START(utf-8)
+// VERSION-DIRECTIVE(1,1)
+// TAG-DIRECTIVE("!","!foo")
+// TAG-DIRECTIVE("!yaml","tag:yaml.org,2002:")
+// DOCUMENT-START
+// STREAM-END
+//
+// Note that the VERSION-DIRECTIVE and TAG-DIRECTIVE tokens occupy a whole
+// line.
+//
+// The document start and end indicators are represented by:
+//
+// DOCUMENT-START
+// DOCUMENT-END
+//
+// Note that if a YAML stream contains an implicit document (without '---'
+// and '...' indicators), no DOCUMENT-START and DOCUMENT-END tokens will be
+// produced.
+//
+// In the following examples, we present whole documents together with the
+// produced tokens.
+//
+// 1. An implicit document:
+//
+// 'a scalar'
+//
+// Tokens:
+//
+// STREAM-START(utf-8)
+// SCALAR("a scalar",single-quoted)
+// STREAM-END
+//
+// 2. An explicit document:
+//
+// ---
+// 'a scalar'
+// ...
+//
+// Tokens:
+//
+// STREAM-START(utf-8)
+// DOCUMENT-START
+// SCALAR("a scalar",single-quoted)
+// DOCUMENT-END
+// STREAM-END
+//
+// 3. Several documents in a stream:
+//
+// 'a scalar'
+// ---
+// 'another scalar'
+// ---
+// 'yet another scalar'
+//
+// Tokens:
+//
+// STREAM-START(utf-8)
+// SCALAR("a scalar",single-quoted)
+// DOCUMENT-START
+// SCALAR("another scalar",single-quoted)
+// DOCUMENT-START
+// SCALAR("yet another scalar",single-quoted)
+// STREAM-END
+//
+// We have already introduced the SCALAR token above. The following tokens are
+// used to describe aliases, anchors, tag, and scalars:
+//
+// ALIAS(anchor)
+// ANCHOR(anchor)
+// TAG(handle,suffix)
+// SCALAR(value,style)
+//
+// The following series of examples illustrate the usage of these tokens:
+//
+// 1. A recursive sequence:
+//
+// &A [ *A ]
+//
+// Tokens:
+//
+// STREAM-START(utf-8)
+// ANCHOR("A")
+// FLOW-SEQUENCE-START
+// ALIAS("A")
+// FLOW-SEQUENCE-END
+// STREAM-END
+//
+// 2. A tagged scalar:
+//
+// !!float "3.14" # A good approximation.
+//
+// Tokens:
+//
+// STREAM-START(utf-8)
+// TAG("!!","float")
+// SCALAR("3.14",double-quoted)
+// STREAM-END
+//
+// 3. Various scalar styles:
+//
+// --- # Implicit empty plain scalars do not produce tokens.
+// --- a plain scalar
+// --- 'a single-quoted scalar'
+// --- "a double-quoted scalar"
+// --- |-
+// a literal scalar
+// --- >-
+// a folded
+// scalar
+//
+// Tokens:
+//
+// STREAM-START(utf-8)
+// DOCUMENT-START
+// DOCUMENT-START
+// SCALAR("a plain scalar",plain)
+// DOCUMENT-START
+// SCALAR("a single-quoted scalar",single-quoted)
+// DOCUMENT-START
+// SCALAR("a double-quoted scalar",double-quoted)
+// DOCUMENT-START
+// SCALAR("a literal scalar",literal)
+// DOCUMENT-START
+// SCALAR("a folded scalar",folded)
+// STREAM-END
+//
+// Now it's time to review collection-related tokens. We will start with
+// flow collections:
+//
+// FLOW-SEQUENCE-START
+// FLOW-SEQUENCE-END
+// FLOW-MAPPING-START
+// FLOW-MAPPING-END
+// FLOW-ENTRY
+// KEY
+// VALUE
+//
+// The tokens FLOW-SEQUENCE-START, FLOW-SEQUENCE-END, FLOW-MAPPING-START, and
+// FLOW-MAPPING-END represent the indicators '[', ']', '{', and '}'
+// correspondingly. FLOW-ENTRY represent the ',' indicator. Finally the
+// indicators '?' and ':', which are used for denoting mapping keys and values,
+// are represented by the KEY and VALUE tokens.
+//
+// The following examples show flow collections:
+//
+// 1. A flow sequence:
+//
+// [item 1, item 2, item 3]
+//
+// Tokens:
+//
+// STREAM-START(utf-8)
+// FLOW-SEQUENCE-START
+// SCALAR("item 1",plain)
+// FLOW-ENTRY
+// SCALAR("item 2",plain)
+// FLOW-ENTRY
+// SCALAR("item 3",plain)
+// FLOW-SEQUENCE-END
+// STREAM-END
+//
+// 2. A flow mapping:
+//
+// {
+// a simple key: a value, # Note that the KEY token is produced.
+// ? a complex key: another value,
+// }
+//
+// Tokens:
+//
+// STREAM-START(utf-8)
+// FLOW-MAPPING-START
+// KEY
+// SCALAR("a simple key",plain)
+// VALUE
+// SCALAR("a value",plain)
+// FLOW-ENTRY
+// KEY
+// SCALAR("a complex key",plain)
+// VALUE
+// SCALAR("another value",plain)
+// FLOW-ENTRY
+// FLOW-MAPPING-END
+// STREAM-END
+//
+// A simple key is a key which is not denoted by the '?' indicator. Note that
+// the Scanner still produce the KEY token whenever it encounters a simple key.
+//
+// For scanning block collections, the following tokens are used (note that we
+// repeat KEY and VALUE here):
+//
+// BLOCK-SEQUENCE-START
+// BLOCK-MAPPING-START
+// BLOCK-END
+// BLOCK-ENTRY
+// KEY
+// VALUE
+//
+// The tokens BLOCK-SEQUENCE-START and BLOCK-MAPPING-START denote indentation
+// increase that precedes a block collection (cf. the INDENT token in Python).
+// The token BLOCK-END denote indentation decrease that ends a block collection
+// (cf. the DEDENT token in Python). However YAML has some syntax pecularities
+// that makes detections of these tokens more complex.
+//
+// The tokens BLOCK-ENTRY, KEY, and VALUE are used to represent the indicators
+// '-', '?', and ':' correspondingly.
+//
+// The following examples show how the tokens BLOCK-SEQUENCE-START,
+// BLOCK-MAPPING-START, and BLOCK-END are emitted by the Scanner:
+//
+// 1. Block sequences:
+//
+// - item 1
+// - item 2
+// -
+// - item 3.1
+// - item 3.2
+// -
+// key 1: value 1
+// key 2: value 2
+//
+// Tokens:
+//
+// STREAM-START(utf-8)
+// BLOCK-SEQUENCE-START
+// BLOCK-ENTRY
+// SCALAR("item 1",plain)
+// BLOCK-ENTRY
+// SCALAR("item 2",plain)
+// BLOCK-ENTRY
+// BLOCK-SEQUENCE-START
+// BLOCK-ENTRY
+// SCALAR("item 3.1",plain)
+// BLOCK-ENTRY
+// SCALAR("item 3.2",plain)
+// BLOCK-END
+// BLOCK-ENTRY
+// BLOCK-MAPPING-START
+// KEY
+// SCALAR("key 1",plain)
+// VALUE
+// SCALAR("value 1",plain)
+// KEY
+// SCALAR("key 2",plain)
+// VALUE
+// SCALAR("value 2",plain)
+// BLOCK-END
+// BLOCK-END
+// STREAM-END
+//
+// 2. Block mappings:
+//
+// a simple key: a value # The KEY token is produced here.
+// ? a complex key
+// : another value
+// a mapping:
+// key 1: value 1
+// key 2: value 2
+// a sequence:
+// - item 1
+// - item 2
+//
+// Tokens:
+//
+// STREAM-START(utf-8)
+// BLOCK-MAPPING-START
+// KEY
+// SCALAR("a simple key",plain)
+// VALUE
+// SCALAR("a value",plain)
+// KEY
+// SCALAR("a complex key",plain)
+// VALUE
+// SCALAR("another value",plain)
+// KEY
+// SCALAR("a mapping",plain)
+// BLOCK-MAPPING-START
+// KEY
+// SCALAR("key 1",plain)
+// VALUE
+// SCALAR("value 1",plain)
+// KEY
+// SCALAR("key 2",plain)
+// VALUE
+// SCALAR("value 2",plain)
+// BLOCK-END
+// KEY
+// SCALAR("a sequence",plain)
+// VALUE
+// BLOCK-SEQUENCE-START
+// BLOCK-ENTRY
+// SCALAR("item 1",plain)
+// BLOCK-ENTRY
+// SCALAR("item 2",plain)
+// BLOCK-END
+// BLOCK-END
+// STREAM-END
+//
+// YAML does not always require to start a new block collection from a new
+// line. If the current line contains only '-', '?', and ':' indicators, a new
+// block collection may start at the current line. The following examples
+// illustrate this case:
+//
+// 1. Collections in a sequence:
+//
+// - - item 1
+// - item 2
+// - key 1: value 1
+// key 2: value 2
+// - ? complex key
+// : complex value
+//
+// Tokens:
+//
+// STREAM-START(utf-8)
+// BLOCK-SEQUENCE-START
+// BLOCK-ENTRY
+// BLOCK-SEQUENCE-START
+// BLOCK-ENTRY
+// SCALAR("item 1",plain)
+// BLOCK-ENTRY
+// SCALAR("item 2",plain)
+// BLOCK-END
+// BLOCK-ENTRY
+// BLOCK-MAPPING-START
+// KEY
+// SCALAR("key 1",plain)
+// VALUE
+// SCALAR("value 1",plain)
+// KEY
+// SCALAR("key 2",plain)
+// VALUE
+// SCALAR("value 2",plain)
+// BLOCK-END
+// BLOCK-ENTRY
+// BLOCK-MAPPING-START
+// KEY
+// SCALAR("complex key")
+// VALUE
+// SCALAR("complex value")
+// BLOCK-END
+// BLOCK-END
+// STREAM-END
+//
+// 2. Collections in a mapping:
+//
+// ? a sequence
+// : - item 1
+// - item 2
+// ? a mapping
+// : key 1: value 1
+// key 2: value 2
+//
+// Tokens:
+//
+// STREAM-START(utf-8)
+// BLOCK-MAPPING-START
+// KEY
+// SCALAR("a sequence",plain)
+// VALUE
+// BLOCK-SEQUENCE-START
+// BLOCK-ENTRY
+// SCALAR("item 1",plain)
+// BLOCK-ENTRY
+// SCALAR("item 2",plain)
+// BLOCK-END
+// KEY
+// SCALAR("a mapping",plain)
+// VALUE
+// BLOCK-MAPPING-START
+// KEY
+// SCALAR("key 1",plain)
+// VALUE
+// SCALAR("value 1",plain)
+// KEY
+// SCALAR("key 2",plain)
+// VALUE
+// SCALAR("value 2",plain)
+// BLOCK-END
+// BLOCK-END
+// STREAM-END
+//
+// YAML also permits non-indented sequences if they are included into a block
+// mapping. In this case, the token BLOCK-SEQUENCE-START is not produced:
+//
+// key:
+// - item 1 # BLOCK-SEQUENCE-START is NOT produced here.
+// - item 2
+//
+// Tokens:
+//
+// STREAM-START(utf-8)
+// BLOCK-MAPPING-START
+// KEY
+// SCALAR("key",plain)
+// VALUE
+// BLOCK-ENTRY
+// SCALAR("item 1",plain)
+// BLOCK-ENTRY
+// SCALAR("item 2",plain)
+// BLOCK-END
+//
+
+// Ensure that the buffer contains the required number of characters.
+// Return true on success, false on failure (reader error or memory error).
+func cache(parser *yaml_parser_t, length int) bool {
+ // [Go] This was inlined: !cache(A, B) -> unread < B && !update(A, B)
+ return parser.unread >= length || yaml_parser_update_buffer(parser, length)
+}
+
+// Advance the buffer pointer.
+func skip(parser *yaml_parser_t) {
+ parser.mark.index++
+ parser.mark.column++
+ parser.unread--
+ parser.buffer_pos += width(parser.buffer[parser.buffer_pos])
+}
+
+func skip_line(parser *yaml_parser_t) {
+ if is_crlf(parser.buffer, parser.buffer_pos) {
+ parser.mark.index += 2
+ parser.mark.column = 0
+ parser.mark.line++
+ parser.unread -= 2
+ parser.buffer_pos += 2
+ } else if is_break(parser.buffer, parser.buffer_pos) {
+ parser.mark.index++
+ parser.mark.column = 0
+ parser.mark.line++
+ parser.unread--
+ parser.buffer_pos += width(parser.buffer[parser.buffer_pos])
+ }
+}
+
+// Copy a character to a string buffer and advance pointers.
+func read(parser *yaml_parser_t, s []byte) []byte {
+ w := width(parser.buffer[parser.buffer_pos])
+ if w == 0 {
+ panic("invalid character sequence")
+ }
+ if len(s) == 0 {
+ s = make([]byte, 0, 32)
+ }
+ if w == 1 && len(s)+w <= cap(s) {
+ s = s[:len(s)+1]
+ s[len(s)-1] = parser.buffer[parser.buffer_pos]
+ parser.buffer_pos++
+ } else {
+ s = append(s, parser.buffer[parser.buffer_pos:parser.buffer_pos+w]...)
+ parser.buffer_pos += w
+ }
+ parser.mark.index++
+ parser.mark.column++
+ parser.unread--
+ return s
+}
+
+// Copy a line break character to a string buffer and advance pointers.
+func read_line(parser *yaml_parser_t, s []byte) []byte {
+ buf := parser.buffer
+ pos := parser.buffer_pos
+ switch {
+ case buf[pos] == '\r' && buf[pos+1] == '\n':
+ // CR LF . LF
+ s = append(s, '\n')
+ parser.buffer_pos += 2
+ parser.mark.index++
+ parser.unread--
+ case buf[pos] == '\r' || buf[pos] == '\n':
+ // CR|LF . LF
+ s = append(s, '\n')
+ parser.buffer_pos += 1
+ case buf[pos] == '\xC2' && buf[pos+1] == '\x85':
+ // NEL . LF
+ s = append(s, '\n')
+ parser.buffer_pos += 2
+ case buf[pos] == '\xE2' && buf[pos+1] == '\x80' && (buf[pos+2] == '\xA8' || buf[pos+2] == '\xA9'):
+ // LS|PS . LS|PS
+ s = append(s, buf[parser.buffer_pos:pos+3]...)
+ parser.buffer_pos += 3
+ default:
+ return s
+ }
+ parser.mark.index++
+ parser.mark.column = 0
+ parser.mark.line++
+ parser.unread--
+ return s
+}
+
+// Get the next token.
+func yaml_parser_scan(parser *yaml_parser_t, token *yaml_token_t) bool {
+ // Erase the token object.
+ *token = yaml_token_t{} // [Go] Is this necessary?
+
+ // No tokens after STREAM-END or error.
+ if parser.stream_end_produced || parser.error != yaml_NO_ERROR {
+ return true
+ }
+
+ // Ensure that the tokens queue contains enough tokens.
+ if !parser.token_available {
+ if !yaml_parser_fetch_more_tokens(parser) {
+ return false
+ }
+ }
+
+ // Fetch the next token from the queue.
+ *token = parser.tokens[parser.tokens_head]
+ parser.tokens_head++
+ parser.tokens_parsed++
+ parser.token_available = false
+
+ if token.typ == yaml_STREAM_END_TOKEN {
+ parser.stream_end_produced = true
+ }
+ return true
+}
+
+// Set the scanner error and return false.
+func yaml_parser_set_scanner_error(parser *yaml_parser_t, context string, context_mark yaml_mark_t, problem string) bool {
+ parser.error = yaml_SCANNER_ERROR
+ parser.context = context
+ parser.context_mark = context_mark
+ parser.problem = problem
+ parser.problem_mark = parser.mark
+ return false
+}
+
+func yaml_parser_set_scanner_tag_error(parser *yaml_parser_t, directive bool, context_mark yaml_mark_t, problem string) bool {
+ context := "while parsing a tag"
+ if directive {
+ context = "while parsing a %TAG directive"
+ }
+ return yaml_parser_set_scanner_error(parser, context, context_mark, problem)
+}
+
+func trace(args ...interface{}) func() {
+ pargs := append([]interface{}{"+++"}, args...)
+ fmt.Println(pargs...)
+ pargs = append([]interface{}{"---"}, args...)
+ return func() { fmt.Println(pargs...) }
+}
+
+// Ensure that the tokens queue contains at least one token which can be
+// returned to the Parser.
+func yaml_parser_fetch_more_tokens(parser *yaml_parser_t) bool {
+ // While we need more tokens to fetch, do it.
+ for {
+ // Check if we really need to fetch more tokens.
+ need_more_tokens := false
+
+ if parser.tokens_head == len(parser.tokens) {
+ // Queue is empty.
+ need_more_tokens = true
+ } else {
+ // Check if any potential simple key may occupy the head position.
+ if !yaml_parser_stale_simple_keys(parser) {
+ return false
+ }
+
+ for i := range parser.simple_keys {
+ simple_key := &parser.simple_keys[i]
+ if simple_key.possible && simple_key.token_number == parser.tokens_parsed {
+ need_more_tokens = true
+ break
+ }
+ }
+ }
+
+ // We are finished.
+ if !need_more_tokens {
+ break
+ }
+ // Fetch the next token.
+ if !yaml_parser_fetch_next_token(parser) {
+ return false
+ }
+ }
+
+ parser.token_available = true
+ return true
+}
+
+// The dispatcher for token fetchers.
+func yaml_parser_fetch_next_token(parser *yaml_parser_t) bool {
+ // Ensure that the buffer is initialized.
+ if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
+ return false
+ }
+
+ // Check if we just started scanning. Fetch STREAM-START then.
+ if !parser.stream_start_produced {
+ return yaml_parser_fetch_stream_start(parser)
+ }
+
+ // Eat whitespaces and comments until we reach the next token.
+ if !yaml_parser_scan_to_next_token(parser) {
+ return false
+ }
+
+ // Remove obsolete potential simple keys.
+ if !yaml_parser_stale_simple_keys(parser) {
+ return false
+ }
+
+ // Check the indentation level against the current column.
+ if !yaml_parser_unroll_indent(parser, parser.mark.column) {
+ return false
+ }
+
+ // Ensure that the buffer contains at least 4 characters. 4 is the length
+ // of the longest indicators ('--- ' and '... ').
+ if parser.unread < 4 && !yaml_parser_update_buffer(parser, 4) {
+ return false
+ }
+
+ // Is it the end of the stream?
+ if is_z(parser.buffer, parser.buffer_pos) {
+ return yaml_parser_fetch_stream_end(parser)
+ }
+
+ // Is it a directive?
+ if parser.mark.column == 0 && parser.buffer[parser.buffer_pos] == '%' {
+ return yaml_parser_fetch_directive(parser)
+ }
+
+ buf := parser.buffer
+ pos := parser.buffer_pos
+
+ // Is it the document start indicator?
+ if parser.mark.column == 0 && buf[pos] == '-' && buf[pos+1] == '-' && buf[pos+2] == '-' && is_blankz(buf, pos+3) {
+ return yaml_parser_fetch_document_indicator(parser, yaml_DOCUMENT_START_TOKEN)
+ }
+
+ // Is it the document end indicator?
+ if parser.mark.column == 0 && buf[pos] == '.' && buf[pos+1] == '.' && buf[pos+2] == '.' && is_blankz(buf, pos+3) {
+ return yaml_parser_fetch_document_indicator(parser, yaml_DOCUMENT_END_TOKEN)
+ }
+
+ // Is it the flow sequence start indicator?
+ if buf[pos] == '[' {
+ return yaml_parser_fetch_flow_collection_start(parser, yaml_FLOW_SEQUENCE_START_TOKEN)
+ }
+
+ // Is it the flow mapping start indicator?
+ if parser.buffer[parser.buffer_pos] == '{' {
+ return yaml_parser_fetch_flow_collection_start(parser, yaml_FLOW_MAPPING_START_TOKEN)
+ }
+
+ // Is it the flow sequence end indicator?
+ if parser.buffer[parser.buffer_pos] == ']' {
+ return yaml_parser_fetch_flow_collection_end(parser,
+ yaml_FLOW_SEQUENCE_END_TOKEN)
+ }
+
+ // Is it the flow mapping end indicator?
+ if parser.buffer[parser.buffer_pos] == '}' {
+ return yaml_parser_fetch_flow_collection_end(parser,
+ yaml_FLOW_MAPPING_END_TOKEN)
+ }
+
+ // Is it the flow entry indicator?
+ if parser.buffer[parser.buffer_pos] == ',' {
+ return yaml_parser_fetch_flow_entry(parser)
+ }
+
+ // Is it the block entry indicator?
+ if parser.buffer[parser.buffer_pos] == '-' && is_blankz(parser.buffer, parser.buffer_pos+1) {
+ return yaml_parser_fetch_block_entry(parser)
+ }
+
+ // Is it the key indicator?
+ if parser.buffer[parser.buffer_pos] == '?' && (parser.flow_level > 0 || is_blankz(parser.buffer, parser.buffer_pos+1)) {
+ return yaml_parser_fetch_key(parser)
+ }
+
+ // Is it the value indicator?
+ if parser.buffer[parser.buffer_pos] == ':' && (parser.flow_level > 0 || is_blankz(parser.buffer, parser.buffer_pos+1)) {
+ return yaml_parser_fetch_value(parser)
+ }
+
+ // Is it an alias?
+ if parser.buffer[parser.buffer_pos] == '*' {
+ return yaml_parser_fetch_anchor(parser, yaml_ALIAS_TOKEN)
+ }
+
+ // Is it an anchor?
+ if parser.buffer[parser.buffer_pos] == '&' {
+ return yaml_parser_fetch_anchor(parser, yaml_ANCHOR_TOKEN)
+ }
+
+ // Is it a tag?
+ if parser.buffer[parser.buffer_pos] == '!' {
+ return yaml_parser_fetch_tag(parser)
+ }
+
+ // Is it a literal scalar?
+ if parser.buffer[parser.buffer_pos] == '|' && parser.flow_level == 0 {
+ return yaml_parser_fetch_block_scalar(parser, true)
+ }
+
+ // Is it a folded scalar?
+ if parser.buffer[parser.buffer_pos] == '>' && parser.flow_level == 0 {
+ return yaml_parser_fetch_block_scalar(parser, false)
+ }
+
+ // Is it a single-quoted scalar?
+ if parser.buffer[parser.buffer_pos] == '\'' {
+ return yaml_parser_fetch_flow_scalar(parser, true)
+ }
+
+ // Is it a double-quoted scalar?
+ if parser.buffer[parser.buffer_pos] == '"' {
+ return yaml_parser_fetch_flow_scalar(parser, false)
+ }
+
+ // Is it a plain scalar?
+ //
+ // A plain scalar may start with any non-blank characters except
+ //
+ // '-', '?', ':', ',', '[', ']', '{', '}',
+ // '#', '&', '*', '!', '|', '>', '\'', '\"',
+ // '%', '@', '`'.
+ //
+ // In the block context (and, for the '-' indicator, in the flow context
+ // too), it may also start with the characters
+ //
+ // '-', '?', ':'
+ //
+ // if it is followed by a non-space character.
+ //
+ // The last rule is more restrictive than the specification requires.
+ // [Go] Make this logic more reasonable.
+ //switch parser.buffer[parser.buffer_pos] {
+ //case '-', '?', ':', ',', '?', '-', ',', ':', ']', '[', '}', '{', '&', '#', '!', '*', '>', '|', '"', '\'', '@', '%', '-', '`':
+ //}
+ if !(is_blankz(parser.buffer, parser.buffer_pos) || parser.buffer[parser.buffer_pos] == '-' ||
+ parser.buffer[parser.buffer_pos] == '?' || parser.buffer[parser.buffer_pos] == ':' ||
+ parser.buffer[parser.buffer_pos] == ',' || parser.buffer[parser.buffer_pos] == '[' ||
+ parser.buffer[parser.buffer_pos] == ']' || parser.buffer[parser.buffer_pos] == '{' ||
+ parser.buffer[parser.buffer_pos] == '}' || parser.buffer[parser.buffer_pos] == '#' ||
+ parser.buffer[parser.buffer_pos] == '&' || parser.buffer[parser.buffer_pos] == '*' ||
+ parser.buffer[parser.buffer_pos] == '!' || parser.buffer[parser.buffer_pos] == '|' ||
+ parser.buffer[parser.buffer_pos] == '>' || parser.buffer[parser.buffer_pos] == '\'' ||
+ parser.buffer[parser.buffer_pos] == '"' || parser.buffer[parser.buffer_pos] == '%' ||
+ parser.buffer[parser.buffer_pos] == '@' || parser.buffer[parser.buffer_pos] == '`') ||
+ (parser.buffer[parser.buffer_pos] == '-' && !is_blank(parser.buffer, parser.buffer_pos+1)) ||
+ (parser.flow_level == 0 &&
+ (parser.buffer[parser.buffer_pos] == '?' || parser.buffer[parser.buffer_pos] == ':') &&
+ !is_blankz(parser.buffer, parser.buffer_pos+1)) {
+ return yaml_parser_fetch_plain_scalar(parser)
+ }
+
+ // If we don't determine the token type so far, it is an error.
+ return yaml_parser_set_scanner_error(parser,
+ "while scanning for the next token", parser.mark,
+ "found character that cannot start any token")
+}
+
+// Check the list of potential simple keys and remove the positions that
+// cannot contain simple keys anymore.
+func yaml_parser_stale_simple_keys(parser *yaml_parser_t) bool {
+ // Check for a potential simple key for each flow level.
+ for i := range parser.simple_keys {
+ simple_key := &parser.simple_keys[i]
+
+ // The specification requires that a simple key
+ //
+ // - is limited to a single line,
+ // - is shorter than 1024 characters.
+ if simple_key.possible && (simple_key.mark.line < parser.mark.line || simple_key.mark.index+1024 < parser.mark.index) {
+
+ // Check if the potential simple key to be removed is required.
+ if simple_key.required {
+ return yaml_parser_set_scanner_error(parser,
+ "while scanning a simple key", simple_key.mark,
+ "could not find expected ':'")
+ }
+ simple_key.possible = false
+ }
+ }
+ return true
+}
+
+// Check if a simple key may start at the current position and add it if
+// needed.
+func yaml_parser_save_simple_key(parser *yaml_parser_t) bool {
+ // A simple key is required at the current position if the scanner is in
+ // the block context and the current column coincides with the indentation
+ // level.
+
+ required := parser.flow_level == 0 && parser.indent == parser.mark.column
+
+ //
+ // If the current position may start a simple key, save it.
+ //
+ if parser.simple_key_allowed {
+ simple_key := yaml_simple_key_t{
+ possible: true,
+ required: required,
+ token_number: parser.tokens_parsed + (len(parser.tokens) - parser.tokens_head),
+ }
+ simple_key.mark = parser.mark
+
+ if !yaml_parser_remove_simple_key(parser) {
+ return false
+ }
+ parser.simple_keys[len(parser.simple_keys)-1] = simple_key
+ }
+ return true
+}
+
+// Remove a potential simple key at the current flow level.
+func yaml_parser_remove_simple_key(parser *yaml_parser_t) bool {
+ i := len(parser.simple_keys) - 1
+ if parser.simple_keys[i].possible {
+ // If the key is required, it is an error.
+ if parser.simple_keys[i].required {
+ return yaml_parser_set_scanner_error(parser,
+ "while scanning a simple key", parser.simple_keys[i].mark,
+ "could not find expected ':'")
+ }
+ }
+ // Remove the key from the stack.
+ parser.simple_keys[i].possible = false
+ return true
+}
+
+// Increase the flow level and resize the simple key list if needed.
+func yaml_parser_increase_flow_level(parser *yaml_parser_t) bool {
+ // Reset the simple key on the next level.
+ parser.simple_keys = append(parser.simple_keys, yaml_simple_key_t{})
+
+ // Increase the flow level.
+ parser.flow_level++
+ return true
+}
+
+// Decrease the flow level.
+func yaml_parser_decrease_flow_level(parser *yaml_parser_t) bool {
+ if parser.flow_level > 0 {
+ parser.flow_level--
+ parser.simple_keys = parser.simple_keys[:len(parser.simple_keys)-1]
+ }
+ return true
+}
+
+// Push the current indentation level to the stack and set the new level
+// the current column is greater than the indentation level. In this case,
+// append or insert the specified token into the token queue.
+func yaml_parser_roll_indent(parser *yaml_parser_t, column, number int, typ yaml_token_type_t, mark yaml_mark_t) bool {
+ // In the flow context, do nothing.
+ if parser.flow_level > 0 {
+ return true
+ }
+
+ if parser.indent < column {
+ // Push the current indentation level to the stack and set the new
+ // indentation level.
+ parser.indents = append(parser.indents, parser.indent)
+ parser.indent = column
+
+ // Create a token and insert it into the queue.
+ token := yaml_token_t{
+ typ: typ,
+ start_mark: mark,
+ end_mark: mark,
+ }
+ if number > -1 {
+ number -= parser.tokens_parsed
+ }
+ yaml_insert_token(parser, number, &token)
+ }
+ return true
+}
+
+// Pop indentation levels from the indents stack until the current level
+// becomes less or equal to the column. For each indentation level, append
+// the BLOCK-END token.
+func yaml_parser_unroll_indent(parser *yaml_parser_t, column int) bool {
+ // In the flow context, do nothing.
+ if parser.flow_level > 0 {
+ return true
+ }
+
+ // Loop through the indentation levels in the stack.
+ for parser.indent > column {
+ // Create a token and append it to the queue.
+ token := yaml_token_t{
+ typ: yaml_BLOCK_END_TOKEN,
+ start_mark: parser.mark,
+ end_mark: parser.mark,
+ }
+ yaml_insert_token(parser, -1, &token)
+
+ // Pop the indentation level.
+ parser.indent = parser.indents[len(parser.indents)-1]
+ parser.indents = parser.indents[:len(parser.indents)-1]
+ }
+ return true
+}
+
+// Initialize the scanner and produce the STREAM-START token.
+func yaml_parser_fetch_stream_start(parser *yaml_parser_t) bool {
+
+ // Set the initial indentation.
+ parser.indent = -1
+
+ // Initialize the simple key stack.
+ parser.simple_keys = append(parser.simple_keys, yaml_simple_key_t{})
+
+ // A simple key is allowed at the beginning of the stream.
+ parser.simple_key_allowed = true
+
+ // We have started.
+ parser.stream_start_produced = true
+
+ // Create the STREAM-START token and append it to the queue.
+ token := yaml_token_t{
+ typ: yaml_STREAM_START_TOKEN,
+ start_mark: parser.mark,
+ end_mark: parser.mark,
+ encoding: parser.encoding,
+ }
+ yaml_insert_token(parser, -1, &token)
+ return true
+}
+
+// Produce the STREAM-END token and shut down the scanner.
+func yaml_parser_fetch_stream_end(parser *yaml_parser_t) bool {
+
+ // Force new line.
+ if parser.mark.column != 0 {
+ parser.mark.column = 0
+ parser.mark.line++
+ }
+
+ // Reset the indentation level.
+ if !yaml_parser_unroll_indent(parser, -1) {
+ return false
+ }
+
+ // Reset simple keys.
+ if !yaml_parser_remove_simple_key(parser) {
+ return false
+ }
+
+ parser.simple_key_allowed = false
+
+ // Create the STREAM-END token and append it to the queue.
+ token := yaml_token_t{
+ typ: yaml_STREAM_END_TOKEN,
+ start_mark: parser.mark,
+ end_mark: parser.mark,
+ }
+ yaml_insert_token(parser, -1, &token)
+ return true
+}
+
+// Produce a VERSION-DIRECTIVE or TAG-DIRECTIVE token.
+func yaml_parser_fetch_directive(parser *yaml_parser_t) bool {
+ // Reset the indentation level.
+ if !yaml_parser_unroll_indent(parser, -1) {
+ return false
+ }
+
+ // Reset simple keys.
+ if !yaml_parser_remove_simple_key(parser) {
+ return false
+ }
+
+ parser.simple_key_allowed = false
+
+ // Create the YAML-DIRECTIVE or TAG-DIRECTIVE token.
+ token := yaml_token_t{}
+ if !yaml_parser_scan_directive(parser, &token) {
+ return false
+ }
+ // Append the token to the queue.
+ yaml_insert_token(parser, -1, &token)
+ return true
+}
+
+// Produce the DOCUMENT-START or DOCUMENT-END token.
+func yaml_parser_fetch_document_indicator(parser *yaml_parser_t, typ yaml_token_type_t) bool {
+ // Reset the indentation level.
+ if !yaml_parser_unroll_indent(parser, -1) {
+ return false
+ }
+
+ // Reset simple keys.
+ if !yaml_parser_remove_simple_key(parser) {
+ return false
+ }
+
+ parser.simple_key_allowed = false
+
+ // Consume the token.
+ start_mark := parser.mark
+
+ skip(parser)
+ skip(parser)
+ skip(parser)
+
+ end_mark := parser.mark
+
+ // Create the DOCUMENT-START or DOCUMENT-END token.
+ token := yaml_token_t{
+ typ: typ,
+ start_mark: start_mark,
+ end_mark: end_mark,
+ }
+ // Append the token to the queue.
+ yaml_insert_token(parser, -1, &token)
+ return true
+}
+
+// Produce the FLOW-SEQUENCE-START or FLOW-MAPPING-START token.
+func yaml_parser_fetch_flow_collection_start(parser *yaml_parser_t, typ yaml_token_type_t) bool {
+ // The indicators '[' and '{' may start a simple key.
+ if !yaml_parser_save_simple_key(parser) {
+ return false
+ }
+
+ // Increase the flow level.
+ if !yaml_parser_increase_flow_level(parser) {
+ return false
+ }
+
+ // A simple key may follow the indicators '[' and '{'.
+ parser.simple_key_allowed = true
+
+ // Consume the token.
+ start_mark := parser.mark
+ skip(parser)
+ end_mark := parser.mark
+
+ // Create the FLOW-SEQUENCE-START of FLOW-MAPPING-START token.
+ token := yaml_token_t{
+ typ: typ,
+ start_mark: start_mark,
+ end_mark: end_mark,
+ }
+ // Append the token to the queue.
+ yaml_insert_token(parser, -1, &token)
+ return true
+}
+
+// Produce the FLOW-SEQUENCE-END or FLOW-MAPPING-END token.
+func yaml_parser_fetch_flow_collection_end(parser *yaml_parser_t, typ yaml_token_type_t) bool {
+ // Reset any potential simple key on the current flow level.
+ if !yaml_parser_remove_simple_key(parser) {
+ return false
+ }
+
+ // Decrease the flow level.
+ if !yaml_parser_decrease_flow_level(parser) {
+ return false
+ }
+
+ // No simple keys after the indicators ']' and '}'.
+ parser.simple_key_allowed = false
+
+ // Consume the token.
+
+ start_mark := parser.mark
+ skip(parser)
+ end_mark := parser.mark
+
+ // Create the FLOW-SEQUENCE-END of FLOW-MAPPING-END token.
+ token := yaml_token_t{
+ typ: typ,
+ start_mark: start_mark,
+ end_mark: end_mark,
+ }
+ // Append the token to the queue.
+ yaml_insert_token(parser, -1, &token)
+ return true
+}
+
+// Produce the FLOW-ENTRY token.
+func yaml_parser_fetch_flow_entry(parser *yaml_parser_t) bool {
+ // Reset any potential simple keys on the current flow level.
+ if !yaml_parser_remove_simple_key(parser) {
+ return false
+ }
+
+ // Simple keys are allowed after ','.
+ parser.simple_key_allowed = true
+
+ // Consume the token.
+ start_mark := parser.mark
+ skip(parser)
+ end_mark := parser.mark
+
+ // Create the FLOW-ENTRY token and append it to the queue.
+ token := yaml_token_t{
+ typ: yaml_FLOW_ENTRY_TOKEN,
+ start_mark: start_mark,
+ end_mark: end_mark,
+ }
+ yaml_insert_token(parser, -1, &token)
+ return true
+}
+
+// Produce the BLOCK-ENTRY token.
+func yaml_parser_fetch_block_entry(parser *yaml_parser_t) bool {
+ // Check if the scanner is in the block context.
+ if parser.flow_level == 0 {
+ // Check if we are allowed to start a new entry.
+ if !parser.simple_key_allowed {
+ return yaml_parser_set_scanner_error(parser, "", parser.mark,
+ "block sequence entries are not allowed in this context")
+ }
+ // Add the BLOCK-SEQUENCE-START token if needed.
+ if !yaml_parser_roll_indent(parser, parser.mark.column, -1, yaml_BLOCK_SEQUENCE_START_TOKEN, parser.mark) {
+ return false
+ }
+ } else {
+ // It is an error for the '-' indicator to occur in the flow context,
+ // but we let the Parser detect and report about it because the Parser
+ // is able to point to the context.
+ }
+
+ // Reset any potential simple keys on the current flow level.
+ if !yaml_parser_remove_simple_key(parser) {
+ return false
+ }
+
+ // Simple keys are allowed after '-'.
+ parser.simple_key_allowed = true
+
+ // Consume the token.
+ start_mark := parser.mark
+ skip(parser)
+ end_mark := parser.mark
+
+ // Create the BLOCK-ENTRY token and append it to the queue.
+ token := yaml_token_t{
+ typ: yaml_BLOCK_ENTRY_TOKEN,
+ start_mark: start_mark,
+ end_mark: end_mark,
+ }
+ yaml_insert_token(parser, -1, &token)
+ return true
+}
+
+// Produce the KEY token.
+func yaml_parser_fetch_key(parser *yaml_parser_t) bool {
+
+ // In the block context, additional checks are required.
+ if parser.flow_level == 0 {
+ // Check if we are allowed to start a new key (not nessesary simple).
+ if !parser.simple_key_allowed {
+ return yaml_parser_set_scanner_error(parser, "", parser.mark,
+ "mapping keys are not allowed in this context")
+ }
+ // Add the BLOCK-MAPPING-START token if needed.
+ if !yaml_parser_roll_indent(parser, parser.mark.column, -1, yaml_BLOCK_MAPPING_START_TOKEN, parser.mark) {
+ return false
+ }
+ }
+
+ // Reset any potential simple keys on the current flow level.
+ if !yaml_parser_remove_simple_key(parser) {
+ return false
+ }
+
+ // Simple keys are allowed after '?' in the block context.
+ parser.simple_key_allowed = parser.flow_level == 0
+
+ // Consume the token.
+ start_mark := parser.mark
+ skip(parser)
+ end_mark := parser.mark
+
+ // Create the KEY token and append it to the queue.
+ token := yaml_token_t{
+ typ: yaml_KEY_TOKEN,
+ start_mark: start_mark,
+ end_mark: end_mark,
+ }
+ yaml_insert_token(parser, -1, &token)
+ return true
+}
+
+// Produce the VALUE token.
+func yaml_parser_fetch_value(parser *yaml_parser_t) bool {
+
+ simple_key := &parser.simple_keys[len(parser.simple_keys)-1]
+
+ // Have we found a simple key?
+ if simple_key.possible {
+ // Create the KEY token and insert it into the queue.
+ token := yaml_token_t{
+ typ: yaml_KEY_TOKEN,
+ start_mark: simple_key.mark,
+ end_mark: simple_key.mark,
+ }
+ yaml_insert_token(parser, simple_key.token_number-parser.tokens_parsed, &token)
+
+ // In the block context, we may need to add the BLOCK-MAPPING-START token.
+ if !yaml_parser_roll_indent(parser, simple_key.mark.column,
+ simple_key.token_number,
+ yaml_BLOCK_MAPPING_START_TOKEN, simple_key.mark) {
+ return false
+ }
+
+ // Remove the simple key.
+ simple_key.possible = false
+
+ // A simple key cannot follow another simple key.
+ parser.simple_key_allowed = false
+
+ } else {
+ // The ':' indicator follows a complex key.
+
+ // In the block context, extra checks are required.
+ if parser.flow_level == 0 {
+
+ // Check if we are allowed to start a complex value.
+ if !parser.simple_key_allowed {
+ return yaml_parser_set_scanner_error(parser, "", parser.mark,
+ "mapping values are not allowed in this context")
+ }
+
+ // Add the BLOCK-MAPPING-START token if needed.
+ if !yaml_parser_roll_indent(parser, parser.mark.column, -1, yaml_BLOCK_MAPPING_START_TOKEN, parser.mark) {
+ return false
+ }
+ }
+
+ // Simple keys after ':' are allowed in the block context.
+ parser.simple_key_allowed = parser.flow_level == 0
+ }
+
+ // Consume the token.
+ start_mark := parser.mark
+ skip(parser)
+ end_mark := parser.mark
+
+ // Create the VALUE token and append it to the queue.
+ token := yaml_token_t{
+ typ: yaml_VALUE_TOKEN,
+ start_mark: start_mark,
+ end_mark: end_mark,
+ }
+ yaml_insert_token(parser, -1, &token)
+ return true
+}
+
+// Produce the ALIAS or ANCHOR token.
+func yaml_parser_fetch_anchor(parser *yaml_parser_t, typ yaml_token_type_t) bool {
+ // An anchor or an alias could be a simple key.
+ if !yaml_parser_save_simple_key(parser) {
+ return false
+ }
+
+ // A simple key cannot follow an anchor or an alias.
+ parser.simple_key_allowed = false
+
+ // Create the ALIAS or ANCHOR token and append it to the queue.
+ var token yaml_token_t
+ if !yaml_parser_scan_anchor(parser, &token, typ) {
+ return false
+ }
+ yaml_insert_token(parser, -1, &token)
+ return true
+}
+
+// Produce the TAG token.
+func yaml_parser_fetch_tag(parser *yaml_parser_t) bool {
+ // A tag could be a simple key.
+ if !yaml_parser_save_simple_key(parser) {
+ return false
+ }
+
+ // A simple key cannot follow a tag.
+ parser.simple_key_allowed = false
+
+ // Create the TAG token and append it to the queue.
+ var token yaml_token_t
+ if !yaml_parser_scan_tag(parser, &token) {
+ return false
+ }
+ yaml_insert_token(parser, -1, &token)
+ return true
+}
+
+// Produce the SCALAR(...,literal) or SCALAR(...,folded) tokens.
+func yaml_parser_fetch_block_scalar(parser *yaml_parser_t, literal bool) bool {
+ // Remove any potential simple keys.
+ if !yaml_parser_remove_simple_key(parser) {
+ return false
+ }
+
+ // A simple key may follow a block scalar.
+ parser.simple_key_allowed = true
+
+ // Create the SCALAR token and append it to the queue.
+ var token yaml_token_t
+ if !yaml_parser_scan_block_scalar(parser, &token, literal) {
+ return false
+ }
+ yaml_insert_token(parser, -1, &token)
+ return true
+}
+
+// Produce the SCALAR(...,single-quoted) or SCALAR(...,double-quoted) tokens.
+func yaml_parser_fetch_flow_scalar(parser *yaml_parser_t, single bool) bool {
+ // A plain scalar could be a simple key.
+ if !yaml_parser_save_simple_key(parser) {
+ return false
+ }
+
+ // A simple key cannot follow a flow scalar.
+ parser.simple_key_allowed = false
+
+ // Create the SCALAR token and append it to the queue.
+ var token yaml_token_t
+ if !yaml_parser_scan_flow_scalar(parser, &token, single) {
+ return false
+ }
+ yaml_insert_token(parser, -1, &token)
+ return true
+}
+
+// Produce the SCALAR(...,plain) token.
+func yaml_parser_fetch_plain_scalar(parser *yaml_parser_t) bool {
+ // A plain scalar could be a simple key.
+ if !yaml_parser_save_simple_key(parser) {
+ return false
+ }
+
+ // A simple key cannot follow a flow scalar.
+ parser.simple_key_allowed = false
+
+ // Create the SCALAR token and append it to the queue.
+ var token yaml_token_t
+ if !yaml_parser_scan_plain_scalar(parser, &token) {
+ return false
+ }
+ yaml_insert_token(parser, -1, &token)
+ return true
+}
+
+// Eat whitespaces and comments until the next token is found.
+func yaml_parser_scan_to_next_token(parser *yaml_parser_t) bool {
+
+ // Until the next token is not found.
+ for {
+ // Allow the BOM mark to start a line.
+ if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
+ return false
+ }
+ if parser.mark.column == 0 && is_bom(parser.buffer, parser.buffer_pos) {
+ skip(parser)
+ }
+
+ // Eat whitespaces.
+ // Tabs are allowed:
+ // - in the flow context
+ // - in the block context, but not at the beginning of the line or
+ // after '-', '?', or ':' (complex value).
+ if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
+ return false
+ }
+
+ for parser.buffer[parser.buffer_pos] == ' ' || ((parser.flow_level > 0 || !parser.simple_key_allowed) && parser.buffer[parser.buffer_pos] == '\t') {
+ skip(parser)
+ if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
+ return false
+ }
+ }
+
+ // Eat a comment until a line break.
+ if parser.buffer[parser.buffer_pos] == '#' {
+ for !is_breakz(parser.buffer, parser.buffer_pos) {
+ skip(parser)
+ if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
+ return false
+ }
+ }
+ }
+
+ // If it is a line break, eat it.
+ if is_break(parser.buffer, parser.buffer_pos) {
+ if parser.unread < 2 && !yaml_parser_update_buffer(parser, 2) {
+ return false
+ }
+ skip_line(parser)
+
+ // In the block context, a new line may start a simple key.
+ if parser.flow_level == 0 {
+ parser.simple_key_allowed = true
+ }
+ } else {
+ break // We have found a token.
+ }
+ }
+
+ return true
+}
+
+// Scan a YAML-DIRECTIVE or TAG-DIRECTIVE token.
+//
+// Scope:
+// %YAML 1.1 # a comment \n
+// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+// %TAG !yaml! tag:yaml.org,2002: \n
+// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+//
+func yaml_parser_scan_directive(parser *yaml_parser_t, token *yaml_token_t) bool {
+ // Eat '%'.
+ start_mark := parser.mark
+ skip(parser)
+
+ // Scan the directive name.
+ var name []byte
+ if !yaml_parser_scan_directive_name(parser, start_mark, &name) {
+ return false
+ }
+
+ // Is it a YAML directive?
+ if bytes.Equal(name, []byte("YAML")) {
+ // Scan the VERSION directive value.
+ var major, minor int8
+ if !yaml_parser_scan_version_directive_value(parser, start_mark, &major, &minor) {
+ return false
+ }
+ end_mark := parser.mark
+
+ // Create a VERSION-DIRECTIVE token.
+ *token = yaml_token_t{
+ typ: yaml_VERSION_DIRECTIVE_TOKEN,
+ start_mark: start_mark,
+ end_mark: end_mark,
+ major: major,
+ minor: minor,
+ }
+
+ // Is it a TAG directive?
+ } else if bytes.Equal(name, []byte("TAG")) {
+ // Scan the TAG directive value.
+ var handle, prefix []byte
+ if !yaml_parser_scan_tag_directive_value(parser, start_mark, &handle, &prefix) {
+ return false
+ }
+ end_mark := parser.mark
+
+ // Create a TAG-DIRECTIVE token.
+ *token = yaml_token_t{
+ typ: yaml_TAG_DIRECTIVE_TOKEN,
+ start_mark: start_mark,
+ end_mark: end_mark,
+ value: handle,
+ prefix: prefix,
+ }
+
+ // Unknown directive.
+ } else {
+ yaml_parser_set_scanner_error(parser, "while scanning a directive",
+ start_mark, "found unknown directive name")
+ return false
+ }
+
+ // Eat the rest of the line including any comments.
+ if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
+ return false
+ }
+
+ for is_blank(parser.buffer, parser.buffer_pos) {
+ skip(parser)
+ if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
+ return false
+ }
+ }
+
+ if parser.buffer[parser.buffer_pos] == '#' {
+ for !is_breakz(parser.buffer, parser.buffer_pos) {
+ skip(parser)
+ if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
+ return false
+ }
+ }
+ }
+
+ // Check if we are at the end of the line.
+ if !is_breakz(parser.buffer, parser.buffer_pos) {
+ yaml_parser_set_scanner_error(parser, "while scanning a directive",
+ start_mark, "did not find expected comment or line break")
+ return false
+ }
+
+ // Eat a line break.
+ if is_break(parser.buffer, parser.buffer_pos) {
+ if parser.unread < 2 && !yaml_parser_update_buffer(parser, 2) {
+ return false
+ }
+ skip_line(parser)
+ }
+
+ return true
+}
+
+// Scan the directive name.
+//
+// Scope:
+// %YAML 1.1 # a comment \n
+// ^^^^
+// %TAG !yaml! tag:yaml.org,2002: \n
+// ^^^
+//
+func yaml_parser_scan_directive_name(parser *yaml_parser_t, start_mark yaml_mark_t, name *[]byte) bool {
+ // Consume the directive name.
+ if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
+ return false
+ }
+
+ var s []byte
+ for is_alpha(parser.buffer, parser.buffer_pos) {
+ s = read(parser, s)
+ if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
+ return false
+ }
+ }
+
+ // Check if the name is empty.
+ if len(s) == 0 {
+ yaml_parser_set_scanner_error(parser, "while scanning a directive",
+ start_mark, "could not find expected directive name")
+ return false
+ }
+
+ // Check for an blank character after the name.
+ if !is_blankz(parser.buffer, parser.buffer_pos) {
+ yaml_parser_set_scanner_error(parser, "while scanning a directive",
+ start_mark, "found unexpected non-alphabetical character")
+ return false
+ }
+ *name = s
+ return true
+}
+
+// Scan the value of VERSION-DIRECTIVE.
+//
+// Scope:
+// %YAML 1.1 # a comment \n
+// ^^^^^^
+func yaml_parser_scan_version_directive_value(parser *yaml_parser_t, start_mark yaml_mark_t, major, minor *int8) bool {
+ // Eat whitespaces.
+ if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
+ return false
+ }
+ for is_blank(parser.buffer, parser.buffer_pos) {
+ skip(parser)
+ if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
+ return false
+ }
+ }
+
+ // Consume the major version number.
+ if !yaml_parser_scan_version_directive_number(parser, start_mark, major) {
+ return false
+ }
+
+ // Eat '.'.
+ if parser.buffer[parser.buffer_pos] != '.' {
+ return yaml_parser_set_scanner_error(parser, "while scanning a %YAML directive",
+ start_mark, "did not find expected digit or '.' character")
+ }
+
+ skip(parser)
+
+ // Consume the minor version number.
+ if !yaml_parser_scan_version_directive_number(parser, start_mark, minor) {
+ return false
+ }
+ return true
+}
+
+const max_number_length = 2
+
+// Scan the version number of VERSION-DIRECTIVE.
+//
+// Scope:
+// %YAML 1.1 # a comment \n
+// ^
+// %YAML 1.1 # a comment \n
+// ^
+func yaml_parser_scan_version_directive_number(parser *yaml_parser_t, start_mark yaml_mark_t, number *int8) bool {
+
+ // Repeat while the next character is digit.
+ if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
+ return false
+ }
+ var value, length int8
+ for is_digit(parser.buffer, parser.buffer_pos) {
+ // Check if the number is too long.
+ length++
+ if length > max_number_length {
+ return yaml_parser_set_scanner_error(parser, "while scanning a %YAML directive",
+ start_mark, "found extremely long version number")
+ }
+ value = value*10 + int8(as_digit(parser.buffer, parser.buffer_pos))
+ skip(parser)
+ if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
+ return false
+ }
+ }
+
+ // Check if the number was present.
+ if length == 0 {
+ return yaml_parser_set_scanner_error(parser, "while scanning a %YAML directive",
+ start_mark, "did not find expected version number")
+ }
+ *number = value
+ return true
+}
+
+// Scan the value of a TAG-DIRECTIVE token.
+//
+// Scope:
+// %TAG !yaml! tag:yaml.org,2002: \n
+// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+//
+func yaml_parser_scan_tag_directive_value(parser *yaml_parser_t, start_mark yaml_mark_t, handle, prefix *[]byte) bool {
+ var handle_value, prefix_value []byte
+
+ // Eat whitespaces.
+ if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
+ return false
+ }
+
+ for is_blank(parser.buffer, parser.buffer_pos) {
+ skip(parser)
+ if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
+ return false
+ }
+ }
+
+ // Scan a handle.
+ if !yaml_parser_scan_tag_handle(parser, true, start_mark, &handle_value) {
+ return false
+ }
+
+ // Expect a whitespace.
+ if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
+ return false
+ }
+ if !is_blank(parser.buffer, parser.buffer_pos) {
+ yaml_parser_set_scanner_error(parser, "while scanning a %TAG directive",
+ start_mark, "did not find expected whitespace")
+ return false
+ }
+
+ // Eat whitespaces.
+ for is_blank(parser.buffer, parser.buffer_pos) {
+ skip(parser)
+ if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
+ return false
+ }
+ }
+
+ // Scan a prefix.
+ if !yaml_parser_scan_tag_uri(parser, true, nil, start_mark, &prefix_value) {
+ return false
+ }
+
+ // Expect a whitespace or line break.
+ if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
+ return false
+ }
+ if !is_blankz(parser.buffer, parser.buffer_pos) {
+ yaml_parser_set_scanner_error(parser, "while scanning a %TAG directive",
+ start_mark, "did not find expected whitespace or line break")
+ return false
+ }
+
+ *handle = handle_value
+ *prefix = prefix_value
+ return true
+}
+
+func yaml_parser_scan_anchor(parser *yaml_parser_t, token *yaml_token_t, typ yaml_token_type_t) bool {
+ var s []byte
+
+ // Eat the indicator character.
+ start_mark := parser.mark
+ skip(parser)
+
+ // Consume the value.
+ if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
+ return false
+ }
+
+ for is_alpha(parser.buffer, parser.buffer_pos) {
+ s = read(parser, s)
+ if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
+ return false
+ }
+ }
+
+ end_mark := parser.mark
+
+ /*
+ * Check if length of the anchor is greater than 0 and it is followed by
+ * a whitespace character or one of the indicators:
+ *
+ * '?', ':', ',', ']', '}', '%', '@', '`'.
+ */
+
+ if len(s) == 0 ||
+ !(is_blankz(parser.buffer, parser.buffer_pos) || parser.buffer[parser.buffer_pos] == '?' ||
+ parser.buffer[parser.buffer_pos] == ':' || parser.buffer[parser.buffer_pos] == ',' ||
+ parser.buffer[parser.buffer_pos] == ']' || parser.buffer[parser.buffer_pos] == '}' ||
+ parser.buffer[parser.buffer_pos] == '%' || parser.buffer[parser.buffer_pos] == '@' ||
+ parser.buffer[parser.buffer_pos] == '`') {
+ context := "while scanning an alias"
+ if typ == yaml_ANCHOR_TOKEN {
+ context = "while scanning an anchor"
+ }
+ yaml_parser_set_scanner_error(parser, context, start_mark,
+ "did not find expected alphabetic or numeric character")
+ return false
+ }
+
+ // Create a token.
+ *token = yaml_token_t{
+ typ: typ,
+ start_mark: start_mark,
+ end_mark: end_mark,
+ value: s,
+ }
+
+ return true
+}
+
+/*
+ * Scan a TAG token.
+ */
+
+func yaml_parser_scan_tag(parser *yaml_parser_t, token *yaml_token_t) bool {
+ var handle, suffix []byte
+
+ start_mark := parser.mark
+
+ // Check if the tag is in the canonical form.
+ if parser.unread < 2 && !yaml_parser_update_buffer(parser, 2) {
+ return false
+ }
+
+ if parser.buffer[parser.buffer_pos+1] == '<' {
+ // Keep the handle as ''
+
+ // Eat '!<'
+ skip(parser)
+ skip(parser)
+
+ // Consume the tag value.
+ if !yaml_parser_scan_tag_uri(parser, false, nil, start_mark, &suffix) {
+ return false
+ }
+
+ // Check for '>' and eat it.
+ if parser.buffer[parser.buffer_pos] != '>' {
+ yaml_parser_set_scanner_error(parser, "while scanning a tag",
+ start_mark, "did not find the expected '>'")
+ return false
+ }
+
+ skip(parser)
+ } else {
+ // The tag has either the '!suffix' or the '!handle!suffix' form.
+
+ // First, try to scan a handle.
+ if !yaml_parser_scan_tag_handle(parser, false, start_mark, &handle) {
+ return false
+ }
+
+ // Check if it is, indeed, handle.
+ if handle[0] == '!' && len(handle) > 1 && handle[len(handle)-1] == '!' {
+ // Scan the suffix now.
+ if !yaml_parser_scan_tag_uri(parser, false, nil, start_mark, &suffix) {
+ return false
+ }
+ } else {
+ // It wasn't a handle after all. Scan the rest of the tag.
+ if !yaml_parser_scan_tag_uri(parser, false, handle, start_mark, &suffix) {
+ return false
+ }
+
+ // Set the handle to '!'.
+ handle = []byte{'!'}
+
+ // A special case: the '!' tag. Set the handle to '' and the
+ // suffix to '!'.
+ if len(suffix) == 0 {
+ handle, suffix = suffix, handle
+ }
+ }
+ }
+
+ // Check the character which ends the tag.
+ if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
+ return false
+ }
+ if !is_blankz(parser.buffer, parser.buffer_pos) {
+ yaml_parser_set_scanner_error(parser, "while scanning a tag",
+ start_mark, "did not find expected whitespace or line break")
+ return false
+ }
+
+ end_mark := parser.mark
+
+ // Create a token.
+ *token = yaml_token_t{
+ typ: yaml_TAG_TOKEN,
+ start_mark: start_mark,
+ end_mark: end_mark,
+ value: handle,
+ suffix: suffix,
+ }
+ return true
+}
+
+// Scan a tag handle.
+func yaml_parser_scan_tag_handle(parser *yaml_parser_t, directive bool, start_mark yaml_mark_t, handle *[]byte) bool {
+ // Check the initial '!' character.
+ if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
+ return false
+ }
+ if parser.buffer[parser.buffer_pos] != '!' {
+ yaml_parser_set_scanner_tag_error(parser, directive,
+ start_mark, "did not find expected '!'")
+ return false
+ }
+
+ var s []byte
+
+ // Copy the '!' character.
+ s = read(parser, s)
+
+ // Copy all subsequent alphabetical and numerical characters.
+ if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
+ return false
+ }
+ for is_alpha(parser.buffer, parser.buffer_pos) {
+ s = read(parser, s)
+ if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
+ return false
+ }
+ }
+
+ // Check if the trailing character is '!' and copy it.
+ if parser.buffer[parser.buffer_pos] == '!' {
+ s = read(parser, s)
+ } else {
+ // It's either the '!' tag or not really a tag handle. If it's a %TAG
+ // directive, it's an error. If it's a tag token, it must be a part of URI.
+ if directive && string(s) != "!" {
+ yaml_parser_set_scanner_tag_error(parser, directive,
+ start_mark, "did not find expected '!'")
+ return false
+ }
+ }
+
+ *handle = s
+ return true
+}
+
+// Scan a tag.
+func yaml_parser_scan_tag_uri(parser *yaml_parser_t, directive bool, head []byte, start_mark yaml_mark_t, uri *[]byte) bool {
+ //size_t length = head ? strlen((char *)head) : 0
+ var s []byte
+ hasTag := len(head) > 0
+
+ // Copy the head if needed.
+ //
+ // Note that we don't copy the leading '!' character.
+ if len(head) > 1 {
+ s = append(s, head[1:]...)
+ }
+
+ // Scan the tag.
+ if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
+ return false
+ }
+
+ // The set of characters that may appear in URI is as follows:
+ //
+ // '0'-'9', 'A'-'Z', 'a'-'z', '_', '-', ';', '/', '?', ':', '@', '&',
+ // '=', '+', '$', ',', '.', '!', '~', '*', '\'', '(', ')', '[', ']',
+ // '%'.
+ // [Go] Convert this into more reasonable logic.
+ for is_alpha(parser.buffer, parser.buffer_pos) || parser.buffer[parser.buffer_pos] == ';' ||
+ parser.buffer[parser.buffer_pos] == '/' || parser.buffer[parser.buffer_pos] == '?' ||
+ parser.buffer[parser.buffer_pos] == ':' || parser.buffer[parser.buffer_pos] == '@' ||
+ parser.buffer[parser.buffer_pos] == '&' || parser.buffer[parser.buffer_pos] == '=' ||
+ parser.buffer[parser.buffer_pos] == '+' || parser.buffer[parser.buffer_pos] == '$' ||
+ parser.buffer[parser.buffer_pos] == ',' || parser.buffer[parser.buffer_pos] == '.' ||
+ parser.buffer[parser.buffer_pos] == '!' || parser.buffer[parser.buffer_pos] == '~' ||
+ parser.buffer[parser.buffer_pos] == '*' || parser.buffer[parser.buffer_pos] == '\'' ||
+ parser.buffer[parser.buffer_pos] == '(' || parser.buffer[parser.buffer_pos] == ')' ||
+ parser.buffer[parser.buffer_pos] == '[' || parser.buffer[parser.buffer_pos] == ']' ||
+ parser.buffer[parser.buffer_pos] == '%' {
+ // Check if it is a URI-escape sequence.
+ if parser.buffer[parser.buffer_pos] == '%' {
+ if !yaml_parser_scan_uri_escapes(parser, directive, start_mark, &s) {
+ return false
+ }
+ } else {
+ s = read(parser, s)
+ }
+ if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
+ return false
+ }
+ hasTag = true
+ }
+
+ if !hasTag {
+ yaml_parser_set_scanner_tag_error(parser, directive,
+ start_mark, "did not find expected tag URI")
+ return false
+ }
+ *uri = s
+ return true
+}
+
+// Decode an URI-escape sequence corresponding to a single UTF-8 character.
+func yaml_parser_scan_uri_escapes(parser *yaml_parser_t, directive bool, start_mark yaml_mark_t, s *[]byte) bool {
+
+ // Decode the required number of characters.
+ w := 1024
+ for w > 0 {
+ // Check for a URI-escaped octet.
+ if parser.unread < 3 && !yaml_parser_update_buffer(parser, 3) {
+ return false
+ }
+
+ if !(parser.buffer[parser.buffer_pos] == '%' &&
+ is_hex(parser.buffer, parser.buffer_pos+1) &&
+ is_hex(parser.buffer, parser.buffer_pos+2)) {
+ return yaml_parser_set_scanner_tag_error(parser, directive,
+ start_mark, "did not find URI escaped octet")
+ }
+
+ // Get the octet.
+ octet := byte((as_hex(parser.buffer, parser.buffer_pos+1) << 4) + as_hex(parser.buffer, parser.buffer_pos+2))
+
+ // If it is the leading octet, determine the length of the UTF-8 sequence.
+ if w == 1024 {
+ w = width(octet)
+ if w == 0 {
+ return yaml_parser_set_scanner_tag_error(parser, directive,
+ start_mark, "found an incorrect leading UTF-8 octet")
+ }
+ } else {
+ // Check if the trailing octet is correct.
+ if octet&0xC0 != 0x80 {
+ return yaml_parser_set_scanner_tag_error(parser, directive,
+ start_mark, "found an incorrect trailing UTF-8 octet")
+ }
+ }
+
+ // Copy the octet and move the pointers.
+ *s = append(*s, octet)
+ skip(parser)
+ skip(parser)
+ skip(parser)
+ w--
+ }
+ return true
+}
+
+// Scan a block scalar.
+func yaml_parser_scan_block_scalar(parser *yaml_parser_t, token *yaml_token_t, literal bool) bool {
+ // Eat the indicator '|' or '>'.
+ start_mark := parser.mark
+ skip(parser)
+
+ // Scan the additional block scalar indicators.
+ if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
+ return false
+ }
+
+ // Check for a chomping indicator.
+ var chomping, increment int
+ if parser.buffer[parser.buffer_pos] == '+' || parser.buffer[parser.buffer_pos] == '-' {
+ // Set the chomping method and eat the indicator.
+ if parser.buffer[parser.buffer_pos] == '+' {
+ chomping = +1
+ } else {
+ chomping = -1
+ }
+ skip(parser)
+
+ // Check for an indentation indicator.
+ if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
+ return false
+ }
+ if is_digit(parser.buffer, parser.buffer_pos) {
+ // Check that the indentation is greater than 0.
+ if parser.buffer[parser.buffer_pos] == '0' {
+ yaml_parser_set_scanner_error(parser, "while scanning a block scalar",
+ start_mark, "found an indentation indicator equal to 0")
+ return false
+ }
+
+ // Get the indentation level and eat the indicator.
+ increment = as_digit(parser.buffer, parser.buffer_pos)
+ skip(parser)
+ }
+
+ } else if is_digit(parser.buffer, parser.buffer_pos) {
+ // Do the same as above, but in the opposite order.
+
+ if parser.buffer[parser.buffer_pos] == '0' {
+ yaml_parser_set_scanner_error(parser, "while scanning a block scalar",
+ start_mark, "found an indentation indicator equal to 0")
+ return false
+ }
+ increment = as_digit(parser.buffer, parser.buffer_pos)
+ skip(parser)
+
+ if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
+ return false
+ }
+ if parser.buffer[parser.buffer_pos] == '+' || parser.buffer[parser.buffer_pos] == '-' {
+ if parser.buffer[parser.buffer_pos] == '+' {
+ chomping = +1
+ } else {
+ chomping = -1
+ }
+ skip(parser)
+ }
+ }
+
+ // Eat whitespaces and comments to the end of the line.
+ if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
+ return false
+ }
+ for is_blank(parser.buffer, parser.buffer_pos) {
+ skip(parser)
+ if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
+ return false
+ }
+ }
+ if parser.buffer[parser.buffer_pos] == '#' {
+ for !is_breakz(parser.buffer, parser.buffer_pos) {
+ skip(parser)
+ if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
+ return false
+ }
+ }
+ }
+
+ // Check if we are at the end of the line.
+ if !is_breakz(parser.buffer, parser.buffer_pos) {
+ yaml_parser_set_scanner_error(parser, "while scanning a block scalar",
+ start_mark, "did not find expected comment or line break")
+ return false
+ }
+
+ // Eat a line break.
+ if is_break(parser.buffer, parser.buffer_pos) {
+ if parser.unread < 2 && !yaml_parser_update_buffer(parser, 2) {
+ return false
+ }
+ skip_line(parser)
+ }
+
+ end_mark := parser.mark
+
+ // Set the indentation level if it was specified.
+ var indent int
+ if increment > 0 {
+ if parser.indent >= 0 {
+ indent = parser.indent + increment
+ } else {
+ indent = increment
+ }
+ }
+
+ // Scan the leading line breaks and determine the indentation level if needed.
+ var s, leading_break, trailing_breaks []byte
+ if !yaml_parser_scan_block_scalar_breaks(parser, &indent, &trailing_breaks, start_mark, &end_mark) {
+ return false
+ }
+
+ // Scan the block scalar content.
+ if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
+ return false
+ }
+ var leading_blank, trailing_blank bool
+ for parser.mark.column == indent && !is_z(parser.buffer, parser.buffer_pos) {
+ // We are at the beginning of a non-empty line.
+
+ // Is it a trailing whitespace?
+ trailing_blank = is_blank(parser.buffer, parser.buffer_pos)
+
+ // Check if we need to fold the leading line break.
+ if !literal && !leading_blank && !trailing_blank && len(leading_break) > 0 && leading_break[0] == '\n' {
+ // Do we need to join the lines by space?
+ if len(trailing_breaks) == 0 {
+ s = append(s, ' ')
+ }
+ } else {
+ s = append(s, leading_break...)
+ }
+ leading_break = leading_break[:0]
+
+ // Append the remaining line breaks.
+ s = append(s, trailing_breaks...)
+ trailing_breaks = trailing_breaks[:0]
+
+ // Is it a leading whitespace?
+ leading_blank = is_blank(parser.buffer, parser.buffer_pos)
+
+ // Consume the current line.
+ for !is_breakz(parser.buffer, parser.buffer_pos) {
+ s = read(parser, s)
+ if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
+ return false
+ }
+ }
+
+ // Consume the line break.
+ if parser.unread < 2 && !yaml_parser_update_buffer(parser, 2) {
+ return false
+ }
+
+ leading_break = read_line(parser, leading_break)
+
+ // Eat the following indentation spaces and line breaks.
+ if !yaml_parser_scan_block_scalar_breaks(parser, &indent, &trailing_breaks, start_mark, &end_mark) {
+ return false
+ }
+ }
+
+ // Chomp the tail.
+ if chomping != -1 {
+ s = append(s, leading_break...)
+ }
+ if chomping == 1 {
+ s = append(s, trailing_breaks...)
+ }
+
+ // Create a token.
+ *token = yaml_token_t{
+ typ: yaml_SCALAR_TOKEN,
+ start_mark: start_mark,
+ end_mark: end_mark,
+ value: s,
+ style: yaml_LITERAL_SCALAR_STYLE,
+ }
+ if !literal {
+ token.style = yaml_FOLDED_SCALAR_STYLE
+ }
+ return true
+}
+
+// Scan indentation spaces and line breaks for a block scalar. Determine the
+// indentation level if needed.
+func yaml_parser_scan_block_scalar_breaks(parser *yaml_parser_t, indent *int, breaks *[]byte, start_mark yaml_mark_t, end_mark *yaml_mark_t) bool {
+ *end_mark = parser.mark
+
+ // Eat the indentation spaces and line breaks.
+ max_indent := 0
+ for {
+ // Eat the indentation spaces.
+ if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
+ return false
+ }
+ for (*indent == 0 || parser.mark.column < *indent) && is_space(parser.buffer, parser.buffer_pos) {
+ skip(parser)
+ if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
+ return false
+ }
+ }
+ if parser.mark.column > max_indent {
+ max_indent = parser.mark.column
+ }
+
+ // Check for a tab character messing the indentation.
+ if (*indent == 0 || parser.mark.column < *indent) && is_tab(parser.buffer, parser.buffer_pos) {
+ return yaml_parser_set_scanner_error(parser, "while scanning a block scalar",
+ start_mark, "found a tab character where an indentation space is expected")
+ }
+
+ // Have we found a non-empty line?
+ if !is_break(parser.buffer, parser.buffer_pos) {
+ break
+ }
+
+ // Consume the line break.
+ if parser.unread < 2 && !yaml_parser_update_buffer(parser, 2) {
+ return false
+ }
+ // [Go] Should really be returning breaks instead.
+ *breaks = read_line(parser, *breaks)
+ *end_mark = parser.mark
+ }
+
+ // Determine the indentation level if needed.
+ if *indent == 0 {
+ *indent = max_indent
+ if *indent < parser.indent+1 {
+ *indent = parser.indent + 1
+ }
+ if *indent < 1 {
+ *indent = 1
+ }
+ }
+ return true
+}
+
+// Scan a quoted scalar.
+func yaml_parser_scan_flow_scalar(parser *yaml_parser_t, token *yaml_token_t, single bool) bool {
+ // Eat the left quote.
+ start_mark := parser.mark
+ skip(parser)
+
+ // Consume the content of the quoted scalar.
+ var s, leading_break, trailing_breaks, whitespaces []byte
+ for {
+ // Check that there are no document indicators at the beginning of the line.
+ if parser.unread < 4 && !yaml_parser_update_buffer(parser, 4) {
+ return false
+ }
+
+ if parser.mark.column == 0 &&
+ ((parser.buffer[parser.buffer_pos+0] == '-' &&
+ parser.buffer[parser.buffer_pos+1] == '-' &&
+ parser.buffer[parser.buffer_pos+2] == '-') ||
+ (parser.buffer[parser.buffer_pos+0] == '.' &&
+ parser.buffer[parser.buffer_pos+1] == '.' &&
+ parser.buffer[parser.buffer_pos+2] == '.')) &&
+ is_blankz(parser.buffer, parser.buffer_pos+3) {
+ yaml_parser_set_scanner_error(parser, "while scanning a quoted scalar",
+ start_mark, "found unexpected document indicator")
+ return false
+ }
+
+ // Check for EOF.
+ if is_z(parser.buffer, parser.buffer_pos) {
+ yaml_parser_set_scanner_error(parser, "while scanning a quoted scalar",
+ start_mark, "found unexpected end of stream")
+ return false
+ }
+
+ // Consume non-blank characters.
+ leading_blanks := false
+ for !is_blankz(parser.buffer, parser.buffer_pos) {
+ if single && parser.buffer[parser.buffer_pos] == '\'' && parser.buffer[parser.buffer_pos+1] == '\'' {
+ // Is is an escaped single quote.
+ s = append(s, '\'')
+ skip(parser)
+ skip(parser)
+
+ } else if single && parser.buffer[parser.buffer_pos] == '\'' {
+ // It is a right single quote.
+ break
+ } else if !single && parser.buffer[parser.buffer_pos] == '"' {
+ // It is a right double quote.
+ break
+
+ } else if !single && parser.buffer[parser.buffer_pos] == '\\' && is_break(parser.buffer, parser.buffer_pos+1) {
+ // It is an escaped line break.
+ if parser.unread < 3 && !yaml_parser_update_buffer(parser, 3) {
+ return false
+ }
+ skip(parser)
+ skip_line(parser)
+ leading_blanks = true
+ break
+
+ } else if !single && parser.buffer[parser.buffer_pos] == '\\' {
+ // It is an escape sequence.
+ code_length := 0
+
+ // Check the escape character.
+ switch parser.buffer[parser.buffer_pos+1] {
+ case '0':
+ s = append(s, 0)
+ case 'a':
+ s = append(s, '\x07')
+ case 'b':
+ s = append(s, '\x08')
+ case 't', '\t':
+ s = append(s, '\x09')
+ case 'n':
+ s = append(s, '\x0A')
+ case 'v':
+ s = append(s, '\x0B')
+ case 'f':
+ s = append(s, '\x0C')
+ case 'r':
+ s = append(s, '\x0D')
+ case 'e':
+ s = append(s, '\x1B')
+ case ' ':
+ s = append(s, '\x20')
+ case '"':
+ s = append(s, '"')
+ case '\'':
+ s = append(s, '\'')
+ case '\\':
+ s = append(s, '\\')
+ case 'N': // NEL (#x85)
+ s = append(s, '\xC2')
+ s = append(s, '\x85')
+ case '_': // #xA0
+ s = append(s, '\xC2')
+ s = append(s, '\xA0')
+ case 'L': // LS (#x2028)
+ s = append(s, '\xE2')
+ s = append(s, '\x80')
+ s = append(s, '\xA8')
+ case 'P': // PS (#x2029)
+ s = append(s, '\xE2')
+ s = append(s, '\x80')
+ s = append(s, '\xA9')
+ case 'x':
+ code_length = 2
+ case 'u':
+ code_length = 4
+ case 'U':
+ code_length = 8
+ default:
+ yaml_parser_set_scanner_error(parser, "while parsing a quoted scalar",
+ start_mark, "found unknown escape character")
+ return false
+ }
+
+ skip(parser)
+ skip(parser)
+
+ // Consume an arbitrary escape code.
+ if code_length > 0 {
+ var value int
+
+ // Scan the character value.
+ if parser.unread < code_length && !yaml_parser_update_buffer(parser, code_length) {
+ return false
+ }
+ for k := 0; k < code_length; k++ {
+ if !is_hex(parser.buffer, parser.buffer_pos+k) {
+ yaml_parser_set_scanner_error(parser, "while parsing a quoted scalar",
+ start_mark, "did not find expected hexdecimal number")
+ return false
+ }
+ value = (value << 4) + as_hex(parser.buffer, parser.buffer_pos+k)
+ }
+
+ // Check the value and write the character.
+ if (value >= 0xD800 && value <= 0xDFFF) || value > 0x10FFFF {
+ yaml_parser_set_scanner_error(parser, "while parsing a quoted scalar",
+ start_mark, "found invalid Unicode character escape code")
+ return false
+ }
+ if value <= 0x7F {
+ s = append(s, byte(value))
+ } else if value <= 0x7FF {
+ s = append(s, byte(0xC0+(value>>6)))
+ s = append(s, byte(0x80+(value&0x3F)))
+ } else if value <= 0xFFFF {
+ s = append(s, byte(0xE0+(value>>12)))
+ s = append(s, byte(0x80+((value>>6)&0x3F)))
+ s = append(s, byte(0x80+(value&0x3F)))
+ } else {
+ s = append(s, byte(0xF0+(value>>18)))
+ s = append(s, byte(0x80+((value>>12)&0x3F)))
+ s = append(s, byte(0x80+((value>>6)&0x3F)))
+ s = append(s, byte(0x80+(value&0x3F)))
+ }
+
+ // Advance the pointer.
+ for k := 0; k < code_length; k++ {
+ skip(parser)
+ }
+ }
+ } else {
+ // It is a non-escaped non-blank character.
+ s = read(parser, s)
+ }
+ if parser.unread < 2 && !yaml_parser_update_buffer(parser, 2) {
+ return false
+ }
+ }
+
+ if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
+ return false
+ }
+
+ // Check if we are at the end of the scalar.
+ if single {
+ if parser.buffer[parser.buffer_pos] == '\'' {
+ break
+ }
+ } else {
+ if parser.buffer[parser.buffer_pos] == '"' {
+ break
+ }
+ }
+
+ // Consume blank characters.
+ for is_blank(parser.buffer, parser.buffer_pos) || is_break(parser.buffer, parser.buffer_pos) {
+ if is_blank(parser.buffer, parser.buffer_pos) {
+ // Consume a space or a tab character.
+ if !leading_blanks {
+ whitespaces = read(parser, whitespaces)
+ } else {
+ skip(parser)
+ }
+ } else {
+ if parser.unread < 2 && !yaml_parser_update_buffer(parser, 2) {
+ return false
+ }
+
+ // Check if it is a first line break.
+ if !leading_blanks {
+ whitespaces = whitespaces[:0]
+ leading_break = read_line(parser, leading_break)
+ leading_blanks = true
+ } else {
+ trailing_breaks = read_line(parser, trailing_breaks)
+ }
+ }
+ if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
+ return false
+ }
+ }
+
+ // Join the whitespaces or fold line breaks.
+ if leading_blanks {
+ // Do we need to fold line breaks?
+ if len(leading_break) > 0 && leading_break[0] == '\n' {
+ if len(trailing_breaks) == 0 {
+ s = append(s, ' ')
+ } else {
+ s = append(s, trailing_breaks...)
+ }
+ } else {
+ s = append(s, leading_break...)
+ s = append(s, trailing_breaks...)
+ }
+ trailing_breaks = trailing_breaks[:0]
+ leading_break = leading_break[:0]
+ } else {
+ s = append(s, whitespaces...)
+ whitespaces = whitespaces[:0]
+ }
+ }
+
+ // Eat the right quote.
+ skip(parser)
+ end_mark := parser.mark
+
+ // Create a token.
+ *token = yaml_token_t{
+ typ: yaml_SCALAR_TOKEN,
+ start_mark: start_mark,
+ end_mark: end_mark,
+ value: s,
+ style: yaml_SINGLE_QUOTED_SCALAR_STYLE,
+ }
+ if !single {
+ token.style = yaml_DOUBLE_QUOTED_SCALAR_STYLE
+ }
+ return true
+}
+
+// Scan a plain scalar.
+func yaml_parser_scan_plain_scalar(parser *yaml_parser_t, token *yaml_token_t) bool {
+
+ var s, leading_break, trailing_breaks, whitespaces []byte
+ var leading_blanks bool
+ var indent = parser.indent + 1
+
+ start_mark := parser.mark
+ end_mark := parser.mark
+
+ // Consume the content of the plain scalar.
+ for {
+ // Check for a document indicator.
+ if parser.unread < 4 && !yaml_parser_update_buffer(parser, 4) {
+ return false
+ }
+ if parser.mark.column == 0 &&
+ ((parser.buffer[parser.buffer_pos+0] == '-' &&
+ parser.buffer[parser.buffer_pos+1] == '-' &&
+ parser.buffer[parser.buffer_pos+2] == '-') ||
+ (parser.buffer[parser.buffer_pos+0] == '.' &&
+ parser.buffer[parser.buffer_pos+1] == '.' &&
+ parser.buffer[parser.buffer_pos+2] == '.')) &&
+ is_blankz(parser.buffer, parser.buffer_pos+3) {
+ break
+ }
+
+ // Check for a comment.
+ if parser.buffer[parser.buffer_pos] == '#' {
+ break
+ }
+
+ // Consume non-blank characters.
+ for !is_blankz(parser.buffer, parser.buffer_pos) {
+
+ // Check for indicators that may end a plain scalar.
+ if (parser.buffer[parser.buffer_pos] == ':' && is_blankz(parser.buffer, parser.buffer_pos+1)) ||
+ (parser.flow_level > 0 &&
+ (parser.buffer[parser.buffer_pos] == ',' ||
+ parser.buffer[parser.buffer_pos] == '?' || parser.buffer[parser.buffer_pos] == '[' ||
+ parser.buffer[parser.buffer_pos] == ']' || parser.buffer[parser.buffer_pos] == '{' ||
+ parser.buffer[parser.buffer_pos] == '}')) {
+ break
+ }
+
+ // Check if we need to join whitespaces and breaks.
+ if leading_blanks || len(whitespaces) > 0 {
+ if leading_blanks {
+ // Do we need to fold line breaks?
+ if leading_break[0] == '\n' {
+ if len(trailing_breaks) == 0 {
+ s = append(s, ' ')
+ } else {
+ s = append(s, trailing_breaks...)
+ }
+ } else {
+ s = append(s, leading_break...)
+ s = append(s, trailing_breaks...)
+ }
+ trailing_breaks = trailing_breaks[:0]
+ leading_break = leading_break[:0]
+ leading_blanks = false
+ } else {
+ s = append(s, whitespaces...)
+ whitespaces = whitespaces[:0]
+ }
+ }
+
+ // Copy the character.
+ s = read(parser, s)
+
+ end_mark = parser.mark
+ if parser.unread < 2 && !yaml_parser_update_buffer(parser, 2) {
+ return false
+ }
+ }
+
+ // Is it the end?
+ if !(is_blank(parser.buffer, parser.buffer_pos) || is_break(parser.buffer, parser.buffer_pos)) {
+ break
+ }
+
+ // Consume blank characters.
+ if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
+ return false
+ }
+
+ for is_blank(parser.buffer, parser.buffer_pos) || is_break(parser.buffer, parser.buffer_pos) {
+ if is_blank(parser.buffer, parser.buffer_pos) {
+
+ // Check for tab characters that abuse indentation.
+ if leading_blanks && parser.mark.column < indent && is_tab(parser.buffer, parser.buffer_pos) {
+ yaml_parser_set_scanner_error(parser, "while scanning a plain scalar",
+ start_mark, "found a tab character that violates indentation")
+ return false
+ }
+
+ // Consume a space or a tab character.
+ if !leading_blanks {
+ whitespaces = read(parser, whitespaces)
+ } else {
+ skip(parser)
+ }
+ } else {
+ if parser.unread < 2 && !yaml_parser_update_buffer(parser, 2) {
+ return false
+ }
+
+ // Check if it is a first line break.
+ if !leading_blanks {
+ whitespaces = whitespaces[:0]
+ leading_break = read_line(parser, leading_break)
+ leading_blanks = true
+ } else {
+ trailing_breaks = read_line(parser, trailing_breaks)
+ }
+ }
+ if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
+ return false
+ }
+ }
+
+ // Check indentation level.
+ if parser.flow_level == 0 && parser.mark.column < indent {
+ break
+ }
+ }
+
+ // Create a token.
+ *token = yaml_token_t{
+ typ: yaml_SCALAR_TOKEN,
+ start_mark: start_mark,
+ end_mark: end_mark,
+ value: s,
+ style: yaml_PLAIN_SCALAR_STYLE,
+ }
+
+ // Note that we change the 'simple_key_allowed' flag.
+ if leading_blanks {
+ parser.simple_key_allowed = true
+ }
+ return true
+}
diff --git a/vendor/gopkg.in/yaml.v2/sorter.go b/vendor/gopkg.in/yaml.v2/sorter.go
new file mode 100644
index 0000000000000000000000000000000000000000..4c45e660a8f2e1020907cd4f05a46cfa3c421e97
--- /dev/null
+++ b/vendor/gopkg.in/yaml.v2/sorter.go
@@ -0,0 +1,113 @@
+package yaml
+
+import (
+ "reflect"
+ "unicode"
+)
+
+type keyList []reflect.Value
+
+func (l keyList) Len() int { return len(l) }
+func (l keyList) Swap(i, j int) { l[i], l[j] = l[j], l[i] }
+func (l keyList) Less(i, j int) bool {
+ a := l[i]
+ b := l[j]
+ ak := a.Kind()
+ bk := b.Kind()
+ for (ak == reflect.Interface || ak == reflect.Ptr) && !a.IsNil() {
+ a = a.Elem()
+ ak = a.Kind()
+ }
+ for (bk == reflect.Interface || bk == reflect.Ptr) && !b.IsNil() {
+ b = b.Elem()
+ bk = b.Kind()
+ }
+ af, aok := keyFloat(a)
+ bf, bok := keyFloat(b)
+ if aok && bok {
+ if af != bf {
+ return af < bf
+ }
+ if ak != bk {
+ return ak < bk
+ }
+ return numLess(a, b)
+ }
+ if ak != reflect.String || bk != reflect.String {
+ return ak < bk
+ }
+ ar, br := []rune(a.String()), []rune(b.String())
+ for i := 0; i < len(ar) && i < len(br); i++ {
+ if ar[i] == br[i] {
+ continue
+ }
+ al := unicode.IsLetter(ar[i])
+ bl := unicode.IsLetter(br[i])
+ if al && bl {
+ return ar[i] < br[i]
+ }
+ if al || bl {
+ return bl
+ }
+ var ai, bi int
+ var an, bn int64
+ if ar[i] == '0' || br[i] == '0' {
+ for j := i-1; j >= 0 && unicode.IsDigit(ar[j]); j-- {
+ if ar[j] != '0' {
+ an = 1
+ bn = 1
+ break
+ }
+ }
+ }
+ for ai = i; ai < len(ar) && unicode.IsDigit(ar[ai]); ai++ {
+ an = an*10 + int64(ar[ai]-'0')
+ }
+ for bi = i; bi < len(br) && unicode.IsDigit(br[bi]); bi++ {
+ bn = bn*10 + int64(br[bi]-'0')
+ }
+ if an != bn {
+ return an < bn
+ }
+ if ai != bi {
+ return ai < bi
+ }
+ return ar[i] < br[i]
+ }
+ return len(ar) < len(br)
+}
+
+// keyFloat returns a float value for v if it is a number/bool
+// and whether it is a number/bool or not.
+func keyFloat(v reflect.Value) (f float64, ok bool) {
+ switch v.Kind() {
+ case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+ return float64(v.Int()), true
+ case reflect.Float32, reflect.Float64:
+ return v.Float(), true
+ case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
+ return float64(v.Uint()), true
+ case reflect.Bool:
+ if v.Bool() {
+ return 1, true
+ }
+ return 0, true
+ }
+ return 0, false
+}
+
+// numLess returns whether a < b.
+// a and b must necessarily have the same kind.
+func numLess(a, b reflect.Value) bool {
+ switch a.Kind() {
+ case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+ return a.Int() < b.Int()
+ case reflect.Float32, reflect.Float64:
+ return a.Float() < b.Float()
+ case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
+ return a.Uint() < b.Uint()
+ case reflect.Bool:
+ return !a.Bool() && b.Bool()
+ }
+ panic("not a number")
+}
diff --git a/vendor/gopkg.in/yaml.v2/writerc.go b/vendor/gopkg.in/yaml.v2/writerc.go
new file mode 100644
index 0000000000000000000000000000000000000000..a2dde608cb7a39850340eba008e796e10a730b26
--- /dev/null
+++ b/vendor/gopkg.in/yaml.v2/writerc.go
@@ -0,0 +1,26 @@
+package yaml
+
+// Set the writer error and return false.
+func yaml_emitter_set_writer_error(emitter *yaml_emitter_t, problem string) bool {
+ emitter.error = yaml_WRITER_ERROR
+ emitter.problem = problem
+ return false
+}
+
+// Flush the output buffer.
+func yaml_emitter_flush(emitter *yaml_emitter_t) bool {
+ if emitter.write_handler == nil {
+ panic("write handler not set")
+ }
+
+ // Check if the buffer is empty.
+ if emitter.buffer_pos == 0 {
+ return true
+ }
+
+ if err := emitter.write_handler(emitter, emitter.buffer[:emitter.buffer_pos]); err != nil {
+ return yaml_emitter_set_writer_error(emitter, "write error: "+err.Error())
+ }
+ emitter.buffer_pos = 0
+ return true
+}
diff --git a/vendor/gopkg.in/yaml.v2/yaml.go b/vendor/gopkg.in/yaml.v2/yaml.go
new file mode 100644
index 0000000000000000000000000000000000000000..de85aa4cdb71b6adf499209d5441c844d6181ff6
--- /dev/null
+++ b/vendor/gopkg.in/yaml.v2/yaml.go
@@ -0,0 +1,466 @@
+// Package yaml implements YAML support for the Go language.
+//
+// Source code and other details for the project are available at GitHub:
+//
+// https://github.com/go-yaml/yaml
+//
+package yaml
+
+import (
+ "errors"
+ "fmt"
+ "io"
+ "reflect"
+ "strings"
+ "sync"
+)
+
+// MapSlice encodes and decodes as a YAML map.
+// The order of keys is preserved when encoding and decoding.
+type MapSlice []MapItem
+
+// MapItem is an item in a MapSlice.
+type MapItem struct {
+ Key, Value interface{}
+}
+
+// The Unmarshaler interface may be implemented by types to customize their
+// behavior when being unmarshaled from a YAML document. The UnmarshalYAML
+// method receives a function that may be called to unmarshal the original
+// YAML value into a field or variable. It is safe to call the unmarshal
+// function parameter more than once if necessary.
+type Unmarshaler interface {
+ UnmarshalYAML(unmarshal func(interface{}) error) error
+}
+
+// The Marshaler interface may be implemented by types to customize their
+// behavior when being marshaled into a YAML document. The returned value
+// is marshaled in place of the original value implementing Marshaler.
+//
+// If an error is returned by MarshalYAML, the marshaling procedure stops
+// and returns with the provided error.
+type Marshaler interface {
+ MarshalYAML() (interface{}, error)
+}
+
+// Unmarshal decodes the first document found within the in byte slice
+// and assigns decoded values into the out value.
+//
+// Maps and pointers (to a struct, string, int, etc) are accepted as out
+// values. If an internal pointer within a struct is not initialized,
+// the yaml package will initialize it if necessary for unmarshalling
+// the provided data. The out parameter must not be nil.
+//
+// The type of the decoded values should be compatible with the respective
+// values in out. If one or more values cannot be decoded due to a type
+// mismatches, decoding continues partially until the end of the YAML
+// content, and a *yaml.TypeError is returned with details for all
+// missed values.
+//
+// Struct fields are only unmarshalled if they are exported (have an
+// upper case first letter), and are unmarshalled using the field name
+// lowercased as the default key. Custom keys may be defined via the
+// "yaml" name in the field tag: the content preceding the first comma
+// is used as the key, and the following comma-separated options are
+// used to tweak the marshalling process (see Marshal).
+// Conflicting names result in a runtime error.
+//
+// For example:
+//
+// type T struct {
+// F int `yaml:"a,omitempty"`
+// B int
+// }
+// var t T
+// yaml.Unmarshal([]byte("a: 1\nb: 2"), &t)
+//
+// See the documentation of Marshal for the format of tags and a list of
+// supported tag options.
+//
+func Unmarshal(in []byte, out interface{}) (err error) {
+ return unmarshal(in, out, false)
+}
+
+// UnmarshalStrict is like Unmarshal except that any fields that are found
+// in the data that do not have corresponding struct members, or mapping
+// keys that are duplicates, will result in
+// an error.
+func UnmarshalStrict(in []byte, out interface{}) (err error) {
+ return unmarshal(in, out, true)
+}
+
+// A Decorder reads and decodes YAML values from an input stream.
+type Decoder struct {
+ strict bool
+ parser *parser
+}
+
+// NewDecoder returns a new decoder that reads from r.
+//
+// The decoder introduces its own buffering and may read
+// data from r beyond the YAML values requested.
+func NewDecoder(r io.Reader) *Decoder {
+ return &Decoder{
+ parser: newParserFromReader(r),
+ }
+}
+
+// SetStrict sets whether strict decoding behaviour is enabled when
+// decoding items in the data (see UnmarshalStrict). By default, decoding is not strict.
+func (dec *Decoder) SetStrict(strict bool) {
+ dec.strict = strict
+}
+
+// Decode reads the next YAML-encoded value from its input
+// and stores it in the value pointed to by v.
+//
+// See the documentation for Unmarshal for details about the
+// conversion of YAML into a Go value.
+func (dec *Decoder) Decode(v interface{}) (err error) {
+ d := newDecoder(dec.strict)
+ defer handleErr(&err)
+ node := dec.parser.parse()
+ if node == nil {
+ return io.EOF
+ }
+ out := reflect.ValueOf(v)
+ if out.Kind() == reflect.Ptr && !out.IsNil() {
+ out = out.Elem()
+ }
+ d.unmarshal(node, out)
+ if len(d.terrors) > 0 {
+ return &TypeError{d.terrors}
+ }
+ return nil
+}
+
+func unmarshal(in []byte, out interface{}, strict bool) (err error) {
+ defer handleErr(&err)
+ d := newDecoder(strict)
+ p := newParser(in)
+ defer p.destroy()
+ node := p.parse()
+ if node != nil {
+ v := reflect.ValueOf(out)
+ if v.Kind() == reflect.Ptr && !v.IsNil() {
+ v = v.Elem()
+ }
+ d.unmarshal(node, v)
+ }
+ if len(d.terrors) > 0 {
+ return &TypeError{d.terrors}
+ }
+ return nil
+}
+
+// Marshal serializes the value provided into a YAML document. The structure
+// of the generated document will reflect the structure of the value itself.
+// Maps and pointers (to struct, string, int, etc) are accepted as the in value.
+//
+// Struct fields are only marshalled if they are exported (have an upper case
+// first letter), and are marshalled using the field name lowercased as the
+// default key. Custom keys may be defined via the "yaml" name in the field
+// tag: the content preceding the first comma is used as the key, and the
+// following comma-separated options are used to tweak the marshalling process.
+// Conflicting names result in a runtime error.
+//
+// The field tag format accepted is:
+//
+// `(...) yaml:"[][,[,]]" (...)`
+//
+// The following flags are currently supported:
+//
+// omitempty Only include the field if it's not set to the zero
+// value for the type or to empty slices or maps.
+// Zero valued structs will be omitted if all their public
+// fields are zero, unless they implement an IsZero
+// method (see the IsZeroer interface type), in which
+// case the field will be included if that method returns true.
+//
+// flow Marshal using a flow style (useful for structs,
+// sequences and maps).
+//
+// inline Inline the field, which must be a struct or a map,
+// causing all of its fields or keys to be processed as if
+// they were part of the outer struct. For maps, keys must
+// not conflict with the yaml keys of other struct fields.
+//
+// In addition, if the key is "-", the field is ignored.
+//
+// For example:
+//
+// type T struct {
+// F int `yaml:"a,omitempty"`
+// B int
+// }
+// yaml.Marshal(&T{B: 2}) // Returns "b: 2\n"
+// yaml.Marshal(&T{F: 1}} // Returns "a: 1\nb: 0\n"
+//
+func Marshal(in interface{}) (out []byte, err error) {
+ defer handleErr(&err)
+ e := newEncoder()
+ defer e.destroy()
+ e.marshalDoc("", reflect.ValueOf(in))
+ e.finish()
+ out = e.out
+ return
+}
+
+// An Encoder writes YAML values to an output stream.
+type Encoder struct {
+ encoder *encoder
+}
+
+// NewEncoder returns a new encoder that writes to w.
+// The Encoder should be closed after use to flush all data
+// to w.
+func NewEncoder(w io.Writer) *Encoder {
+ return &Encoder{
+ encoder: newEncoderWithWriter(w),
+ }
+}
+
+// Encode writes the YAML encoding of v to the stream.
+// If multiple items are encoded to the stream, the
+// second and subsequent document will be preceded
+// with a "---" document separator, but the first will not.
+//
+// See the documentation for Marshal for details about the conversion of Go
+// values to YAML.
+func (e *Encoder) Encode(v interface{}) (err error) {
+ defer handleErr(&err)
+ e.encoder.marshalDoc("", reflect.ValueOf(v))
+ return nil
+}
+
+// Close closes the encoder by writing any remaining data.
+// It does not write a stream terminating string "...".
+func (e *Encoder) Close() (err error) {
+ defer handleErr(&err)
+ e.encoder.finish()
+ return nil
+}
+
+func handleErr(err *error) {
+ if v := recover(); v != nil {
+ if e, ok := v.(yamlError); ok {
+ *err = e.err
+ } else {
+ panic(v)
+ }
+ }
+}
+
+type yamlError struct {
+ err error
+}
+
+func fail(err error) {
+ panic(yamlError{err})
+}
+
+func failf(format string, args ...interface{}) {
+ panic(yamlError{fmt.Errorf("yaml: "+format, args...)})
+}
+
+// A TypeError is returned by Unmarshal when one or more fields in
+// the YAML document cannot be properly decoded into the requested
+// types. When this error is returned, the value is still
+// unmarshaled partially.
+type TypeError struct {
+ Errors []string
+}
+
+func (e *TypeError) Error() string {
+ return fmt.Sprintf("yaml: unmarshal errors:\n %s", strings.Join(e.Errors, "\n "))
+}
+
+// --------------------------------------------------------------------------
+// Maintain a mapping of keys to structure field indexes
+
+// The code in this section was copied from mgo/bson.
+
+// structInfo holds details for the serialization of fields of
+// a given struct.
+type structInfo struct {
+ FieldsMap map[string]fieldInfo
+ FieldsList []fieldInfo
+
+ // InlineMap is the number of the field in the struct that
+ // contains an ,inline map, or -1 if there's none.
+ InlineMap int
+}
+
+type fieldInfo struct {
+ Key string
+ Num int
+ OmitEmpty bool
+ Flow bool
+ // Id holds the unique field identifier, so we can cheaply
+ // check for field duplicates without maintaining an extra map.
+ Id int
+
+ // Inline holds the field index if the field is part of an inlined struct.
+ Inline []int
+}
+
+var structMap = make(map[reflect.Type]*structInfo)
+var fieldMapMutex sync.RWMutex
+
+func getStructInfo(st reflect.Type) (*structInfo, error) {
+ fieldMapMutex.RLock()
+ sinfo, found := structMap[st]
+ fieldMapMutex.RUnlock()
+ if found {
+ return sinfo, nil
+ }
+
+ n := st.NumField()
+ fieldsMap := make(map[string]fieldInfo)
+ fieldsList := make([]fieldInfo, 0, n)
+ inlineMap := -1
+ for i := 0; i != n; i++ {
+ field := st.Field(i)
+ if field.PkgPath != "" && !field.Anonymous {
+ continue // Private field
+ }
+
+ info := fieldInfo{Num: i}
+
+ tag := field.Tag.Get("yaml")
+ if tag == "" && strings.Index(string(field.Tag), ":") < 0 {
+ tag = string(field.Tag)
+ }
+ if tag == "-" {
+ continue
+ }
+
+ inline := false
+ fields := strings.Split(tag, ",")
+ if len(fields) > 1 {
+ for _, flag := range fields[1:] {
+ switch flag {
+ case "omitempty":
+ info.OmitEmpty = true
+ case "flow":
+ info.Flow = true
+ case "inline":
+ inline = true
+ default:
+ return nil, errors.New(fmt.Sprintf("Unsupported flag %q in tag %q of type %s", flag, tag, st))
+ }
+ }
+ tag = fields[0]
+ }
+
+ if inline {
+ switch field.Type.Kind() {
+ case reflect.Map:
+ if inlineMap >= 0 {
+ return nil, errors.New("Multiple ,inline maps in struct " + st.String())
+ }
+ if field.Type.Key() != reflect.TypeOf("") {
+ return nil, errors.New("Option ,inline needs a map with string keys in struct " + st.String())
+ }
+ inlineMap = info.Num
+ case reflect.Struct:
+ sinfo, err := getStructInfo(field.Type)
+ if err != nil {
+ return nil, err
+ }
+ for _, finfo := range sinfo.FieldsList {
+ if _, found := fieldsMap[finfo.Key]; found {
+ msg := "Duplicated key '" + finfo.Key + "' in struct " + st.String()
+ return nil, errors.New(msg)
+ }
+ if finfo.Inline == nil {
+ finfo.Inline = []int{i, finfo.Num}
+ } else {
+ finfo.Inline = append([]int{i}, finfo.Inline...)
+ }
+ finfo.Id = len(fieldsList)
+ fieldsMap[finfo.Key] = finfo
+ fieldsList = append(fieldsList, finfo)
+ }
+ default:
+ //return nil, errors.New("Option ,inline needs a struct value or map field")
+ return nil, errors.New("Option ,inline needs a struct value field")
+ }
+ continue
+ }
+
+ if tag != "" {
+ info.Key = tag
+ } else {
+ info.Key = strings.ToLower(field.Name)
+ }
+
+ if _, found = fieldsMap[info.Key]; found {
+ msg := "Duplicated key '" + info.Key + "' in struct " + st.String()
+ return nil, errors.New(msg)
+ }
+
+ info.Id = len(fieldsList)
+ fieldsList = append(fieldsList, info)
+ fieldsMap[info.Key] = info
+ }
+
+ sinfo = &structInfo{
+ FieldsMap: fieldsMap,
+ FieldsList: fieldsList,
+ InlineMap: inlineMap,
+ }
+
+ fieldMapMutex.Lock()
+ structMap[st] = sinfo
+ fieldMapMutex.Unlock()
+ return sinfo, nil
+}
+
+// IsZeroer is used to check whether an object is zero to
+// determine whether it should be omitted when marshaling
+// with the omitempty flag. One notable implementation
+// is time.Time.
+type IsZeroer interface {
+ IsZero() bool
+}
+
+func isZero(v reflect.Value) bool {
+ kind := v.Kind()
+ if z, ok := v.Interface().(IsZeroer); ok {
+ if (kind == reflect.Ptr || kind == reflect.Interface) && v.IsNil() {
+ return true
+ }
+ return z.IsZero()
+ }
+ switch kind {
+ case reflect.String:
+ return len(v.String()) == 0
+ case reflect.Interface, reflect.Ptr:
+ return v.IsNil()
+ case reflect.Slice:
+ return v.Len() == 0
+ case reflect.Map:
+ return v.Len() == 0
+ case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+ return v.Int() == 0
+ case reflect.Float32, reflect.Float64:
+ return v.Float() == 0
+ case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
+ return v.Uint() == 0
+ case reflect.Bool:
+ return !v.Bool()
+ case reflect.Struct:
+ vt := v.Type()
+ for i := v.NumField() - 1; i >= 0; i-- {
+ if vt.Field(i).PkgPath != "" {
+ continue // Private field
+ }
+ if !isZero(v.Field(i)) {
+ return false
+ }
+ }
+ return true
+ }
+ return false
+}
diff --git a/vendor/gopkg.in/yaml.v2/yamlh.go b/vendor/gopkg.in/yaml.v2/yamlh.go
new file mode 100644
index 0000000000000000000000000000000000000000..e25cee563be827c201da827c9c3aacc4bfef7830
--- /dev/null
+++ b/vendor/gopkg.in/yaml.v2/yamlh.go
@@ -0,0 +1,738 @@
+package yaml
+
+import (
+ "fmt"
+ "io"
+)
+
+// The version directive data.
+type yaml_version_directive_t struct {
+ major int8 // The major version number.
+ minor int8 // The minor version number.
+}
+
+// The tag directive data.
+type yaml_tag_directive_t struct {
+ handle []byte // The tag handle.
+ prefix []byte // The tag prefix.
+}
+
+type yaml_encoding_t int
+
+// The stream encoding.
+const (
+ // Let the parser choose the encoding.
+ yaml_ANY_ENCODING yaml_encoding_t = iota
+
+ yaml_UTF8_ENCODING // The default UTF-8 encoding.
+ yaml_UTF16LE_ENCODING // The UTF-16-LE encoding with BOM.
+ yaml_UTF16BE_ENCODING // The UTF-16-BE encoding with BOM.
+)
+
+type yaml_break_t int
+
+// Line break types.
+const (
+ // Let the parser choose the break type.
+ yaml_ANY_BREAK yaml_break_t = iota
+
+ yaml_CR_BREAK // Use CR for line breaks (Mac style).
+ yaml_LN_BREAK // Use LN for line breaks (Unix style).
+ yaml_CRLN_BREAK // Use CR LN for line breaks (DOS style).
+)
+
+type yaml_error_type_t int
+
+// Many bad things could happen with the parser and emitter.
+const (
+ // No error is produced.
+ yaml_NO_ERROR yaml_error_type_t = iota
+
+ yaml_MEMORY_ERROR // Cannot allocate or reallocate a block of memory.
+ yaml_READER_ERROR // Cannot read or decode the input stream.
+ yaml_SCANNER_ERROR // Cannot scan the input stream.
+ yaml_PARSER_ERROR // Cannot parse the input stream.
+ yaml_COMPOSER_ERROR // Cannot compose a YAML document.
+ yaml_WRITER_ERROR // Cannot write to the output stream.
+ yaml_EMITTER_ERROR // Cannot emit a YAML stream.
+)
+
+// The pointer position.
+type yaml_mark_t struct {
+ index int // The position index.
+ line int // The position line.
+ column int // The position column.
+}
+
+// Node Styles
+
+type yaml_style_t int8
+
+type yaml_scalar_style_t yaml_style_t
+
+// Scalar styles.
+const (
+ // Let the emitter choose the style.
+ yaml_ANY_SCALAR_STYLE yaml_scalar_style_t = iota
+
+ yaml_PLAIN_SCALAR_STYLE // The plain scalar style.
+ yaml_SINGLE_QUOTED_SCALAR_STYLE // The single-quoted scalar style.
+ yaml_DOUBLE_QUOTED_SCALAR_STYLE // The double-quoted scalar style.
+ yaml_LITERAL_SCALAR_STYLE // The literal scalar style.
+ yaml_FOLDED_SCALAR_STYLE // The folded scalar style.
+)
+
+type yaml_sequence_style_t yaml_style_t
+
+// Sequence styles.
+const (
+ // Let the emitter choose the style.
+ yaml_ANY_SEQUENCE_STYLE yaml_sequence_style_t = iota
+
+ yaml_BLOCK_SEQUENCE_STYLE // The block sequence style.
+ yaml_FLOW_SEQUENCE_STYLE // The flow sequence style.
+)
+
+type yaml_mapping_style_t yaml_style_t
+
+// Mapping styles.
+const (
+ // Let the emitter choose the style.
+ yaml_ANY_MAPPING_STYLE yaml_mapping_style_t = iota
+
+ yaml_BLOCK_MAPPING_STYLE // The block mapping style.
+ yaml_FLOW_MAPPING_STYLE // The flow mapping style.
+)
+
+// Tokens
+
+type yaml_token_type_t int
+
+// Token types.
+const (
+ // An empty token.
+ yaml_NO_TOKEN yaml_token_type_t = iota
+
+ yaml_STREAM_START_TOKEN // A STREAM-START token.
+ yaml_STREAM_END_TOKEN // A STREAM-END token.
+
+ yaml_VERSION_DIRECTIVE_TOKEN // A VERSION-DIRECTIVE token.
+ yaml_TAG_DIRECTIVE_TOKEN // A TAG-DIRECTIVE token.
+ yaml_DOCUMENT_START_TOKEN // A DOCUMENT-START token.
+ yaml_DOCUMENT_END_TOKEN // A DOCUMENT-END token.
+
+ yaml_BLOCK_SEQUENCE_START_TOKEN // A BLOCK-SEQUENCE-START token.
+ yaml_BLOCK_MAPPING_START_TOKEN // A BLOCK-SEQUENCE-END token.
+ yaml_BLOCK_END_TOKEN // A BLOCK-END token.
+
+ yaml_FLOW_SEQUENCE_START_TOKEN // A FLOW-SEQUENCE-START token.
+ yaml_FLOW_SEQUENCE_END_TOKEN // A FLOW-SEQUENCE-END token.
+ yaml_FLOW_MAPPING_START_TOKEN // A FLOW-MAPPING-START token.
+ yaml_FLOW_MAPPING_END_TOKEN // A FLOW-MAPPING-END token.
+
+ yaml_BLOCK_ENTRY_TOKEN // A BLOCK-ENTRY token.
+ yaml_FLOW_ENTRY_TOKEN // A FLOW-ENTRY token.
+ yaml_KEY_TOKEN // A KEY token.
+ yaml_VALUE_TOKEN // A VALUE token.
+
+ yaml_ALIAS_TOKEN // An ALIAS token.
+ yaml_ANCHOR_TOKEN // An ANCHOR token.
+ yaml_TAG_TOKEN // A TAG token.
+ yaml_SCALAR_TOKEN // A SCALAR token.
+)
+
+func (tt yaml_token_type_t) String() string {
+ switch tt {
+ case yaml_NO_TOKEN:
+ return "yaml_NO_TOKEN"
+ case yaml_STREAM_START_TOKEN:
+ return "yaml_STREAM_START_TOKEN"
+ case yaml_STREAM_END_TOKEN:
+ return "yaml_STREAM_END_TOKEN"
+ case yaml_VERSION_DIRECTIVE_TOKEN:
+ return "yaml_VERSION_DIRECTIVE_TOKEN"
+ case yaml_TAG_DIRECTIVE_TOKEN:
+ return "yaml_TAG_DIRECTIVE_TOKEN"
+ case yaml_DOCUMENT_START_TOKEN:
+ return "yaml_DOCUMENT_START_TOKEN"
+ case yaml_DOCUMENT_END_TOKEN:
+ return "yaml_DOCUMENT_END_TOKEN"
+ case yaml_BLOCK_SEQUENCE_START_TOKEN:
+ return "yaml_BLOCK_SEQUENCE_START_TOKEN"
+ case yaml_BLOCK_MAPPING_START_TOKEN:
+ return "yaml_BLOCK_MAPPING_START_TOKEN"
+ case yaml_BLOCK_END_TOKEN:
+ return "yaml_BLOCK_END_TOKEN"
+ case yaml_FLOW_SEQUENCE_START_TOKEN:
+ return "yaml_FLOW_SEQUENCE_START_TOKEN"
+ case yaml_FLOW_SEQUENCE_END_TOKEN:
+ return "yaml_FLOW_SEQUENCE_END_TOKEN"
+ case yaml_FLOW_MAPPING_START_TOKEN:
+ return "yaml_FLOW_MAPPING_START_TOKEN"
+ case yaml_FLOW_MAPPING_END_TOKEN:
+ return "yaml_FLOW_MAPPING_END_TOKEN"
+ case yaml_BLOCK_ENTRY_TOKEN:
+ return "yaml_BLOCK_ENTRY_TOKEN"
+ case yaml_FLOW_ENTRY_TOKEN:
+ return "yaml_FLOW_ENTRY_TOKEN"
+ case yaml_KEY_TOKEN:
+ return "yaml_KEY_TOKEN"
+ case yaml_VALUE_TOKEN:
+ return "yaml_VALUE_TOKEN"
+ case yaml_ALIAS_TOKEN:
+ return "yaml_ALIAS_TOKEN"
+ case yaml_ANCHOR_TOKEN:
+ return "yaml_ANCHOR_TOKEN"
+ case yaml_TAG_TOKEN:
+ return "yaml_TAG_TOKEN"
+ case yaml_SCALAR_TOKEN:
+ return "yaml_SCALAR_TOKEN"
+ }
+ return ""
+}
+
+// The token structure.
+type yaml_token_t struct {
+ // The token type.
+ typ yaml_token_type_t
+
+ // The start/end of the token.
+ start_mark, end_mark yaml_mark_t
+
+ // The stream encoding (for yaml_STREAM_START_TOKEN).
+ encoding yaml_encoding_t
+
+ // The alias/anchor/scalar value or tag/tag directive handle
+ // (for yaml_ALIAS_TOKEN, yaml_ANCHOR_TOKEN, yaml_SCALAR_TOKEN, yaml_TAG_TOKEN, yaml_TAG_DIRECTIVE_TOKEN).
+ value []byte
+
+ // The tag suffix (for yaml_TAG_TOKEN).
+ suffix []byte
+
+ // The tag directive prefix (for yaml_TAG_DIRECTIVE_TOKEN).
+ prefix []byte
+
+ // The scalar style (for yaml_SCALAR_TOKEN).
+ style yaml_scalar_style_t
+
+ // The version directive major/minor (for yaml_VERSION_DIRECTIVE_TOKEN).
+ major, minor int8
+}
+
+// Events
+
+type yaml_event_type_t int8
+
+// Event types.
+const (
+ // An empty event.
+ yaml_NO_EVENT yaml_event_type_t = iota
+
+ yaml_STREAM_START_EVENT // A STREAM-START event.
+ yaml_STREAM_END_EVENT // A STREAM-END event.
+ yaml_DOCUMENT_START_EVENT // A DOCUMENT-START event.
+ yaml_DOCUMENT_END_EVENT // A DOCUMENT-END event.
+ yaml_ALIAS_EVENT // An ALIAS event.
+ yaml_SCALAR_EVENT // A SCALAR event.
+ yaml_SEQUENCE_START_EVENT // A SEQUENCE-START event.
+ yaml_SEQUENCE_END_EVENT // A SEQUENCE-END event.
+ yaml_MAPPING_START_EVENT // A MAPPING-START event.
+ yaml_MAPPING_END_EVENT // A MAPPING-END event.
+)
+
+var eventStrings = []string{
+ yaml_NO_EVENT: "none",
+ yaml_STREAM_START_EVENT: "stream start",
+ yaml_STREAM_END_EVENT: "stream end",
+ yaml_DOCUMENT_START_EVENT: "document start",
+ yaml_DOCUMENT_END_EVENT: "document end",
+ yaml_ALIAS_EVENT: "alias",
+ yaml_SCALAR_EVENT: "scalar",
+ yaml_SEQUENCE_START_EVENT: "sequence start",
+ yaml_SEQUENCE_END_EVENT: "sequence end",
+ yaml_MAPPING_START_EVENT: "mapping start",
+ yaml_MAPPING_END_EVENT: "mapping end",
+}
+
+func (e yaml_event_type_t) String() string {
+ if e < 0 || int(e) >= len(eventStrings) {
+ return fmt.Sprintf("unknown event %d", e)
+ }
+ return eventStrings[e]
+}
+
+// The event structure.
+type yaml_event_t struct {
+
+ // The event type.
+ typ yaml_event_type_t
+
+ // The start and end of the event.
+ start_mark, end_mark yaml_mark_t
+
+ // The document encoding (for yaml_STREAM_START_EVENT).
+ encoding yaml_encoding_t
+
+ // The version directive (for yaml_DOCUMENT_START_EVENT).
+ version_directive *yaml_version_directive_t
+
+ // The list of tag directives (for yaml_DOCUMENT_START_EVENT).
+ tag_directives []yaml_tag_directive_t
+
+ // The anchor (for yaml_SCALAR_EVENT, yaml_SEQUENCE_START_EVENT, yaml_MAPPING_START_EVENT, yaml_ALIAS_EVENT).
+ anchor []byte
+
+ // The tag (for yaml_SCALAR_EVENT, yaml_SEQUENCE_START_EVENT, yaml_MAPPING_START_EVENT).
+ tag []byte
+
+ // The scalar value (for yaml_SCALAR_EVENT).
+ value []byte
+
+ // Is the document start/end indicator implicit, or the tag optional?
+ // (for yaml_DOCUMENT_START_EVENT, yaml_DOCUMENT_END_EVENT, yaml_SEQUENCE_START_EVENT, yaml_MAPPING_START_EVENT, yaml_SCALAR_EVENT).
+ implicit bool
+
+ // Is the tag optional for any non-plain style? (for yaml_SCALAR_EVENT).
+ quoted_implicit bool
+
+ // The style (for yaml_SCALAR_EVENT, yaml_SEQUENCE_START_EVENT, yaml_MAPPING_START_EVENT).
+ style yaml_style_t
+}
+
+func (e *yaml_event_t) scalar_style() yaml_scalar_style_t { return yaml_scalar_style_t(e.style) }
+func (e *yaml_event_t) sequence_style() yaml_sequence_style_t { return yaml_sequence_style_t(e.style) }
+func (e *yaml_event_t) mapping_style() yaml_mapping_style_t { return yaml_mapping_style_t(e.style) }
+
+// Nodes
+
+const (
+ yaml_NULL_TAG = "tag:yaml.org,2002:null" // The tag !!null with the only possible value: null.
+ yaml_BOOL_TAG = "tag:yaml.org,2002:bool" // The tag !!bool with the values: true and false.
+ yaml_STR_TAG = "tag:yaml.org,2002:str" // The tag !!str for string values.
+ yaml_INT_TAG = "tag:yaml.org,2002:int" // The tag !!int for integer values.
+ yaml_FLOAT_TAG = "tag:yaml.org,2002:float" // The tag !!float for float values.
+ yaml_TIMESTAMP_TAG = "tag:yaml.org,2002:timestamp" // The tag !!timestamp for date and time values.
+
+ yaml_SEQ_TAG = "tag:yaml.org,2002:seq" // The tag !!seq is used to denote sequences.
+ yaml_MAP_TAG = "tag:yaml.org,2002:map" // The tag !!map is used to denote mapping.
+
+ // Not in original libyaml.
+ yaml_BINARY_TAG = "tag:yaml.org,2002:binary"
+ yaml_MERGE_TAG = "tag:yaml.org,2002:merge"
+
+ yaml_DEFAULT_SCALAR_TAG = yaml_STR_TAG // The default scalar tag is !!str.
+ yaml_DEFAULT_SEQUENCE_TAG = yaml_SEQ_TAG // The default sequence tag is !!seq.
+ yaml_DEFAULT_MAPPING_TAG = yaml_MAP_TAG // The default mapping tag is !!map.
+)
+
+type yaml_node_type_t int
+
+// Node types.
+const (
+ // An empty node.
+ yaml_NO_NODE yaml_node_type_t = iota
+
+ yaml_SCALAR_NODE // A scalar node.
+ yaml_SEQUENCE_NODE // A sequence node.
+ yaml_MAPPING_NODE // A mapping node.
+)
+
+// An element of a sequence node.
+type yaml_node_item_t int
+
+// An element of a mapping node.
+type yaml_node_pair_t struct {
+ key int // The key of the element.
+ value int // The value of the element.
+}
+
+// The node structure.
+type yaml_node_t struct {
+ typ yaml_node_type_t // The node type.
+ tag []byte // The node tag.
+
+ // The node data.
+
+ // The scalar parameters (for yaml_SCALAR_NODE).
+ scalar struct {
+ value []byte // The scalar value.
+ length int // The length of the scalar value.
+ style yaml_scalar_style_t // The scalar style.
+ }
+
+ // The sequence parameters (for YAML_SEQUENCE_NODE).
+ sequence struct {
+ items_data []yaml_node_item_t // The stack of sequence items.
+ style yaml_sequence_style_t // The sequence style.
+ }
+
+ // The mapping parameters (for yaml_MAPPING_NODE).
+ mapping struct {
+ pairs_data []yaml_node_pair_t // The stack of mapping pairs (key, value).
+ pairs_start *yaml_node_pair_t // The beginning of the stack.
+ pairs_end *yaml_node_pair_t // The end of the stack.
+ pairs_top *yaml_node_pair_t // The top of the stack.
+ style yaml_mapping_style_t // The mapping style.
+ }
+
+ start_mark yaml_mark_t // The beginning of the node.
+ end_mark yaml_mark_t // The end of the node.
+
+}
+
+// The document structure.
+type yaml_document_t struct {
+
+ // The document nodes.
+ nodes []yaml_node_t
+
+ // The version directive.
+ version_directive *yaml_version_directive_t
+
+ // The list of tag directives.
+ tag_directives_data []yaml_tag_directive_t
+ tag_directives_start int // The beginning of the tag directives list.
+ tag_directives_end int // The end of the tag directives list.
+
+ start_implicit int // Is the document start indicator implicit?
+ end_implicit int // Is the document end indicator implicit?
+
+ // The start/end of the document.
+ start_mark, end_mark yaml_mark_t
+}
+
+// The prototype of a read handler.
+//
+// The read handler is called when the parser needs to read more bytes from the
+// source. The handler should write not more than size bytes to the buffer.
+// The number of written bytes should be set to the size_read variable.
+//
+// [in,out] data A pointer to an application data specified by
+// yaml_parser_set_input().
+// [out] buffer The buffer to write the data from the source.
+// [in] size The size of the buffer.
+// [out] size_read The actual number of bytes read from the source.
+//
+// On success, the handler should return 1. If the handler failed,
+// the returned value should be 0. On EOF, the handler should set the
+// size_read to 0 and return 1.
+type yaml_read_handler_t func(parser *yaml_parser_t, buffer []byte) (n int, err error)
+
+// This structure holds information about a potential simple key.
+type yaml_simple_key_t struct {
+ possible bool // Is a simple key possible?
+ required bool // Is a simple key required?
+ token_number int // The number of the token.
+ mark yaml_mark_t // The position mark.
+}
+
+// The states of the parser.
+type yaml_parser_state_t int
+
+const (
+ yaml_PARSE_STREAM_START_STATE yaml_parser_state_t = iota
+
+ yaml_PARSE_IMPLICIT_DOCUMENT_START_STATE // Expect the beginning of an implicit document.
+ yaml_PARSE_DOCUMENT_START_STATE // Expect DOCUMENT-START.
+ yaml_PARSE_DOCUMENT_CONTENT_STATE // Expect the content of a document.
+ yaml_PARSE_DOCUMENT_END_STATE // Expect DOCUMENT-END.
+ yaml_PARSE_BLOCK_NODE_STATE // Expect a block node.
+ yaml_PARSE_BLOCK_NODE_OR_INDENTLESS_SEQUENCE_STATE // Expect a block node or indentless sequence.
+ yaml_PARSE_FLOW_NODE_STATE // Expect a flow node.
+ yaml_PARSE_BLOCK_SEQUENCE_FIRST_ENTRY_STATE // Expect the first entry of a block sequence.
+ yaml_PARSE_BLOCK_SEQUENCE_ENTRY_STATE // Expect an entry of a block sequence.
+ yaml_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE // Expect an entry of an indentless sequence.
+ yaml_PARSE_BLOCK_MAPPING_FIRST_KEY_STATE // Expect the first key of a block mapping.
+ yaml_PARSE_BLOCK_MAPPING_KEY_STATE // Expect a block mapping key.
+ yaml_PARSE_BLOCK_MAPPING_VALUE_STATE // Expect a block mapping value.
+ yaml_PARSE_FLOW_SEQUENCE_FIRST_ENTRY_STATE // Expect the first entry of a flow sequence.
+ yaml_PARSE_FLOW_SEQUENCE_ENTRY_STATE // Expect an entry of a flow sequence.
+ yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_KEY_STATE // Expect a key of an ordered mapping.
+ yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_VALUE_STATE // Expect a value of an ordered mapping.
+ yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_END_STATE // Expect the and of an ordered mapping entry.
+ yaml_PARSE_FLOW_MAPPING_FIRST_KEY_STATE // Expect the first key of a flow mapping.
+ yaml_PARSE_FLOW_MAPPING_KEY_STATE // Expect a key of a flow mapping.
+ yaml_PARSE_FLOW_MAPPING_VALUE_STATE // Expect a value of a flow mapping.
+ yaml_PARSE_FLOW_MAPPING_EMPTY_VALUE_STATE // Expect an empty value of a flow mapping.
+ yaml_PARSE_END_STATE // Expect nothing.
+)
+
+func (ps yaml_parser_state_t) String() string {
+ switch ps {
+ case yaml_PARSE_STREAM_START_STATE:
+ return "yaml_PARSE_STREAM_START_STATE"
+ case yaml_PARSE_IMPLICIT_DOCUMENT_START_STATE:
+ return "yaml_PARSE_IMPLICIT_DOCUMENT_START_STATE"
+ case yaml_PARSE_DOCUMENT_START_STATE:
+ return "yaml_PARSE_DOCUMENT_START_STATE"
+ case yaml_PARSE_DOCUMENT_CONTENT_STATE:
+ return "yaml_PARSE_DOCUMENT_CONTENT_STATE"
+ case yaml_PARSE_DOCUMENT_END_STATE:
+ return "yaml_PARSE_DOCUMENT_END_STATE"
+ case yaml_PARSE_BLOCK_NODE_STATE:
+ return "yaml_PARSE_BLOCK_NODE_STATE"
+ case yaml_PARSE_BLOCK_NODE_OR_INDENTLESS_SEQUENCE_STATE:
+ return "yaml_PARSE_BLOCK_NODE_OR_INDENTLESS_SEQUENCE_STATE"
+ case yaml_PARSE_FLOW_NODE_STATE:
+ return "yaml_PARSE_FLOW_NODE_STATE"
+ case yaml_PARSE_BLOCK_SEQUENCE_FIRST_ENTRY_STATE:
+ return "yaml_PARSE_BLOCK_SEQUENCE_FIRST_ENTRY_STATE"
+ case yaml_PARSE_BLOCK_SEQUENCE_ENTRY_STATE:
+ return "yaml_PARSE_BLOCK_SEQUENCE_ENTRY_STATE"
+ case yaml_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE:
+ return "yaml_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE"
+ case yaml_PARSE_BLOCK_MAPPING_FIRST_KEY_STATE:
+ return "yaml_PARSE_BLOCK_MAPPING_FIRST_KEY_STATE"
+ case yaml_PARSE_BLOCK_MAPPING_KEY_STATE:
+ return "yaml_PARSE_BLOCK_MAPPING_KEY_STATE"
+ case yaml_PARSE_BLOCK_MAPPING_VALUE_STATE:
+ return "yaml_PARSE_BLOCK_MAPPING_VALUE_STATE"
+ case yaml_PARSE_FLOW_SEQUENCE_FIRST_ENTRY_STATE:
+ return "yaml_PARSE_FLOW_SEQUENCE_FIRST_ENTRY_STATE"
+ case yaml_PARSE_FLOW_SEQUENCE_ENTRY_STATE:
+ return "yaml_PARSE_FLOW_SEQUENCE_ENTRY_STATE"
+ case yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_KEY_STATE:
+ return "yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_KEY_STATE"
+ case yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_VALUE_STATE:
+ return "yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_VALUE_STATE"
+ case yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_END_STATE:
+ return "yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_END_STATE"
+ case yaml_PARSE_FLOW_MAPPING_FIRST_KEY_STATE:
+ return "yaml_PARSE_FLOW_MAPPING_FIRST_KEY_STATE"
+ case yaml_PARSE_FLOW_MAPPING_KEY_STATE:
+ return "yaml_PARSE_FLOW_MAPPING_KEY_STATE"
+ case yaml_PARSE_FLOW_MAPPING_VALUE_STATE:
+ return "yaml_PARSE_FLOW_MAPPING_VALUE_STATE"
+ case yaml_PARSE_FLOW_MAPPING_EMPTY_VALUE_STATE:
+ return "yaml_PARSE_FLOW_MAPPING_EMPTY_VALUE_STATE"
+ case yaml_PARSE_END_STATE:
+ return "yaml_PARSE_END_STATE"
+ }
+ return ""
+}
+
+// This structure holds aliases data.
+type yaml_alias_data_t struct {
+ anchor []byte // The anchor.
+ index int // The node id.
+ mark yaml_mark_t // The anchor mark.
+}
+
+// The parser structure.
+//
+// All members are internal. Manage the structure using the
+// yaml_parser_ family of functions.
+type yaml_parser_t struct {
+
+ // Error handling
+
+ error yaml_error_type_t // Error type.
+
+ problem string // Error description.
+
+ // The byte about which the problem occurred.
+ problem_offset int
+ problem_value int
+ problem_mark yaml_mark_t
+
+ // The error context.
+ context string
+ context_mark yaml_mark_t
+
+ // Reader stuff
+
+ read_handler yaml_read_handler_t // Read handler.
+
+ input_reader io.Reader // File input data.
+ input []byte // String input data.
+ input_pos int
+
+ eof bool // EOF flag
+
+ buffer []byte // The working buffer.
+ buffer_pos int // The current position of the buffer.
+
+ unread int // The number of unread characters in the buffer.
+
+ raw_buffer []byte // The raw buffer.
+ raw_buffer_pos int // The current position of the buffer.
+
+ encoding yaml_encoding_t // The input encoding.
+
+ offset int // The offset of the current position (in bytes).
+ mark yaml_mark_t // The mark of the current position.
+
+ // Scanner stuff
+
+ stream_start_produced bool // Have we started to scan the input stream?
+ stream_end_produced bool // Have we reached the end of the input stream?
+
+ flow_level int // The number of unclosed '[' and '{' indicators.
+
+ tokens []yaml_token_t // The tokens queue.
+ tokens_head int // The head of the tokens queue.
+ tokens_parsed int // The number of tokens fetched from the queue.
+ token_available bool // Does the tokens queue contain a token ready for dequeueing.
+
+ indent int // The current indentation level.
+ indents []int // The indentation levels stack.
+
+ simple_key_allowed bool // May a simple key occur at the current position?
+ simple_keys []yaml_simple_key_t // The stack of simple keys.
+
+ // Parser stuff
+
+ state yaml_parser_state_t // The current parser state.
+ states []yaml_parser_state_t // The parser states stack.
+ marks []yaml_mark_t // The stack of marks.
+ tag_directives []yaml_tag_directive_t // The list of TAG directives.
+
+ // Dumper stuff
+
+ aliases []yaml_alias_data_t // The alias data.
+
+ document *yaml_document_t // The currently parsed document.
+}
+
+// Emitter Definitions
+
+// The prototype of a write handler.
+//
+// The write handler is called when the emitter needs to flush the accumulated
+// characters to the output. The handler should write @a size bytes of the
+// @a buffer to the output.
+//
+// @param[in,out] data A pointer to an application data specified by
+// yaml_emitter_set_output().
+// @param[in] buffer The buffer with bytes to be written.
+// @param[in] size The size of the buffer.
+//
+// @returns On success, the handler should return @c 1. If the handler failed,
+// the returned value should be @c 0.
+//
+type yaml_write_handler_t func(emitter *yaml_emitter_t, buffer []byte) error
+
+type yaml_emitter_state_t int
+
+// The emitter states.
+const (
+ // Expect STREAM-START.
+ yaml_EMIT_STREAM_START_STATE yaml_emitter_state_t = iota
+
+ yaml_EMIT_FIRST_DOCUMENT_START_STATE // Expect the first DOCUMENT-START or STREAM-END.
+ yaml_EMIT_DOCUMENT_START_STATE // Expect DOCUMENT-START or STREAM-END.
+ yaml_EMIT_DOCUMENT_CONTENT_STATE // Expect the content of a document.
+ yaml_EMIT_DOCUMENT_END_STATE // Expect DOCUMENT-END.
+ yaml_EMIT_FLOW_SEQUENCE_FIRST_ITEM_STATE // Expect the first item of a flow sequence.
+ yaml_EMIT_FLOW_SEQUENCE_ITEM_STATE // Expect an item of a flow sequence.
+ yaml_EMIT_FLOW_MAPPING_FIRST_KEY_STATE // Expect the first key of a flow mapping.
+ yaml_EMIT_FLOW_MAPPING_KEY_STATE // Expect a key of a flow mapping.
+ yaml_EMIT_FLOW_MAPPING_SIMPLE_VALUE_STATE // Expect a value for a simple key of a flow mapping.
+ yaml_EMIT_FLOW_MAPPING_VALUE_STATE // Expect a value of a flow mapping.
+ yaml_EMIT_BLOCK_SEQUENCE_FIRST_ITEM_STATE // Expect the first item of a block sequence.
+ yaml_EMIT_BLOCK_SEQUENCE_ITEM_STATE // Expect an item of a block sequence.
+ yaml_EMIT_BLOCK_MAPPING_FIRST_KEY_STATE // Expect the first key of a block mapping.
+ yaml_EMIT_BLOCK_MAPPING_KEY_STATE // Expect the key of a block mapping.
+ yaml_EMIT_BLOCK_MAPPING_SIMPLE_VALUE_STATE // Expect a value for a simple key of a block mapping.
+ yaml_EMIT_BLOCK_MAPPING_VALUE_STATE // Expect a value of a block mapping.
+ yaml_EMIT_END_STATE // Expect nothing.
+)
+
+// The emitter structure.
+//
+// All members are internal. Manage the structure using the @c yaml_emitter_
+// family of functions.
+type yaml_emitter_t struct {
+
+ // Error handling
+
+ error yaml_error_type_t // Error type.
+ problem string // Error description.
+
+ // Writer stuff
+
+ write_handler yaml_write_handler_t // Write handler.
+
+ output_buffer *[]byte // String output data.
+ output_writer io.Writer // File output data.
+
+ buffer []byte // The working buffer.
+ buffer_pos int // The current position of the buffer.
+
+ raw_buffer []byte // The raw buffer.
+ raw_buffer_pos int // The current position of the buffer.
+
+ encoding yaml_encoding_t // The stream encoding.
+
+ // Emitter stuff
+
+ canonical bool // If the output is in the canonical style?
+ best_indent int // The number of indentation spaces.
+ best_width int // The preferred width of the output lines.
+ unicode bool // Allow unescaped non-ASCII characters?
+ line_break yaml_break_t // The preferred line break.
+
+ state yaml_emitter_state_t // The current emitter state.
+ states []yaml_emitter_state_t // The stack of states.
+
+ events []yaml_event_t // The event queue.
+ events_head int // The head of the event queue.
+
+ indents []int // The stack of indentation levels.
+
+ tag_directives []yaml_tag_directive_t // The list of tag directives.
+
+ indent int // The current indentation level.
+
+ flow_level int // The current flow level.
+
+ root_context bool // Is it the document root context?
+ sequence_context bool // Is it a sequence context?
+ mapping_context bool // Is it a mapping context?
+ simple_key_context bool // Is it a simple mapping key context?
+
+ line int // The current line.
+ column int // The current column.
+ whitespace bool // If the last character was a whitespace?
+ indention bool // If the last character was an indentation character (' ', '-', '?', ':')?
+ open_ended bool // If an explicit document end is required?
+
+ // Anchor analysis.
+ anchor_data struct {
+ anchor []byte // The anchor value.
+ alias bool // Is it an alias?
+ }
+
+ // Tag analysis.
+ tag_data struct {
+ handle []byte // The tag handle.
+ suffix []byte // The tag suffix.
+ }
+
+ // Scalar analysis.
+ scalar_data struct {
+ value []byte // The scalar value.
+ multiline bool // Does the scalar contain line breaks?
+ flow_plain_allowed bool // Can the scalar be expessed in the flow plain style?
+ block_plain_allowed bool // Can the scalar be expressed in the block plain style?
+ single_quoted_allowed bool // Can the scalar be expressed in the single quoted style?
+ block_allowed bool // Can the scalar be expressed in the literal or folded styles?
+ style yaml_scalar_style_t // The output style.
+ }
+
+ // Dumper stuff
+
+ opened bool // If the stream was already opened?
+ closed bool // If the stream was already closed?
+
+ // The information associated with the document nodes.
+ anchors *struct {
+ references int // The number of references.
+ anchor int // The anchor id.
+ serialized bool // If the node has been emitted?
+ }
+
+ last_anchor_id int // The last assigned anchor id.
+
+ document *yaml_document_t // The currently emitted document.
+}
diff --git a/vendor/gopkg.in/yaml.v2/yamlprivateh.go b/vendor/gopkg.in/yaml.v2/yamlprivateh.go
new file mode 100644
index 0000000000000000000000000000000000000000..8110ce3c37a6b4e152aee0fb65e36b99f55be6b6
--- /dev/null
+++ b/vendor/gopkg.in/yaml.v2/yamlprivateh.go
@@ -0,0 +1,173 @@
+package yaml
+
+const (
+ // The size of the input raw buffer.
+ input_raw_buffer_size = 512
+
+ // The size of the input buffer.
+ // It should be possible to decode the whole raw buffer.
+ input_buffer_size = input_raw_buffer_size * 3
+
+ // The size of the output buffer.
+ output_buffer_size = 128
+
+ // The size of the output raw buffer.
+ // It should be possible to encode the whole output buffer.
+ output_raw_buffer_size = (output_buffer_size*2 + 2)
+
+ // The size of other stacks and queues.
+ initial_stack_size = 16
+ initial_queue_size = 16
+ initial_string_size = 16
+)
+
+// Check if the character at the specified position is an alphabetical
+// character, a digit, '_', or '-'.
+func is_alpha(b []byte, i int) bool {
+ return b[i] >= '0' && b[i] <= '9' || b[i] >= 'A' && b[i] <= 'Z' || b[i] >= 'a' && b[i] <= 'z' || b[i] == '_' || b[i] == '-'
+}
+
+// Check if the character at the specified position is a digit.
+func is_digit(b []byte, i int) bool {
+ return b[i] >= '0' && b[i] <= '9'
+}
+
+// Get the value of a digit.
+func as_digit(b []byte, i int) int {
+ return int(b[i]) - '0'
+}
+
+// Check if the character at the specified position is a hex-digit.
+func is_hex(b []byte, i int) bool {
+ return b[i] >= '0' && b[i] <= '9' || b[i] >= 'A' && b[i] <= 'F' || b[i] >= 'a' && b[i] <= 'f'
+}
+
+// Get the value of a hex-digit.
+func as_hex(b []byte, i int) int {
+ bi := b[i]
+ if bi >= 'A' && bi <= 'F' {
+ return int(bi) - 'A' + 10
+ }
+ if bi >= 'a' && bi <= 'f' {
+ return int(bi) - 'a' + 10
+ }
+ return int(bi) - '0'
+}
+
+// Check if the character is ASCII.
+func is_ascii(b []byte, i int) bool {
+ return b[i] <= 0x7F
+}
+
+// Check if the character at the start of the buffer can be printed unescaped.
+func is_printable(b []byte, i int) bool {
+ return ((b[i] == 0x0A) || // . == #x0A
+ (b[i] >= 0x20 && b[i] <= 0x7E) || // #x20 <= . <= #x7E
+ (b[i] == 0xC2 && b[i+1] >= 0xA0) || // #0xA0 <= . <= #xD7FF
+ (b[i] > 0xC2 && b[i] < 0xED) ||
+ (b[i] == 0xED && b[i+1] < 0xA0) ||
+ (b[i] == 0xEE) ||
+ (b[i] == 0xEF && // #xE000 <= . <= #xFFFD
+ !(b[i+1] == 0xBB && b[i+2] == 0xBF) && // && . != #xFEFF
+ !(b[i+1] == 0xBF && (b[i+2] == 0xBE || b[i+2] == 0xBF))))
+}
+
+// Check if the character at the specified position is NUL.
+func is_z(b []byte, i int) bool {
+ return b[i] == 0x00
+}
+
+// Check if the beginning of the buffer is a BOM.
+func is_bom(b []byte, i int) bool {
+ return b[0] == 0xEF && b[1] == 0xBB && b[2] == 0xBF
+}
+
+// Check if the character at the specified position is space.
+func is_space(b []byte, i int) bool {
+ return b[i] == ' '
+}
+
+// Check if the character at the specified position is tab.
+func is_tab(b []byte, i int) bool {
+ return b[i] == '\t'
+}
+
+// Check if the character at the specified position is blank (space or tab).
+func is_blank(b []byte, i int) bool {
+ //return is_space(b, i) || is_tab(b, i)
+ return b[i] == ' ' || b[i] == '\t'
+}
+
+// Check if the character at the specified position is a line break.
+func is_break(b []byte, i int) bool {
+ return (b[i] == '\r' || // CR (#xD)
+ b[i] == '\n' || // LF (#xA)
+ b[i] == 0xC2 && b[i+1] == 0x85 || // NEL (#x85)
+ b[i] == 0xE2 && b[i+1] == 0x80 && b[i+2] == 0xA8 || // LS (#x2028)
+ b[i] == 0xE2 && b[i+1] == 0x80 && b[i+2] == 0xA9) // PS (#x2029)
+}
+
+func is_crlf(b []byte, i int) bool {
+ return b[i] == '\r' && b[i+1] == '\n'
+}
+
+// Check if the character is a line break or NUL.
+func is_breakz(b []byte, i int) bool {
+ //return is_break(b, i) || is_z(b, i)
+ return ( // is_break:
+ b[i] == '\r' || // CR (#xD)
+ b[i] == '\n' || // LF (#xA)
+ b[i] == 0xC2 && b[i+1] == 0x85 || // NEL (#x85)
+ b[i] == 0xE2 && b[i+1] == 0x80 && b[i+2] == 0xA8 || // LS (#x2028)
+ b[i] == 0xE2 && b[i+1] == 0x80 && b[i+2] == 0xA9 || // PS (#x2029)
+ // is_z:
+ b[i] == 0)
+}
+
+// Check if the character is a line break, space, or NUL.
+func is_spacez(b []byte, i int) bool {
+ //return is_space(b, i) || is_breakz(b, i)
+ return ( // is_space:
+ b[i] == ' ' ||
+ // is_breakz:
+ b[i] == '\r' || // CR (#xD)
+ b[i] == '\n' || // LF (#xA)
+ b[i] == 0xC2 && b[i+1] == 0x85 || // NEL (#x85)
+ b[i] == 0xE2 && b[i+1] == 0x80 && b[i+2] == 0xA8 || // LS (#x2028)
+ b[i] == 0xE2 && b[i+1] == 0x80 && b[i+2] == 0xA9 || // PS (#x2029)
+ b[i] == 0)
+}
+
+// Check if the character is a line break, space, tab, or NUL.
+func is_blankz(b []byte, i int) bool {
+ //return is_blank(b, i) || is_breakz(b, i)
+ return ( // is_blank:
+ b[i] == ' ' || b[i] == '\t' ||
+ // is_breakz:
+ b[i] == '\r' || // CR (#xD)
+ b[i] == '\n' || // LF (#xA)
+ b[i] == 0xC2 && b[i+1] == 0x85 || // NEL (#x85)
+ b[i] == 0xE2 && b[i+1] == 0x80 && b[i+2] == 0xA8 || // LS (#x2028)
+ b[i] == 0xE2 && b[i+1] == 0x80 && b[i+2] == 0xA9 || // PS (#x2029)
+ b[i] == 0)
+}
+
+// Determine the width of the character.
+func width(b byte) int {
+ // Don't replace these by a switch without first
+ // confirming that it is being inlined.
+ if b&0x80 == 0x00 {
+ return 1
+ }
+ if b&0xE0 == 0xC0 {
+ return 2
+ }
+ if b&0xF0 == 0xE0 {
+ return 3
+ }
+ if b&0xF8 == 0xF0 {
+ return 4
+ }
+ return 0
+
+}
diff --git a/vendor/modules.txt b/vendor/modules.txt
new file mode 100644
index 0000000000000000000000000000000000000000..ca28922e6442e4da4bff5424f288c8adf5fd78e8
--- /dev/null
+++ b/vendor/modules.txt
@@ -0,0 +1,34 @@
+# gitee.com/openeuler/go-gitee v0.0.0-20200320051710-5687412fb922
+gitee.com/openeuler/go-gitee/gitee
+# github.com/antihax/optional v1.0.0
+github.com/antihax/optional
+# github.com/go-sql-driver/mysql v1.4.1
+github.com/go-sql-driver/mysql
+# github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b
+github.com/golang/glog
+# github.com/golang/protobuf v1.3.2
+github.com/golang/protobuf/proto
+# github.com/jinzhu/gorm v1.9.11
+github.com/jinzhu/gorm
+github.com/jinzhu/gorm/dialects/mysql
+# github.com/jinzhu/inflection v1.0.0
+github.com/jinzhu/inflection
+# github.com/spf13/pflag v1.0.5
+github.com/spf13/pflag
+# golang.org/x/net v0.0.0-20190923162816-aa69164e4478
+golang.org/x/net/context
+golang.org/x/net/context/ctxhttp
+# golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45
+golang.org/x/oauth2
+golang.org/x/oauth2/internal
+# google.golang.org/appengine v1.6.3
+google.golang.org/appengine/cloudsql
+google.golang.org/appengine/internal
+google.golang.org/appengine/internal/base
+google.golang.org/appengine/internal/datastore
+google.golang.org/appengine/internal/log
+google.golang.org/appengine/internal/remote_api
+google.golang.org/appengine/internal/urlfetch
+google.golang.org/appengine/urlfetch
+# gopkg.in/yaml.v2 v2.2.2
+gopkg.in/yaml.v2