Merge pull request #15 from drone-plugins/feature/migrate-0.5
Migrated to 0.5
This commit is contained in:
		
						commit
						db2a647af4
					
				| @ -1 +0,0 @@ | |||||||
| eyJhbGciOiJSU0EtT0FFUCIsImVuYyI6IkExMjhHQ00ifQ.FkEZBgVid8dtRY6m3KbTWcbD4R67_D6Gy9DewVwbUySaQx0wuydNg6qHAyJ5barBvJqZqVT1njA_gZJ2c5jrNWvfGeXpbVWVxt88bIv1mqBV-WMcyuGXQ6JcCaDMYaof6Mb9Dguc8HqY8I2fYTgHtLpm2_AC2C-QzgD42B88TFkpre4-rUn2yYNgFLky_ctzgugcRbvjZgaJRKgNW002W3sGN-VChIiseTDyaPmeZUSzOS69nsWASLyXR1kngGUg3sqiSDlPeK3j6i1ur_F1bf71yyeiCSfEgTb6jixtwXEst2Etvb5lptN6pXqI_OAfmuLpxuRnAwzTE2RvlMBQZw.3eYpJLFsb3wr8xTa.Y_4czOKbbUZCa1_MBQISgcnQnlsLpPo3nQ5JCxa2WfG3R65vTgey_xwGWB846es1eIugf-NE9_pAhsD81tJHVhYNExxcMZbMM_q_iXFfFYMPBeT2fL9ApsJKqd6F2xf2p1pAEqCXNdhrJUd_-nOkKdOVlgk-OCvXfXuZZjxcrmkvo4B_0pe41DJIo0yxAPAGpNBlt5mCTrktC8CJZwkN6jFSrn1NGpoWCZ_Q6V7TslBkekHMf3BCDroPDTQi0a8QcGaquEl1C2baDSnLc-IrmWXM6ezpMJ_OjEL7pU45KQ9CG5-IQEVxBAhZmLHRJ5ZewJJjj0KpWYjPPOFx7bL7nDpBeANwOTwgflGALFAhYipT9oUnxkOCcuh5UVLZahHEqZ4p2WQbtlyC6IZvd-7ueyrIANm5TF6YpnY0RP076LE.kTQAsUediM3ibGMIkZa8Dg |  | ||||||
							
								
								
									
										46
									
								
								.drone.yml
									
									
									
									
									
								
							
							
						
						
									
										46
									
								
								.drone.yml
									
									
									
									
									
								
							| @ -1,39 +1,29 @@ | |||||||
| build: | workspace: | ||||||
|   image: golang:1.5 |   base: /go | ||||||
|   environment: |  | ||||||
|     - CGO_ENABLED=0 |  | ||||||
|   commands: |  | ||||||
|     - make deps |  | ||||||
|     - make vet |  | ||||||
|     - make build |  | ||||||
|     - make test |  | ||||||
| 
 | 
 | ||||||
| publish: | pipeline: | ||||||
|   coverage: |   test: | ||||||
|  |     image: golang:1.6 | ||||||
|  |     environment: | ||||||
|  |       - CGO_ENABLED=0 | ||||||
|  |     commands: | ||||||
|  |       - go vet | ||||||
|  |       - go test -cover -coverprofile=coverage.out | ||||||
|  |       - go build -ldflags "-s -w -X main.build=$DRONE_BUILD_NUMBER" -a -tags netgo | ||||||
|  | 
 | ||||||
|  |   latest: | ||||||
|  |     image: docker | ||||||
|  |     repo: plugins/github-release | ||||||
|  |     tags: [ "latest", "1.0", "1" ] | ||||||
|     when: |     when: | ||||||
|       branch: master |       branch: master | ||||||
|   docker: |       event: push | ||||||
|     username: $$DOCKER_USER |  | ||||||
|     password: $$DOCKER_PASS |  | ||||||
|     email: $$DOCKER_EMAIL |  | ||||||
|     repo: plugins/drone-github-release |  | ||||||
|     tag: latest |  | ||||||
|     when: |  | ||||||
|       branch: master |  | ||||||
|   docker: |  | ||||||
|     username: $$DOCKER_USER |  | ||||||
|     password: $$DOCKER_PASS |  | ||||||
|     email: $$DOCKER_EMAIL |  | ||||||
|     repo: plugins/drone-github-release |  | ||||||
|     tag: develop |  | ||||||
|     when: |  | ||||||
|       branch: develop |  | ||||||
| 
 | 
 | ||||||
| plugin: | plugin: | ||||||
|   name: GitHub Release |   name: GitHub Release | ||||||
|   desc: Publish files and artifacts to GitHub Releases |   desc: Publish files and artifacts to GitHub Releases | ||||||
|   type: publish |   type: publish | ||||||
|   image: plugins/drone-github-release |   image: plugins/github-release | ||||||
|   labels: |   labels: | ||||||
|     - github |     - github | ||||||
|     - release |     - release | ||||||
|  | |||||||
							
								
								
									
										1
									
								
								.drone.yml.sig
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								.drone.yml.sig
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1 @@ | |||||||
|  | eyJhbGciOiJIUzI1NiJ9.d29ya3NwYWNlOgogIGJhc2U6IC9nbwoKcGlwZWxpbmU6CiAgdGVzdDoKICAgIGltYWdlOiBnb2xhbmc6MS42CiAgICBlbnZpcm9ubWVudDoKICAgICAgLSBDR09fRU5BQkxFRD0wCiAgICBjb21tYW5kczoKICAgICAgLSBnbyB2ZXQKICAgICAgLSBnbyB0ZXN0IC1jb3ZlciAtY292ZXJwcm9maWxlPWNvdmVyYWdlLm91dAogICAgICAtIGdvIGJ1aWxkIC1sZGZsYWdzICItcyAtdyAtWCBtYWluLmJ1aWxkPSREUk9ORV9CVUlMRF9OVU1CRVIiIC1hIC10YWdzIG5ldGdvCgogIGxhdGVzdDoKICAgIGltYWdlOiBkb2NrZXIKICAgIHJlcG86IHBsdWdpbnMvZ2l0aHViLXJlbGVhc2UKICAgIHRhZ3M6IFsgImxhdGVzdCIsICIxLjAiLCAiMSIgXQogICAgd2hlbjoKICAgICAgYnJhbmNoOiBtYXN0ZXIKICAgICAgZXZlbnQ6IHB1c2gKCnBsdWdpbjoKICBuYW1lOiBHaXRIdWIgUmVsZWFzZQogIGRlc2M6IFB1Ymxpc2ggZmlsZXMgYW5kIGFydGlmYWN0cyB0byBHaXRIdWIgUmVsZWFzZXMKICB0eXBlOiBwdWJsaXNoCiAgaW1hZ2U6IHBsdWdpbnMvZ2l0aHViLXJlbGVhc2UKICBsYWJlbHM6CiAgICAtIGdpdGh1YgogICAgLSByZWxlYXNlCg.5FZW1Auk18CljY9LW5P82r9RM_spPCYMYg82PFj2irM | ||||||
							
								
								
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| @ -22,6 +22,7 @@ _testmain.go | |||||||
| *.exe | *.exe | ||||||
| *.test | *.test | ||||||
| *.prof | *.prof | ||||||
|  | .env | ||||||
| 
 | 
 | ||||||
| coverage.out | coverage.out | ||||||
| drone-github-release | drone-github-release | ||||||
|  | |||||||
							
								
								
									
										71
									
								
								DOCS.md
									
									
									
									
									
								
							
							
						
						
									
										71
									
								
								DOCS.md
									
									
									
									
									
								
							| @ -1,30 +1,61 @@ | |||||||
| Use this  plugin for publishing files and artifacts to GitHub releases. You | Use this plugin for publishing files and artifacts to GitHub releases. Be aware | ||||||
| can override the default configuration with the following parameters: | that you can use this plugin only for tags, GitHub doesn't support the release | ||||||
|  | of branches. | ||||||
| 
 | 
 | ||||||
| * `api_key` - GitHub oauth token with public_repo or repo permission | ## Config | ||||||
| * `files` - Files to upload to GitHub Release, globs are allowed |  | ||||||
| * `file_exists` - What to do if an file asset already exists, supported values: **overwrite** (default), **skip** and **fail** |  | ||||||
| * `checksum` - Checksum takes hash methods to include in your GitHub release for the files specified. Supported hash methods include md5, sha1, sha256, sha512, adler32, and crc32. |  | ||||||
| * `draft` - create a draft release if set to true |  | ||||||
| * `base_url` - GitHub base URL, only required for GHE |  | ||||||
| * `upload_url` - GitHub upload URL, only required for GHE |  | ||||||
| 
 | 
 | ||||||
| Sample configuration: | The following parameters are used to configure the plugin: | ||||||
| 
 | 
 | ||||||
| ```yaml | * **api_key** - GitHub oauth token with public_repo or repo permission | ||||||
| publish: | * **files** - files to upload to GitHub Release, globs are allowed | ||||||
|   github_release: | * **file_exists** - what to do if an file asset already exists, supported values: **overwrite** (default), **skip** and **fail** | ||||||
|     api_key: my_github_api_key | * **checksum** - checksum takes hash methods to include in your GitHub release for the files specified. Supported hash methods include md5, sha1, sha256, sha512, adler32, and crc32. | ||||||
|     files: dist/* | * **draft** - create a draft release if set to true | ||||||
|     checksum: sha1 | * **base_url** - GitHub base URL, only required for GHE | ||||||
|  | * **upload_url** - GitHub upload URL, only required for GHE | ||||||
|  | 
 | ||||||
|  | The following secret values can be set to configure the plugin. | ||||||
|  | 
 | ||||||
|  | * **GITHUB_RELEASE_API_KEY** - corresponds to **api_key** | ||||||
|  | * **GITHUB_RELEASE_BASE_URL** - corresponds to **base_url** | ||||||
|  | * **GITHUB_RELEASE_UPLOAD_URL** - corresponds to **upload_url** | ||||||
|  | 
 | ||||||
|  | It is highly recommended to put the **GITHUB_RELEASE_API_KEY** into a secret so | ||||||
|  | it is not exposed to users. This can be done using the drone-cli. | ||||||
|  | 
 | ||||||
|  | ```bash | ||||||
|  | drone secret add --image=plugins/github-release \ | ||||||
|  |     octocat/hello-world GITHUB_RELEASE_API_KEY my_github_api_key | ||||||
| ``` | ``` | ||||||
| 
 | 
 | ||||||
| or | Then sign the YAML file after all secrets are added. | ||||||
|  | 
 | ||||||
|  | ```bash | ||||||
|  | drone sign octocat/hello-world | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | See [secrets](http://readme.drone.io/0.5/usage/secrets/) for additional | ||||||
|  | information on secrets | ||||||
|  | 
 | ||||||
|  | ## Examples | ||||||
|  | 
 | ||||||
|  | The following is a sample configuration in your .drone.yml file: | ||||||
| 
 | 
 | ||||||
| ```yaml | ```yaml | ||||||
| publish: | pipeline: | ||||||
|   github_release: |   github_release: | ||||||
|     api_key: my_github_api_key |     image: plugins/github-release | ||||||
|  |     files: dist/* | ||||||
|  |     when: | ||||||
|  |       event: tag | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | An example for generating checksums and upload additional files: | ||||||
|  | 
 | ||||||
|  | ```yaml | ||||||
|  | pipeline: | ||||||
|  |   github_release: | ||||||
|  |     image: plugins/github-release | ||||||
|     files: |     files: | ||||||
|       - dist/* |       - dist/* | ||||||
|       - bin/binary.exe |       - bin/binary.exe | ||||||
| @ -35,4 +66,6 @@ publish: | |||||||
|       - sha512 |       - sha512 | ||||||
|       - adler32 |       - adler32 | ||||||
|       - crc32 |       - crc32 | ||||||
|  |     when: | ||||||
|  |       event: tag | ||||||
| ``` | ``` | ||||||
|  | |||||||
| @ -1,9 +1,4 @@ | |||||||
| # Docker image for the Drone GitHub Release plugin | FROM alpine:3.4 | ||||||
| # |  | ||||||
| #     cd $GOPATH/src/github.com/drone-plugins/drone-github-release |  | ||||||
| #     make deps build docker |  | ||||||
| 
 |  | ||||||
| FROM alpine:3.3 |  | ||||||
| 
 | 
 | ||||||
| RUN apk update && \ | RUN apk update && \ | ||||||
|   apk add \ |   apk add \ | ||||||
|  | |||||||
							
								
								
									
										9
									
								
								Dockerfile.armhf
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								Dockerfile.armhf
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,9 @@ | |||||||
|  | FROM armhfbuild/alpine:3.4 | ||||||
|  | 
 | ||||||
|  | RUN apk update && \ | ||||||
|  |   apk add \ | ||||||
|  |     ca-certificates && \ | ||||||
|  |   rm -rf /var/cache/apk/* | ||||||
|  | 
 | ||||||
|  | ADD drone-github-release /bin/ | ||||||
|  | ENTRYPOINT ["/bin/drone-github-release"] | ||||||
							
								
								
									
										34
									
								
								Makefile
									
									
									
									
									
								
							
							
						
						
									
										34
									
								
								Makefile
									
									
									
									
									
								
							| @ -1,34 +0,0 @@ | |||||||
| .PHONY: all clean deps fmt vet test docker |  | ||||||
| 
 |  | ||||||
| EXECUTABLE ?= drone-github-release |  | ||||||
| IMAGE ?= plugins/$(EXECUTABLE) |  | ||||||
| COMMIT ?= $(shell git rev-parse --short HEAD) |  | ||||||
| 
 |  | ||||||
| LDFLAGS = -X "main.buildCommit=$(COMMIT)" |  | ||||||
| PACKAGES = $(shell go list ./... | grep -v /vendor/) |  | ||||||
| 
 |  | ||||||
| all: deps build test |  | ||||||
| 
 |  | ||||||
| clean: |  | ||||||
| 	go clean -i ./... |  | ||||||
| 
 |  | ||||||
| deps: |  | ||||||
| 	go get -t ./... |  | ||||||
| 
 |  | ||||||
| fmt: |  | ||||||
| 	go fmt $(PACKAGES) |  | ||||||
| 
 |  | ||||||
| vet: |  | ||||||
| 	go vet $(PACKAGES) |  | ||||||
| 
 |  | ||||||
| test: |  | ||||||
| 	@for PKG in $(PACKAGES); do go test -cover -coverprofile $$GOPATH/src/$$PKG/coverage.out $$PKG || exit 1; done; |  | ||||||
| 
 |  | ||||||
| docker: |  | ||||||
| 	GOOS=linux GOARCH=amd64 CGO_ENABLED=0 go build -ldflags '-s -w $(LDFLAGS)' |  | ||||||
| 	docker build --rm -t $(IMAGE) . |  | ||||||
| 
 |  | ||||||
| $(EXECUTABLE): $(wildcard *.go) |  | ||||||
| 	go build -ldflags '-s -w $(LDFLAGS)' |  | ||||||
| 
 |  | ||||||
| build: $(EXECUTABLE) |  | ||||||
							
								
								
									
										132
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										132
									
								
								README.md
									
									
									
									
									
								
							| @ -1,117 +1,53 @@ | |||||||
| # drone-github-release | # drone-github-release | ||||||
| 
 | 
 | ||||||
| [](http://beta.drone.io/drone-plugins/drone-github-release) | [](http://beta.drone.io/drone-plugins/drone-github-release) | ||||||
| [](https://aircover.co/drone-plugins/drone-github-release) | [](http://godoc.org/github.com/drone-plugins/drone-github-release) | ||||||
| [](https://imagelayers.io/?images=plugins/drone-github-release:latest 'Get your own badge on imagelayers.io') | [](https://goreportcard.com/report/github.com/drone-plugins/drone-github-release) | ||||||
|  | [](https://gitter.im/drone/drone) | ||||||
| 
 | 
 | ||||||
| Drone plugin to publish files and artifacts to GitHub Release. For the usage information and a listing of the available options please take a look at [the docs](DOCS.md). | Drone plugin to publish files and artifacts to GitHub Release. For the usage | ||||||
|  | information and a listing of the available options please take a look at | ||||||
|  | [the docs](DOCS.md). | ||||||
| 
 | 
 | ||||||
| ## Binary | ## Build | ||||||
| 
 | 
 | ||||||
| Build the binary using `make`: | Build the binary with the following commands: | ||||||
| 
 | 
 | ||||||
| ``` | ``` | ||||||
| make deps build | go build | ||||||
| ``` | go test | ||||||
| 
 |  | ||||||
| ### Example |  | ||||||
| 
 |  | ||||||
| ```sh |  | ||||||
| ./drone-github-release <<EOF |  | ||||||
| { |  | ||||||
|     "repo": { |  | ||||||
|         "clone_url": "git://github.com/drone/drone", |  | ||||||
|         "owner": "drone", |  | ||||||
|         "name": "drone", |  | ||||||
|         "full_name": "drone/drone" |  | ||||||
|     }, |  | ||||||
|     "system": { |  | ||||||
|         "link_url": "https://beta.drone.io" |  | ||||||
|     }, |  | ||||||
|     "build": { |  | ||||||
|         "number": 22, |  | ||||||
|         "status": "success", |  | ||||||
|         "started_at": 1421029603, |  | ||||||
|         "finished_at": 1421029813, |  | ||||||
|         "message": "Update the Readme", |  | ||||||
|         "author": "johnsmith", |  | ||||||
|         "author_email": "john.smith@gmail.com" |  | ||||||
|         "event": "push", |  | ||||||
|         "branch": "master", |  | ||||||
|         "commit": "436b7a6e2abaddfd35740527353e78a227ddcb2c", |  | ||||||
|         "ref": "refs/heads/master" |  | ||||||
|     }, |  | ||||||
|     "workspace": { |  | ||||||
|         "root": "/drone/src", |  | ||||||
|         "path": "/drone/src/github.com/drone/drone" |  | ||||||
|     }, |  | ||||||
|     "vargs": { |  | ||||||
|         "api_key": "your_api_key", |  | ||||||
|         "files": [ |  | ||||||
|             "dist/*.txt", |  | ||||||
|             "dist/other-file" |  | ||||||
|         ], |  | ||||||
|         "checksum": [ |  | ||||||
|             "sha1", |  | ||||||
|             "sha256", |  | ||||||
|             "sha512" |  | ||||||
|         ] |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| EOF |  | ||||||
| ``` | ``` | ||||||
| 
 | 
 | ||||||
| ## Docker | ## Docker | ||||||
| 
 | 
 | ||||||
| Build the container using `make`: | Build the docker image with the following commands: | ||||||
| 
 | 
 | ||||||
| ``` | ``` | ||||||
| make deps docker | CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -a -tags netgo | ||||||
|  | docker build --rm=true -t plugins/github-release . | ||||||
| ``` | ``` | ||||||
| 
 | 
 | ||||||
| ### Example | Please note incorrectly building the image for the correct x64 linux and with | ||||||
|  | GCO disabled will result in an error when running the Docker image: | ||||||
|  | 
 | ||||||
|  | ``` | ||||||
|  | docker: Error response from daemon: Container command | ||||||
|  | '/bin/drone-github-release' not found or does not exist.. | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | ## Usage | ||||||
|  | 
 | ||||||
|  | Execute from the working directory: | ||||||
| 
 | 
 | ||||||
| ```sh | ```sh | ||||||
| docker run -i plugins/drone-github-release <<EOF | docker run --rm \ | ||||||
| { |   -e DRONE_BUILD_EVENT=tag \ | ||||||
|     "repo": { |   -e DRONE_REPO_OWNER=octocat \ | ||||||
|         "clone_url": "git://github.com/drone/drone", |   -e DRONE_REPO_NAME=foo \ | ||||||
|         "owner": "drone", |   -e DRONE_COMMIT_REF=refs/heads/master \ | ||||||
|         "name": "drone", |   -e PLUGIN_API_KEY=${HOME}/.ssh/id_rsa \ | ||||||
|         "full_name": "drone/drone" |   -e PLUGIN_FILES=master \ | ||||||
|     }, |   -v $(pwd):$(pwd) \ | ||||||
|     "system": { |   -w $(pwd) \ | ||||||
|         "link_url": "https://beta.drone.io" |   plugins/github-release | ||||||
|     }, |  | ||||||
|     "build": { |  | ||||||
|         "number": 22, |  | ||||||
|         "status": "success", |  | ||||||
|         "started_at": 1421029603, |  | ||||||
|         "finished_at": 1421029813, |  | ||||||
|         "message": "Update the Readme", |  | ||||||
|         "author": "johnsmith", |  | ||||||
|         "author_email": "john.smith@gmail.com" |  | ||||||
|         "event": "push", |  | ||||||
|         "branch": "master", |  | ||||||
|         "commit": "436b7a6e2abaddfd35740527353e78a227ddcb2c", |  | ||||||
|         "ref": "refs/heads/master" |  | ||||||
|     }, |  | ||||||
|     "workspace": { |  | ||||||
|         "root": "/drone/src", |  | ||||||
|         "path": "/drone/src/github.com/drone/drone" |  | ||||||
|     }, |  | ||||||
|     "vargs": { |  | ||||||
|         "api_key": "your_api_key", |  | ||||||
|         "files": [ |  | ||||||
|             "dist/*.txt", |  | ||||||
|             "dist/other-file" |  | ||||||
|         ], |  | ||||||
|         "checksum": [ |  | ||||||
|             "sha1", |  | ||||||
|             "sha256", |  | ||||||
|             "sha512" |  | ||||||
|         ] |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| EOF |  | ||||||
| ``` | ``` | ||||||
|  | |||||||
							
								
								
									
										38
									
								
								checksum.go
									
									
									
									
									
								
							
							
						
						
									
										38
									
								
								checksum.go
									
									
									
									
									
								
							| @ -1,38 +0,0 @@ | |||||||
| package main |  | ||||||
| 
 |  | ||||||
| import ( |  | ||||||
| 	"crypto/md5" |  | ||||||
| 	"crypto/sha1" |  | ||||||
| 	"crypto/sha256" |  | ||||||
| 	"crypto/sha512" |  | ||||||
| 	"fmt" |  | ||||||
| 	"hash/adler32" |  | ||||||
| 	"hash/crc32" |  | ||||||
| 	"io" |  | ||||||
| 	"io/ioutil" |  | ||||||
| 	"strconv" |  | ||||||
| ) |  | ||||||
| 
 |  | ||||||
| func checksum(r io.Reader, method string) (string, error) { |  | ||||||
| 	b, err := ioutil.ReadAll(r) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return "", err |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	switch method { |  | ||||||
| 	case "md5": |  | ||||||
| 		return fmt.Sprintf("%x", md5.Sum(b)), nil |  | ||||||
| 	case "sha1": |  | ||||||
| 		return fmt.Sprintf("%x", sha1.Sum(b)), nil |  | ||||||
| 	case "sha256": |  | ||||||
| 		return fmt.Sprintf("%x", sha256.Sum256(b)), nil |  | ||||||
| 	case "sha512": |  | ||||||
| 		return fmt.Sprintf("%x", sha512.Sum512(b)), nil |  | ||||||
| 	case "adler32": |  | ||||||
| 		return strconv.FormatUint(uint64(adler32.Checksum(b)), 10), nil |  | ||||||
| 	case "crc32": |  | ||||||
| 		return strconv.FormatUint(uint64(crc32.ChecksumIEEE(b)), 10), nil |  | ||||||
| 	default: |  | ||||||
| 		return "", fmt.Errorf("hashing method %s is not supported", method) |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
							
								
								
									
										364
									
								
								main.go
									
									
									
									
									
								
							
							
						
						
									
										364
									
								
								main.go
									
									
									
									
									
								
							| @ -2,276 +2,120 @@ package main | |||||||
| 
 | 
 | ||||||
| import ( | import ( | ||||||
| 	"fmt" | 	"fmt" | ||||||
| 	"net/url" |  | ||||||
| 	"os" | 	"os" | ||||||
| 	"path" |  | ||||||
| 	"path/filepath" |  | ||||||
| 	"strings" |  | ||||||
| 
 | 
 | ||||||
| 	"github.com/drone/drone-go/drone" | 	"github.com/Sirupsen/logrus" | ||||||
| 	"github.com/drone/drone-go/plugin" | 	"github.com/joho/godotenv" | ||||||
| 	"github.com/google/go-github/github" | 	"github.com/urfave/cli" | ||||||
| 	"golang.org/x/oauth2" |  | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| var ( | var build = "0" // build number set at compile-time
 | ||||||
| 	buildCommit string |  | ||||||
| ) |  | ||||||
| 
 | 
 | ||||||
| func main() { | func main() { | ||||||
| 	fmt.Printf("Drone GitHub Release Plugin built from %s\n", buildCommit) | 	app := cli.NewApp() | ||||||
|  | 	app.Name = "github-release plugin" | ||||||
|  | 	app.Usage = "github-release plugin" | ||||||
|  | 	app.Action = run | ||||||
|  | 	app.Version = fmt.Sprintf("1.0.%s", build) | ||||||
|  | 	app.Flags = []cli.Flag{ | ||||||
|  | 		cli.StringFlag{ | ||||||
|  | 			Name:   "api-key", | ||||||
|  | 			Usage:  "api key to access github api", | ||||||
|  | 			EnvVar: "PLUGIN_API_KEY,GITHUB_RELEASE_API_KEY", | ||||||
|  | 		}, | ||||||
|  | 		cli.StringSliceFlag{ | ||||||
|  | 			Name:   "files", | ||||||
|  | 			Usage:  "list of files to upload", | ||||||
|  | 			EnvVar: "PLUGIN_FILES,GITHUB_RELEASE_FILES", | ||||||
|  | 		}, | ||||||
|  | 		cli.StringFlag{ | ||||||
|  | 			Name:   "file-exists", | ||||||
|  | 			Value:  "overwrite", | ||||||
|  | 			Usage:  "what to do if file already exist", | ||||||
|  | 			EnvVar: "PLUGIN_FILE_EXISTS,GITHUB_RELEASE_FILE_EXISTS", | ||||||
|  | 		}, | ||||||
|  | 		cli.StringSliceFlag{ | ||||||
|  | 			Name:   "checksum", | ||||||
|  | 			Usage:  "generate specific checksums", | ||||||
|  | 			EnvVar: "PLUGIN_CHECKSUM,GITHUB_RELEASE_CHECKSUM", | ||||||
|  | 		}, | ||||||
|  | 		cli.BoolFlag{ | ||||||
|  | 			Name:   "draft", | ||||||
|  | 			Usage:  "create a draft release", | ||||||
|  | 			EnvVar: "PLUGIN_DRAFT,GITHUB_RELEASE_DRAFT", | ||||||
|  | 		}, | ||||||
|  | 		cli.StringFlag{ | ||||||
|  | 			Name:   "base-url", | ||||||
|  | 			Value:  "https://api.github.com/", | ||||||
|  | 			Usage:  "api url, needs to be changed for ghe", | ||||||
|  | 			EnvVar: "PLUGIN_BASE_URL,GITHUB_RELEASE_BASE_URL", | ||||||
|  | 		}, | ||||||
|  | 		cli.StringFlag{ | ||||||
|  | 			Name:   "upload-url", | ||||||
|  | 			Value:  "https://uploads.github.com/", | ||||||
|  | 			Usage:  "upload url, needs to be changed for ghe", | ||||||
|  | 			EnvVar: "PLUGIN_UPLOAD_URL,GITHUB_RELEASE_UPLOAD_URL", | ||||||
|  | 		}, | ||||||
| 
 | 
 | ||||||
| 	workspace := drone.Workspace{} | 		cli.StringFlag{ | ||||||
| 	repo := drone.Repo{} | 			Name:   "repo.owner", | ||||||
| 	build := drone.Build{} | 			Usage:  "repository owner", | ||||||
| 	vargs := Params{} | 			EnvVar: "DRONE_REPO_OWNER", | ||||||
| 
 | 		}, | ||||||
| 	plugin.Param("workspace", &workspace) | 		cli.StringFlag{ | ||||||
| 	plugin.Param("repo", &repo) | 			Name:   "repo.name", | ||||||
| 	plugin.Param("build", &build) | 			Usage:  "repository name", | ||||||
| 	plugin.Param("vargs", &vargs) | 			EnvVar: "DRONE_REPO_NAME", | ||||||
| 	plugin.MustParse() | 		}, | ||||||
| 
 | 		cli.StringFlag{ | ||||||
| 	if build.Event != "tag" { | 			Name:   "build.event", | ||||||
| 		fmt.Printf("The GitHub Release plugin is only available for tags\n") | 			Value:  "push", | ||||||
| 		os.Exit(0) | 			Usage:  "build event", | ||||||
|  | 			EnvVar: "DRONE_BUILD_EVENT", | ||||||
|  | 		}, | ||||||
|  | 		cli.StringFlag{ | ||||||
|  | 			Name:   "commit.ref", | ||||||
|  | 			Value:  "refs/heads/master", | ||||||
|  | 			Usage:  "git commit ref", | ||||||
|  | 			EnvVar: "DRONE_COMMIT_REF", | ||||||
|  | 		}, | ||||||
|  | 		cli.StringFlag{ | ||||||
|  | 			Name:  "env-file", | ||||||
|  | 			Usage: "source env file", | ||||||
|  | 		}, | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	if vargs.FileExists == "" { | 	if err := app.Run(os.Args); err != nil { | ||||||
| 		vargs.FileExists = "overwrite" | 		logrus.Fatal(err) | ||||||
| 	} |  | ||||||
| 	if !fileExistsValues[vargs.FileExists] { |  | ||||||
| 		fmt.Printf("invalid value for file_exists: use [empty], overwrite, skip or fail") |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	if vargs.BaseURL == "" { |  | ||||||
| 		vargs.BaseURL = "https://api.github.com/" |  | ||||||
| 	} else if !strings.HasSuffix(vargs.BaseURL, "/") { |  | ||||||
| 		vargs.BaseURL = vargs.BaseURL + "/" |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	if vargs.UploadURL == "" { |  | ||||||
| 		vargs.UploadURL = "https://uploads.github.com/" |  | ||||||
| 	} else if !strings.HasSuffix(vargs.UploadURL, "/") { |  | ||||||
| 		vargs.UploadURL = vargs.UploadURL + "/" |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	if vargs.APIKey == "" { |  | ||||||
| 		fmt.Printf("You must provide an API key\n") |  | ||||||
| 		os.Exit(1) |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	if workspace.Path != "" { |  | ||||||
| 		os.Chdir(workspace.Path) |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	var files []string |  | ||||||
| 	for _, glob := range vargs.Files.Slice() { |  | ||||||
| 		globed, err := filepath.Glob(glob) |  | ||||||
| 		if err != nil { |  | ||||||
| 			fmt.Printf("Failed to glob %s\n", glob) |  | ||||||
| 			os.Exit(1) |  | ||||||
| 		} |  | ||||||
| 		if globed != nil { |  | ||||||
| 			files = append(files, globed...) |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	if vargs.Checksum.Len() > 0 { |  | ||||||
| 		var err error |  | ||||||
| 		files, err = writeChecksums(files, vargs.Checksum.Slice()) |  | ||||||
| 		if err != nil { |  | ||||||
| 			fmt.Println(err) |  | ||||||
| 			os.Exit(1) |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	baseURL, err := url.Parse(vargs.BaseURL) |  | ||||||
| 	if err != nil { |  | ||||||
| 		fmt.Printf("Failed to parse base URL\n") |  | ||||||
| 		os.Exit(1) |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	uploadURL, err := url.Parse(vargs.UploadURL) |  | ||||||
| 	if err != nil { |  | ||||||
| 		fmt.Printf("Failed to parse upload URL\n") |  | ||||||
| 		os.Exit(1) |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	ts := oauth2.StaticTokenSource(&oauth2.Token{AccessToken: vargs.APIKey}) |  | ||||||
| 	tc := oauth2.NewClient(oauth2.NoContext, ts) |  | ||||||
| 
 |  | ||||||
| 	client := github.NewClient(tc) |  | ||||||
| 	client.BaseURL = baseURL |  | ||||||
| 	client.UploadURL = uploadURL |  | ||||||
| 
 |  | ||||||
| 	rc := releaseClient{ |  | ||||||
| 		Client: client, |  | ||||||
| 		Owner:  repo.Owner, |  | ||||||
| 		Repo:   repo.Name, |  | ||||||
| 		Tag:    filepath.Base(build.Ref), |  | ||||||
| 		Draft:  vargs.Draft, |  | ||||||
| 		FileExists: vargs.FileExists, |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	release, err := rc.buildRelease() |  | ||||||
| 	if err != nil { |  | ||||||
| 		fmt.Println(err) |  | ||||||
| 		os.Exit(1) |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	if err := rc.uploadFiles(*release.ID, files); err != nil { |  | ||||||
| 		fmt.Println(err) |  | ||||||
| 		os.Exit(1) |  | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| var fileExistsValues = map[string]bool{ | func run(c *cli.Context) error { | ||||||
| 	"overwrite": true, | 	if c.String("env-file") != "" { | ||||||
| 	"fail":      true, | 		_ = godotenv.Load(c.String("env-file")) | ||||||
| 	"skip":      true, | 	} | ||||||
| } | 
 | ||||||
| 
 | 	plugin := Plugin{ | ||||||
| // Release holds ties the drone env data and github client together.
 | 		Repo: Repo{ | ||||||
| type releaseClient struct { | 			Owner: c.String("repo.owner"), | ||||||
| 	*github.Client | 			Name:  c.String("repo.name"), | ||||||
| 	Owner      string | 		}, | ||||||
| 	Repo       string | 		Build: Build{ | ||||||
| 	Tag        string | 			Event: c.String("build.event"), | ||||||
| 	Draft      bool | 		}, | ||||||
| 	FileExists string | 		Commit: Commit{ | ||||||
| } | 			Ref: c.String("commit.sha"), | ||||||
| 
 | 		}, | ||||||
| func (rc *releaseClient) buildRelease() (*github.RepositoryRelease, error) { | 		Config: Config{ | ||||||
| 
 | 			APIKey:     c.String("api-key"), | ||||||
| 	// first attempt to get a release by that tag
 | 			Files:      c.StringSlice("api-key"), | ||||||
| 	release, err := rc.getRelease() | 			FileExists: c.String("file-exists"), | ||||||
| 	if err != nil && release == nil { | 			Checksum:   c.StringSlice("checksum"), | ||||||
| 		fmt.Println(err) | 			Draft:      c.Bool("draft"), | ||||||
| 	} else if release != nil { | 			BaseURL:    c.String("base-url"), | ||||||
| 		return release, nil | 			UploadURL:  c.String("upload-url"), | ||||||
| 	} | 		}, | ||||||
| 
 | 	} | ||||||
| 	// if no release was found by that tag, create a new one
 | 
 | ||||||
| 	release, err = rc.newRelease() | 	return plugin.Exec() | ||||||
| 	if err != nil { |  | ||||||
| 		return nil, fmt.Errorf("Failed to retrieve or create a release: %s", err) |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	return release, nil |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (rc *releaseClient) getRelease() (*github.RepositoryRelease, error) { |  | ||||||
| 	release, _, err := rc.Client.Repositories.GetReleaseByTag(rc.Owner, rc.Repo, rc.Tag) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return nil, fmt.Errorf("Release %s not found", rc.Tag) |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	fmt.Printf("Successfully retrieved %s release\n", rc.Tag) |  | ||||||
| 	return release, nil |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (rc *releaseClient) newRelease() (*github.RepositoryRelease, error) { |  | ||||||
| 	rr := &github.RepositoryRelease{ |  | ||||||
| 		TagName: github.String(rc.Tag), |  | ||||||
| 		Draft:   &rc.Draft, |  | ||||||
| 	} |  | ||||||
| 	release, _, err := rc.Client.Repositories.CreateRelease(rc.Owner, rc.Repo, rr) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return nil, fmt.Errorf("Failed to create release: %s", err) |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	fmt.Printf("Successfully created %s release\n", rc.Tag) |  | ||||||
| 	return release, nil |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (rc *releaseClient) uploadFiles(id int, files []string) error { |  | ||||||
| 	assets, _, err := rc.Client.Repositories.ListReleaseAssets(rc.Owner, rc.Repo, id, &github.ListOptions{}) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return fmt.Errorf("Failed to fetch existing assets: %s", err) |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	var uploadFiles []string |  | ||||||
| files: |  | ||||||
| 	for _, file := range files { |  | ||||||
| 		for _, asset := range assets { |  | ||||||
| 			if *asset.Name == path.Base(file) { |  | ||||||
| 				switch rc.FileExists { |  | ||||||
| 				case "overwrite": |  | ||||||
| 					// do nothing
 |  | ||||||
| 				case "fail": |  | ||||||
| 					return fmt.Errorf("Asset file %s already exists", path.Base(file)) |  | ||||||
| 				case "skip": |  | ||||||
| 					fmt.Printf("Skipping pre-existing %s artifact\n", *asset.Name) |  | ||||||
| 					continue files |  | ||||||
| 				default: |  | ||||||
| 					return fmt.Errorf("Internal error, unkown file_exist value %s", rc.FileExists) |  | ||||||
| 				} |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
| 		uploadFiles = append(uploadFiles, file) |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	for _, file := range uploadFiles { |  | ||||||
| 		handle, err := os.Open(file) |  | ||||||
| 		if err != nil { |  | ||||||
| 			return fmt.Errorf("Failed to read %s artifact: %s", file, err) |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		for _, asset := range assets { |  | ||||||
| 			if *asset.Name == path.Base(file) { |  | ||||||
| 				if _, err := rc.Client.Repositories.DeleteReleaseAsset(rc.Owner, rc.Repo, *asset.ID); err != nil { |  | ||||||
| 					return fmt.Errorf("Failed to delete %s artifact: %s", file, err) |  | ||||||
| 				} |  | ||||||
| 				fmt.Printf("Successfully deleted old %s artifact\n", *asset.Name) |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		uo := &github.UploadOptions{Name: path.Base(file)} |  | ||||||
| 		if _, _, err = rc.Client.Repositories.UploadReleaseAsset(rc.Owner, rc.Repo, id, uo, handle); err != nil { |  | ||||||
| 			return fmt.Errorf("Failed to upload %s artifact: %s", file, err) |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		fmt.Printf("Successfully uploaded %s artifact\n", file) |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	return nil |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func writeChecksums(files, methods []string) ([]string, error) { |  | ||||||
| 
 |  | ||||||
| 	checksums := make(map[string][]string) |  | ||||||
| 	for _, method := range methods { |  | ||||||
| 		for _, file := range files { |  | ||||||
| 			handle, err := os.Open(file) |  | ||||||
| 			if err != nil { |  | ||||||
| 				return nil, fmt.Errorf("Failed to read %s artifact: %s", file, err) |  | ||||||
| 			} |  | ||||||
| 
 |  | ||||||
| 			hash, err := checksum(handle, method) |  | ||||||
| 			if err != nil { |  | ||||||
| 				return nil, err |  | ||||||
| 			} |  | ||||||
| 
 |  | ||||||
| 			checksums[method] = append(checksums[method], hash, file) |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	for method, results := range checksums { |  | ||||||
| 		filename := method + "sum.txt" |  | ||||||
| 		f, err := os.Create(filename) |  | ||||||
| 		if err != nil { |  | ||||||
| 			return nil, err |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		for i := 0; i < len(results); i += 2 { |  | ||||||
| 			hash := results[i] |  | ||||||
| 			file := results[i+1] |  | ||||||
| 			if _, err := f.WriteString(fmt.Sprintf("%s  %s\n", hash, file)); err != nil { |  | ||||||
| 				return nil, err |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
| 		files = append(files, filename) |  | ||||||
| 	} |  | ||||||
| 	return files, nil |  | ||||||
| } | } | ||||||
|  | |||||||
							
								
								
									
										134
									
								
								plugin.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										134
									
								
								plugin.go
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,134 @@ | |||||||
|  | package main | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  | 	"fmt" | ||||||
|  | 	"net/url" | ||||||
|  | 	"path/filepath" | ||||||
|  | 	"strings" | ||||||
|  | 
 | ||||||
|  | 	"github.com/google/go-github/github" | ||||||
|  | 	"golang.org/x/oauth2" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | type ( | ||||||
|  | 	Repo struct { | ||||||
|  | 		Owner string | ||||||
|  | 		Name  string | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	Build struct { | ||||||
|  | 		Event string | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	Commit struct { | ||||||
|  | 		Ref string | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	Config struct { | ||||||
|  | 		APIKey     string | ||||||
|  | 		Files      []string | ||||||
|  | 		FileExists string | ||||||
|  | 		Checksum   []string | ||||||
|  | 		Draft      bool | ||||||
|  | 		BaseURL    string | ||||||
|  | 		UploadURL  string | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	Plugin struct { | ||||||
|  | 		Repo   Repo | ||||||
|  | 		Build  Build | ||||||
|  | 		Commit Commit | ||||||
|  | 		Config Config | ||||||
|  | 	} | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | func (p Plugin) Exec() error { | ||||||
|  | 	var ( | ||||||
|  | 		files []string | ||||||
|  | 	) | ||||||
|  | 
 | ||||||
|  | 	if p.Build.Event != "tag" { | ||||||
|  | 		return fmt.Errorf("The GitHub Release plugin is only available for tags") | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if p.Config.APIKey == "" { | ||||||
|  | 		return fmt.Errorf("You must provide an API key") | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if !fileExistsValues[p.Config.FileExists] { | ||||||
|  | 		return fmt.Errorf("Invalid value for file_exists") | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if !strings.HasSuffix(p.Config.BaseURL, "/") { | ||||||
|  | 		p.Config.BaseURL = p.Config.BaseURL + "/" | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if !strings.HasSuffix(p.Config.UploadURL, "/") { | ||||||
|  | 		p.Config.UploadURL = p.Config.UploadURL + "/" | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	for _, glob := range p.Config.Files { | ||||||
|  | 		globed, err := filepath.Glob(glob) | ||||||
|  | 
 | ||||||
|  | 		if err != nil { | ||||||
|  | 			return fmt.Errorf("Failed to glob %s. %s", glob, err) | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		if globed != nil { | ||||||
|  | 			files = append(files, globed...) | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if len(p.Config.Checksum) > 0 { | ||||||
|  | 		var ( | ||||||
|  | 			err error | ||||||
|  | 		) | ||||||
|  | 
 | ||||||
|  | 		files, err = writeChecksums(files, p.Config.Checksum) | ||||||
|  | 
 | ||||||
|  | 		if err != nil { | ||||||
|  | 			return fmt.Errorf("Failed to write checksums. %s", err) | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	baseURL, err := url.Parse(p.Config.BaseURL) | ||||||
|  | 
 | ||||||
|  | 	if err != nil { | ||||||
|  | 		return fmt.Errorf("Failed to parse base URL. %s", err) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	uploadURL, err := url.Parse(p.Config.UploadURL) | ||||||
|  | 
 | ||||||
|  | 	if err != nil { | ||||||
|  | 		return fmt.Errorf("Failed to parse upload URL. %s", err) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	ts := oauth2.StaticTokenSource(&oauth2.Token{AccessToken: p.Config.APIKey}) | ||||||
|  | 	tc := oauth2.NewClient(oauth2.NoContext, ts) | ||||||
|  | 
 | ||||||
|  | 	client := github.NewClient(tc) | ||||||
|  | 
 | ||||||
|  | 	client.BaseURL = baseURL | ||||||
|  | 	client.UploadURL = uploadURL | ||||||
|  | 
 | ||||||
|  | 	rc := releaseClient{ | ||||||
|  | 		Client:     client, | ||||||
|  | 		Owner:      p.Repo.Owner, | ||||||
|  | 		Repo:       p.Repo.Name, | ||||||
|  | 		Tag:        filepath.Base(p.Commit.Ref), | ||||||
|  | 		Draft:      p.Config.Draft, | ||||||
|  | 		FileExists: p.Config.FileExists, | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	release, err := rc.buildRelease() | ||||||
|  | 
 | ||||||
|  | 	if err != nil { | ||||||
|  | 		return fmt.Errorf("Failed to create the release. %s", err) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if err := rc.uploadFiles(*release.ID, files); err != nil { | ||||||
|  | 		return fmt.Errorf("Failed to upload the files. %s", err) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
							
								
								
									
										125
									
								
								release.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										125
									
								
								release.go
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,125 @@ | |||||||
|  | package main | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  | 	"fmt" | ||||||
|  | 	"os" | ||||||
|  | 	"path" | ||||||
|  | 
 | ||||||
|  | 	"github.com/google/go-github/github" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | // Release holds ties the drone env data and github client together.
 | ||||||
|  | type releaseClient struct { | ||||||
|  | 	*github.Client | ||||||
|  | 	Owner      string | ||||||
|  | 	Repo       string | ||||||
|  | 	Tag        string | ||||||
|  | 	Draft      bool | ||||||
|  | 	FileExists string | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (rc *releaseClient) buildRelease() (*github.RepositoryRelease, error) { | ||||||
|  | 	// first attempt to get a release by that tag
 | ||||||
|  | 	release, err := rc.getRelease() | ||||||
|  | 
 | ||||||
|  | 	if err != nil && release == nil { | ||||||
|  | 		fmt.Println(err) | ||||||
|  | 	} else if release != nil { | ||||||
|  | 		return release, nil | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	// if no release was found by that tag, create a new one
 | ||||||
|  | 	release, err = rc.newRelease() | ||||||
|  | 
 | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, fmt.Errorf("Failed to retrieve or create a release: %s", err) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return release, nil | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (rc *releaseClient) getRelease() (*github.RepositoryRelease, error) { | ||||||
|  | 	release, _, err := rc.Client.Repositories.GetReleaseByTag(rc.Owner, rc.Repo, rc.Tag) | ||||||
|  | 
 | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, fmt.Errorf("Release %s not found", rc.Tag) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	fmt.Printf("Successfully retrieved %s release\n", rc.Tag) | ||||||
|  | 	return release, nil | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (rc *releaseClient) newRelease() (*github.RepositoryRelease, error) { | ||||||
|  | 	rr := &github.RepositoryRelease{ | ||||||
|  | 		TagName: github.String(rc.Tag), | ||||||
|  | 		Draft:   &rc.Draft, | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	release, _, err := rc.Client.Repositories.CreateRelease(rc.Owner, rc.Repo, rr) | ||||||
|  | 
 | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, fmt.Errorf("Failed to create release: %s", err) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	fmt.Printf("Successfully created %s release\n", rc.Tag) | ||||||
|  | 	return release, nil | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (rc *releaseClient) uploadFiles(id int, files []string) error { | ||||||
|  | 	assets, _, err := rc.Client.Repositories.ListReleaseAssets(rc.Owner, rc.Repo, id, &github.ListOptions{}) | ||||||
|  | 
 | ||||||
|  | 	if err != nil { | ||||||
|  | 		return fmt.Errorf("Failed to fetch existing assets: %s", err) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	var uploadFiles []string | ||||||
|  | 
 | ||||||
|  | files: | ||||||
|  | 	for _, file := range files { | ||||||
|  | 		for _, asset := range assets { | ||||||
|  | 			if *asset.Name == path.Base(file) { | ||||||
|  | 				switch rc.FileExists { | ||||||
|  | 				case "overwrite": | ||||||
|  | 					// do nothing
 | ||||||
|  | 				case "fail": | ||||||
|  | 					return fmt.Errorf("Asset file %s already exists", path.Base(file)) | ||||||
|  | 				case "skip": | ||||||
|  | 					fmt.Printf("Skipping pre-existing %s artifact\n", *asset.Name) | ||||||
|  | 					continue files | ||||||
|  | 				default: | ||||||
|  | 					return fmt.Errorf("Internal error, unkown file_exist value %s", rc.FileExists) | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		uploadFiles = append(uploadFiles, file) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	for _, file := range uploadFiles { | ||||||
|  | 		handle, err := os.Open(file) | ||||||
|  | 
 | ||||||
|  | 		if err != nil { | ||||||
|  | 			return fmt.Errorf("Failed to read %s artifact: %s", file, err) | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		for _, asset := range assets { | ||||||
|  | 			if *asset.Name == path.Base(file) { | ||||||
|  | 				if _, err := rc.Client.Repositories.DeleteReleaseAsset(rc.Owner, rc.Repo, *asset.ID); err != nil { | ||||||
|  | 					return fmt.Errorf("Failed to delete %s artifact: %s", file, err) | ||||||
|  | 				} | ||||||
|  | 
 | ||||||
|  | 				fmt.Printf("Successfully deleted old %s artifact\n", *asset.Name) | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		uo := &github.UploadOptions{Name: path.Base(file)} | ||||||
|  | 
 | ||||||
|  | 		if _, _, err = rc.Client.Repositories.UploadReleaseAsset(rc.Owner, rc.Repo, id, uo, handle); err != nil { | ||||||
|  | 			return fmt.Errorf("Failed to upload %s artifact: %s", file, err) | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		fmt.Printf("Successfully uploaded %s artifact\n", file) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
							
								
								
									
										14
									
								
								types.go
									
									
									
									
									
								
							
							
						
						
									
										14
									
								
								types.go
									
									
									
									
									
								
							| @ -1,14 +0,0 @@ | |||||||
| package main |  | ||||||
| 
 |  | ||||||
| import "github.com/drone/drone-go/drone" |  | ||||||
| 
 |  | ||||||
| // Params are the parameters that the GitHub Release plugin can parse.
 |  | ||||||
| type Params struct { |  | ||||||
| 	BaseURL    string            `json:"base_url"` |  | ||||||
| 	UploadURL  string            `json:"upload_url"` |  | ||||||
| 	APIKey     string            `json:"api_key"` |  | ||||||
| 	Files      drone.StringSlice `json:"files"` |  | ||||||
| 	Checksum   drone.StringSlice `json:"checksum"` |  | ||||||
| 	Draft      bool              `json:"draft"` |  | ||||||
| 	FileExists string            `json:"file_exists"` |  | ||||||
| } |  | ||||||
							
								
								
									
										103
									
								
								utils.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										103
									
								
								utils.go
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,103 @@ | |||||||
|  | package main | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  | 	"crypto/md5" | ||||||
|  | 	"crypto/sha1" | ||||||
|  | 	"crypto/sha256" | ||||||
|  | 	"crypto/sha512" | ||||||
|  | 	"fmt" | ||||||
|  | 	"hash/adler32" | ||||||
|  | 	"hash/crc32" | ||||||
|  | 	"io" | ||||||
|  | 	"io/ioutil" | ||||||
|  | 	"os" | ||||||
|  | 	"os/exec" | ||||||
|  | 	"strconv" | ||||||
|  | 	"strings" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | var ( | ||||||
|  | 	fileExistsValues = map[string]bool{ | ||||||
|  | 		"overwrite": true, | ||||||
|  | 		"fail":      true, | ||||||
|  | 		"skip":      true, | ||||||
|  | 	} | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | func execute(cmd *exec.Cmd) error { | ||||||
|  | 	fmt.Println("+", strings.Join(cmd.Args, " ")) | ||||||
|  | 
 | ||||||
|  | 	cmd.Stderr = os.Stderr | ||||||
|  | 	cmd.Stdin = os.Stdin | ||||||
|  | 
 | ||||||
|  | 	return cmd.Run() | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func checksum(r io.Reader, method string) (string, error) { | ||||||
|  | 	b, err := ioutil.ReadAll(r) | ||||||
|  | 
 | ||||||
|  | 	if err != nil { | ||||||
|  | 		return "", err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	switch method { | ||||||
|  | 	case "md5": | ||||||
|  | 		return fmt.Sprintf("%x", md5.Sum(b)), nil | ||||||
|  | 	case "sha1": | ||||||
|  | 		return fmt.Sprintf("%x", sha1.Sum(b)), nil | ||||||
|  | 	case "sha256": | ||||||
|  | 		return fmt.Sprintf("%x", sha256.Sum256(b)), nil | ||||||
|  | 	case "sha512": | ||||||
|  | 		return fmt.Sprintf("%x", sha512.Sum512(b)), nil | ||||||
|  | 	case "adler32": | ||||||
|  | 		return strconv.FormatUint(uint64(adler32.Checksum(b)), 10), nil | ||||||
|  | 	case "crc32": | ||||||
|  | 		return strconv.FormatUint(uint64(crc32.ChecksumIEEE(b)), 10), nil | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return "", fmt.Errorf("Hashing method %s is not supported", method) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func writeChecksums(files, methods []string) ([]string, error) { | ||||||
|  | 	checksums := make(map[string][]string) | ||||||
|  | 
 | ||||||
|  | 	for _, method := range methods { | ||||||
|  | 		for _, file := range files { | ||||||
|  | 			handle, err := os.Open(file) | ||||||
|  | 
 | ||||||
|  | 			if err != nil { | ||||||
|  | 				return nil, fmt.Errorf("Failed to read %s artifact: %s", file, err) | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
|  | 			hash, err := checksum(handle, method) | ||||||
|  | 
 | ||||||
|  | 			if err != nil { | ||||||
|  | 				return nil, err | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
|  | 			checksums[method] = append(checksums[method], hash, file) | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	for method, results := range checksums { | ||||||
|  | 		filename := method + "sum.txt" | ||||||
|  | 		f, err := os.Create(filename) | ||||||
|  | 
 | ||||||
|  | 		if err != nil { | ||||||
|  | 			return nil, err | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		for i := 0; i < len(results); i += 2 { | ||||||
|  | 			hash := results[i] | ||||||
|  | 			file := results[i+1] | ||||||
|  | 
 | ||||||
|  | 			if _, err := f.WriteString(fmt.Sprintf("%s  %s\n", hash, file)); err != nil { | ||||||
|  | 				return nil, err | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		files = append(files, filename) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return files, nil | ||||||
|  | } | ||||||
							
								
								
									
										47
									
								
								vendor/github.com/Sirupsen/logrus/CHANGELOG.md
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										47
									
								
								vendor/github.com/Sirupsen/logrus/CHANGELOG.md
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,47 @@ | |||||||
|  | # 0.8.7 | ||||||
|  | 
 | ||||||
|  | * logrus/core: fix possible race (#216) | ||||||
|  | * logrus/doc: small typo fixes and doc improvements | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | # 0.8.6 | ||||||
|  | 
 | ||||||
|  | * hooks/raven: allow passing an initialized client | ||||||
|  | 
 | ||||||
|  | # 0.8.5 | ||||||
|  | 
 | ||||||
|  | * logrus/core: revert #208 | ||||||
|  | 
 | ||||||
|  | # 0.8.4 | ||||||
|  | 
 | ||||||
|  | * formatter/text: fix data race (#218) | ||||||
|  | 
 | ||||||
|  | # 0.8.3 | ||||||
|  | 
 | ||||||
|  | * logrus/core: fix entry log level (#208) | ||||||
|  | * logrus/core: improve performance of text formatter by 40% | ||||||
|  | * logrus/core: expose `LevelHooks` type | ||||||
|  | * logrus/core: add support for DragonflyBSD and NetBSD | ||||||
|  | * formatter/text: print structs more verbosely | ||||||
|  | 
 | ||||||
|  | # 0.8.2 | ||||||
|  | 
 | ||||||
|  | * logrus: fix more Fatal family functions | ||||||
|  | 
 | ||||||
|  | # 0.8.1 | ||||||
|  | 
 | ||||||
|  | * logrus: fix not exiting on `Fatalf` and `Fatalln` | ||||||
|  | 
 | ||||||
|  | # 0.8.0 | ||||||
|  | 
 | ||||||
|  | * logrus: defaults to stderr instead of stdout | ||||||
|  | * hooks/sentry: add special field for `*http.Request` | ||||||
|  | * formatter/text: ignore Windows for colors | ||||||
|  | 
 | ||||||
|  | # 0.7.3 | ||||||
|  | 
 | ||||||
|  | * formatter/\*: allow configuration of timestamp layout | ||||||
|  | 
 | ||||||
|  | # 0.7.2 | ||||||
|  | 
 | ||||||
|  | * formatter/text: Add configuration option for time format (#158) | ||||||
							
								
								
									
										21
									
								
								vendor/github.com/Sirupsen/logrus/LICENSE
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								vendor/github.com/Sirupsen/logrus/LICENSE
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,21 @@ | |||||||
|  | The MIT License (MIT) | ||||||
|  | 
 | ||||||
|  | Copyright (c) 2014 Simon Eskildsen | ||||||
|  | 
 | ||||||
|  | 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. | ||||||
							
								
								
									
										357
									
								
								vendor/github.com/Sirupsen/logrus/README.md
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										357
									
								
								vendor/github.com/Sirupsen/logrus/README.md
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,357 @@ | |||||||
|  | # Logrus <img src="http://i.imgur.com/hTeVwmJ.png" width="40" height="40" alt=":walrus:" class="emoji" title=":walrus:"/> [](https://travis-ci.org/Sirupsen/logrus) [][godoc] | ||||||
|  | 
 | ||||||
|  | Logrus is a structured logger for Go (golang), completely API compatible with | ||||||
|  | the standard library logger. [Godoc][godoc]. **Please note the Logrus API is not | ||||||
|  | yet stable (pre 1.0). Logrus itself is completely stable and has been used in | ||||||
|  | many large deployments. The core API is unlikely to change much but please | ||||||
|  | version control your Logrus to make sure you aren't fetching latest `master` on | ||||||
|  | every build.** | ||||||
|  | 
 | ||||||
|  | Nicely color-coded in development (when a TTY is attached, otherwise just | ||||||
|  | plain text): | ||||||
|  | 
 | ||||||
|  |  | ||||||
|  | 
 | ||||||
|  | With `log.Formatter = new(logrus.JSONFormatter)`, for easy parsing by logstash | ||||||
|  | or Splunk: | ||||||
|  | 
 | ||||||
|  | ```json | ||||||
|  | {"animal":"walrus","level":"info","msg":"A group of walrus emerges from the | ||||||
|  | ocean","size":10,"time":"2014-03-10 19:57:38.562264131 -0400 EDT"} | ||||||
|  | 
 | ||||||
|  | {"level":"warning","msg":"The group's number increased tremendously!", | ||||||
|  | "number":122,"omg":true,"time":"2014-03-10 19:57:38.562471297 -0400 EDT"} | ||||||
|  | 
 | ||||||
|  | {"animal":"walrus","level":"info","msg":"A giant walrus appears!", | ||||||
|  | "size":10,"time":"2014-03-10 19:57:38.562500591 -0400 EDT"} | ||||||
|  | 
 | ||||||
|  | {"animal":"walrus","level":"info","msg":"Tremendously sized cow enters the ocean.", | ||||||
|  | "size":9,"time":"2014-03-10 19:57:38.562527896 -0400 EDT"} | ||||||
|  | 
 | ||||||
|  | {"level":"fatal","msg":"The ice breaks!","number":100,"omg":true, | ||||||
|  | "time":"2014-03-10 19:57:38.562543128 -0400 EDT"} | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | With the default `log.Formatter = new(&log.TextFormatter{})` when a TTY is not | ||||||
|  | attached, the output is compatible with the | ||||||
|  | [logfmt](http://godoc.org/github.com/kr/logfmt) format: | ||||||
|  | 
 | ||||||
|  | ```text | ||||||
|  | time="2015-03-26T01:27:38-04:00" level=debug msg="Started observing beach" animal=walrus number=8 | ||||||
|  | time="2015-03-26T01:27:38-04:00" level=info msg="A group of walrus emerges from the ocean" animal=walrus size=10 | ||||||
|  | time="2015-03-26T01:27:38-04:00" level=warning msg="The group's number increased tremendously!" number=122 omg=true | ||||||
|  | time="2015-03-26T01:27:38-04:00" level=debug msg="Temperature changes" temperature=-4 | ||||||
|  | time="2015-03-26T01:27:38-04:00" level=panic msg="It's over 9000!" animal=orca size=9009 | ||||||
|  | time="2015-03-26T01:27:38-04:00" level=fatal msg="The ice breaks!" err=&{0x2082280c0 map[animal:orca size:9009] 2015-03-26 01:27:38.441574009 -0400 EDT panic It's over 9000!} number=100 omg=true | ||||||
|  | exit status 1 | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | #### Example | ||||||
|  | 
 | ||||||
|  | The simplest way to use Logrus is simply the package-level exported logger: | ||||||
|  | 
 | ||||||
|  | ```go | ||||||
|  | package main | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  |   log "github.com/Sirupsen/logrus" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | func main() { | ||||||
|  |   log.WithFields(log.Fields{ | ||||||
|  |     "animal": "walrus", | ||||||
|  |   }).Info("A walrus appears") | ||||||
|  | } | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | Note that it's completely api-compatible with the stdlib logger, so you can | ||||||
|  | replace your `log` imports everywhere with `log "github.com/Sirupsen/logrus"` | ||||||
|  | and you'll now have the flexibility of Logrus. You can customize it all you | ||||||
|  | want: | ||||||
|  | 
 | ||||||
|  | ```go | ||||||
|  | package main | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  |   "os" | ||||||
|  |   log "github.com/Sirupsen/logrus" | ||||||
|  |   "github.com/Sirupsen/logrus/hooks/airbrake" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | func init() { | ||||||
|  |   // Log as JSON instead of the default ASCII formatter. | ||||||
|  |   log.SetFormatter(&log.JSONFormatter{}) | ||||||
|  | 
 | ||||||
|  |   // Use the Airbrake hook to report errors that have Error severity or above to | ||||||
|  |   // an exception tracker. You can create custom hooks, see the Hooks section. | ||||||
|  |   log.AddHook(airbrake.NewHook("https://example.com", "xyz", "development")) | ||||||
|  | 
 | ||||||
|  |   // Output to stderr instead of stdout, could also be a file. | ||||||
|  |   log.SetOutput(os.Stderr) | ||||||
|  | 
 | ||||||
|  |   // Only log the warning severity or above. | ||||||
|  |   log.SetLevel(log.WarnLevel) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func main() { | ||||||
|  |   log.WithFields(log.Fields{ | ||||||
|  |     "animal": "walrus", | ||||||
|  |     "size":   10, | ||||||
|  |   }).Info("A group of walrus emerges from the ocean") | ||||||
|  | 
 | ||||||
|  |   log.WithFields(log.Fields{ | ||||||
|  |     "omg":    true, | ||||||
|  |     "number": 122, | ||||||
|  |   }).Warn("The group's number increased tremendously!") | ||||||
|  | 
 | ||||||
|  |   log.WithFields(log.Fields{ | ||||||
|  |     "omg":    true, | ||||||
|  |     "number": 100, | ||||||
|  |   }).Fatal("The ice breaks!") | ||||||
|  | 
 | ||||||
|  |   // A common pattern is to re-use fields between logging statements by re-using | ||||||
|  |   // the logrus.Entry returned from WithFields() | ||||||
|  |   contextLogger := log.WithFields(log.Fields{ | ||||||
|  |     "common": "this is a common field", | ||||||
|  |     "other": "I also should be logged always", | ||||||
|  |   }) | ||||||
|  | 
 | ||||||
|  |   contextLogger.Info("I'll be logged with common and other field") | ||||||
|  |   contextLogger.Info("Me too") | ||||||
|  | } | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | For more advanced usage such as logging to multiple locations from the same | ||||||
|  | application, you can also create an instance of the `logrus` Logger: | ||||||
|  | 
 | ||||||
|  | ```go | ||||||
|  | package main | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  |   "github.com/Sirupsen/logrus" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | // Create a new instance of the logger. You can have any number of instances. | ||||||
|  | var log = logrus.New() | ||||||
|  | 
 | ||||||
|  | func main() { | ||||||
|  |   // The API for setting attributes is a little different than the package level | ||||||
|  |   // exported logger. See Godoc. | ||||||
|  |   log.Out = os.Stderr | ||||||
|  | 
 | ||||||
|  |   log.WithFields(logrus.Fields{ | ||||||
|  |     "animal": "walrus", | ||||||
|  |     "size":   10, | ||||||
|  |   }).Info("A group of walrus emerges from the ocean") | ||||||
|  | } | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | #### Fields | ||||||
|  | 
 | ||||||
|  | Logrus encourages careful, structured logging though logging fields instead of | ||||||
|  | long, unparseable error messages. For example, instead of: `log.Fatalf("Failed | ||||||
|  | to send event %s to topic %s with key %d")`, you should log the much more | ||||||
|  | discoverable: | ||||||
|  | 
 | ||||||
|  | ```go | ||||||
|  | log.WithFields(log.Fields{ | ||||||
|  |   "event": event, | ||||||
|  |   "topic": topic, | ||||||
|  |   "key": key, | ||||||
|  | }).Fatal("Failed to send event") | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | We've found this API forces you to think about logging in a way that produces | ||||||
|  | much more useful logging messages. We've been in countless situations where just | ||||||
|  | a single added field to a log statement that was already there would've saved us | ||||||
|  | hours. The `WithFields` call is optional. | ||||||
|  | 
 | ||||||
|  | In general, with Logrus using any of the `printf`-family functions should be | ||||||
|  | seen as a hint you should add a field, however, you can still use the | ||||||
|  | `printf`-family functions with Logrus. | ||||||
|  | 
 | ||||||
|  | #### Hooks | ||||||
|  | 
 | ||||||
|  | You can add hooks for logging levels. For example to send errors to an exception | ||||||
|  | tracking service on `Error`, `Fatal` and `Panic`, info to StatsD or log to | ||||||
|  | multiple places simultaneously, e.g. syslog. | ||||||
|  | 
 | ||||||
|  | Logrus comes with [built-in hooks](hooks/). Add those, or your custom hook, in | ||||||
|  | `init`: | ||||||
|  | 
 | ||||||
|  | ```go | ||||||
|  | import ( | ||||||
|  |   log "github.com/Sirupsen/logrus" | ||||||
|  |   "github.com/Sirupsen/logrus/hooks/airbrake" | ||||||
|  |   logrus_syslog "github.com/Sirupsen/logrus/hooks/syslog" | ||||||
|  |   "log/syslog" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | func init() { | ||||||
|  |   log.AddHook(airbrake.NewHook("https://example.com", "xyz", "development")) | ||||||
|  | 
 | ||||||
|  |   hook, err := logrus_syslog.NewSyslogHook("udp", "localhost:514", syslog.LOG_INFO, "") | ||||||
|  |   if err != nil { | ||||||
|  |     log.Error("Unable to connect to local syslog daemon") | ||||||
|  |   } else { | ||||||
|  |     log.AddHook(hook) | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | | Hook  | Description | | ||||||
|  | | ----- | ----------- | | ||||||
|  | | [Airbrake](https://github.com/Sirupsen/logrus/blob/master/hooks/airbrake/airbrake.go) | Send errors to an exception tracking service compatible with the Airbrake API. Uses [`airbrake-go`](https://github.com/tobi/airbrake-go) behind the scenes. | | ||||||
|  | | [Papertrail](https://github.com/Sirupsen/logrus/blob/master/hooks/papertrail/papertrail.go) | Send errors to the Papertrail hosted logging service via UDP. | | ||||||
|  | | [Syslog](https://github.com/Sirupsen/logrus/blob/master/hooks/syslog/syslog.go) | Send errors to remote syslog server. Uses standard library `log/syslog` behind the scenes. | | ||||||
|  | | [BugSnag](https://github.com/Sirupsen/logrus/blob/master/hooks/bugsnag/bugsnag.go) | Send errors to the Bugsnag exception tracking service. | | ||||||
|  | | [Sentry](https://github.com/Sirupsen/logrus/blob/master/hooks/sentry/sentry.go) | Send errors to the Sentry error logging and aggregation service. | | ||||||
|  | | [Hiprus](https://github.com/nubo/hiprus) | Send errors to a channel in hipchat. | | ||||||
|  | | [Logrusly](https://github.com/sebest/logrusly) | Send logs to [Loggly](https://www.loggly.com/) | | ||||||
|  | | [Slackrus](https://github.com/johntdyer/slackrus) | Hook for Slack chat. | | ||||||
|  | | [Journalhook](https://github.com/wercker/journalhook) | Hook for logging to `systemd-journald` | | ||||||
|  | | [Graylog](https://github.com/gemnasium/logrus-hooks/tree/master/graylog) | Hook for logging to [Graylog](http://graylog2.org/) | | ||||||
|  | | [Raygun](https://github.com/squirkle/logrus-raygun-hook) | Hook for logging to [Raygun.io](http://raygun.io/) | | ||||||
|  | | [LFShook](https://github.com/rifflock/lfshook) | Hook for logging to the local filesystem | | ||||||
|  | | [Honeybadger](https://github.com/agonzalezro/logrus_honeybadger) | Hook for sending exceptions to Honeybadger | | ||||||
|  | | [Mail](https://github.com/zbindenren/logrus_mail) | Hook for sending exceptions via mail | | ||||||
|  | | [Rollrus](https://github.com/heroku/rollrus) | Hook for sending errors to rollbar | | ||||||
|  | | [Fluentd](https://github.com/evalphobia/logrus_fluent) | Hook for logging to fluentd | | ||||||
|  | | [Mongodb](https://github.com/weekface/mgorus) | Hook for logging to mongodb | | ||||||
|  | 
 | ||||||
|  | #### Level logging | ||||||
|  | 
 | ||||||
|  | Logrus has six logging levels: Debug, Info, Warning, Error, Fatal and Panic. | ||||||
|  | 
 | ||||||
|  | ```go | ||||||
|  | log.Debug("Useful debugging information.") | ||||||
|  | log.Info("Something noteworthy happened!") | ||||||
|  | log.Warn("You should probably take a look at this.") | ||||||
|  | log.Error("Something failed but I'm not quitting.") | ||||||
|  | // Calls os.Exit(1) after logging | ||||||
|  | log.Fatal("Bye.") | ||||||
|  | // Calls panic() after logging | ||||||
|  | log.Panic("I'm bailing.") | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | You can set the logging level on a `Logger`, then it will only log entries with | ||||||
|  | that severity or anything above it: | ||||||
|  | 
 | ||||||
|  | ```go | ||||||
|  | // Will log anything that is info or above (warn, error, fatal, panic). Default. | ||||||
|  | log.SetLevel(log.InfoLevel) | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | It may be useful to set `log.Level = logrus.DebugLevel` in a debug or verbose | ||||||
|  | environment if your application has that. | ||||||
|  | 
 | ||||||
|  | #### Entries | ||||||
|  | 
 | ||||||
|  | Besides the fields added with `WithField` or `WithFields` some fields are | ||||||
|  | automatically added to all logging events: | ||||||
|  | 
 | ||||||
|  | 1. `time`. The timestamp when the entry was created. | ||||||
|  | 2. `msg`. The logging message passed to `{Info,Warn,Error,Fatal,Panic}` after | ||||||
|  |    the `AddFields` call. E.g. `Failed to send event.` | ||||||
|  | 3. `level`. The logging level. E.g. `info`. | ||||||
|  | 
 | ||||||
|  | #### Environments | ||||||
|  | 
 | ||||||
|  | Logrus has no notion of environment. | ||||||
|  | 
 | ||||||
|  | If you wish for hooks and formatters to only be used in specific environments, | ||||||
|  | you should handle that yourself. For example, if your application has a global | ||||||
|  | variable `Environment`, which is a string representation of the environment you | ||||||
|  | could do: | ||||||
|  | 
 | ||||||
|  | ```go | ||||||
|  | import ( | ||||||
|  |   log "github.com/Sirupsen/logrus" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | init() { | ||||||
|  |   // do something here to set environment depending on an environment variable | ||||||
|  |   // or command-line flag | ||||||
|  |   if Environment == "production" { | ||||||
|  |     log.SetFormatter(&log.JSONFormatter{}) | ||||||
|  |   } else { | ||||||
|  |     // The TextFormatter is default, you don't actually have to do this. | ||||||
|  |     log.SetFormatter(&log.TextFormatter{}) | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | This configuration is how `logrus` was intended to be used, but JSON in | ||||||
|  | production is mostly only useful if you do log aggregation with tools like | ||||||
|  | Splunk or Logstash. | ||||||
|  | 
 | ||||||
|  | #### Formatters | ||||||
|  | 
 | ||||||
|  | The built-in logging formatters are: | ||||||
|  | 
 | ||||||
|  | * `logrus.TextFormatter`. Logs the event in colors if stdout is a tty, otherwise | ||||||
|  |   without colors. | ||||||
|  |   * *Note:* to force colored output when there is no TTY, set the `ForceColors` | ||||||
|  |     field to `true`.  To force no colored output even if there is a TTY  set the | ||||||
|  |     `DisableColors` field to `true` | ||||||
|  | * `logrus.JSONFormatter`. Logs fields as JSON. | ||||||
|  | * `logrus_logstash.LogstashFormatter`. Logs fields as Logstash Events (http://logstash.net). | ||||||
|  | 
 | ||||||
|  |     ```go | ||||||
|  |       logrus.SetFormatter(&logrus_logstash.LogstashFormatter{Type: “application_name"}) | ||||||
|  |     ``` | ||||||
|  | 
 | ||||||
|  | Third party logging formatters: | ||||||
|  | 
 | ||||||
|  | * [`zalgo`](https://github.com/aybabtme/logzalgo): invoking the P͉̫o̳̼̊w̖͈̰͎e̬͔̭͂r͚̼̹̲ ̫͓͉̳͈ō̠͕͖̚f̝͍̠ ͕̲̞͖͑Z̖̫̤̫ͪa͉̬͈̗l͖͎g̳̥o̰̥̅!̣͔̲̻͊̄ ̙̘̦̹̦. | ||||||
|  | 
 | ||||||
|  | You can define your formatter by implementing the `Formatter` interface, | ||||||
|  | requiring a `Format` method. `Format` takes an `*Entry`. `entry.Data` is a | ||||||
|  | `Fields` type (`map[string]interface{}`) with all your fields as well as the | ||||||
|  | default ones (see Entries section above): | ||||||
|  | 
 | ||||||
|  | ```go | ||||||
|  | type MyJSONFormatter struct { | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | log.SetFormatter(new(MyJSONFormatter)) | ||||||
|  | 
 | ||||||
|  | func (f *MyJSONFormatter) Format(entry *Entry) ([]byte, error) { | ||||||
|  |   // Note this doesn't include Time, Level and Message which are available on | ||||||
|  |   // the Entry. Consult `godoc` on information about those fields or read the | ||||||
|  |   // source of the official loggers. | ||||||
|  |   serialized, err := json.Marshal(entry.Data) | ||||||
|  |     if err != nil { | ||||||
|  |       return nil, fmt.Errorf("Failed to marshal fields to JSON, %v", err) | ||||||
|  |     } | ||||||
|  |   return append(serialized, '\n'), nil | ||||||
|  | } | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | #### Logger as an `io.Writer` | ||||||
|  | 
 | ||||||
|  | Logrus can be transformed into an `io.Writer`. That writer is the end of an `io.Pipe` and it is your responsibility to close it. | ||||||
|  | 
 | ||||||
|  | ```go | ||||||
|  | w := logger.Writer() | ||||||
|  | defer w.Close() | ||||||
|  | 
 | ||||||
|  | srv := http.Server{ | ||||||
|  |     // create a stdlib log.Logger that writes to | ||||||
|  |     // logrus.Logger. | ||||||
|  |     ErrorLog: log.New(w, "", 0), | ||||||
|  | } | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | Each line written to that writer will be printed the usual way, using formatters | ||||||
|  | and hooks. The level for those entries is `info`. | ||||||
|  | 
 | ||||||
|  | #### Rotation | ||||||
|  | 
 | ||||||
|  | Log rotation is not provided with Logrus. Log rotation should be done by an | ||||||
|  | external program (like `logrotate(8)`) that can compress and delete old log | ||||||
|  | entries. It should not be a feature of the application-level logger. | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | [godoc]: https://godoc.org/github.com/Sirupsen/logrus | ||||||
							
								
								
									
										26
									
								
								vendor/github.com/Sirupsen/logrus/doc.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								vendor/github.com/Sirupsen/logrus/doc.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,26 @@ | |||||||
|  | /* | ||||||
|  | Package logrus is a structured logger for Go, completely API compatible with the standard library logger. | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | The simplest way to use Logrus is simply the package-level exported logger: | ||||||
|  | 
 | ||||||
|  |   package main | ||||||
|  | 
 | ||||||
|  |   import ( | ||||||
|  |     log "github.com/Sirupsen/logrus" | ||||||
|  |   ) | ||||||
|  | 
 | ||||||
|  |   func main() { | ||||||
|  |     log.WithFields(log.Fields{ | ||||||
|  |       "animal": "walrus", | ||||||
|  |       "number": 1, | ||||||
|  |       "size":   10, | ||||||
|  |     }).Info("A walrus appears") | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  | Output: | ||||||
|  |   time="2015-09-07T08:48:33Z" level=info msg="A walrus appears" animal=walrus number=1 size=10 | ||||||
|  | 
 | ||||||
|  | For a full guide visit https://github.com/Sirupsen/logrus
 | ||||||
|  | */ | ||||||
|  | package logrus | ||||||
							
								
								
									
										264
									
								
								vendor/github.com/Sirupsen/logrus/entry.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										264
									
								
								vendor/github.com/Sirupsen/logrus/entry.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,264 @@ | |||||||
|  | package logrus | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  | 	"bytes" | ||||||
|  | 	"fmt" | ||||||
|  | 	"io" | ||||||
|  | 	"os" | ||||||
|  | 	"time" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | // Defines the key when adding errors using WithError.
 | ||||||
|  | var ErrorKey = "error" | ||||||
|  | 
 | ||||||
|  | // An entry is the final or intermediate Logrus logging entry. It contains all
 | ||||||
|  | // the fields passed with WithField{,s}. It's finally logged when Debug, Info,
 | ||||||
|  | // Warn, Error, Fatal or Panic is called on it. These objects can be reused and
 | ||||||
|  | // passed around as much as you wish to avoid field duplication.
 | ||||||
|  | type Entry struct { | ||||||
|  | 	Logger *Logger | ||||||
|  | 
 | ||||||
|  | 	// Contains all the fields set by the user.
 | ||||||
|  | 	Data Fields | ||||||
|  | 
 | ||||||
|  | 	// Time at which the log entry was created
 | ||||||
|  | 	Time time.Time | ||||||
|  | 
 | ||||||
|  | 	// Level the log entry was logged at: Debug, Info, Warn, Error, Fatal or Panic
 | ||||||
|  | 	Level Level | ||||||
|  | 
 | ||||||
|  | 	// Message passed to Debug, Info, Warn, Error, Fatal or Panic
 | ||||||
|  | 	Message string | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func NewEntry(logger *Logger) *Entry { | ||||||
|  | 	return &Entry{ | ||||||
|  | 		Logger: logger, | ||||||
|  | 		// Default is three fields, give a little extra room
 | ||||||
|  | 		Data: make(Fields, 5), | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Returns a reader for the entry, which is a proxy to the formatter.
 | ||||||
|  | func (entry *Entry) Reader() (*bytes.Buffer, error) { | ||||||
|  | 	serialized, err := entry.Logger.Formatter.Format(entry) | ||||||
|  | 	return bytes.NewBuffer(serialized), err | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Returns the string representation from the reader and ultimately the
 | ||||||
|  | // formatter.
 | ||||||
|  | func (entry *Entry) String() (string, error) { | ||||||
|  | 	reader, err := entry.Reader() | ||||||
|  | 	if err != nil { | ||||||
|  | 		return "", err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return reader.String(), err | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Add an error as single field (using the key defined in ErrorKey) to the Entry.
 | ||||||
|  | func (entry *Entry) WithError(err error) *Entry { | ||||||
|  | 	return entry.WithField(ErrorKey, err) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Add a single field to the Entry.
 | ||||||
|  | func (entry *Entry) WithField(key string, value interface{}) *Entry { | ||||||
|  | 	return entry.WithFields(Fields{key: value}) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Add a map of fields to the Entry.
 | ||||||
|  | func (entry *Entry) WithFields(fields Fields) *Entry { | ||||||
|  | 	data := Fields{} | ||||||
|  | 	for k, v := range entry.Data { | ||||||
|  | 		data[k] = v | ||||||
|  | 	} | ||||||
|  | 	for k, v := range fields { | ||||||
|  | 		data[k] = v | ||||||
|  | 	} | ||||||
|  | 	return &Entry{Logger: entry.Logger, Data: data} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // This function is not declared with a pointer value because otherwise
 | ||||||
|  | // race conditions will occur when using multiple goroutines
 | ||||||
|  | func (entry Entry) log(level Level, msg string) { | ||||||
|  | 	entry.Time = time.Now() | ||||||
|  | 	entry.Level = level | ||||||
|  | 	entry.Message = msg | ||||||
|  | 
 | ||||||
|  | 	if err := entry.Logger.Hooks.Fire(level, &entry); err != nil { | ||||||
|  | 		entry.Logger.mu.Lock() | ||||||
|  | 		fmt.Fprintf(os.Stderr, "Failed to fire hook: %v\n", err) | ||||||
|  | 		entry.Logger.mu.Unlock() | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	reader, err := entry.Reader() | ||||||
|  | 	if err != nil { | ||||||
|  | 		entry.Logger.mu.Lock() | ||||||
|  | 		fmt.Fprintf(os.Stderr, "Failed to obtain reader, %v\n", err) | ||||||
|  | 		entry.Logger.mu.Unlock() | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	entry.Logger.mu.Lock() | ||||||
|  | 	defer entry.Logger.mu.Unlock() | ||||||
|  | 
 | ||||||
|  | 	_, err = io.Copy(entry.Logger.Out, reader) | ||||||
|  | 	if err != nil { | ||||||
|  | 		fmt.Fprintf(os.Stderr, "Failed to write to log, %v\n", err) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	// To avoid Entry#log() returning a value that only would make sense for
 | ||||||
|  | 	// panic() to use in Entry#Panic(), we avoid the allocation by checking
 | ||||||
|  | 	// directly here.
 | ||||||
|  | 	if level <= PanicLevel { | ||||||
|  | 		panic(&entry) | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (entry *Entry) Debug(args ...interface{}) { | ||||||
|  | 	if entry.Logger.Level >= DebugLevel { | ||||||
|  | 		entry.log(DebugLevel, fmt.Sprint(args...)) | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (entry *Entry) Print(args ...interface{}) { | ||||||
|  | 	entry.Info(args...) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (entry *Entry) Info(args ...interface{}) { | ||||||
|  | 	if entry.Logger.Level >= InfoLevel { | ||||||
|  | 		entry.log(InfoLevel, fmt.Sprint(args...)) | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (entry *Entry) Warn(args ...interface{}) { | ||||||
|  | 	if entry.Logger.Level >= WarnLevel { | ||||||
|  | 		entry.log(WarnLevel, fmt.Sprint(args...)) | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (entry *Entry) Warning(args ...interface{}) { | ||||||
|  | 	entry.Warn(args...) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (entry *Entry) Error(args ...interface{}) { | ||||||
|  | 	if entry.Logger.Level >= ErrorLevel { | ||||||
|  | 		entry.log(ErrorLevel, fmt.Sprint(args...)) | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (entry *Entry) Fatal(args ...interface{}) { | ||||||
|  | 	if entry.Logger.Level >= FatalLevel { | ||||||
|  | 		entry.log(FatalLevel, fmt.Sprint(args...)) | ||||||
|  | 	} | ||||||
|  | 	os.Exit(1) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (entry *Entry) Panic(args ...interface{}) { | ||||||
|  | 	if entry.Logger.Level >= PanicLevel { | ||||||
|  | 		entry.log(PanicLevel, fmt.Sprint(args...)) | ||||||
|  | 	} | ||||||
|  | 	panic(fmt.Sprint(args...)) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Entry Printf family functions
 | ||||||
|  | 
 | ||||||
|  | func (entry *Entry) Debugf(format string, args ...interface{}) { | ||||||
|  | 	if entry.Logger.Level >= DebugLevel { | ||||||
|  | 		entry.Debug(fmt.Sprintf(format, args...)) | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (entry *Entry) Infof(format string, args ...interface{}) { | ||||||
|  | 	if entry.Logger.Level >= InfoLevel { | ||||||
|  | 		entry.Info(fmt.Sprintf(format, args...)) | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (entry *Entry) Printf(format string, args ...interface{}) { | ||||||
|  | 	entry.Infof(format, args...) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (entry *Entry) Warnf(format string, args ...interface{}) { | ||||||
|  | 	if entry.Logger.Level >= WarnLevel { | ||||||
|  | 		entry.Warn(fmt.Sprintf(format, args...)) | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (entry *Entry) Warningf(format string, args ...interface{}) { | ||||||
|  | 	entry.Warnf(format, args...) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (entry *Entry) Errorf(format string, args ...interface{}) { | ||||||
|  | 	if entry.Logger.Level >= ErrorLevel { | ||||||
|  | 		entry.Error(fmt.Sprintf(format, args...)) | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (entry *Entry) Fatalf(format string, args ...interface{}) { | ||||||
|  | 	if entry.Logger.Level >= FatalLevel { | ||||||
|  | 		entry.Fatal(fmt.Sprintf(format, args...)) | ||||||
|  | 	} | ||||||
|  | 	os.Exit(1) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (entry *Entry) Panicf(format string, args ...interface{}) { | ||||||
|  | 	if entry.Logger.Level >= PanicLevel { | ||||||
|  | 		entry.Panic(fmt.Sprintf(format, args...)) | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Entry Println family functions
 | ||||||
|  | 
 | ||||||
|  | func (entry *Entry) Debugln(args ...interface{}) { | ||||||
|  | 	if entry.Logger.Level >= DebugLevel { | ||||||
|  | 		entry.Debug(entry.sprintlnn(args...)) | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (entry *Entry) Infoln(args ...interface{}) { | ||||||
|  | 	if entry.Logger.Level >= InfoLevel { | ||||||
|  | 		entry.Info(entry.sprintlnn(args...)) | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (entry *Entry) Println(args ...interface{}) { | ||||||
|  | 	entry.Infoln(args...) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (entry *Entry) Warnln(args ...interface{}) { | ||||||
|  | 	if entry.Logger.Level >= WarnLevel { | ||||||
|  | 		entry.Warn(entry.sprintlnn(args...)) | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (entry *Entry) Warningln(args ...interface{}) { | ||||||
|  | 	entry.Warnln(args...) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (entry *Entry) Errorln(args ...interface{}) { | ||||||
|  | 	if entry.Logger.Level >= ErrorLevel { | ||||||
|  | 		entry.Error(entry.sprintlnn(args...)) | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (entry *Entry) Fatalln(args ...interface{}) { | ||||||
|  | 	if entry.Logger.Level >= FatalLevel { | ||||||
|  | 		entry.Fatal(entry.sprintlnn(args...)) | ||||||
|  | 	} | ||||||
|  | 	os.Exit(1) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (entry *Entry) Panicln(args ...interface{}) { | ||||||
|  | 	if entry.Logger.Level >= PanicLevel { | ||||||
|  | 		entry.Panic(entry.sprintlnn(args...)) | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Sprintlnn => Sprint no newline. This is to get the behavior of how
 | ||||||
|  | // fmt.Sprintln where spaces are always added between operands, regardless of
 | ||||||
|  | // their type. Instead of vendoring the Sprintln implementation to spare a
 | ||||||
|  | // string allocation, we do the simplest thing.
 | ||||||
|  | func (entry *Entry) sprintlnn(args ...interface{}) string { | ||||||
|  | 	msg := fmt.Sprintln(args...) | ||||||
|  | 	return msg[:len(msg)-1] | ||||||
|  | } | ||||||
							
								
								
									
										193
									
								
								vendor/github.com/Sirupsen/logrus/exported.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										193
									
								
								vendor/github.com/Sirupsen/logrus/exported.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,193 @@ | |||||||
|  | package logrus | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  | 	"io" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | var ( | ||||||
|  | 	// std is the name of the standard logger in stdlib `log`
 | ||||||
|  | 	std = New() | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | func StandardLogger() *Logger { | ||||||
|  | 	return std | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // SetOutput sets the standard logger output.
 | ||||||
|  | func SetOutput(out io.Writer) { | ||||||
|  | 	std.mu.Lock() | ||||||
|  | 	defer std.mu.Unlock() | ||||||
|  | 	std.Out = out | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // SetFormatter sets the standard logger formatter.
 | ||||||
|  | func SetFormatter(formatter Formatter) { | ||||||
|  | 	std.mu.Lock() | ||||||
|  | 	defer std.mu.Unlock() | ||||||
|  | 	std.Formatter = formatter | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // SetLevel sets the standard logger level.
 | ||||||
|  | func SetLevel(level Level) { | ||||||
|  | 	std.mu.Lock() | ||||||
|  | 	defer std.mu.Unlock() | ||||||
|  | 	std.Level = level | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // GetLevel returns the standard logger level.
 | ||||||
|  | func GetLevel() Level { | ||||||
|  | 	std.mu.Lock() | ||||||
|  | 	defer std.mu.Unlock() | ||||||
|  | 	return std.Level | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // AddHook adds a hook to the standard logger hooks.
 | ||||||
|  | func AddHook(hook Hook) { | ||||||
|  | 	std.mu.Lock() | ||||||
|  | 	defer std.mu.Unlock() | ||||||
|  | 	std.Hooks.Add(hook) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // WithError creates an entry from the standard logger and adds an error to it, using the value defined in ErrorKey as key.
 | ||||||
|  | func WithError(err error) *Entry { | ||||||
|  | 	return std.WithField(ErrorKey, err) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // WithField creates an entry from the standard logger and adds a field to
 | ||||||
|  | // it. If you want multiple fields, use `WithFields`.
 | ||||||
|  | //
 | ||||||
|  | // Note that it doesn't log until you call Debug, Print, Info, Warn, Fatal
 | ||||||
|  | // or Panic on the Entry it returns.
 | ||||||
|  | func WithField(key string, value interface{}) *Entry { | ||||||
|  | 	return std.WithField(key, value) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // WithFields creates an entry from the standard logger and adds multiple
 | ||||||
|  | // fields to it. This is simply a helper for `WithField`, invoking it
 | ||||||
|  | // once for each field.
 | ||||||
|  | //
 | ||||||
|  | // Note that it doesn't log until you call Debug, Print, Info, Warn, Fatal
 | ||||||
|  | // or Panic on the Entry it returns.
 | ||||||
|  | func WithFields(fields Fields) *Entry { | ||||||
|  | 	return std.WithFields(fields) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Debug logs a message at level Debug on the standard logger.
 | ||||||
|  | func Debug(args ...interface{}) { | ||||||
|  | 	std.Debug(args...) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Print logs a message at level Info on the standard logger.
 | ||||||
|  | func Print(args ...interface{}) { | ||||||
|  | 	std.Print(args...) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Info logs a message at level Info on the standard logger.
 | ||||||
|  | func Info(args ...interface{}) { | ||||||
|  | 	std.Info(args...) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Warn logs a message at level Warn on the standard logger.
 | ||||||
|  | func Warn(args ...interface{}) { | ||||||
|  | 	std.Warn(args...) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Warning logs a message at level Warn on the standard logger.
 | ||||||
|  | func Warning(args ...interface{}) { | ||||||
|  | 	std.Warning(args...) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Error logs a message at level Error on the standard logger.
 | ||||||
|  | func Error(args ...interface{}) { | ||||||
|  | 	std.Error(args...) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Panic logs a message at level Panic on the standard logger.
 | ||||||
|  | func Panic(args ...interface{}) { | ||||||
|  | 	std.Panic(args...) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Fatal logs a message at level Fatal on the standard logger.
 | ||||||
|  | func Fatal(args ...interface{}) { | ||||||
|  | 	std.Fatal(args...) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Debugf logs a message at level Debug on the standard logger.
 | ||||||
|  | func Debugf(format string, args ...interface{}) { | ||||||
|  | 	std.Debugf(format, args...) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Printf logs a message at level Info on the standard logger.
 | ||||||
|  | func Printf(format string, args ...interface{}) { | ||||||
|  | 	std.Printf(format, args...) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Infof logs a message at level Info on the standard logger.
 | ||||||
|  | func Infof(format string, args ...interface{}) { | ||||||
|  | 	std.Infof(format, args...) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Warnf logs a message at level Warn on the standard logger.
 | ||||||
|  | func Warnf(format string, args ...interface{}) { | ||||||
|  | 	std.Warnf(format, args...) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Warningf logs a message at level Warn on the standard logger.
 | ||||||
|  | func Warningf(format string, args ...interface{}) { | ||||||
|  | 	std.Warningf(format, args...) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Errorf logs a message at level Error on the standard logger.
 | ||||||
|  | func Errorf(format string, args ...interface{}) { | ||||||
|  | 	std.Errorf(format, args...) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Panicf logs a message at level Panic on the standard logger.
 | ||||||
|  | func Panicf(format string, args ...interface{}) { | ||||||
|  | 	std.Panicf(format, args...) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Fatalf logs a message at level Fatal on the standard logger.
 | ||||||
|  | func Fatalf(format string, args ...interface{}) { | ||||||
|  | 	std.Fatalf(format, args...) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Debugln logs a message at level Debug on the standard logger.
 | ||||||
|  | func Debugln(args ...interface{}) { | ||||||
|  | 	std.Debugln(args...) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Println logs a message at level Info on the standard logger.
 | ||||||
|  | func Println(args ...interface{}) { | ||||||
|  | 	std.Println(args...) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Infoln logs a message at level Info on the standard logger.
 | ||||||
|  | func Infoln(args ...interface{}) { | ||||||
|  | 	std.Infoln(args...) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Warnln logs a message at level Warn on the standard logger.
 | ||||||
|  | func Warnln(args ...interface{}) { | ||||||
|  | 	std.Warnln(args...) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Warningln logs a message at level Warn on the standard logger.
 | ||||||
|  | func Warningln(args ...interface{}) { | ||||||
|  | 	std.Warningln(args...) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Errorln logs a message at level Error on the standard logger.
 | ||||||
|  | func Errorln(args ...interface{}) { | ||||||
|  | 	std.Errorln(args...) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Panicln logs a message at level Panic on the standard logger.
 | ||||||
|  | func Panicln(args ...interface{}) { | ||||||
|  | 	std.Panicln(args...) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Fatalln logs a message at level Fatal on the standard logger.
 | ||||||
|  | func Fatalln(args ...interface{}) { | ||||||
|  | 	std.Fatalln(args...) | ||||||
|  | } | ||||||
							
								
								
									
										48
									
								
								vendor/github.com/Sirupsen/logrus/formatter.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										48
									
								
								vendor/github.com/Sirupsen/logrus/formatter.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,48 @@ | |||||||
|  | package logrus | ||||||
|  | 
 | ||||||
|  | import "time" | ||||||
|  | 
 | ||||||
|  | const DefaultTimestampFormat = time.RFC3339 | ||||||
|  | 
 | ||||||
|  | // The Formatter interface is used to implement a custom Formatter. It takes an
 | ||||||
|  | // `Entry`. It exposes all the fields, including the default ones:
 | ||||||
|  | //
 | ||||||
|  | // * `entry.Data["msg"]`. The message passed from Info, Warn, Error ..
 | ||||||
|  | // * `entry.Data["time"]`. The timestamp.
 | ||||||
|  | // * `entry.Data["level"]. The level the entry was logged at.
 | ||||||
|  | //
 | ||||||
|  | // Any additional fields added with `WithField` or `WithFields` are also in
 | ||||||
|  | // `entry.Data`. Format is expected to return an array of bytes which are then
 | ||||||
|  | // logged to `logger.Out`.
 | ||||||
|  | type Formatter interface { | ||||||
|  | 	Format(*Entry) ([]byte, error) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // This is to not silently overwrite `time`, `msg` and `level` fields when
 | ||||||
|  | // dumping it. If this code wasn't there doing:
 | ||||||
|  | //
 | ||||||
|  | //  logrus.WithField("level", 1).Info("hello")
 | ||||||
|  | //
 | ||||||
|  | // Would just silently drop the user provided level. Instead with this code
 | ||||||
|  | // it'll logged as:
 | ||||||
|  | //
 | ||||||
|  | //  {"level": "info", "fields.level": 1, "msg": "hello", "time": "..."}
 | ||||||
|  | //
 | ||||||
|  | // It's not exported because it's still using Data in an opinionated way. It's to
 | ||||||
|  | // avoid code duplication between the two default formatters.
 | ||||||
|  | func prefixFieldClashes(data Fields) { | ||||||
|  | 	_, ok := data["time"] | ||||||
|  | 	if ok { | ||||||
|  | 		data["fields.time"] = data["time"] | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	_, ok = data["msg"] | ||||||
|  | 	if ok { | ||||||
|  | 		data["fields.msg"] = data["msg"] | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	_, ok = data["level"] | ||||||
|  | 	if ok { | ||||||
|  | 		data["fields.level"] = data["level"] | ||||||
|  | 	} | ||||||
|  | } | ||||||
							
								
								
									
										34
									
								
								vendor/github.com/Sirupsen/logrus/hooks.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								vendor/github.com/Sirupsen/logrus/hooks.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,34 @@ | |||||||
|  | package logrus | ||||||
|  | 
 | ||||||
|  | // A hook to be fired when logging on the logging levels returned from
 | ||||||
|  | // `Levels()` on your implementation of the interface. Note that this is not
 | ||||||
|  | // fired in a goroutine or a channel with workers, you should handle such
 | ||||||
|  | // functionality yourself if your call is non-blocking and you don't wish for
 | ||||||
|  | // the logging calls for levels returned from `Levels()` to block.
 | ||||||
|  | type Hook interface { | ||||||
|  | 	Levels() []Level | ||||||
|  | 	Fire(*Entry) error | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Internal type for storing the hooks on a logger instance.
 | ||||||
|  | type LevelHooks map[Level][]Hook | ||||||
|  | 
 | ||||||
|  | // Add a hook to an instance of logger. This is called with
 | ||||||
|  | // `log.Hooks.Add(new(MyHook))` where `MyHook` implements the `Hook` interface.
 | ||||||
|  | func (hooks LevelHooks) Add(hook Hook) { | ||||||
|  | 	for _, level := range hook.Levels() { | ||||||
|  | 		hooks[level] = append(hooks[level], hook) | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Fire all the hooks for the passed level. Used by `entry.log` to fire
 | ||||||
|  | // appropriate hooks for a log entry.
 | ||||||
|  | func (hooks LevelHooks) Fire(level Level, entry *Entry) error { | ||||||
|  | 	for _, hook := range hooks[level] { | ||||||
|  | 		if err := hook.Fire(entry); err != nil { | ||||||
|  | 			return err | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
							
								
								
									
										41
									
								
								vendor/github.com/Sirupsen/logrus/json_formatter.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										41
									
								
								vendor/github.com/Sirupsen/logrus/json_formatter.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,41 @@ | |||||||
|  | package logrus | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  | 	"encoding/json" | ||||||
|  | 	"fmt" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | type JSONFormatter struct { | ||||||
|  | 	// TimestampFormat sets the format used for marshaling timestamps.
 | ||||||
|  | 	TimestampFormat string | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (f *JSONFormatter) Format(entry *Entry) ([]byte, error) { | ||||||
|  | 	data := make(Fields, len(entry.Data)+3) | ||||||
|  | 	for k, v := range entry.Data { | ||||||
|  | 		switch v := v.(type) { | ||||||
|  | 		case error: | ||||||
|  | 			// Otherwise errors are ignored by `encoding/json`
 | ||||||
|  | 			// https://github.com/Sirupsen/logrus/issues/137
 | ||||||
|  | 			data[k] = v.Error() | ||||||
|  | 		default: | ||||||
|  | 			data[k] = v | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	prefixFieldClashes(data) | ||||||
|  | 
 | ||||||
|  | 	timestampFormat := f.TimestampFormat | ||||||
|  | 	if timestampFormat == "" { | ||||||
|  | 		timestampFormat = DefaultTimestampFormat | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	data["time"] = entry.Time.Format(timestampFormat) | ||||||
|  | 	data["msg"] = entry.Message | ||||||
|  | 	data["level"] = entry.Level.String() | ||||||
|  | 
 | ||||||
|  | 	serialized, err := json.Marshal(data) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, fmt.Errorf("Failed to marshal fields to JSON, %v", err) | ||||||
|  | 	} | ||||||
|  | 	return append(serialized, '\n'), nil | ||||||
|  | } | ||||||
							
								
								
									
										206
									
								
								vendor/github.com/Sirupsen/logrus/logger.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										206
									
								
								vendor/github.com/Sirupsen/logrus/logger.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,206 @@ | |||||||
|  | package logrus | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  | 	"io" | ||||||
|  | 	"os" | ||||||
|  | 	"sync" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | type Logger struct { | ||||||
|  | 	// The logs are `io.Copy`'d to this in a mutex. It's common to set this to a
 | ||||||
|  | 	// file, or leave it default which is `os.Stderr`. You can also set this to
 | ||||||
|  | 	// something more adventorous, such as logging to Kafka.
 | ||||||
|  | 	Out io.Writer | ||||||
|  | 	// Hooks for the logger instance. These allow firing events based on logging
 | ||||||
|  | 	// levels and log entries. For example, to send errors to an error tracking
 | ||||||
|  | 	// service, log to StatsD or dump the core on fatal errors.
 | ||||||
|  | 	Hooks LevelHooks | ||||||
|  | 	// All log entries pass through the formatter before logged to Out. The
 | ||||||
|  | 	// included formatters are `TextFormatter` and `JSONFormatter` for which
 | ||||||
|  | 	// TextFormatter is the default. In development (when a TTY is attached) it
 | ||||||
|  | 	// logs with colors, but to a file it wouldn't. You can easily implement your
 | ||||||
|  | 	// own that implements the `Formatter` interface, see the `README` or included
 | ||||||
|  | 	// formatters for examples.
 | ||||||
|  | 	Formatter Formatter | ||||||
|  | 	// The logging level the logger should log at. This is typically (and defaults
 | ||||||
|  | 	// to) `logrus.Info`, which allows Info(), Warn(), Error() and Fatal() to be
 | ||||||
|  | 	// logged. `logrus.Debug` is useful in
 | ||||||
|  | 	Level Level | ||||||
|  | 	// Used to sync writing to the log.
 | ||||||
|  | 	mu sync.Mutex | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Creates a new logger. Configuration should be set by changing `Formatter`,
 | ||||||
|  | // `Out` and `Hooks` directly on the default logger instance. You can also just
 | ||||||
|  | // instantiate your own:
 | ||||||
|  | //
 | ||||||
|  | //    var log = &Logger{
 | ||||||
|  | //      Out: os.Stderr,
 | ||||||
|  | //      Formatter: new(JSONFormatter),
 | ||||||
|  | //      Hooks: make(LevelHooks),
 | ||||||
|  | //      Level: logrus.DebugLevel,
 | ||||||
|  | //    }
 | ||||||
|  | //
 | ||||||
|  | // It's recommended to make this a global instance called `log`.
 | ||||||
|  | func New() *Logger { | ||||||
|  | 	return &Logger{ | ||||||
|  | 		Out:       os.Stderr, | ||||||
|  | 		Formatter: new(TextFormatter), | ||||||
|  | 		Hooks:     make(LevelHooks), | ||||||
|  | 		Level:     InfoLevel, | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Adds a field to the log entry, note that you it doesn't log until you call
 | ||||||
|  | // Debug, Print, Info, Warn, Fatal or Panic. It only creates a log entry.
 | ||||||
|  | // If you want multiple fields, use `WithFields`.
 | ||||||
|  | func (logger *Logger) WithField(key string, value interface{}) *Entry { | ||||||
|  | 	return NewEntry(logger).WithField(key, value) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Adds a struct of fields to the log entry. All it does is call `WithField` for
 | ||||||
|  | // each `Field`.
 | ||||||
|  | func (logger *Logger) WithFields(fields Fields) *Entry { | ||||||
|  | 	return NewEntry(logger).WithFields(fields) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (logger *Logger) Debugf(format string, args ...interface{}) { | ||||||
|  | 	if logger.Level >= DebugLevel { | ||||||
|  | 		NewEntry(logger).Debugf(format, args...) | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (logger *Logger) Infof(format string, args ...interface{}) { | ||||||
|  | 	if logger.Level >= InfoLevel { | ||||||
|  | 		NewEntry(logger).Infof(format, args...) | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (logger *Logger) Printf(format string, args ...interface{}) { | ||||||
|  | 	NewEntry(logger).Printf(format, args...) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (logger *Logger) Warnf(format string, args ...interface{}) { | ||||||
|  | 	if logger.Level >= WarnLevel { | ||||||
|  | 		NewEntry(logger).Warnf(format, args...) | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (logger *Logger) Warningf(format string, args ...interface{}) { | ||||||
|  | 	if logger.Level >= WarnLevel { | ||||||
|  | 		NewEntry(logger).Warnf(format, args...) | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (logger *Logger) Errorf(format string, args ...interface{}) { | ||||||
|  | 	if logger.Level >= ErrorLevel { | ||||||
|  | 		NewEntry(logger).Errorf(format, args...) | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (logger *Logger) Fatalf(format string, args ...interface{}) { | ||||||
|  | 	if logger.Level >= FatalLevel { | ||||||
|  | 		NewEntry(logger).Fatalf(format, args...) | ||||||
|  | 	} | ||||||
|  | 	os.Exit(1) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (logger *Logger) Panicf(format string, args ...interface{}) { | ||||||
|  | 	if logger.Level >= PanicLevel { | ||||||
|  | 		NewEntry(logger).Panicf(format, args...) | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (logger *Logger) Debug(args ...interface{}) { | ||||||
|  | 	if logger.Level >= DebugLevel { | ||||||
|  | 		NewEntry(logger).Debug(args...) | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (logger *Logger) Info(args ...interface{}) { | ||||||
|  | 	if logger.Level >= InfoLevel { | ||||||
|  | 		NewEntry(logger).Info(args...) | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (logger *Logger) Print(args ...interface{}) { | ||||||
|  | 	NewEntry(logger).Info(args...) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (logger *Logger) Warn(args ...interface{}) { | ||||||
|  | 	if logger.Level >= WarnLevel { | ||||||
|  | 		NewEntry(logger).Warn(args...) | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (logger *Logger) Warning(args ...interface{}) { | ||||||
|  | 	if logger.Level >= WarnLevel { | ||||||
|  | 		NewEntry(logger).Warn(args...) | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (logger *Logger) Error(args ...interface{}) { | ||||||
|  | 	if logger.Level >= ErrorLevel { | ||||||
|  | 		NewEntry(logger).Error(args...) | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (logger *Logger) Fatal(args ...interface{}) { | ||||||
|  | 	if logger.Level >= FatalLevel { | ||||||
|  | 		NewEntry(logger).Fatal(args...) | ||||||
|  | 	} | ||||||
|  | 	os.Exit(1) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (logger *Logger) Panic(args ...interface{}) { | ||||||
|  | 	if logger.Level >= PanicLevel { | ||||||
|  | 		NewEntry(logger).Panic(args...) | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (logger *Logger) Debugln(args ...interface{}) { | ||||||
|  | 	if logger.Level >= DebugLevel { | ||||||
|  | 		NewEntry(logger).Debugln(args...) | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (logger *Logger) Infoln(args ...interface{}) { | ||||||
|  | 	if logger.Level >= InfoLevel { | ||||||
|  | 		NewEntry(logger).Infoln(args...) | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (logger *Logger) Println(args ...interface{}) { | ||||||
|  | 	NewEntry(logger).Println(args...) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (logger *Logger) Warnln(args ...interface{}) { | ||||||
|  | 	if logger.Level >= WarnLevel { | ||||||
|  | 		NewEntry(logger).Warnln(args...) | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (logger *Logger) Warningln(args ...interface{}) { | ||||||
|  | 	if logger.Level >= WarnLevel { | ||||||
|  | 		NewEntry(logger).Warnln(args...) | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (logger *Logger) Errorln(args ...interface{}) { | ||||||
|  | 	if logger.Level >= ErrorLevel { | ||||||
|  | 		NewEntry(logger).Errorln(args...) | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (logger *Logger) Fatalln(args ...interface{}) { | ||||||
|  | 	if logger.Level >= FatalLevel { | ||||||
|  | 		NewEntry(logger).Fatalln(args...) | ||||||
|  | 	} | ||||||
|  | 	os.Exit(1) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (logger *Logger) Panicln(args ...interface{}) { | ||||||
|  | 	if logger.Level >= PanicLevel { | ||||||
|  | 		NewEntry(logger).Panicln(args...) | ||||||
|  | 	} | ||||||
|  | } | ||||||
							
								
								
									
										98
									
								
								vendor/github.com/Sirupsen/logrus/logrus.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										98
									
								
								vendor/github.com/Sirupsen/logrus/logrus.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,98 @@ | |||||||
|  | package logrus | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  | 	"fmt" | ||||||
|  | 	"log" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | // Fields type, used to pass to `WithFields`.
 | ||||||
|  | type Fields map[string]interface{} | ||||||
|  | 
 | ||||||
|  | // Level type
 | ||||||
|  | type Level uint8 | ||||||
|  | 
 | ||||||
|  | // Convert the Level to a string. E.g. PanicLevel becomes "panic".
 | ||||||
|  | func (level Level) String() string { | ||||||
|  | 	switch level { | ||||||
|  | 	case DebugLevel: | ||||||
|  | 		return "debug" | ||||||
|  | 	case InfoLevel: | ||||||
|  | 		return "info" | ||||||
|  | 	case WarnLevel: | ||||||
|  | 		return "warning" | ||||||
|  | 	case ErrorLevel: | ||||||
|  | 		return "error" | ||||||
|  | 	case FatalLevel: | ||||||
|  | 		return "fatal" | ||||||
|  | 	case PanicLevel: | ||||||
|  | 		return "panic" | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return "unknown" | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ParseLevel takes a string level and returns the Logrus log level constant.
 | ||||||
|  | func ParseLevel(lvl string) (Level, error) { | ||||||
|  | 	switch lvl { | ||||||
|  | 	case "panic": | ||||||
|  | 		return PanicLevel, nil | ||||||
|  | 	case "fatal": | ||||||
|  | 		return FatalLevel, nil | ||||||
|  | 	case "error": | ||||||
|  | 		return ErrorLevel, nil | ||||||
|  | 	case "warn", "warning": | ||||||
|  | 		return WarnLevel, nil | ||||||
|  | 	case "info": | ||||||
|  | 		return InfoLevel, nil | ||||||
|  | 	case "debug": | ||||||
|  | 		return DebugLevel, nil | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	var l Level | ||||||
|  | 	return l, fmt.Errorf("not a valid logrus Level: %q", lvl) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // These are the different logging levels. You can set the logging level to log
 | ||||||
|  | // on your instance of logger, obtained with `logrus.New()`.
 | ||||||
|  | const ( | ||||||
|  | 	// PanicLevel level, highest level of severity. Logs and then calls panic with the
 | ||||||
|  | 	// message passed to Debug, Info, ...
 | ||||||
|  | 	PanicLevel Level = iota | ||||||
|  | 	// FatalLevel level. Logs and then calls `os.Exit(1)`. It will exit even if the
 | ||||||
|  | 	// logging level is set to Panic.
 | ||||||
|  | 	FatalLevel | ||||||
|  | 	// ErrorLevel level. Logs. Used for errors that should definitely be noted.
 | ||||||
|  | 	// Commonly used for hooks to send errors to an error tracking service.
 | ||||||
|  | 	ErrorLevel | ||||||
|  | 	// WarnLevel level. Non-critical entries that deserve eyes.
 | ||||||
|  | 	WarnLevel | ||||||
|  | 	// InfoLevel level. General operational entries about what's going on inside the
 | ||||||
|  | 	// application.
 | ||||||
|  | 	InfoLevel | ||||||
|  | 	// DebugLevel level. Usually only enabled when debugging. Very verbose logging.
 | ||||||
|  | 	DebugLevel | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | // Won't compile if StdLogger can't be realized by a log.Logger
 | ||||||
|  | var ( | ||||||
|  | 	_ StdLogger = &log.Logger{} | ||||||
|  | 	_ StdLogger = &Entry{} | ||||||
|  | 	_ StdLogger = &Logger{} | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | // StdLogger is what your logrus-enabled library should take, that way
 | ||||||
|  | // it'll accept a stdlib logger and a logrus logger. There's no standard
 | ||||||
|  | // interface, this is the closest we get, unfortunately.
 | ||||||
|  | type StdLogger interface { | ||||||
|  | 	Print(...interface{}) | ||||||
|  | 	Printf(string, ...interface{}) | ||||||
|  | 	Println(...interface{}) | ||||||
|  | 
 | ||||||
|  | 	Fatal(...interface{}) | ||||||
|  | 	Fatalf(string, ...interface{}) | ||||||
|  | 	Fatalln(...interface{}) | ||||||
|  | 
 | ||||||
|  | 	Panic(...interface{}) | ||||||
|  | 	Panicf(string, ...interface{}) | ||||||
|  | 	Panicln(...interface{}) | ||||||
|  | } | ||||||
							
								
								
									
										9
									
								
								vendor/github.com/Sirupsen/logrus/terminal_bsd.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								vendor/github.com/Sirupsen/logrus/terminal_bsd.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,9 @@ | |||||||
|  | // +build darwin freebsd openbsd netbsd dragonfly
 | ||||||
|  | 
 | ||||||
|  | package logrus | ||||||
|  | 
 | ||||||
|  | import "syscall" | ||||||
|  | 
 | ||||||
|  | const ioctlReadTermios = syscall.TIOCGETA | ||||||
|  | 
 | ||||||
|  | type Termios syscall.Termios | ||||||
							
								
								
									
										12
									
								
								vendor/github.com/Sirupsen/logrus/terminal_linux.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								vendor/github.com/Sirupsen/logrus/terminal_linux.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,12 @@ | |||||||
|  | // Based on ssh/terminal:
 | ||||||
|  | // Copyright 2013 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 logrus | ||||||
|  | 
 | ||||||
|  | import "syscall" | ||||||
|  | 
 | ||||||
|  | const ioctlReadTermios = syscall.TCGETS | ||||||
|  | 
 | ||||||
|  | type Termios syscall.Termios | ||||||
							
								
								
									
										21
									
								
								vendor/github.com/Sirupsen/logrus/terminal_notwindows.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								vendor/github.com/Sirupsen/logrus/terminal_notwindows.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,21 @@ | |||||||
|  | // Based on ssh/terminal:
 | ||||||
|  | // Copyright 2011 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 linux darwin freebsd openbsd netbsd dragonfly
 | ||||||
|  | 
 | ||||||
|  | package logrus | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  | 	"syscall" | ||||||
|  | 	"unsafe" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | // IsTerminal returns true if the given file descriptor is a terminal.
 | ||||||
|  | func IsTerminal() bool { | ||||||
|  | 	fd := syscall.Stdout | ||||||
|  | 	var termios Termios | ||||||
|  | 	_, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), ioctlReadTermios, uintptr(unsafe.Pointer(&termios)), 0, 0, 0) | ||||||
|  | 	return err == 0 | ||||||
|  | } | ||||||
							
								
								
									
										27
									
								
								vendor/github.com/Sirupsen/logrus/terminal_windows.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								vendor/github.com/Sirupsen/logrus/terminal_windows.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,27 @@ | |||||||
|  | // Based on ssh/terminal:
 | ||||||
|  | // Copyright 2011 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 windows
 | ||||||
|  | 
 | ||||||
|  | package logrus | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  | 	"syscall" | ||||||
|  | 	"unsafe" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | var kernel32 = syscall.NewLazyDLL("kernel32.dll") | ||||||
|  | 
 | ||||||
|  | var ( | ||||||
|  | 	procGetConsoleMode = kernel32.NewProc("GetConsoleMode") | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | // IsTerminal returns true if the given file descriptor is a terminal.
 | ||||||
|  | func IsTerminal() bool { | ||||||
|  | 	fd := syscall.Stdout | ||||||
|  | 	var st uint32 | ||||||
|  | 	r, _, e := syscall.Syscall(procGetConsoleMode.Addr(), 2, uintptr(fd), uintptr(unsafe.Pointer(&st)), 0) | ||||||
|  | 	return r != 0 && e == 0 | ||||||
|  | } | ||||||
							
								
								
									
										159
									
								
								vendor/github.com/Sirupsen/logrus/text_formatter.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										159
									
								
								vendor/github.com/Sirupsen/logrus/text_formatter.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,159 @@ | |||||||
|  | package logrus | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  | 	"bytes" | ||||||
|  | 	"fmt" | ||||||
|  | 	"runtime" | ||||||
|  | 	"sort" | ||||||
|  | 	"strings" | ||||||
|  | 	"time" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | const ( | ||||||
|  | 	nocolor = 0 | ||||||
|  | 	red     = 31 | ||||||
|  | 	green   = 32 | ||||||
|  | 	yellow  = 33 | ||||||
|  | 	blue    = 34 | ||||||
|  | 	gray    = 37 | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | var ( | ||||||
|  | 	baseTimestamp time.Time | ||||||
|  | 	isTerminal    bool | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | func init() { | ||||||
|  | 	baseTimestamp = time.Now() | ||||||
|  | 	isTerminal = IsTerminal() | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func miniTS() int { | ||||||
|  | 	return int(time.Since(baseTimestamp) / time.Second) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | type TextFormatter struct { | ||||||
|  | 	// Set to true to bypass checking for a TTY before outputting colors.
 | ||||||
|  | 	ForceColors bool | ||||||
|  | 
 | ||||||
|  | 	// Force disabling colors.
 | ||||||
|  | 	DisableColors bool | ||||||
|  | 
 | ||||||
|  | 	// Disable timestamp logging. useful when output is redirected to logging
 | ||||||
|  | 	// system that already adds timestamps.
 | ||||||
|  | 	DisableTimestamp bool | ||||||
|  | 
 | ||||||
|  | 	// Enable logging the full timestamp when a TTY is attached instead of just
 | ||||||
|  | 	// the time passed since beginning of execution.
 | ||||||
|  | 	FullTimestamp bool | ||||||
|  | 
 | ||||||
|  | 	// TimestampFormat to use for display when a full timestamp is printed
 | ||||||
|  | 	TimestampFormat string | ||||||
|  | 
 | ||||||
|  | 	// The fields are sorted by default for a consistent output. For applications
 | ||||||
|  | 	// that log extremely frequently and don't use the JSON formatter this may not
 | ||||||
|  | 	// be desired.
 | ||||||
|  | 	DisableSorting bool | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (f *TextFormatter) Format(entry *Entry) ([]byte, error) { | ||||||
|  | 	var keys []string = make([]string, 0, len(entry.Data)) | ||||||
|  | 	for k := range entry.Data { | ||||||
|  | 		keys = append(keys, k) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if !f.DisableSorting { | ||||||
|  | 		sort.Strings(keys) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	b := &bytes.Buffer{} | ||||||
|  | 
 | ||||||
|  | 	prefixFieldClashes(entry.Data) | ||||||
|  | 
 | ||||||
|  | 	isColorTerminal := isTerminal && (runtime.GOOS != "windows") | ||||||
|  | 	isColored := (f.ForceColors || isColorTerminal) && !f.DisableColors | ||||||
|  | 
 | ||||||
|  | 	timestampFormat := f.TimestampFormat | ||||||
|  | 	if timestampFormat == "" { | ||||||
|  | 		timestampFormat = DefaultTimestampFormat | ||||||
|  | 	} | ||||||
|  | 	if isColored { | ||||||
|  | 		f.printColored(b, entry, keys, timestampFormat) | ||||||
|  | 	} else { | ||||||
|  | 		if !f.DisableTimestamp { | ||||||
|  | 			f.appendKeyValue(b, "time", entry.Time.Format(timestampFormat)) | ||||||
|  | 		} | ||||||
|  | 		f.appendKeyValue(b, "level", entry.Level.String()) | ||||||
|  | 		f.appendKeyValue(b, "msg", entry.Message) | ||||||
|  | 		for _, key := range keys { | ||||||
|  | 			f.appendKeyValue(b, key, entry.Data[key]) | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	b.WriteByte('\n') | ||||||
|  | 	return b.Bytes(), nil | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (f *TextFormatter) printColored(b *bytes.Buffer, entry *Entry, keys []string, timestampFormat string) { | ||||||
|  | 	var levelColor int | ||||||
|  | 	switch entry.Level { | ||||||
|  | 	case DebugLevel: | ||||||
|  | 		levelColor = gray | ||||||
|  | 	case WarnLevel: | ||||||
|  | 		levelColor = yellow | ||||||
|  | 	case ErrorLevel, FatalLevel, PanicLevel: | ||||||
|  | 		levelColor = red | ||||||
|  | 	default: | ||||||
|  | 		levelColor = blue | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	levelText := strings.ToUpper(entry.Level.String())[0:4] | ||||||
|  | 
 | ||||||
|  | 	if !f.FullTimestamp { | ||||||
|  | 		fmt.Fprintf(b, "\x1b[%dm%s\x1b[0m[%04d] %-44s ", levelColor, levelText, miniTS(), entry.Message) | ||||||
|  | 	} else { | ||||||
|  | 		fmt.Fprintf(b, "\x1b[%dm%s\x1b[0m[%s] %-44s ", levelColor, levelText, entry.Time.Format(timestampFormat), entry.Message) | ||||||
|  | 	} | ||||||
|  | 	for _, k := range keys { | ||||||
|  | 		v := entry.Data[k] | ||||||
|  | 		fmt.Fprintf(b, " \x1b[%dm%s\x1b[0m=%+v", levelColor, k, v) | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func needsQuoting(text string) bool { | ||||||
|  | 	for _, ch := range text { | ||||||
|  | 		if !((ch >= 'a' && ch <= 'z') || | ||||||
|  | 			(ch >= 'A' && ch <= 'Z') || | ||||||
|  | 			(ch >= '0' && ch <= '9') || | ||||||
|  | 			ch == '-' || ch == '.') { | ||||||
|  | 			return false | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	return true | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (f *TextFormatter) appendKeyValue(b *bytes.Buffer, key string, value interface{}) { | ||||||
|  | 
 | ||||||
|  | 	b.WriteString(key) | ||||||
|  | 	b.WriteByte('=') | ||||||
|  | 
 | ||||||
|  | 	switch value := value.(type) { | ||||||
|  | 	case string: | ||||||
|  | 		if needsQuoting(value) { | ||||||
|  | 			b.WriteString(value) | ||||||
|  | 		} else { | ||||||
|  | 			fmt.Fprintf(b, "%q", value) | ||||||
|  | 		} | ||||||
|  | 	case error: | ||||||
|  | 		errmsg := value.Error() | ||||||
|  | 		if needsQuoting(errmsg) { | ||||||
|  | 			b.WriteString(errmsg) | ||||||
|  | 		} else { | ||||||
|  | 			fmt.Fprintf(b, "%q", value) | ||||||
|  | 		} | ||||||
|  | 	default: | ||||||
|  | 		fmt.Fprint(b, value) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	b.WriteByte(' ') | ||||||
|  | } | ||||||
							
								
								
									
										31
									
								
								vendor/github.com/Sirupsen/logrus/writer.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								vendor/github.com/Sirupsen/logrus/writer.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,31 @@ | |||||||
|  | package logrus | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  | 	"bufio" | ||||||
|  | 	"io" | ||||||
|  | 	"runtime" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | func (logger *Logger) Writer() *io.PipeWriter { | ||||||
|  | 	reader, writer := io.Pipe() | ||||||
|  | 
 | ||||||
|  | 	go logger.writerScanner(reader) | ||||||
|  | 	runtime.SetFinalizer(writer, writerFinalizer) | ||||||
|  | 
 | ||||||
|  | 	return writer | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (logger *Logger) writerScanner(reader *io.PipeReader) { | ||||||
|  | 	scanner := bufio.NewScanner(reader) | ||||||
|  | 	for scanner.Scan() { | ||||||
|  | 		logger.Print(scanner.Text()) | ||||||
|  | 	} | ||||||
|  | 	if err := scanner.Err(); err != nil { | ||||||
|  | 		logger.Errorf("Error while reading from Writer: %s", err) | ||||||
|  | 	} | ||||||
|  | 	reader.Close() | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func writerFinalizer(writer *io.PipeWriter) { | ||||||
|  | 	writer.Close() | ||||||
|  | } | ||||||
							
								
								
									
										31
									
								
								vendor/github.com/golang/protobuf/LICENSE
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								vendor/github.com/golang/protobuf/LICENSE
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,31 @@ | |||||||
|  | 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. | ||||||
|  | 
 | ||||||
							
								
								
									
										43
									
								
								vendor/github.com/golang/protobuf/proto/Makefile
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										43
									
								
								vendor/github.com/golang/protobuf/proto/Makefile
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,43 @@ | |||||||
|  | # 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.
 | ||||||
|  | 
 | ||||||
|  | install: | ||||||
|  | 	go install | ||||||
|  | 
 | ||||||
|  | test: install generate-test-pbs | ||||||
|  | 	go test | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | generate-test-pbs: | ||||||
|  | 	make install | ||||||
|  | 	make -C testdata | ||||||
|  | 	protoc --go_out=Mtestdata/test.proto=github.com/golang/protobuf/proto/testdata:. proto3_proto/proto3.proto | ||||||
|  | 	make | ||||||
							
								
								
									
										223
									
								
								vendor/github.com/golang/protobuf/proto/clone.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										223
									
								
								vendor/github.com/golang/protobuf/proto/clone.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,223 @@ | |||||||
|  | // 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 ( | ||||||
|  | 	"log" | ||||||
|  | 	"reflect" | ||||||
|  | 	"strings" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | // Clone returns a deep copy of a protocol buffer.
 | ||||||
|  | func Clone(pb Message) Message { | ||||||
|  | 	in := reflect.ValueOf(pb) | ||||||
|  | 	if in.IsNil() { | ||||||
|  | 		return pb | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	out := reflect.New(in.Type().Elem()) | ||||||
|  | 	// out is empty so a merge is a deep copy.
 | ||||||
|  | 	mergeStruct(out.Elem(), in.Elem()) | ||||||
|  | 	return out.Interface().(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) { | ||||||
|  | 	in := reflect.ValueOf(src) | ||||||
|  | 	out := reflect.ValueOf(dst) | ||||||
|  | 	if out.IsNil() { | ||||||
|  | 		panic("proto: nil destination") | ||||||
|  | 	} | ||||||
|  | 	if in.Type() != out.Type() { | ||||||
|  | 		// Explicit test prior to mergeStruct so that mistyped nils will fail
 | ||||||
|  | 		panic("proto: type mismatch") | ||||||
|  | 	} | ||||||
|  | 	if in.IsNil() { | ||||||
|  | 		// Merging nil into non-nil is a quiet no-op
 | ||||||
|  | 		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, ok := in.Addr().Interface().(extendableProto); ok { | ||||||
|  | 		emOut := out.Addr().Interface().(extendableProto) | ||||||
|  | 		mergeExtension(emOut.ExtensionMap(), emIn.ExtensionMap()) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	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 | ||||||
|  | 	} | ||||||
|  | } | ||||||
							
								
								
									
										867
									
								
								vendor/github.com/golang/protobuf/proto/decode.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										867
									
								
								vendor/github.com/golang/protobuf/proto/decode.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,867 @@ | |||||||
|  | // 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" | ||||||
|  | 	"os" | ||||||
|  | 	"reflect" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | // 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") | ||||||
|  | 
 | ||||||
|  | // The fundamental decoders that interpret bytes on the wire.
 | ||||||
|  | // Those that take integer types all return uint64 and are
 | ||||||
|  | // therefore of type valueDecoder.
 | ||||||
|  | 
 | ||||||
|  | // 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) { | ||||||
|  | 	// x, n already 0
 | ||||||
|  | 	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 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // 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) { | ||||||
|  | 	// x, err already 0
 | ||||||
|  | 
 | ||||||
|  | 	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 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // 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 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // These are not ValueDecoders: they produce an array of bytes or a string.
 | ||||||
|  | // bytes, embedded messages
 | ||||||
|  | 
 | ||||||
|  | // 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 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Skip the next item in the buffer. Its wire type is decoded and presented as an argument.
 | ||||||
|  | // If the protocol buffer has extensions, and the field matches, add it as an extension.
 | ||||||
|  | // Otherwise, if the XXX_unrecognized field exists, append the skipped data there.
 | ||||||
|  | func (o *Buffer) skipAndSave(t reflect.Type, tag, wire int, base structPointer, unrecField field) error { | ||||||
|  | 	oi := o.index | ||||||
|  | 
 | ||||||
|  | 	err := o.skip(t, tag, wire) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if !unrecField.IsValid() { | ||||||
|  | 		return nil | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	ptr := structPointer_Bytes(base, unrecField) | ||||||
|  | 
 | ||||||
|  | 	// Add the skipped field to struct field
 | ||||||
|  | 	obuf := o.buf | ||||||
|  | 
 | ||||||
|  | 	o.buf = *ptr | ||||||
|  | 	o.EncodeVarint(uint64(tag<<3 | wire)) | ||||||
|  | 	*ptr = append(o.buf, obuf[oi:o.index]...) | ||||||
|  | 
 | ||||||
|  | 	o.buf = obuf | ||||||
|  | 
 | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Skip the next item in the buffer. Its wire type is decoded and presented as an argument.
 | ||||||
|  | func (o *Buffer) skip(t reflect.Type, tag, wire int) error { | ||||||
|  | 
 | ||||||
|  | 	var u uint64 | ||||||
|  | 	var err error | ||||||
|  | 
 | ||||||
|  | 	switch wire { | ||||||
|  | 	case WireVarint: | ||||||
|  | 		_, err = o.DecodeVarint() | ||||||
|  | 	case WireFixed64: | ||||||
|  | 		_, err = o.DecodeFixed64() | ||||||
|  | 	case WireBytes: | ||||||
|  | 		_, err = o.DecodeRawBytes(false) | ||||||
|  | 	case WireFixed32: | ||||||
|  | 		_, err = o.DecodeFixed32() | ||||||
|  | 	case WireStartGroup: | ||||||
|  | 		for { | ||||||
|  | 			u, err = o.DecodeVarint() | ||||||
|  | 			if err != nil { | ||||||
|  | 				break | ||||||
|  | 			} | ||||||
|  | 			fwire := int(u & 0x7) | ||||||
|  | 			if fwire == WireEndGroup { | ||||||
|  | 				break | ||||||
|  | 			} | ||||||
|  | 			ftag := int(u >> 3) | ||||||
|  | 			err = o.skip(t, ftag, fwire) | ||||||
|  | 			if err != nil { | ||||||
|  | 				break | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 	default: | ||||||
|  | 		err = fmt.Errorf("proto: can't skip unknown wire type %d for %s", wire, t) | ||||||
|  | 	} | ||||||
|  | 	return err | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Unmarshaler is the interface representing objects that can
 | ||||||
|  | // unmarshal themselves.  The method should reset the receiver before
 | ||||||
|  | // decoding starts.  The argument points to data that may be
 | ||||||
|  | // overwritten, so implementations should not keep references to the
 | ||||||
|  | // buffer.
 | ||||||
|  | type Unmarshaler interface { | ||||||
|  | 	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() | ||||||
|  | 	return UnmarshalMerge(buf, 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 the object can unmarshal itself, let it.
 | ||||||
|  | 	if u, ok := pb.(Unmarshaler); ok { | ||||||
|  | 		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.
 | ||||||
|  | func (p *Buffer) DecodeGroup(pb Message) error { | ||||||
|  | 	typ, base, err := getbase(pb) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return err | ||||||
|  | 	} | ||||||
|  | 	return p.unmarshalType(typ.Elem(), GetProperties(typ.Elem()), true, base) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // 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.
 | ||||||
|  | func (p *Buffer) Unmarshal(pb Message) error { | ||||||
|  | 	// If the object can unmarshal itself, let it.
 | ||||||
|  | 	if u, ok := pb.(Unmarshaler); ok { | ||||||
|  | 		err := u.Unmarshal(p.buf[p.index:]) | ||||||
|  | 		p.index = len(p.buf) | ||||||
|  | 		return err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	typ, base, err := getbase(pb) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	err = p.unmarshalType(typ.Elem(), GetProperties(typ.Elem()), false, base) | ||||||
|  | 
 | ||||||
|  | 	if collectStats { | ||||||
|  | 		stats.Decode++ | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return err | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // unmarshalType does the work of unmarshaling a structure.
 | ||||||
|  | func (o *Buffer) unmarshalType(st reflect.Type, prop *StructProperties, is_group bool, base structPointer) error { | ||||||
|  | 	var state errorState | ||||||
|  | 	required, reqFields := prop.reqCount, uint64(0) | ||||||
|  | 
 | ||||||
|  | 	var err error | ||||||
|  | 	for err == nil && o.index < len(o.buf) { | ||||||
|  | 		oi := o.index | ||||||
|  | 		var u uint64 | ||||||
|  | 		u, err = o.DecodeVarint() | ||||||
|  | 		if err != nil { | ||||||
|  | 			break | ||||||
|  | 		} | ||||||
|  | 		wire := int(u & 0x7) | ||||||
|  | 		if wire == WireEndGroup { | ||||||
|  | 			if is_group { | ||||||
|  | 				return nil // input is satisfied
 | ||||||
|  | 			} | ||||||
|  | 			return fmt.Errorf("proto: %s: wiretype end group for non-group", st) | ||||||
|  | 		} | ||||||
|  | 		tag := int(u >> 3) | ||||||
|  | 		if tag <= 0 { | ||||||
|  | 			return fmt.Errorf("proto: %s: illegal tag %d (wire type %d)", st, tag, wire) | ||||||
|  | 		} | ||||||
|  | 		fieldnum, ok := prop.decoderTags.get(tag) | ||||||
|  | 		if !ok { | ||||||
|  | 			// Maybe it's an extension?
 | ||||||
|  | 			if prop.extendable { | ||||||
|  | 				if e := structPointer_Interface(base, st).(extendableProto); isExtensionField(e, int32(tag)) { | ||||||
|  | 					if err = o.skip(st, tag, wire); err == nil { | ||||||
|  | 						ext := e.ExtensionMap()[int32(tag)] // may be missing
 | ||||||
|  | 						ext.enc = append(ext.enc, o.buf[oi:o.index]...) | ||||||
|  | 						e.ExtensionMap()[int32(tag)] = ext | ||||||
|  | 					} | ||||||
|  | 					continue | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
|  | 			// Maybe it's a oneof?
 | ||||||
|  | 			if prop.oneofUnmarshaler != nil { | ||||||
|  | 				m := structPointer_Interface(base, st).(Message) | ||||||
|  | 				// First return value indicates whether tag is a oneof field.
 | ||||||
|  | 				ok, err = prop.oneofUnmarshaler(m, tag, wire, o) | ||||||
|  | 				if err == ErrInternalBadWireType { | ||||||
|  | 					// Map the error to something more descriptive.
 | ||||||
|  | 					// Do the formatting here to save generated code space.
 | ||||||
|  | 					err = fmt.Errorf("bad wiretype for oneof field in %T", m) | ||||||
|  | 				} | ||||||
|  | 				if ok { | ||||||
|  | 					continue | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
|  | 			err = o.skipAndSave(st, tag, wire, base, prop.unrecField) | ||||||
|  | 			continue | ||||||
|  | 		} | ||||||
|  | 		p := prop.Prop[fieldnum] | ||||||
|  | 
 | ||||||
|  | 		if p.dec == nil { | ||||||
|  | 			fmt.Fprintf(os.Stderr, "proto: no protobuf decoder for %s.%s\n", st, st.Field(fieldnum).Name) | ||||||
|  | 			continue | ||||||
|  | 		} | ||||||
|  | 		dec := p.dec | ||||||
|  | 		if wire != WireStartGroup && wire != p.WireType { | ||||||
|  | 			if wire == WireBytes && p.packedDec != nil { | ||||||
|  | 				// a packable field
 | ||||||
|  | 				dec = p.packedDec | ||||||
|  | 			} else { | ||||||
|  | 				err = fmt.Errorf("proto: bad wiretype for field %s.%s: got wiretype %d, want %d", st, st.Field(fieldnum).Name, wire, p.WireType) | ||||||
|  | 				continue | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 		decErr := dec(o, p, base) | ||||||
|  | 		if decErr != nil && !state.shouldContinue(decErr, p) { | ||||||
|  | 			err = decErr | ||||||
|  | 		} | ||||||
|  | 		if err == nil && p.Required { | ||||||
|  | 			// Successfully decoded a required field.
 | ||||||
|  | 			if tag <= 64 { | ||||||
|  | 				// use bitmap for fields 1-64 to catch field reuse.
 | ||||||
|  | 				var mask uint64 = 1 << uint64(tag-1) | ||||||
|  | 				if reqFields&mask == 0 { | ||||||
|  | 					// new required field
 | ||||||
|  | 					reqFields |= mask | ||||||
|  | 					required-- | ||||||
|  | 				} | ||||||
|  | 			} else { | ||||||
|  | 				// This is imprecise. It can be fooled by a required field
 | ||||||
|  | 				// with a tag > 64 that is encoded twice; that's very rare.
 | ||||||
|  | 				// A fully correct implementation would require allocating
 | ||||||
|  | 				// a data structure, which we would like to avoid.
 | ||||||
|  | 				required-- | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	if err == nil { | ||||||
|  | 		if is_group { | ||||||
|  | 			return io.ErrUnexpectedEOF | ||||||
|  | 		} | ||||||
|  | 		if state.err != nil { | ||||||
|  | 			return state.err | ||||||
|  | 		} | ||||||
|  | 		if required > 0 { | ||||||
|  | 			// Not enough information to determine the exact field. If we use extra
 | ||||||
|  | 			// CPU, we could determine the field only if the missing required field
 | ||||||
|  | 			// has a tag <= 64 and we check reqFields.
 | ||||||
|  | 			return &RequiredNotSetError{"{Unknown}"} | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	return err | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Individual type decoders
 | ||||||
|  | // For each,
 | ||||||
|  | //	u is the decoded value,
 | ||||||
|  | //	v is a pointer to the field (pointer) in the struct
 | ||||||
|  | 
 | ||||||
|  | // Sizes of the pools to allocate inside the Buffer.
 | ||||||
|  | // The goal is modest amortization and allocation
 | ||||||
|  | // on at least 16-byte boundaries.
 | ||||||
|  | const ( | ||||||
|  | 	boolPoolSize   = 16 | ||||||
|  | 	uint32PoolSize = 8 | ||||||
|  | 	uint64PoolSize = 4 | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | // Decode a bool.
 | ||||||
|  | func (o *Buffer) dec_bool(p *Properties, base structPointer) error { | ||||||
|  | 	u, err := p.valDec(o) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return err | ||||||
|  | 	} | ||||||
|  | 	if len(o.bools) == 0 { | ||||||
|  | 		o.bools = make([]bool, boolPoolSize) | ||||||
|  | 	} | ||||||
|  | 	o.bools[0] = u != 0 | ||||||
|  | 	*structPointer_Bool(base, p.field) = &o.bools[0] | ||||||
|  | 	o.bools = o.bools[1:] | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (o *Buffer) dec_proto3_bool(p *Properties, base structPointer) error { | ||||||
|  | 	u, err := p.valDec(o) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return err | ||||||
|  | 	} | ||||||
|  | 	*structPointer_BoolVal(base, p.field) = u != 0 | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Decode an int32.
 | ||||||
|  | func (o *Buffer) dec_int32(p *Properties, base structPointer) error { | ||||||
|  | 	u, err := p.valDec(o) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return err | ||||||
|  | 	} | ||||||
|  | 	word32_Set(structPointer_Word32(base, p.field), o, uint32(u)) | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (o *Buffer) dec_proto3_int32(p *Properties, base structPointer) error { | ||||||
|  | 	u, err := p.valDec(o) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return err | ||||||
|  | 	} | ||||||
|  | 	word32Val_Set(structPointer_Word32Val(base, p.field), uint32(u)) | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Decode an int64.
 | ||||||
|  | func (o *Buffer) dec_int64(p *Properties, base structPointer) error { | ||||||
|  | 	u, err := p.valDec(o) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return err | ||||||
|  | 	} | ||||||
|  | 	word64_Set(structPointer_Word64(base, p.field), o, u) | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (o *Buffer) dec_proto3_int64(p *Properties, base structPointer) error { | ||||||
|  | 	u, err := p.valDec(o) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return err | ||||||
|  | 	} | ||||||
|  | 	word64Val_Set(structPointer_Word64Val(base, p.field), o, u) | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Decode a string.
 | ||||||
|  | func (o *Buffer) dec_string(p *Properties, base structPointer) error { | ||||||
|  | 	s, err := o.DecodeStringBytes() | ||||||
|  | 	if err != nil { | ||||||
|  | 		return err | ||||||
|  | 	} | ||||||
|  | 	*structPointer_String(base, p.field) = &s | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (o *Buffer) dec_proto3_string(p *Properties, base structPointer) error { | ||||||
|  | 	s, err := o.DecodeStringBytes() | ||||||
|  | 	if err != nil { | ||||||
|  | 		return err | ||||||
|  | 	} | ||||||
|  | 	*structPointer_StringVal(base, p.field) = s | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Decode a slice of bytes ([]byte).
 | ||||||
|  | func (o *Buffer) dec_slice_byte(p *Properties, base structPointer) error { | ||||||
|  | 	b, err := o.DecodeRawBytes(true) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return err | ||||||
|  | 	} | ||||||
|  | 	*structPointer_Bytes(base, p.field) = b | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Decode a slice of bools ([]bool).
 | ||||||
|  | func (o *Buffer) dec_slice_bool(p *Properties, base structPointer) error { | ||||||
|  | 	u, err := p.valDec(o) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return err | ||||||
|  | 	} | ||||||
|  | 	v := structPointer_BoolSlice(base, p.field) | ||||||
|  | 	*v = append(*v, u != 0) | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Decode a slice of bools ([]bool) in packed format.
 | ||||||
|  | func (o *Buffer) dec_slice_packed_bool(p *Properties, base structPointer) error { | ||||||
|  | 	v := structPointer_BoolSlice(base, p.field) | ||||||
|  | 
 | ||||||
|  | 	nn, err := o.DecodeVarint() | ||||||
|  | 	if err != nil { | ||||||
|  | 		return err | ||||||
|  | 	} | ||||||
|  | 	nb := int(nn) // number of bytes of encoded bools
 | ||||||
|  | 	fin := o.index + nb | ||||||
|  | 	if fin < o.index { | ||||||
|  | 		return errOverflow | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	y := *v | ||||||
|  | 	for o.index < fin { | ||||||
|  | 		u, err := p.valDec(o) | ||||||
|  | 		if err != nil { | ||||||
|  | 			return err | ||||||
|  | 		} | ||||||
|  | 		y = append(y, u != 0) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	*v = y | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Decode a slice of int32s ([]int32).
 | ||||||
|  | func (o *Buffer) dec_slice_int32(p *Properties, base structPointer) error { | ||||||
|  | 	u, err := p.valDec(o) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return err | ||||||
|  | 	} | ||||||
|  | 	structPointer_Word32Slice(base, p.field).Append(uint32(u)) | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Decode a slice of int32s ([]int32) in packed format.
 | ||||||
|  | func (o *Buffer) dec_slice_packed_int32(p *Properties, base structPointer) error { | ||||||
|  | 	v := structPointer_Word32Slice(base, p.field) | ||||||
|  | 
 | ||||||
|  | 	nn, err := o.DecodeVarint() | ||||||
|  | 	if err != nil { | ||||||
|  | 		return err | ||||||
|  | 	} | ||||||
|  | 	nb := int(nn) // number of bytes of encoded int32s
 | ||||||
|  | 
 | ||||||
|  | 	fin := o.index + nb | ||||||
|  | 	if fin < o.index { | ||||||
|  | 		return errOverflow | ||||||
|  | 	} | ||||||
|  | 	for o.index < fin { | ||||||
|  | 		u, err := p.valDec(o) | ||||||
|  | 		if err != nil { | ||||||
|  | 			return err | ||||||
|  | 		} | ||||||
|  | 		v.Append(uint32(u)) | ||||||
|  | 	} | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Decode a slice of int64s ([]int64).
 | ||||||
|  | func (o *Buffer) dec_slice_int64(p *Properties, base structPointer) error { | ||||||
|  | 	u, err := p.valDec(o) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	structPointer_Word64Slice(base, p.field).Append(u) | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Decode a slice of int64s ([]int64) in packed format.
 | ||||||
|  | func (o *Buffer) dec_slice_packed_int64(p *Properties, base structPointer) error { | ||||||
|  | 	v := structPointer_Word64Slice(base, p.field) | ||||||
|  | 
 | ||||||
|  | 	nn, err := o.DecodeVarint() | ||||||
|  | 	if err != nil { | ||||||
|  | 		return err | ||||||
|  | 	} | ||||||
|  | 	nb := int(nn) // number of bytes of encoded int64s
 | ||||||
|  | 
 | ||||||
|  | 	fin := o.index + nb | ||||||
|  | 	if fin < o.index { | ||||||
|  | 		return errOverflow | ||||||
|  | 	} | ||||||
|  | 	for o.index < fin { | ||||||
|  | 		u, err := p.valDec(o) | ||||||
|  | 		if err != nil { | ||||||
|  | 			return err | ||||||
|  | 		} | ||||||
|  | 		v.Append(u) | ||||||
|  | 	} | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Decode a slice of strings ([]string).
 | ||||||
|  | func (o *Buffer) dec_slice_string(p *Properties, base structPointer) error { | ||||||
|  | 	s, err := o.DecodeStringBytes() | ||||||
|  | 	if err != nil { | ||||||
|  | 		return err | ||||||
|  | 	} | ||||||
|  | 	v := structPointer_StringSlice(base, p.field) | ||||||
|  | 	*v = append(*v, s) | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Decode a slice of slice of bytes ([][]byte).
 | ||||||
|  | func (o *Buffer) dec_slice_slice_byte(p *Properties, base structPointer) error { | ||||||
|  | 	b, err := o.DecodeRawBytes(true) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return err | ||||||
|  | 	} | ||||||
|  | 	v := structPointer_BytesSlice(base, p.field) | ||||||
|  | 	*v = append(*v, b) | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Decode a map field.
 | ||||||
|  | func (o *Buffer) dec_new_map(p *Properties, base structPointer) error { | ||||||
|  | 	raw, err := o.DecodeRawBytes(false) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return err | ||||||
|  | 	} | ||||||
|  | 	oi := o.index       // index at the end of this map entry
 | ||||||
|  | 	o.index -= len(raw) // move buffer back to start of map entry
 | ||||||
|  | 
 | ||||||
|  | 	mptr := structPointer_NewAt(base, p.field, p.mtype) // *map[K]V
 | ||||||
|  | 	if mptr.Elem().IsNil() { | ||||||
|  | 		mptr.Elem().Set(reflect.MakeMap(mptr.Type().Elem())) | ||||||
|  | 	} | ||||||
|  | 	v := mptr.Elem() // map[K]V
 | ||||||
|  | 
 | ||||||
|  | 	// Prepare addressable doubly-indirect placeholders for the key and value types.
 | ||||||
|  | 	// See enc_new_map for why.
 | ||||||
|  | 	keyptr := reflect.New(reflect.PtrTo(p.mtype.Key())).Elem() // addressable *K
 | ||||||
|  | 	keybase := toStructPointer(keyptr.Addr())                  // **K
 | ||||||
|  | 
 | ||||||
|  | 	var valbase structPointer | ||||||
|  | 	var valptr reflect.Value | ||||||
|  | 	switch p.mtype.Elem().Kind() { | ||||||
|  | 	case reflect.Slice: | ||||||
|  | 		// []byte
 | ||||||
|  | 		var dummy []byte | ||||||
|  | 		valptr = reflect.ValueOf(&dummy)  // *[]byte
 | ||||||
|  | 		valbase = toStructPointer(valptr) // *[]byte
 | ||||||
|  | 	case reflect.Ptr: | ||||||
|  | 		// message; valptr is **Msg; need to allocate the intermediate pointer
 | ||||||
|  | 		valptr = reflect.New(reflect.PtrTo(p.mtype.Elem())).Elem() // addressable *V
 | ||||||
|  | 		valptr.Set(reflect.New(valptr.Type().Elem())) | ||||||
|  | 		valbase = toStructPointer(valptr) | ||||||
|  | 	default: | ||||||
|  | 		// everything else
 | ||||||
|  | 		valptr = reflect.New(reflect.PtrTo(p.mtype.Elem())).Elem() // addressable *V
 | ||||||
|  | 		valbase = toStructPointer(valptr.Addr())                   // **V
 | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	// Decode.
 | ||||||
|  | 	// This parses a restricted wire format, namely the encoding of a message
 | ||||||
|  | 	// with two fields. See enc_new_map for the format.
 | ||||||
|  | 	for o.index < oi { | ||||||
|  | 		// tagcode for key and value properties are always a single byte
 | ||||||
|  | 		// because they have tags 1 and 2.
 | ||||||
|  | 		tagcode := o.buf[o.index] | ||||||
|  | 		o.index++ | ||||||
|  | 		switch tagcode { | ||||||
|  | 		case p.mkeyprop.tagcode[0]: | ||||||
|  | 			if err := p.mkeyprop.dec(o, p.mkeyprop, keybase); err != nil { | ||||||
|  | 				return err | ||||||
|  | 			} | ||||||
|  | 		case p.mvalprop.tagcode[0]: | ||||||
|  | 			if err := p.mvalprop.dec(o, p.mvalprop, valbase); err != nil { | ||||||
|  | 				return err | ||||||
|  | 			} | ||||||
|  | 		default: | ||||||
|  | 			// TODO: Should we silently skip this instead?
 | ||||||
|  | 			return fmt.Errorf("proto: bad map data tag %d", raw[0]) | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	keyelem, valelem := keyptr.Elem(), valptr.Elem() | ||||||
|  | 	if !keyelem.IsValid() || !valelem.IsValid() { | ||||||
|  | 		// We did not decode the key or the value in the map entry.
 | ||||||
|  | 		// Either way, it's an invalid map entry.
 | ||||||
|  | 		return fmt.Errorf("proto: bad map data: missing key/val") | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	v.SetMapIndex(keyelem, valelem) | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Decode a group.
 | ||||||
|  | func (o *Buffer) dec_struct_group(p *Properties, base structPointer) error { | ||||||
|  | 	bas := structPointer_GetStructPointer(base, p.field) | ||||||
|  | 	if structPointer_IsNil(bas) { | ||||||
|  | 		// allocate new nested message
 | ||||||
|  | 		bas = toStructPointer(reflect.New(p.stype)) | ||||||
|  | 		structPointer_SetStructPointer(base, p.field, bas) | ||||||
|  | 	} | ||||||
|  | 	return o.unmarshalType(p.stype, p.sprop, true, bas) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Decode an embedded message.
 | ||||||
|  | func (o *Buffer) dec_struct_message(p *Properties, base structPointer) (err error) { | ||||||
|  | 	raw, e := o.DecodeRawBytes(false) | ||||||
|  | 	if e != nil { | ||||||
|  | 		return e | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	bas := structPointer_GetStructPointer(base, p.field) | ||||||
|  | 	if structPointer_IsNil(bas) { | ||||||
|  | 		// allocate new nested message
 | ||||||
|  | 		bas = toStructPointer(reflect.New(p.stype)) | ||||||
|  | 		structPointer_SetStructPointer(base, p.field, bas) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	// If the object can unmarshal itself, let it.
 | ||||||
|  | 	if p.isUnmarshaler { | ||||||
|  | 		iv := structPointer_Interface(bas, p.stype) | ||||||
|  | 		return iv.(Unmarshaler).Unmarshal(raw) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	obuf := o.buf | ||||||
|  | 	oi := o.index | ||||||
|  | 	o.buf = raw | ||||||
|  | 	o.index = 0 | ||||||
|  | 
 | ||||||
|  | 	err = o.unmarshalType(p.stype, p.sprop, false, bas) | ||||||
|  | 	o.buf = obuf | ||||||
|  | 	o.index = oi | ||||||
|  | 
 | ||||||
|  | 	return err | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Decode a slice of embedded messages.
 | ||||||
|  | func (o *Buffer) dec_slice_struct_message(p *Properties, base structPointer) error { | ||||||
|  | 	return o.dec_slice_struct(p, false, base) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Decode a slice of embedded groups.
 | ||||||
|  | func (o *Buffer) dec_slice_struct_group(p *Properties, base structPointer) error { | ||||||
|  | 	return o.dec_slice_struct(p, true, base) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Decode a slice of structs ([]*struct).
 | ||||||
|  | func (o *Buffer) dec_slice_struct(p *Properties, is_group bool, base structPointer) error { | ||||||
|  | 	v := reflect.New(p.stype) | ||||||
|  | 	bas := toStructPointer(v) | ||||||
|  | 	structPointer_StructPointerSlice(base, p.field).Append(bas) | ||||||
|  | 
 | ||||||
|  | 	if is_group { | ||||||
|  | 		err := o.unmarshalType(p.stype, p.sprop, is_group, bas) | ||||||
|  | 		return err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	raw, err := o.DecodeRawBytes(false) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	// If the object can unmarshal itself, let it.
 | ||||||
|  | 	if p.isUnmarshaler { | ||||||
|  | 		iv := v.Interface() | ||||||
|  | 		return iv.(Unmarshaler).Unmarshal(raw) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	obuf := o.buf | ||||||
|  | 	oi := o.index | ||||||
|  | 	o.buf = raw | ||||||
|  | 	o.index = 0 | ||||||
|  | 
 | ||||||
|  | 	err = o.unmarshalType(p.stype, p.sprop, is_group, bas) | ||||||
|  | 
 | ||||||
|  | 	o.buf = obuf | ||||||
|  | 	o.index = oi | ||||||
|  | 
 | ||||||
|  | 	return err | ||||||
|  | } | ||||||
							
								
								
									
										1325
									
								
								vendor/github.com/golang/protobuf/proto/encode.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1325
									
								
								vendor/github.com/golang/protobuf/proto/encode.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										276
									
								
								vendor/github.com/golang/protobuf/proto/equal.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										276
									
								
								vendor/github.com/golang/protobuf/proto/equal.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,276 @@ | |||||||
|  | // 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 (a "bytes" field, | ||||||
|  |     although represented by []byte, is not a repeated field) | ||||||
|  |   - 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. | ||||||
|  |   - 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 | ||||||
|  | 			} | ||||||
|  | 			b1, ok := f1.Interface().(raw) | ||||||
|  | 			if ok { | ||||||
|  | 				b2 := f2.Interface().(raw) | ||||||
|  | 				// RawMessage
 | ||||||
|  | 				if !bytes.Equal(b1.Bytes(), b2.Bytes()) { | ||||||
|  | 					return false | ||||||
|  | 				} | ||||||
|  | 				continue | ||||||
|  | 			} | ||||||
|  | 			f1, f2 = f1.Elem(), f2.Elem() | ||||||
|  | 		} | ||||||
|  | 		if !equalAny(f1, f2, sprop.Prop[i]) { | ||||||
|  | 			return false | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if em1 := v1.FieldByName("XXX_extensions"); em1.IsValid() { | ||||||
|  | 		em2 := v2.FieldByName("XXX_extensions") | ||||||
|  | 		if !equalExtensions(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() | ||||||
|  | 	if !bytes.Equal(u1, u2) { | ||||||
|  | 		return false | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return true | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // 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: | ||||||
|  | 		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.
 | ||||||
|  | // em1 and em2 are extension maps.
 | ||||||
|  | func equalExtensions(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, m2 := e1.value, e2.value | ||||||
|  | 
 | ||||||
|  | 		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 { | ||||||
|  | 			log.Printf("proto: don't know how to compare extension %d of %v", extNum, base) | ||||||
|  | 			continue | ||||||
|  | 		} | ||||||
|  | 		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 | ||||||
|  | } | ||||||
							
								
								
									
										399
									
								
								vendor/github.com/golang/protobuf/proto/extensions.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										399
									
								
								vendor/github.com/golang/protobuf/proto/extensions.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,399 @@ | |||||||
|  | // 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" | ||||||
|  | 	"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 that may be extended.
 | ||||||
|  | type extendableProto interface { | ||||||
|  | 	Message | ||||||
|  | 	ExtensionRangeArray() []ExtensionRange | ||||||
|  | 	ExtensionMap() map[int32]Extension | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | var extendableProtoType = reflect.TypeOf((*extendableProto)(nil)).Elem() | ||||||
|  | 
 | ||||||
|  | // 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
 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 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 interface{} | ||||||
|  | 	enc   []byte | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // SetRawExtension is for testing only.
 | ||||||
|  | func SetRawExtension(base extendableProto, id int32, b []byte) { | ||||||
|  | 	base.ExtensionMap()[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 { | ||||||
|  | 	// Check the extended type.
 | ||||||
|  | 	if a, b := reflect.TypeOf(pb), reflect.TypeOf(extension.ExtendedType); a != b { | ||||||
|  | 		return errors.New("proto: bad extended type; " + b.String() + " does not extend " + a.String()) | ||||||
|  | 	} | ||||||
|  | 	// 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 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // encodeExtensionMap encodes any unmarshaled (unencoded) extensions in m.
 | ||||||
|  | func encodeExtensionMap(m map[int32]Extension) error { | ||||||
|  | 	for k, e := range m { | ||||||
|  | 		if e.value == nil || e.desc == nil { | ||||||
|  | 			// Extension is only in its encoded form.
 | ||||||
|  | 			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.
 | ||||||
|  | 
 | ||||||
|  | 		et := reflect.TypeOf(e.desc.ExtensionType) | ||||||
|  | 		props := extensionProperties(e.desc) | ||||||
|  | 
 | ||||||
|  | 		p := NewBuffer(nil) | ||||||
|  | 		// If e.value has type T, the encoder expects a *struct{ X T }.
 | ||||||
|  | 		// Pass a *T with a zero field and hope it all works out.
 | ||||||
|  | 		x := reflect.New(et) | ||||||
|  | 		x.Elem().Set(reflect.ValueOf(e.value)) | ||||||
|  | 		if err := props.enc(p, props, toStructPointer(x)); err != nil { | ||||||
|  | 			return err | ||||||
|  | 		} | ||||||
|  | 		e.enc = p.buf | ||||||
|  | 		m[k] = e | ||||||
|  | 	} | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func sizeExtensionMap(m map[int32]Extension) (n int) { | ||||||
|  | 	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.
 | ||||||
|  | 
 | ||||||
|  | 		et := reflect.TypeOf(e.desc.ExtensionType) | ||||||
|  | 		props := extensionProperties(e.desc) | ||||||
|  | 
 | ||||||
|  | 		// If e.value has type T, the encoder expects a *struct{ X T }.
 | ||||||
|  | 		// Pass a *T with a zero field and hope it all works out.
 | ||||||
|  | 		x := reflect.New(et) | ||||||
|  | 		x.Elem().Set(reflect.ValueOf(e.value)) | ||||||
|  | 		n += props.size(props, toStructPointer(x)) | ||||||
|  | 	} | ||||||
|  | 	return | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // HasExtension returns whether the given extension is present in pb.
 | ||||||
|  | func HasExtension(pb extendableProto, extension *ExtensionDesc) bool { | ||||||
|  | 	// TODO: Check types, field numbers, etc.?
 | ||||||
|  | 	_, ok := pb.ExtensionMap()[extension.Field] | ||||||
|  | 	return ok | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ClearExtension removes the given extension from pb.
 | ||||||
|  | func ClearExtension(pb extendableProto, extension *ExtensionDesc) { | ||||||
|  | 	// TODO: Check types, field numbers, etc.?
 | ||||||
|  | 	delete(pb.ExtensionMap(), extension.Field) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // GetExtension parses and returns the given extension of pb.
 | ||||||
|  | // If the extension is not present and has no default value it returns ErrMissingExtension.
 | ||||||
|  | func GetExtension(pb extendableProto, extension *ExtensionDesc) (interface{}, error) { | ||||||
|  | 	if err := checkExtensionTypes(pb, extension); err != nil { | ||||||
|  | 		return nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	emap := pb.ExtensionMap() | ||||||
|  | 	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 e.value, 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 = v | ||||||
|  | 	e.desc = extension | ||||||
|  | 	e.enc = nil | ||||||
|  | 	emap[extension.Field] = e | ||||||
|  | 	return 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) { | ||||||
|  | 	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) { | ||||||
|  | 	o := NewBuffer(b) | ||||||
|  | 
 | ||||||
|  | 	t := reflect.TypeOf(extension.ExtensionType) | ||||||
|  | 
 | ||||||
|  | 	props := extensionProperties(extension) | ||||||
|  | 
 | ||||||
|  | 	// t is a pointer to a struct, pointer to basic type or a slice.
 | ||||||
|  | 	// Allocate a "field" to store the pointer/slice itself; the
 | ||||||
|  | 	// pointer/slice will be stored here. We pass
 | ||||||
|  | 	// the address of this field to props.dec.
 | ||||||
|  | 	// This passes a zero field and a *t and lets props.dec
 | ||||||
|  | 	// interpret it as a *struct{ x t }.
 | ||||||
|  | 	value := reflect.New(t).Elem() | ||||||
|  | 
 | ||||||
|  | 	for { | ||||||
|  | 		// Discard wire type and field number varint. It isn't needed.
 | ||||||
|  | 		if _, err := o.DecodeVarint(); err != nil { | ||||||
|  | 			return nil, err | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		if err := props.dec(o, props, toStructPointer(value.Addr())); err != nil { | ||||||
|  | 			return nil, err | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		if o.index >= len(o.buf) { | ||||||
|  | 			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, ok := pb.(extendableProto) | ||||||
|  | 	if !ok { | ||||||
|  | 		err = errors.New("proto: not an extendable proto") | ||||||
|  | 		return | ||||||
|  | 	} | ||||||
|  | 	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 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // SetExtension sets the specified extension of pb to the specified value.
 | ||||||
|  | func SetExtension(pb extendableProto, extension *ExtensionDesc, value interface{}) error { | ||||||
|  | 	if err := checkExtensionTypes(pb, extension); err != nil { | ||||||
|  | 		return err | ||||||
|  | 	} | ||||||
|  | 	typ := reflect.TypeOf(extension.ExtensionType) | ||||||
|  | 	if typ != reflect.TypeOf(value) { | ||||||
|  | 		return errors.New("proto: bad extension value type") | ||||||
|  | 	} | ||||||
|  | 	// 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) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	pb.ExtensionMap()[extension.Field] = Extension{desc: extension, value: value} | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // 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()] | ||||||
|  | } | ||||||
							
								
								
									
										894
									
								
								vendor/github.com/golang/protobuf/proto/lib.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										894
									
								
								vendor/github.com/golang/protobuf/proto/lib.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,894 @@ | |||||||
|  | // 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. | ||||||
|  |   - Getters are only generated for message and oneof fields. | ||||||
|  |   - 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" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | // Message is implemented by generated protocol buffer messages.
 | ||||||
|  | type Message interface { | ||||||
|  | 	Reset() | ||||||
|  | 	String() string | ||||||
|  | 	ProtoMessage() | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Stats records allocation details about the protocol buffer encoders
 | ||||||
|  | // and decoders.  Useful for tuning the library itself.
 | ||||||
|  | type Stats struct { | ||||||
|  | 	Emalloc uint64 // mallocs in encode
 | ||||||
|  | 	Dmalloc uint64 // mallocs in decode
 | ||||||
|  | 	Encode  uint64 // number of encodes
 | ||||||
|  | 	Decode  uint64 // number of decodes
 | ||||||
|  | 	Chit    uint64 // number of cache hits
 | ||||||
|  | 	Cmiss   uint64 // number of cache misses
 | ||||||
|  | 	Size    uint64 // number of sizes
 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Set to true to enable stats collection.
 | ||||||
|  | const collectStats = false | ||||||
|  | 
 | ||||||
|  | var stats Stats | ||||||
|  | 
 | ||||||
|  | // GetStats returns a copy of the global Stats structure.
 | ||||||
|  | func GetStats() Stats { return stats } | ||||||
|  | 
 | ||||||
|  | // 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    // write point
 | ||||||
|  | 
 | ||||||
|  | 	// pools of basic types to amortize allocation.
 | ||||||
|  | 	bools   []bool | ||||||
|  | 	uint32s []uint32 | ||||||
|  | 	uint64s []uint64 | ||||||
|  | 
 | ||||||
|  | 	// extra pools, only used with pointer_reflect.go
 | ||||||
|  | 	int32s   []int32 | ||||||
|  | 	int64s   []int64 | ||||||
|  | 	float32s []float32 | ||||||
|  | 	float64s []float64 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // 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 } | ||||||
|  | 
 | ||||||
|  | /* | ||||||
|  |  * 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 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Map fields may have key types of non-float scalars, strings and enums.
 | ||||||
|  | // The easiest way to sort them in some deterministic order is to use fmt.
 | ||||||
|  | // If this turns out to be inefficient we can always consider other options,
 | ||||||
|  | // such as doing a Schwartzian transform.
 | ||||||
|  | 
 | ||||||
|  | func mapKeys(vs []reflect.Value) sort.Interface { | ||||||
|  | 	s := mapKeySorter{ | ||||||
|  | 		vs: vs, | ||||||
|  | 		// default Less function: textual comparison
 | ||||||
|  | 		less: func(a, b reflect.Value) bool { | ||||||
|  | 			return fmt.Sprint(a.Interface()) < fmt.Sprint(b.Interface()) | ||||||
|  | 		}, | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	// Type specialization per https://developers.google.com/protocol-buffers/docs/proto#maps;
 | ||||||
|  | 	// numeric keys are sorted numerically.
 | ||||||
|  | 	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() } | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	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 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ProtoPackageIsVersion1 is referenced from generated protocol buffer files
 | ||||||
|  | // to assert that that code is compatible with this version of the proto package.
 | ||||||
|  | const ProtoPackageIsVersion1 = true | ||||||
							
								
								
									
										280
									
								
								vendor/github.com/golang/protobuf/proto/message_set.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										280
									
								
								vendor/github.com/golang/protobuf/proto/message_set.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,280 @@ | |||||||
|  | // 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 ( | ||||||
|  | 	"bytes" | ||||||
|  | 	"encoding/json" | ||||||
|  | 	"errors" | ||||||
|  | 	"fmt" | ||||||
|  | 	"reflect" | ||||||
|  | 	"sort" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | // 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 { | ||||||
|  | 	if ms.find(pb) != nil { | ||||||
|  | 		return true | ||||||
|  | 	} | ||||||
|  | 	return false | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 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:] | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // MarshalMessageSet encodes the extension map represented by m in the message set wire format.
 | ||||||
|  | // It is called by generated Marshal methods on protocol buffer messages with the message_set_wire_format option.
 | ||||||
|  | func MarshalMessageSet(m map[int32]Extension) ([]byte, error) { | ||||||
|  | 	if err := encodeExtensionMap(m); err != nil { | ||||||
|  | 		return nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	// Sort extension IDs to provide a deterministic encoding.
 | ||||||
|  | 	// See also enc_map in encode.go.
 | ||||||
|  | 	ids := make([]int, 0, len(m)) | ||||||
|  | 	for id := range m { | ||||||
|  | 		ids = append(ids, int(id)) | ||||||
|  | 	} | ||||||
|  | 	sort.Ints(ids) | ||||||
|  | 
 | ||||||
|  | 	ms := &messageSet{Item: make([]*_MessageSet_Item, 0, len(m))} | ||||||
|  | 	for _, id := range ids { | ||||||
|  | 		e := m[int32(id)] | ||||||
|  | 		// Remove the wire type and field number varint, as well as the length varint.
 | ||||||
|  | 		msg := skipVarint(skipVarint(e.enc)) | ||||||
|  | 
 | ||||||
|  | 		ms.Item = append(ms.Item, &_MessageSet_Item{ | ||||||
|  | 			TypeId:  Int32(int32(id)), | ||||||
|  | 			Message: msg, | ||||||
|  | 		}) | ||||||
|  | 	} | ||||||
|  | 	return Marshal(ms) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // UnmarshalMessageSet decodes the extension map encoded in buf in the message set wire format.
 | ||||||
|  | // It is called by generated Unmarshal methods on protocol buffer messages with the message_set_wire_format option.
 | ||||||
|  | func UnmarshalMessageSet(buf []byte, m map[int32]Extension) error { | ||||||
|  | 	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 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // MarshalMessageSetJSON encodes the extension map represented by m in JSON format.
 | ||||||
|  | // It is called by generated MarshalJSON methods on protocol buffer messages with the message_set_wire_format option.
 | ||||||
|  | func MarshalMessageSetJSON(m map[int32]Extension) ([]byte, error) { | ||||||
|  | 	var b bytes.Buffer | ||||||
|  | 	b.WriteByte('{') | ||||||
|  | 
 | ||||||
|  | 	// Process the map in key order for deterministic output.
 | ||||||
|  | 	ids := make([]int32, 0, len(m)) | ||||||
|  | 	for id := range m { | ||||||
|  | 		ids = append(ids, id) | ||||||
|  | 	} | ||||||
|  | 	sort.Sort(int32Slice(ids)) // int32Slice defined in text.go
 | ||||||
|  | 
 | ||||||
|  | 	for i, id := range ids { | ||||||
|  | 		ext := m[id] | ||||||
|  | 		if i > 0 { | ||||||
|  | 			b.WriteByte(',') | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		msd, ok := messageSetMap[id] | ||||||
|  | 		if !ok { | ||||||
|  | 			// Unknown type; we can't render it, so skip it.
 | ||||||
|  | 			continue | ||||||
|  | 		} | ||||||
|  | 		fmt.Fprintf(&b, `"[%s]":`, msd.name) | ||||||
|  | 
 | ||||||
|  | 		x := ext.value | ||||||
|  | 		if x == nil { | ||||||
|  | 			x = reflect.New(msd.t.Elem()).Interface() | ||||||
|  | 			if err := Unmarshal(ext.enc, x.(Message)); err != nil { | ||||||
|  | 				return nil, err | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 		d, err := json.Marshal(x) | ||||||
|  | 		if err != nil { | ||||||
|  | 			return nil, err | ||||||
|  | 		} | ||||||
|  | 		b.Write(d) | ||||||
|  | 	} | ||||||
|  | 	b.WriteByte('}') | ||||||
|  | 	return b.Bytes(), nil | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // UnmarshalMessageSetJSON decodes the extension map encoded in buf in JSON format.
 | ||||||
|  | // It is called by generated UnmarshalJSON methods on protocol buffer messages with the message_set_wire_format option.
 | ||||||
|  | func UnmarshalMessageSetJSON(buf []byte, m map[int32]Extension) error { | ||||||
|  | 	// Common-case fast path.
 | ||||||
|  | 	if len(buf) == 0 || bytes.Equal(buf, []byte("{}")) { | ||||||
|  | 		return nil | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	// This is fairly tricky, and it's not clear that it is needed.
 | ||||||
|  | 	return errors.New("TODO: UnmarshalMessageSetJSON not yet implemented") | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // A global registry of types that can be used in a MessageSet.
 | ||||||
|  | 
 | ||||||
|  | var messageSetMap = make(map[int32]messageSetDesc) | ||||||
|  | 
 | ||||||
|  | type messageSetDesc struct { | ||||||
|  | 	t    reflect.Type // pointer to struct
 | ||||||
|  | 	name string | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // RegisterMessageSetType is called from the generated code.
 | ||||||
|  | func RegisterMessageSetType(m Message, fieldNum int32, name string) { | ||||||
|  | 	messageSetMap[fieldNum] = messageSetDesc{ | ||||||
|  | 		t:    reflect.TypeOf(m), | ||||||
|  | 		name: name, | ||||||
|  | 	} | ||||||
|  | } | ||||||
							
								
								
									
										479
									
								
								vendor/github.com/golang/protobuf/proto/pointer_reflect.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										479
									
								
								vendor/github.com/golang/protobuf/proto/pointer_reflect.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,479 @@ | |||||||
|  | // 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 appengine
 | ||||||
|  | 
 | ||||||
|  | // 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 ( | ||||||
|  | 	"math" | ||||||
|  | 	"reflect" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | // A structPointer is a pointer to a struct.
 | ||||||
|  | type structPointer struct { | ||||||
|  | 	v reflect.Value | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // toStructPointer returns a structPointer equivalent to the given reflect value.
 | ||||||
|  | // The reflect value must itself be a pointer to a struct.
 | ||||||
|  | func toStructPointer(v reflect.Value) structPointer { | ||||||
|  | 	return structPointer{v} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // IsNil reports whether p is nil.
 | ||||||
|  | func structPointer_IsNil(p structPointer) bool { | ||||||
|  | 	return p.v.IsNil() | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Interface returns the struct pointer as an interface value.
 | ||||||
|  | func structPointer_Interface(p structPointer, _ reflect.Type) interface{} { | ||||||
|  | 	return p.v.Interface() | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // A field identifies a field in a struct, accessible from a structPointer.
 | ||||||
|  | // 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) | ||||||
|  | 
 | ||||||
|  | // IsValid reports whether the field identifier is valid.
 | ||||||
|  | func (f field) IsValid() bool { return f != nil } | ||||||
|  | 
 | ||||||
|  | // field returns the given field in the struct as a reflect value.
 | ||||||
|  | func structPointer_field(p structPointer, f field) reflect.Value { | ||||||
|  | 	// Special case: an extension map entry with a value of type T
 | ||||||
|  | 	// passes a *T to the struct-handling code with a zero field,
 | ||||||
|  | 	// expecting that it will be treated as equivalent to *struct{ X T },
 | ||||||
|  | 	// which has the same memory layout. We have to handle that case
 | ||||||
|  | 	// specially, because reflect will panic if we call FieldByIndex on a
 | ||||||
|  | 	// non-struct.
 | ||||||
|  | 	if f == nil { | ||||||
|  | 		return p.v.Elem() | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return p.v.Elem().FieldByIndex(f) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ifield returns the given field in the struct as an interface value.
 | ||||||
|  | func structPointer_ifield(p structPointer, f field) interface{} { | ||||||
|  | 	return structPointer_field(p, f).Addr().Interface() | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Bytes returns the address of a []byte field in the struct.
 | ||||||
|  | func structPointer_Bytes(p structPointer, f field) *[]byte { | ||||||
|  | 	return structPointer_ifield(p, f).(*[]byte) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // BytesSlice returns the address of a [][]byte field in the struct.
 | ||||||
|  | func structPointer_BytesSlice(p structPointer, f field) *[][]byte { | ||||||
|  | 	return structPointer_ifield(p, f).(*[][]byte) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Bool returns the address of a *bool field in the struct.
 | ||||||
|  | func structPointer_Bool(p structPointer, f field) **bool { | ||||||
|  | 	return structPointer_ifield(p, f).(**bool) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // BoolVal returns the address of a bool field in the struct.
 | ||||||
|  | func structPointer_BoolVal(p structPointer, f field) *bool { | ||||||
|  | 	return structPointer_ifield(p, f).(*bool) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // BoolSlice returns the address of a []bool field in the struct.
 | ||||||
|  | func structPointer_BoolSlice(p structPointer, f field) *[]bool { | ||||||
|  | 	return structPointer_ifield(p, f).(*[]bool) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // String returns the address of a *string field in the struct.
 | ||||||
|  | func structPointer_String(p structPointer, f field) **string { | ||||||
|  | 	return structPointer_ifield(p, f).(**string) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // StringVal returns the address of a string field in the struct.
 | ||||||
|  | func structPointer_StringVal(p structPointer, f field) *string { | ||||||
|  | 	return structPointer_ifield(p, f).(*string) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // StringSlice returns the address of a []string field in the struct.
 | ||||||
|  | func structPointer_StringSlice(p structPointer, f field) *[]string { | ||||||
|  | 	return structPointer_ifield(p, f).(*[]string) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ExtMap returns the address of an extension map field in the struct.
 | ||||||
|  | func structPointer_ExtMap(p structPointer, f field) *map[int32]Extension { | ||||||
|  | 	return structPointer_ifield(p, f).(*map[int32]Extension) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // NewAt returns the reflect.Value for a pointer to a field in the struct.
 | ||||||
|  | func structPointer_NewAt(p structPointer, f field, typ reflect.Type) reflect.Value { | ||||||
|  | 	return structPointer_field(p, f).Addr() | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // SetStructPointer writes a *struct field in the struct.
 | ||||||
|  | func structPointer_SetStructPointer(p structPointer, f field, q structPointer) { | ||||||
|  | 	structPointer_field(p, f).Set(q.v) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // GetStructPointer reads a *struct field in the struct.
 | ||||||
|  | func structPointer_GetStructPointer(p structPointer, f field) structPointer { | ||||||
|  | 	return structPointer{structPointer_field(p, f)} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // StructPointerSlice the address of a []*struct field in the struct.
 | ||||||
|  | func structPointer_StructPointerSlice(p structPointer, f field) structPointerSlice { | ||||||
|  | 	return structPointerSlice{structPointer_field(p, f)} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // A structPointerSlice represents the address of a slice of pointers to structs
 | ||||||
|  | // (themselves messages or groups). That is, v.Type() is *[]*struct{...}.
 | ||||||
|  | type structPointerSlice struct { | ||||||
|  | 	v reflect.Value | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (p structPointerSlice) Len() int                  { return p.v.Len() } | ||||||
|  | func (p structPointerSlice) Index(i int) structPointer { return structPointer{p.v.Index(i)} } | ||||||
|  | func (p structPointerSlice) Append(q structPointer) { | ||||||
|  | 	p.v.Set(reflect.Append(p.v, q.v)) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | var ( | ||||||
|  | 	int32Type   = reflect.TypeOf(int32(0)) | ||||||
|  | 	uint32Type  = reflect.TypeOf(uint32(0)) | ||||||
|  | 	float32Type = reflect.TypeOf(float32(0)) | ||||||
|  | 	int64Type   = reflect.TypeOf(int64(0)) | ||||||
|  | 	uint64Type  = reflect.TypeOf(uint64(0)) | ||||||
|  | 	float64Type = reflect.TypeOf(float64(0)) | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | // A word32 represents a field of type *int32, *uint32, *float32, or *enum.
 | ||||||
|  | // That is, v.Type() is *int32, *uint32, *float32, or *enum and v is assignable.
 | ||||||
|  | type word32 struct { | ||||||
|  | 	v reflect.Value | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // IsNil reports whether p is nil.
 | ||||||
|  | func word32_IsNil(p word32) bool { | ||||||
|  | 	return p.v.IsNil() | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Set sets p to point at a newly allocated word with bits set to x.
 | ||||||
|  | func word32_Set(p word32, o *Buffer, x uint32) { | ||||||
|  | 	t := p.v.Type().Elem() | ||||||
|  | 	switch t { | ||||||
|  | 	case int32Type: | ||||||
|  | 		if len(o.int32s) == 0 { | ||||||
|  | 			o.int32s = make([]int32, uint32PoolSize) | ||||||
|  | 		} | ||||||
|  | 		o.int32s[0] = int32(x) | ||||||
|  | 		p.v.Set(reflect.ValueOf(&o.int32s[0])) | ||||||
|  | 		o.int32s = o.int32s[1:] | ||||||
|  | 		return | ||||||
|  | 	case uint32Type: | ||||||
|  | 		if len(o.uint32s) == 0 { | ||||||
|  | 			o.uint32s = make([]uint32, uint32PoolSize) | ||||||
|  | 		} | ||||||
|  | 		o.uint32s[0] = x | ||||||
|  | 		p.v.Set(reflect.ValueOf(&o.uint32s[0])) | ||||||
|  | 		o.uint32s = o.uint32s[1:] | ||||||
|  | 		return | ||||||
|  | 	case float32Type: | ||||||
|  | 		if len(o.float32s) == 0 { | ||||||
|  | 			o.float32s = make([]float32, uint32PoolSize) | ||||||
|  | 		} | ||||||
|  | 		o.float32s[0] = math.Float32frombits(x) | ||||||
|  | 		p.v.Set(reflect.ValueOf(&o.float32s[0])) | ||||||
|  | 		o.float32s = o.float32s[1:] | ||||||
|  | 		return | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	// must be enum
 | ||||||
|  | 	p.v.Set(reflect.New(t)) | ||||||
|  | 	p.v.Elem().SetInt(int64(int32(x))) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Get gets the bits pointed at by p, as a uint32.
 | ||||||
|  | func word32_Get(p word32) uint32 { | ||||||
|  | 	elem := p.v.Elem() | ||||||
|  | 	switch elem.Kind() { | ||||||
|  | 	case reflect.Int32: | ||||||
|  | 		return uint32(elem.Int()) | ||||||
|  | 	case reflect.Uint32: | ||||||
|  | 		return uint32(elem.Uint()) | ||||||
|  | 	case reflect.Float32: | ||||||
|  | 		return math.Float32bits(float32(elem.Float())) | ||||||
|  | 	} | ||||||
|  | 	panic("unreachable") | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Word32 returns a reference to a *int32, *uint32, *float32, or *enum field in the struct.
 | ||||||
|  | func structPointer_Word32(p structPointer, f field) word32 { | ||||||
|  | 	return word32{structPointer_field(p, f)} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // A word32Val represents a field of type int32, uint32, float32, or enum.
 | ||||||
|  | // That is, v.Type() is int32, uint32, float32, or enum and v is assignable.
 | ||||||
|  | type word32Val struct { | ||||||
|  | 	v reflect.Value | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Set sets *p to x.
 | ||||||
|  | func word32Val_Set(p word32Val, x uint32) { | ||||||
|  | 	switch p.v.Type() { | ||||||
|  | 	case int32Type: | ||||||
|  | 		p.v.SetInt(int64(x)) | ||||||
|  | 		return | ||||||
|  | 	case uint32Type: | ||||||
|  | 		p.v.SetUint(uint64(x)) | ||||||
|  | 		return | ||||||
|  | 	case float32Type: | ||||||
|  | 		p.v.SetFloat(float64(math.Float32frombits(x))) | ||||||
|  | 		return | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	// must be enum
 | ||||||
|  | 	p.v.SetInt(int64(int32(x))) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Get gets the bits pointed at by p, as a uint32.
 | ||||||
|  | func word32Val_Get(p word32Val) uint32 { | ||||||
|  | 	elem := p.v | ||||||
|  | 	switch elem.Kind() { | ||||||
|  | 	case reflect.Int32: | ||||||
|  | 		return uint32(elem.Int()) | ||||||
|  | 	case reflect.Uint32: | ||||||
|  | 		return uint32(elem.Uint()) | ||||||
|  | 	case reflect.Float32: | ||||||
|  | 		return math.Float32bits(float32(elem.Float())) | ||||||
|  | 	} | ||||||
|  | 	panic("unreachable") | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Word32Val returns a reference to a int32, uint32, float32, or enum field in the struct.
 | ||||||
|  | func structPointer_Word32Val(p structPointer, f field) word32Val { | ||||||
|  | 	return word32Val{structPointer_field(p, f)} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // A word32Slice is a slice of 32-bit values.
 | ||||||
|  | // That is, v.Type() is []int32, []uint32, []float32, or []enum.
 | ||||||
|  | type word32Slice struct { | ||||||
|  | 	v reflect.Value | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (p word32Slice) Append(x uint32) { | ||||||
|  | 	n, m := p.v.Len(), p.v.Cap() | ||||||
|  | 	if n < m { | ||||||
|  | 		p.v.SetLen(n + 1) | ||||||
|  | 	} else { | ||||||
|  | 		t := p.v.Type().Elem() | ||||||
|  | 		p.v.Set(reflect.Append(p.v, reflect.Zero(t))) | ||||||
|  | 	} | ||||||
|  | 	elem := p.v.Index(n) | ||||||
|  | 	switch elem.Kind() { | ||||||
|  | 	case reflect.Int32: | ||||||
|  | 		elem.SetInt(int64(int32(x))) | ||||||
|  | 	case reflect.Uint32: | ||||||
|  | 		elem.SetUint(uint64(x)) | ||||||
|  | 	case reflect.Float32: | ||||||
|  | 		elem.SetFloat(float64(math.Float32frombits(x))) | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (p word32Slice) Len() int { | ||||||
|  | 	return p.v.Len() | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (p word32Slice) Index(i int) uint32 { | ||||||
|  | 	elem := p.v.Index(i) | ||||||
|  | 	switch elem.Kind() { | ||||||
|  | 	case reflect.Int32: | ||||||
|  | 		return uint32(elem.Int()) | ||||||
|  | 	case reflect.Uint32: | ||||||
|  | 		return uint32(elem.Uint()) | ||||||
|  | 	case reflect.Float32: | ||||||
|  | 		return math.Float32bits(float32(elem.Float())) | ||||||
|  | 	} | ||||||
|  | 	panic("unreachable") | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Word32Slice returns a reference to a []int32, []uint32, []float32, or []enum field in the struct.
 | ||||||
|  | func structPointer_Word32Slice(p structPointer, f field) word32Slice { | ||||||
|  | 	return word32Slice{structPointer_field(p, f)} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // word64 is like word32 but for 64-bit values.
 | ||||||
|  | type word64 struct { | ||||||
|  | 	v reflect.Value | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func word64_Set(p word64, o *Buffer, x uint64) { | ||||||
|  | 	t := p.v.Type().Elem() | ||||||
|  | 	switch t { | ||||||
|  | 	case int64Type: | ||||||
|  | 		if len(o.int64s) == 0 { | ||||||
|  | 			o.int64s = make([]int64, uint64PoolSize) | ||||||
|  | 		} | ||||||
|  | 		o.int64s[0] = int64(x) | ||||||
|  | 		p.v.Set(reflect.ValueOf(&o.int64s[0])) | ||||||
|  | 		o.int64s = o.int64s[1:] | ||||||
|  | 		return | ||||||
|  | 	case uint64Type: | ||||||
|  | 		if len(o.uint64s) == 0 { | ||||||
|  | 			o.uint64s = make([]uint64, uint64PoolSize) | ||||||
|  | 		} | ||||||
|  | 		o.uint64s[0] = x | ||||||
|  | 		p.v.Set(reflect.ValueOf(&o.uint64s[0])) | ||||||
|  | 		o.uint64s = o.uint64s[1:] | ||||||
|  | 		return | ||||||
|  | 	case float64Type: | ||||||
|  | 		if len(o.float64s) == 0 { | ||||||
|  | 			o.float64s = make([]float64, uint64PoolSize) | ||||||
|  | 		} | ||||||
|  | 		o.float64s[0] = math.Float64frombits(x) | ||||||
|  | 		p.v.Set(reflect.ValueOf(&o.float64s[0])) | ||||||
|  | 		o.float64s = o.float64s[1:] | ||||||
|  | 		return | ||||||
|  | 	} | ||||||
|  | 	panic("unreachable") | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func word64_IsNil(p word64) bool { | ||||||
|  | 	return p.v.IsNil() | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func word64_Get(p word64) uint64 { | ||||||
|  | 	elem := p.v.Elem() | ||||||
|  | 	switch elem.Kind() { | ||||||
|  | 	case reflect.Int64: | ||||||
|  | 		return uint64(elem.Int()) | ||||||
|  | 	case reflect.Uint64: | ||||||
|  | 		return elem.Uint() | ||||||
|  | 	case reflect.Float64: | ||||||
|  | 		return math.Float64bits(elem.Float()) | ||||||
|  | 	} | ||||||
|  | 	panic("unreachable") | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func structPointer_Word64(p structPointer, f field) word64 { | ||||||
|  | 	return word64{structPointer_field(p, f)} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // word64Val is like word32Val but for 64-bit values.
 | ||||||
|  | type word64Val struct { | ||||||
|  | 	v reflect.Value | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func word64Val_Set(p word64Val, o *Buffer, x uint64) { | ||||||
|  | 	switch p.v.Type() { | ||||||
|  | 	case int64Type: | ||||||
|  | 		p.v.SetInt(int64(x)) | ||||||
|  | 		return | ||||||
|  | 	case uint64Type: | ||||||
|  | 		p.v.SetUint(x) | ||||||
|  | 		return | ||||||
|  | 	case float64Type: | ||||||
|  | 		p.v.SetFloat(math.Float64frombits(x)) | ||||||
|  | 		return | ||||||
|  | 	} | ||||||
|  | 	panic("unreachable") | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func word64Val_Get(p word64Val) uint64 { | ||||||
|  | 	elem := p.v | ||||||
|  | 	switch elem.Kind() { | ||||||
|  | 	case reflect.Int64: | ||||||
|  | 		return uint64(elem.Int()) | ||||||
|  | 	case reflect.Uint64: | ||||||
|  | 		return elem.Uint() | ||||||
|  | 	case reflect.Float64: | ||||||
|  | 		return math.Float64bits(elem.Float()) | ||||||
|  | 	} | ||||||
|  | 	panic("unreachable") | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func structPointer_Word64Val(p structPointer, f field) word64Val { | ||||||
|  | 	return word64Val{structPointer_field(p, f)} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | type word64Slice struct { | ||||||
|  | 	v reflect.Value | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (p word64Slice) Append(x uint64) { | ||||||
|  | 	n, m := p.v.Len(), p.v.Cap() | ||||||
|  | 	if n < m { | ||||||
|  | 		p.v.SetLen(n + 1) | ||||||
|  | 	} else { | ||||||
|  | 		t := p.v.Type().Elem() | ||||||
|  | 		p.v.Set(reflect.Append(p.v, reflect.Zero(t))) | ||||||
|  | 	} | ||||||
|  | 	elem := p.v.Index(n) | ||||||
|  | 	switch elem.Kind() { | ||||||
|  | 	case reflect.Int64: | ||||||
|  | 		elem.SetInt(int64(int64(x))) | ||||||
|  | 	case reflect.Uint64: | ||||||
|  | 		elem.SetUint(uint64(x)) | ||||||
|  | 	case reflect.Float64: | ||||||
|  | 		elem.SetFloat(float64(math.Float64frombits(x))) | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (p word64Slice) Len() int { | ||||||
|  | 	return p.v.Len() | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (p word64Slice) Index(i int) uint64 { | ||||||
|  | 	elem := p.v.Index(i) | ||||||
|  | 	switch elem.Kind() { | ||||||
|  | 	case reflect.Int64: | ||||||
|  | 		return uint64(elem.Int()) | ||||||
|  | 	case reflect.Uint64: | ||||||
|  | 		return uint64(elem.Uint()) | ||||||
|  | 	case reflect.Float64: | ||||||
|  | 		return math.Float64bits(float64(elem.Float())) | ||||||
|  | 	} | ||||||
|  | 	panic("unreachable") | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func structPointer_Word64Slice(p structPointer, f field) word64Slice { | ||||||
|  | 	return word64Slice{structPointer_field(p, f)} | ||||||
|  | } | ||||||
							
								
								
									
										266
									
								
								vendor/github.com/golang/protobuf/proto/pointer_unsafe.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										266
									
								
								vendor/github.com/golang/protobuf/proto/pointer_unsafe.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,266 @@ | |||||||
|  | // 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 !appengine
 | ||||||
|  | 
 | ||||||
|  | // This file contains the implementation of the proto field accesses using package unsafe.
 | ||||||
|  | 
 | ||||||
|  | package proto | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  | 	"reflect" | ||||||
|  | 	"unsafe" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | // NOTE: These type_Foo functions would more idiomatically be methods,
 | ||||||
|  | // but Go does not allow methods on pointer types, and we must preserve
 | ||||||
|  | // some pointer type for the garbage collector. We use these
 | ||||||
|  | // funcs with clunky names as our poor approximation to methods.
 | ||||||
|  | //
 | ||||||
|  | // An alternative would be
 | ||||||
|  | //	type structPointer struct { p unsafe.Pointer }
 | ||||||
|  | // but that does not registerize as well.
 | ||||||
|  | 
 | ||||||
|  | // A structPointer is a pointer to a struct.
 | ||||||
|  | type structPointer unsafe.Pointer | ||||||
|  | 
 | ||||||
|  | // toStructPointer returns a structPointer equivalent to the given reflect value.
 | ||||||
|  | func toStructPointer(v reflect.Value) structPointer { | ||||||
|  | 	return structPointer(unsafe.Pointer(v.Pointer())) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // IsNil reports whether p is nil.
 | ||||||
|  | func structPointer_IsNil(p structPointer) bool { | ||||||
|  | 	return p == nil | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Interface returns the struct pointer, assumed to have element type t,
 | ||||||
|  | // as an interface value.
 | ||||||
|  | func structPointer_Interface(p structPointer, t reflect.Type) interface{} { | ||||||
|  | 	return reflect.NewAt(t, unsafe.Pointer(p)).Interface() | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // A field identifies a field in a struct, accessible from a structPointer.
 | ||||||
|  | // 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) | ||||||
|  | 
 | ||||||
|  | // IsValid reports whether the field identifier is valid.
 | ||||||
|  | func (f field) IsValid() bool { | ||||||
|  | 	return f != ^field(0) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Bytes returns the address of a []byte field in the struct.
 | ||||||
|  | func structPointer_Bytes(p structPointer, f field) *[]byte { | ||||||
|  | 	return (*[]byte)(unsafe.Pointer(uintptr(p) + uintptr(f))) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // BytesSlice returns the address of a [][]byte field in the struct.
 | ||||||
|  | func structPointer_BytesSlice(p structPointer, f field) *[][]byte { | ||||||
|  | 	return (*[][]byte)(unsafe.Pointer(uintptr(p) + uintptr(f))) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Bool returns the address of a *bool field in the struct.
 | ||||||
|  | func structPointer_Bool(p structPointer, f field) **bool { | ||||||
|  | 	return (**bool)(unsafe.Pointer(uintptr(p) + uintptr(f))) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // BoolVal returns the address of a bool field in the struct.
 | ||||||
|  | func structPointer_BoolVal(p structPointer, f field) *bool { | ||||||
|  | 	return (*bool)(unsafe.Pointer(uintptr(p) + uintptr(f))) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // BoolSlice returns the address of a []bool field in the struct.
 | ||||||
|  | func structPointer_BoolSlice(p structPointer, f field) *[]bool { | ||||||
|  | 	return (*[]bool)(unsafe.Pointer(uintptr(p) + uintptr(f))) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // String returns the address of a *string field in the struct.
 | ||||||
|  | func structPointer_String(p structPointer, f field) **string { | ||||||
|  | 	return (**string)(unsafe.Pointer(uintptr(p) + uintptr(f))) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // StringVal returns the address of a string field in the struct.
 | ||||||
|  | func structPointer_StringVal(p structPointer, f field) *string { | ||||||
|  | 	return (*string)(unsafe.Pointer(uintptr(p) + uintptr(f))) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // StringSlice returns the address of a []string field in the struct.
 | ||||||
|  | func structPointer_StringSlice(p structPointer, f field) *[]string { | ||||||
|  | 	return (*[]string)(unsafe.Pointer(uintptr(p) + uintptr(f))) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ExtMap returns the address of an extension map field in the struct.
 | ||||||
|  | func structPointer_ExtMap(p structPointer, f field) *map[int32]Extension { | ||||||
|  | 	return (*map[int32]Extension)(unsafe.Pointer(uintptr(p) + uintptr(f))) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // NewAt returns the reflect.Value for a pointer to a field in the struct.
 | ||||||
|  | func structPointer_NewAt(p structPointer, f field, typ reflect.Type) reflect.Value { | ||||||
|  | 	return reflect.NewAt(typ, unsafe.Pointer(uintptr(p)+uintptr(f))) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // SetStructPointer writes a *struct field in the struct.
 | ||||||
|  | func structPointer_SetStructPointer(p structPointer, f field, q structPointer) { | ||||||
|  | 	*(*structPointer)(unsafe.Pointer(uintptr(p) + uintptr(f))) = q | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // GetStructPointer reads a *struct field in the struct.
 | ||||||
|  | func structPointer_GetStructPointer(p structPointer, f field) structPointer { | ||||||
|  | 	return *(*structPointer)(unsafe.Pointer(uintptr(p) + uintptr(f))) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // StructPointerSlice the address of a []*struct field in the struct.
 | ||||||
|  | func structPointer_StructPointerSlice(p structPointer, f field) *structPointerSlice { | ||||||
|  | 	return (*structPointerSlice)(unsafe.Pointer(uintptr(p) + uintptr(f))) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // A structPointerSlice represents a slice of pointers to structs (themselves submessages or groups).
 | ||||||
|  | type structPointerSlice []structPointer | ||||||
|  | 
 | ||||||
|  | func (v *structPointerSlice) Len() int                  { return len(*v) } | ||||||
|  | func (v *structPointerSlice) Index(i int) structPointer { return (*v)[i] } | ||||||
|  | func (v *structPointerSlice) Append(p structPointer)    { *v = append(*v, p) } | ||||||
|  | 
 | ||||||
|  | // A word32 is the address of a "pointer to 32-bit value" field.
 | ||||||
|  | type word32 **uint32 | ||||||
|  | 
 | ||||||
|  | // IsNil reports whether *v is nil.
 | ||||||
|  | func word32_IsNil(p word32) bool { | ||||||
|  | 	return *p == nil | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Set sets *v to point at a newly allocated word set to x.
 | ||||||
|  | func word32_Set(p word32, o *Buffer, x uint32) { | ||||||
|  | 	if len(o.uint32s) == 0 { | ||||||
|  | 		o.uint32s = make([]uint32, uint32PoolSize) | ||||||
|  | 	} | ||||||
|  | 	o.uint32s[0] = x | ||||||
|  | 	*p = &o.uint32s[0] | ||||||
|  | 	o.uint32s = o.uint32s[1:] | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Get gets the value pointed at by *v.
 | ||||||
|  | func word32_Get(p word32) uint32 { | ||||||
|  | 	return **p | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Word32 returns the address of a *int32, *uint32, *float32, or *enum field in the struct.
 | ||||||
|  | func structPointer_Word32(p structPointer, f field) word32 { | ||||||
|  | 	return word32((**uint32)(unsafe.Pointer(uintptr(p) + uintptr(f)))) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // A word32Val is the address of a 32-bit value field.
 | ||||||
|  | type word32Val *uint32 | ||||||
|  | 
 | ||||||
|  | // Set sets *p to x.
 | ||||||
|  | func word32Val_Set(p word32Val, x uint32) { | ||||||
|  | 	*p = x | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Get gets the value pointed at by p.
 | ||||||
|  | func word32Val_Get(p word32Val) uint32 { | ||||||
|  | 	return *p | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Word32Val returns the address of a *int32, *uint32, *float32, or *enum field in the struct.
 | ||||||
|  | func structPointer_Word32Val(p structPointer, f field) word32Val { | ||||||
|  | 	return word32Val((*uint32)(unsafe.Pointer(uintptr(p) + uintptr(f)))) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // A word32Slice is a slice of 32-bit values.
 | ||||||
|  | type word32Slice []uint32 | ||||||
|  | 
 | ||||||
|  | func (v *word32Slice) Append(x uint32)    { *v = append(*v, x) } | ||||||
|  | func (v *word32Slice) Len() int           { return len(*v) } | ||||||
|  | func (v *word32Slice) Index(i int) uint32 { return (*v)[i] } | ||||||
|  | 
 | ||||||
|  | // Word32Slice returns the address of a []int32, []uint32, []float32, or []enum field in the struct.
 | ||||||
|  | func structPointer_Word32Slice(p structPointer, f field) *word32Slice { | ||||||
|  | 	return (*word32Slice)(unsafe.Pointer(uintptr(p) + uintptr(f))) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // word64 is like word32 but for 64-bit values.
 | ||||||
|  | type word64 **uint64 | ||||||
|  | 
 | ||||||
|  | func word64_Set(p word64, o *Buffer, x uint64) { | ||||||
|  | 	if len(o.uint64s) == 0 { | ||||||
|  | 		o.uint64s = make([]uint64, uint64PoolSize) | ||||||
|  | 	} | ||||||
|  | 	o.uint64s[0] = x | ||||||
|  | 	*p = &o.uint64s[0] | ||||||
|  | 	o.uint64s = o.uint64s[1:] | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func word64_IsNil(p word64) bool { | ||||||
|  | 	return *p == nil | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func word64_Get(p word64) uint64 { | ||||||
|  | 	return **p | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func structPointer_Word64(p structPointer, f field) word64 { | ||||||
|  | 	return word64((**uint64)(unsafe.Pointer(uintptr(p) + uintptr(f)))) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // word64Val is like word32Val but for 64-bit values.
 | ||||||
|  | type word64Val *uint64 | ||||||
|  | 
 | ||||||
|  | func word64Val_Set(p word64Val, o *Buffer, x uint64) { | ||||||
|  | 	*p = x | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func word64Val_Get(p word64Val) uint64 { | ||||||
|  | 	return *p | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func structPointer_Word64Val(p structPointer, f field) word64Val { | ||||||
|  | 	return word64Val((*uint64)(unsafe.Pointer(uintptr(p) + uintptr(f)))) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // word64Slice is like word32Slice but for 64-bit values.
 | ||||||
|  | type word64Slice []uint64 | ||||||
|  | 
 | ||||||
|  | func (v *word64Slice) Append(x uint64)    { *v = append(*v, x) } | ||||||
|  | func (v *word64Slice) Len() int           { return len(*v) } | ||||||
|  | func (v *word64Slice) Index(i int) uint64 { return (*v)[i] } | ||||||
|  | 
 | ||||||
|  | func structPointer_Word64Slice(p structPointer, f field) *word64Slice { | ||||||
|  | 	return (*word64Slice)(unsafe.Pointer(uintptr(p) + uintptr(f))) | ||||||
|  | } | ||||||
							
								
								
									
										846
									
								
								vendor/github.com/golang/protobuf/proto/properties.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										846
									
								
								vendor/github.com/golang/protobuf/proto/properties.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,846 @@ | |||||||
|  | // 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" | ||||||
|  | 	"os" | ||||||
|  | 	"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 | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | const startSize = 10 // initial slice/string sizes
 | ||||||
|  | 
 | ||||||
|  | // Encoders are defined in encode.go
 | ||||||
|  | // An encoder outputs the full representation of a field, including its
 | ||||||
|  | // tag and encoder type.
 | ||||||
|  | type encoder func(p *Buffer, prop *Properties, base structPointer) error | ||||||
|  | 
 | ||||||
|  | // A valueEncoder encodes a single integer in a particular encoding.
 | ||||||
|  | type valueEncoder func(o *Buffer, x uint64) error | ||||||
|  | 
 | ||||||
|  | // Sizers are defined in encode.go
 | ||||||
|  | // A sizer returns the encoded size of a field, including its tag and encoder
 | ||||||
|  | // type.
 | ||||||
|  | type sizer func(prop *Properties, base structPointer) int | ||||||
|  | 
 | ||||||
|  | // A valueSizer returns the encoded size of a single integer in a particular
 | ||||||
|  | // encoding.
 | ||||||
|  | type valueSizer func(x uint64) int | ||||||
|  | 
 | ||||||
|  | // Decoders are defined in decode.go
 | ||||||
|  | // A decoder creates a value from its wire representation.
 | ||||||
|  | // Unrecognized subelements are saved in unrec.
 | ||||||
|  | type decoder func(p *Buffer, prop *Properties, base structPointer) error | ||||||
|  | 
 | ||||||
|  | // A valueDecoder decodes a single integer in a particular encoding.
 | ||||||
|  | type valueDecoder func(o *Buffer) (x uint64, err error) | ||||||
|  | 
 | ||||||
|  | // A oneofMarshaler does the marshaling for all oneof fields in a message.
 | ||||||
|  | type oneofMarshaler func(Message, *Buffer) error | ||||||
|  | 
 | ||||||
|  | // A oneofUnmarshaler does the unmarshaling for a oneof field in a message.
 | ||||||
|  | type oneofUnmarshaler func(Message, int, int, *Buffer) (bool, error) | ||||||
|  | 
 | ||||||
|  | // A oneofSizer does the sizing for all oneof fields in a message.
 | ||||||
|  | type oneofSizer func(Message) int | ||||||
|  | 
 | ||||||
|  | // 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
 | ||||||
|  | 	unrecField       field          // field id of the XXX_unrecognized []byte field
 | ||||||
|  | 	extendable       bool           // is this an extendable proto
 | ||||||
|  | 
 | ||||||
|  | 	oneofMarshaler   oneofMarshaler | ||||||
|  | 	oneofUnmarshaler oneofUnmarshaler | ||||||
|  | 	oneofSizer       oneofSizer | ||||||
|  | 	stype            reflect.Type | ||||||
|  | 
 | ||||||
|  | 	// 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; set for []byte only
 | ||||||
|  | 	oneof    bool   // whether this is a oneof field
 | ||||||
|  | 
 | ||||||
|  | 	Default    string // default value
 | ||||||
|  | 	HasDefault bool   // whether an explicit default was provided
 | ||||||
|  | 	def_uint64 uint64 | ||||||
|  | 
 | ||||||
|  | 	enc           encoder | ||||||
|  | 	valEnc        valueEncoder // set for bool and numeric types only
 | ||||||
|  | 	field         field | ||||||
|  | 	tagcode       []byte // encoding of EncodeVarint((Tag<<3)|WireType)
 | ||||||
|  | 	tagbuf        [8]byte | ||||||
|  | 	stype         reflect.Type      // set for struct types only
 | ||||||
|  | 	sprop         *StructProperties // set for struct types only
 | ||||||
|  | 	isMarshaler   bool | ||||||
|  | 	isUnmarshaler bool | ||||||
|  | 
 | ||||||
|  | 	mtype    reflect.Type // set for map types only
 | ||||||
|  | 	mkeyprop *Properties  // set for map types only
 | ||||||
|  | 	mvalprop *Properties  // set for map types only
 | ||||||
|  | 
 | ||||||
|  | 	size    sizer | ||||||
|  | 	valSize valueSizer // set for bool and numeric types only
 | ||||||
|  | 
 | ||||||
|  | 	dec    decoder | ||||||
|  | 	valDec valueDecoder // set for bool and numeric types only
 | ||||||
|  | 
 | ||||||
|  | 	// If this is a packable field, this will be the decoder for the packed version of the field.
 | ||||||
|  | 	packedDec decoder | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // 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 { | ||||||
|  | 		fmt.Fprintf(os.Stderr, "proto: tag has too few fields: %q\n", s) | ||||||
|  | 		return | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	p.Wire = fields[0] | ||||||
|  | 	switch p.Wire { | ||||||
|  | 	case "varint": | ||||||
|  | 		p.WireType = WireVarint | ||||||
|  | 		p.valEnc = (*Buffer).EncodeVarint | ||||||
|  | 		p.valDec = (*Buffer).DecodeVarint | ||||||
|  | 		p.valSize = sizeVarint | ||||||
|  | 	case "fixed32": | ||||||
|  | 		p.WireType = WireFixed32 | ||||||
|  | 		p.valEnc = (*Buffer).EncodeFixed32 | ||||||
|  | 		p.valDec = (*Buffer).DecodeFixed32 | ||||||
|  | 		p.valSize = sizeFixed32 | ||||||
|  | 	case "fixed64": | ||||||
|  | 		p.WireType = WireFixed64 | ||||||
|  | 		p.valEnc = (*Buffer).EncodeFixed64 | ||||||
|  | 		p.valDec = (*Buffer).DecodeFixed64 | ||||||
|  | 		p.valSize = sizeFixed64 | ||||||
|  | 	case "zigzag32": | ||||||
|  | 		p.WireType = WireVarint | ||||||
|  | 		p.valEnc = (*Buffer).EncodeZigzag32 | ||||||
|  | 		p.valDec = (*Buffer).DecodeZigzag32 | ||||||
|  | 		p.valSize = sizeZigzag32 | ||||||
|  | 	case "zigzag64": | ||||||
|  | 		p.WireType = WireVarint | ||||||
|  | 		p.valEnc = (*Buffer).EncodeZigzag64 | ||||||
|  | 		p.valDec = (*Buffer).DecodeZigzag64 | ||||||
|  | 		p.valSize = sizeZigzag64 | ||||||
|  | 	case "bytes", "group": | ||||||
|  | 		p.WireType = WireBytes | ||||||
|  | 		// no numeric converter for non-numeric types
 | ||||||
|  | 	default: | ||||||
|  | 		fmt.Fprintf(os.Stderr, "proto: tag has unknown wire type: %q\n", s) | ||||||
|  | 		return | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	var err error | ||||||
|  | 	p.Tag, err = strconv.Atoi(fields[1]) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	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 | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func logNoSliceEnc(t1, t2 reflect.Type) { | ||||||
|  | 	fmt.Fprintf(os.Stderr, "proto: no slice oenc for %T = []%T\n", t1, t2) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | var protoMessageType = reflect.TypeOf((*Message)(nil)).Elem() | ||||||
|  | 
 | ||||||
|  | // Initialize the fields for encoding and decoding.
 | ||||||
|  | func (p *Properties) setEncAndDec(typ reflect.Type, f *reflect.StructField, lockGetProp bool) { | ||||||
|  | 	p.enc = nil | ||||||
|  | 	p.dec = nil | ||||||
|  | 	p.size = nil | ||||||
|  | 
 | ||||||
|  | 	switch t1 := typ; t1.Kind() { | ||||||
|  | 	default: | ||||||
|  | 		fmt.Fprintf(os.Stderr, "proto: no coders for %v\n", t1) | ||||||
|  | 
 | ||||||
|  | 	// proto3 scalar types
 | ||||||
|  | 
 | ||||||
|  | 	case reflect.Bool: | ||||||
|  | 		p.enc = (*Buffer).enc_proto3_bool | ||||||
|  | 		p.dec = (*Buffer).dec_proto3_bool | ||||||
|  | 		p.size = size_proto3_bool | ||||||
|  | 	case reflect.Int32: | ||||||
|  | 		p.enc = (*Buffer).enc_proto3_int32 | ||||||
|  | 		p.dec = (*Buffer).dec_proto3_int32 | ||||||
|  | 		p.size = size_proto3_int32 | ||||||
|  | 	case reflect.Uint32: | ||||||
|  | 		p.enc = (*Buffer).enc_proto3_uint32 | ||||||
|  | 		p.dec = (*Buffer).dec_proto3_int32 // can reuse
 | ||||||
|  | 		p.size = size_proto3_uint32 | ||||||
|  | 	case reflect.Int64, reflect.Uint64: | ||||||
|  | 		p.enc = (*Buffer).enc_proto3_int64 | ||||||
|  | 		p.dec = (*Buffer).dec_proto3_int64 | ||||||
|  | 		p.size = size_proto3_int64 | ||||||
|  | 	case reflect.Float32: | ||||||
|  | 		p.enc = (*Buffer).enc_proto3_uint32 // can just treat them as bits
 | ||||||
|  | 		p.dec = (*Buffer).dec_proto3_int32 | ||||||
|  | 		p.size = size_proto3_uint32 | ||||||
|  | 	case reflect.Float64: | ||||||
|  | 		p.enc = (*Buffer).enc_proto3_int64 // can just treat them as bits
 | ||||||
|  | 		p.dec = (*Buffer).dec_proto3_int64 | ||||||
|  | 		p.size = size_proto3_int64 | ||||||
|  | 	case reflect.String: | ||||||
|  | 		p.enc = (*Buffer).enc_proto3_string | ||||||
|  | 		p.dec = (*Buffer).dec_proto3_string | ||||||
|  | 		p.size = size_proto3_string | ||||||
|  | 
 | ||||||
|  | 	case reflect.Ptr: | ||||||
|  | 		switch t2 := t1.Elem(); t2.Kind() { | ||||||
|  | 		default: | ||||||
|  | 			fmt.Fprintf(os.Stderr, "proto: no encoder function for %v -> %v\n", t1, t2) | ||||||
|  | 			break | ||||||
|  | 		case reflect.Bool: | ||||||
|  | 			p.enc = (*Buffer).enc_bool | ||||||
|  | 			p.dec = (*Buffer).dec_bool | ||||||
|  | 			p.size = size_bool | ||||||
|  | 		case reflect.Int32: | ||||||
|  | 			p.enc = (*Buffer).enc_int32 | ||||||
|  | 			p.dec = (*Buffer).dec_int32 | ||||||
|  | 			p.size = size_int32 | ||||||
|  | 		case reflect.Uint32: | ||||||
|  | 			p.enc = (*Buffer).enc_uint32 | ||||||
|  | 			p.dec = (*Buffer).dec_int32 // can reuse
 | ||||||
|  | 			p.size = size_uint32 | ||||||
|  | 		case reflect.Int64, reflect.Uint64: | ||||||
|  | 			p.enc = (*Buffer).enc_int64 | ||||||
|  | 			p.dec = (*Buffer).dec_int64 | ||||||
|  | 			p.size = size_int64 | ||||||
|  | 		case reflect.Float32: | ||||||
|  | 			p.enc = (*Buffer).enc_uint32 // can just treat them as bits
 | ||||||
|  | 			p.dec = (*Buffer).dec_int32 | ||||||
|  | 			p.size = size_uint32 | ||||||
|  | 		case reflect.Float64: | ||||||
|  | 			p.enc = (*Buffer).enc_int64 // can just treat them as bits
 | ||||||
|  | 			p.dec = (*Buffer).dec_int64 | ||||||
|  | 			p.size = size_int64 | ||||||
|  | 		case reflect.String: | ||||||
|  | 			p.enc = (*Buffer).enc_string | ||||||
|  | 			p.dec = (*Buffer).dec_string | ||||||
|  | 			p.size = size_string | ||||||
|  | 		case reflect.Struct: | ||||||
|  | 			p.stype = t1.Elem() | ||||||
|  | 			p.isMarshaler = isMarshaler(t1) | ||||||
|  | 			p.isUnmarshaler = isUnmarshaler(t1) | ||||||
|  | 			if p.Wire == "bytes" { | ||||||
|  | 				p.enc = (*Buffer).enc_struct_message | ||||||
|  | 				p.dec = (*Buffer).dec_struct_message | ||||||
|  | 				p.size = size_struct_message | ||||||
|  | 			} else { | ||||||
|  | 				p.enc = (*Buffer).enc_struct_group | ||||||
|  | 				p.dec = (*Buffer).dec_struct_group | ||||||
|  | 				p.size = size_struct_group | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 	case reflect.Slice: | ||||||
|  | 		switch t2 := t1.Elem(); t2.Kind() { | ||||||
|  | 		default: | ||||||
|  | 			logNoSliceEnc(t1, t2) | ||||||
|  | 			break | ||||||
|  | 		case reflect.Bool: | ||||||
|  | 			if p.Packed { | ||||||
|  | 				p.enc = (*Buffer).enc_slice_packed_bool | ||||||
|  | 				p.size = size_slice_packed_bool | ||||||
|  | 			} else { | ||||||
|  | 				p.enc = (*Buffer).enc_slice_bool | ||||||
|  | 				p.size = size_slice_bool | ||||||
|  | 			} | ||||||
|  | 			p.dec = (*Buffer).dec_slice_bool | ||||||
|  | 			p.packedDec = (*Buffer).dec_slice_packed_bool | ||||||
|  | 		case reflect.Int32: | ||||||
|  | 			if p.Packed { | ||||||
|  | 				p.enc = (*Buffer).enc_slice_packed_int32 | ||||||
|  | 				p.size = size_slice_packed_int32 | ||||||
|  | 			} else { | ||||||
|  | 				p.enc = (*Buffer).enc_slice_int32 | ||||||
|  | 				p.size = size_slice_int32 | ||||||
|  | 			} | ||||||
|  | 			p.dec = (*Buffer).dec_slice_int32 | ||||||
|  | 			p.packedDec = (*Buffer).dec_slice_packed_int32 | ||||||
|  | 		case reflect.Uint32: | ||||||
|  | 			if p.Packed { | ||||||
|  | 				p.enc = (*Buffer).enc_slice_packed_uint32 | ||||||
|  | 				p.size = size_slice_packed_uint32 | ||||||
|  | 			} else { | ||||||
|  | 				p.enc = (*Buffer).enc_slice_uint32 | ||||||
|  | 				p.size = size_slice_uint32 | ||||||
|  | 			} | ||||||
|  | 			p.dec = (*Buffer).dec_slice_int32 | ||||||
|  | 			p.packedDec = (*Buffer).dec_slice_packed_int32 | ||||||
|  | 		case reflect.Int64, reflect.Uint64: | ||||||
|  | 			if p.Packed { | ||||||
|  | 				p.enc = (*Buffer).enc_slice_packed_int64 | ||||||
|  | 				p.size = size_slice_packed_int64 | ||||||
|  | 			} else { | ||||||
|  | 				p.enc = (*Buffer).enc_slice_int64 | ||||||
|  | 				p.size = size_slice_int64 | ||||||
|  | 			} | ||||||
|  | 			p.dec = (*Buffer).dec_slice_int64 | ||||||
|  | 			p.packedDec = (*Buffer).dec_slice_packed_int64 | ||||||
|  | 		case reflect.Uint8: | ||||||
|  | 			p.enc = (*Buffer).enc_slice_byte | ||||||
|  | 			p.dec = (*Buffer).dec_slice_byte | ||||||
|  | 			p.size = size_slice_byte | ||||||
|  | 			// This is a []byte, which is either a bytes field,
 | ||||||
|  | 			// or the value of a map field. In the latter case,
 | ||||||
|  | 			// we always encode an empty []byte, so we should not
 | ||||||
|  | 			// use the proto3 enc/size funcs.
 | ||||||
|  | 			// f == nil iff this is the key/value of a map field.
 | ||||||
|  | 			if p.proto3 && f != nil { | ||||||
|  | 				p.enc = (*Buffer).enc_proto3_slice_byte | ||||||
|  | 				p.size = size_proto3_slice_byte | ||||||
|  | 			} | ||||||
|  | 		case reflect.Float32, reflect.Float64: | ||||||
|  | 			switch t2.Bits() { | ||||||
|  | 			case 32: | ||||||
|  | 				// can just treat them as bits
 | ||||||
|  | 				if p.Packed { | ||||||
|  | 					p.enc = (*Buffer).enc_slice_packed_uint32 | ||||||
|  | 					p.size = size_slice_packed_uint32 | ||||||
|  | 				} else { | ||||||
|  | 					p.enc = (*Buffer).enc_slice_uint32 | ||||||
|  | 					p.size = size_slice_uint32 | ||||||
|  | 				} | ||||||
|  | 				p.dec = (*Buffer).dec_slice_int32 | ||||||
|  | 				p.packedDec = (*Buffer).dec_slice_packed_int32 | ||||||
|  | 			case 64: | ||||||
|  | 				// can just treat them as bits
 | ||||||
|  | 				if p.Packed { | ||||||
|  | 					p.enc = (*Buffer).enc_slice_packed_int64 | ||||||
|  | 					p.size = size_slice_packed_int64 | ||||||
|  | 				} else { | ||||||
|  | 					p.enc = (*Buffer).enc_slice_int64 | ||||||
|  | 					p.size = size_slice_int64 | ||||||
|  | 				} | ||||||
|  | 				p.dec = (*Buffer).dec_slice_int64 | ||||||
|  | 				p.packedDec = (*Buffer).dec_slice_packed_int64 | ||||||
|  | 			default: | ||||||
|  | 				logNoSliceEnc(t1, t2) | ||||||
|  | 				break | ||||||
|  | 			} | ||||||
|  | 		case reflect.String: | ||||||
|  | 			p.enc = (*Buffer).enc_slice_string | ||||||
|  | 			p.dec = (*Buffer).dec_slice_string | ||||||
|  | 			p.size = size_slice_string | ||||||
|  | 		case reflect.Ptr: | ||||||
|  | 			switch t3 := t2.Elem(); t3.Kind() { | ||||||
|  | 			default: | ||||||
|  | 				fmt.Fprintf(os.Stderr, "proto: no ptr oenc for %T -> %T -> %T\n", t1, t2, t3) | ||||||
|  | 				break | ||||||
|  | 			case reflect.Struct: | ||||||
|  | 				p.stype = t2.Elem() | ||||||
|  | 				p.isMarshaler = isMarshaler(t2) | ||||||
|  | 				p.isUnmarshaler = isUnmarshaler(t2) | ||||||
|  | 				if p.Wire == "bytes" { | ||||||
|  | 					p.enc = (*Buffer).enc_slice_struct_message | ||||||
|  | 					p.dec = (*Buffer).dec_slice_struct_message | ||||||
|  | 					p.size = size_slice_struct_message | ||||||
|  | 				} else { | ||||||
|  | 					p.enc = (*Buffer).enc_slice_struct_group | ||||||
|  | 					p.dec = (*Buffer).dec_slice_struct_group | ||||||
|  | 					p.size = size_slice_struct_group | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
|  | 		case reflect.Slice: | ||||||
|  | 			switch t2.Elem().Kind() { | ||||||
|  | 			default: | ||||||
|  | 				fmt.Fprintf(os.Stderr, "proto: no slice elem oenc for %T -> %T -> %T\n", t1, t2, t2.Elem()) | ||||||
|  | 				break | ||||||
|  | 			case reflect.Uint8: | ||||||
|  | 				p.enc = (*Buffer).enc_slice_slice_byte | ||||||
|  | 				p.dec = (*Buffer).dec_slice_slice_byte | ||||||
|  | 				p.size = size_slice_slice_byte | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 	case reflect.Map: | ||||||
|  | 		p.enc = (*Buffer).enc_new_map | ||||||
|  | 		p.dec = (*Buffer).dec_new_map | ||||||
|  | 		p.size = size_new_map | ||||||
|  | 
 | ||||||
|  | 		p.mtype = t1 | ||||||
|  | 		p.mkeyprop = &Properties{} | ||||||
|  | 		p.mkeyprop.init(reflect.PtrTo(p.mtype.Key()), "Key", f.Tag.Get("protobuf_key"), nil, lockGetProp) | ||||||
|  | 		p.mvalprop = &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.mvalprop.init(vtype, "Value", f.Tag.Get("protobuf_val"), nil, lockGetProp) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	// precalculate tag code
 | ||||||
|  | 	wire := p.WireType | ||||||
|  | 	if p.Packed { | ||||||
|  | 		wire = WireBytes | ||||||
|  | 	} | ||||||
|  | 	x := uint32(p.Tag)<<3 | uint32(wire) | ||||||
|  | 	i := 0 | ||||||
|  | 	for i = 0; x > 127; i++ { | ||||||
|  | 		p.tagbuf[i] = 0x80 | uint8(x&0x7F) | ||||||
|  | 		x >>= 7 | ||||||
|  | 	} | ||||||
|  | 	p.tagbuf[i] = uint8(x) | ||||||
|  | 	p.tagcode = p.tagbuf[0 : i+1] | ||||||
|  | 
 | ||||||
|  | 	if p.stype != nil { | ||||||
|  | 		if lockGetProp { | ||||||
|  | 			p.sprop = GetProperties(p.stype) | ||||||
|  | 		} else { | ||||||
|  | 			p.sprop = getPropertiesLocked(p.stype) | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | var ( | ||||||
|  | 	marshalerType   = reflect.TypeOf((*Marshaler)(nil)).Elem() | ||||||
|  | 	unmarshalerType = reflect.TypeOf((*Unmarshaler)(nil)).Elem() | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | // isMarshaler reports whether type t implements Marshaler.
 | ||||||
|  | func isMarshaler(t reflect.Type) bool { | ||||||
|  | 	// We're checking for (likely) pointer-receiver methods
 | ||||||
|  | 	// so if t is not a pointer, something is very wrong.
 | ||||||
|  | 	// The calls above only invoke isMarshaler on pointer types.
 | ||||||
|  | 	if t.Kind() != reflect.Ptr { | ||||||
|  | 		panic("proto: misuse of isMarshaler") | ||||||
|  | 	} | ||||||
|  | 	return t.Implements(marshalerType) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // isUnmarshaler reports whether type t implements Unmarshaler.
 | ||||||
|  | func isUnmarshaler(t reflect.Type) bool { | ||||||
|  | 	// We're checking for (likely) pointer-receiver methods
 | ||||||
|  | 	// so if t is not a pointer, something is very wrong.
 | ||||||
|  | 	// The calls above only invoke isUnmarshaler on pointer types.
 | ||||||
|  | 	if t.Kind() != reflect.Ptr { | ||||||
|  | 		panic("proto: misuse of isUnmarshaler") | ||||||
|  | 	} | ||||||
|  | 	return t.Implements(unmarshalerType) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // 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 f != nil { | ||||||
|  | 		p.field = toField(f) | ||||||
|  | 	} | ||||||
|  | 	if tag == "" { | ||||||
|  | 		return | ||||||
|  | 	} | ||||||
|  | 	p.Parse(tag) | ||||||
|  | 	p.setEncAndDec(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 { | ||||||
|  | 		if collectStats { | ||||||
|  | 			stats.Chit++ | ||||||
|  | 		} | ||||||
|  | 		return sprop | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	propertiesMu.Lock() | ||||||
|  | 	sprop = getPropertiesLocked(t) | ||||||
|  | 	propertiesMu.Unlock() | ||||||
|  | 	return sprop | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // getPropertiesLocked requires that propertiesMu is held.
 | ||||||
|  | func getPropertiesLocked(t reflect.Type) *StructProperties { | ||||||
|  | 	if prop, ok := propertiesMap[t]; ok { | ||||||
|  | 		if collectStats { | ||||||
|  | 			stats.Chit++ | ||||||
|  | 		} | ||||||
|  | 		return prop | ||||||
|  | 	} | ||||||
|  | 	if collectStats { | ||||||
|  | 		stats.Cmiss++ | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	prop := new(StructProperties) | ||||||
|  | 	// in case of recursive protos, fill this in now.
 | ||||||
|  | 	propertiesMap[t] = prop | ||||||
|  | 
 | ||||||
|  | 	// build properties
 | ||||||
|  | 	prop.extendable = reflect.PtrTo(t).Implements(extendableProtoType) | ||||||
|  | 	prop.unrecField = invalidField | ||||||
|  | 	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) | ||||||
|  | 
 | ||||||
|  | 		if f.Name == "XXX_extensions" { // special case
 | ||||||
|  | 			p.enc = (*Buffer).enc_map | ||||||
|  | 			p.dec = nil // not needed
 | ||||||
|  | 			p.size = size_map | ||||||
|  | 		} | ||||||
|  | 		if f.Name == "XXX_unrecognized" { // special case
 | ||||||
|  | 			prop.unrecField = toField(&f) | ||||||
|  | 		} | ||||||
|  | 		oneof := f.Tag.Get("protobuf_oneof") != "" // special case
 | ||||||
|  | 		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") | ||||||
|  | 		} | ||||||
|  | 		if p.enc == nil && !strings.HasPrefix(f.Name, "XXX_") && !oneof { | ||||||
|  | 			fmt.Fprintln(os.Stderr, "proto: no encoder for", f.Name, f.Type.String(), "[GetProperties]") | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	// Re-order prop.order.
 | ||||||
|  | 	sort.Sort(prop) | ||||||
|  | 
 | ||||||
|  | 	type oneofMessage interface { | ||||||
|  | 		XXX_OneofFuncs() (func(Message, *Buffer) error, func(Message, int, int, *Buffer) (bool, error), func(Message) int, []interface{}) | ||||||
|  | 	} | ||||||
|  | 	if om, ok := reflect.Zero(reflect.PtrTo(t)).Interface().(oneofMessage); ok { | ||||||
|  | 		var oots []interface{} | ||||||
|  | 		prop.oneofMarshaler, prop.oneofUnmarshaler, prop.oneofSizer, oots = om.XXX_OneofFuncs() | ||||||
|  | 		prop.stype = t | ||||||
|  | 
 | ||||||
|  | 		// 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 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Return the Properties object for the x[0]'th field of the structure.
 | ||||||
|  | func propByIndex(t reflect.Type, x []int) *Properties { | ||||||
|  | 	if len(x) != 1 { | ||||||
|  | 		fmt.Fprintf(os.Stderr, "proto: field index dimension %d (not 1) for type %s\n", len(x), t) | ||||||
|  | 		return nil | ||||||
|  | 	} | ||||||
|  | 	prop := GetProperties(t) | ||||||
|  | 	return prop.Prop[x[0]] | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Get the address and type of a pointer to a struct from an interface.
 | ||||||
|  | func getbase(pb Message) (t reflect.Type, b structPointer, err error) { | ||||||
|  | 	if pb == nil { | ||||||
|  | 		err = ErrNil | ||||||
|  | 		return | ||||||
|  | 	} | ||||||
|  | 	// get the reflect type of the pointer to the struct.
 | ||||||
|  | 	t = reflect.TypeOf(pb) | ||||||
|  | 	// get the address of the struct.
 | ||||||
|  | 	value := reflect.ValueOf(pb) | ||||||
|  | 	b = toStructPointer(value) | ||||||
|  | 	return | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // 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 ( | ||||||
|  | 	protoTypes    = make(map[string]reflect.Type) | ||||||
|  | 	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 := protoTypes[name]; ok { | ||||||
|  | 		// TODO: Some day, make this a panic.
 | ||||||
|  | 		log.Printf("proto: duplicate proto type registered: %s", name) | ||||||
|  | 		return | ||||||
|  | 	} | ||||||
|  | 	t := reflect.TypeOf(x) | ||||||
|  | 	protoTypes[name] = t | ||||||
|  | 	revProtoTypes[t] = name | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // MessageName returns the fully-qualified proto name for the given message type.
 | ||||||
|  | func MessageName(x Message) string { return revProtoTypes[reflect.TypeOf(x)] } | ||||||
|  | 
 | ||||||
|  | // MessageType returns the message type (pointer to struct) for a named message.
 | ||||||
|  | func MessageType(name string) reflect.Type { return protoTypes[name] } | ||||||
							
								
								
									
										762
									
								
								vendor/github.com/golang/protobuf/proto/text.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										762
									
								
								vendor/github.com/golang/protobuf/proto/text.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,762 @@ | |||||||
|  | // 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("                                        ") | ||||||
|  | 	gtNewline       = []byte(">\n") | ||||||
|  | 	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.Printf("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 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // raw is the interface satisfied by RawMessage.
 | ||||||
|  | type raw interface { | ||||||
|  | 	Bytes() []byte | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func writeStruct(w *textWriter, sv reflect.Value) error { | ||||||
|  | 	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 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("<nil>\n")); err != nil { | ||||||
|  | 						return err | ||||||
|  | 					} | ||||||
|  | 					continue | ||||||
|  | 				} | ||||||
|  | 				if err := 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 := writeAny(w, key, props.mkeyprop); 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 := writeAny(w, val, props.mvalprop); 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 | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 		if b, ok := fv.Interface().(raw); ok { | ||||||
|  | 			if err := writeRaw(w, b.Bytes()); err != nil { | ||||||
|  | 				return err | ||||||
|  | 			} | ||||||
|  | 			continue | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		// Enums have a String method, so writeAny will work fine.
 | ||||||
|  | 		if err := 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 pv.Type().Implements(extendableProtoType) { | ||||||
|  | 		if err := writeExtensions(w, pv); err != nil { | ||||||
|  | 			return err | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // writeRaw writes an uninterpreted raw message.
 | ||||||
|  | func writeRaw(w *textWriter, b []byte) error { | ||||||
|  | 	if err := w.WriteByte('<'); err != nil { | ||||||
|  | 		return err | ||||||
|  | 	} | ||||||
|  | 	if !w.compact { | ||||||
|  | 		if err := w.WriteByte('\n'); err != nil { | ||||||
|  | 			return err | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	w.indent() | ||||||
|  | 	if err := writeUnknownStruct(w, b); err != nil { | ||||||
|  | 		return err | ||||||
|  | 	} | ||||||
|  | 	w.unindent() | ||||||
|  | 	if err := w.WriteByte('>'); err != nil { | ||||||
|  | 		return err | ||||||
|  | 	} | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // writeAny writes an arbitrary field.
 | ||||||
|  | func 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.Interface().([]byte))); 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 tm, ok := v.Interface().(encoding.TextMarshaler); ok { | ||||||
|  | 			text, err := tm.MarshalText() | ||||||
|  | 			if err != nil { | ||||||
|  | 				return err | ||||||
|  | 			} | ||||||
|  | 			if _, err = w.Write(text); err != nil { | ||||||
|  | 				return err | ||||||
|  | 			} | ||||||
|  | 		} else if err := 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 writeExtensions(w *textWriter, pv reflect.Value) error { | ||||||
|  | 	emap := extensionMaps[pv.Type().Elem()] | ||||||
|  | 	ep := pv.Interface().(extendableProto) | ||||||
|  | 
 | ||||||
|  | 	// Order the extensions by ID.
 | ||||||
|  | 	// This isn't strictly necessary, but it will give us
 | ||||||
|  | 	// canonical output, which will also make testing easier.
 | ||||||
|  | 	m := ep.ExtensionMap() | ||||||
|  | 	ids := make([]int32, 0, len(m)) | ||||||
|  | 	for id := range m { | ||||||
|  | 		ids = append(ids, id) | ||||||
|  | 	} | ||||||
|  | 	sort.Sort(int32Slice(ids)) | ||||||
|  | 
 | ||||||
|  | 	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 := writeExtension(w, desc.Name, pb); err != nil { | ||||||
|  | 				return err | ||||||
|  | 			} | ||||||
|  | 		} else { | ||||||
|  | 			v := reflect.ValueOf(pb) | ||||||
|  | 			for i := 0; i < v.Len(); i++ { | ||||||
|  | 				if err := writeExtension(w, desc.Name, v.Index(i).Interface()); err != nil { | ||||||
|  | 					return err | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func 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 := 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).
 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Marshal writes a given protocol buffer in text format.
 | ||||||
|  | // The only errors returned are from w.
 | ||||||
|  | func (m *TextMarshaler) Marshal(w io.Writer, pb Message) error { | ||||||
|  | 	val := reflect.ValueOf(pb) | ||||||
|  | 	if pb == nil || val.IsNil() { | ||||||
|  | 		w.Write([]byte("<nil>")) | ||||||
|  | 		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:  m.Compact, | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if tm, ok := pb.(encoding.TextMarshaler); ok { | ||||||
|  | 		text, err := tm.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 := 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 (m *TextMarshaler) Text(pb Message) string { | ||||||
|  | 	var buf bytes.Buffer | ||||||
|  | 	m.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) } | ||||||
							
								
								
									
										806
									
								
								vendor/github.com/golang/protobuf/proto/text_parser.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										806
									
								
								vendor/github.com/golang/protobuf/proto/text_parser.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,806 @@ | |||||||
|  | // 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" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | 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") | ||||||
|  | 	errBadHex  = errors.New("proto: bad hexadecimal") | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | 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', 'x', 'X': | ||||||
|  | 		if len(s) < 2 { | ||||||
|  | 			return "", "", fmt.Errorf(`\%c requires 2 following digits`, r) | ||||||
|  | 		} | ||||||
|  | 		base := 8 | ||||||
|  | 		ss := s[:2] | ||||||
|  | 		s = s[2:] | ||||||
|  | 		if r == 'x' || r == 'X' { | ||||||
|  | 			base = 16 | ||||||
|  | 		} else { | ||||||
|  | 			ss = string(r) + ss | ||||||
|  | 		} | ||||||
|  | 		i, err := strconv.ParseUint(ss, base, 8) | ||||||
|  | 		if err != nil { | ||||||
|  | 			return "", "", err | ||||||
|  | 		} | ||||||
|  | 		return string([]byte{byte(i)}), s, nil | ||||||
|  | 	case 'u', 'U': | ||||||
|  | 		n := 4 | ||||||
|  | 		if r == 'U' { | ||||||
|  | 			n = 8 | ||||||
|  | 		} | ||||||
|  | 		if len(s) < n { | ||||||
|  | 			return "", "", fmt.Errorf(`\%c requires %d digits`, r, n) | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		bs := make([]byte, n/2) | ||||||
|  | 		for i := 0; i < n; i += 2 { | ||||||
|  | 			a, ok1 := unhex(s[i]) | ||||||
|  | 			b, ok2 := unhex(s[i+1]) | ||||||
|  | 			if !ok1 || !ok2 { | ||||||
|  | 				return "", "", errBadHex | ||||||
|  | 			} | ||||||
|  | 			bs[i/2] = a<<4 | b | ||||||
|  | 		} | ||||||
|  | 		s = s[n:] | ||||||
|  | 		return string(bs), s, nil | ||||||
|  | 	} | ||||||
|  | 	return "", "", fmt.Errorf(`unknown escape \%c`, r) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Adapted from src/pkg/strconv/quote.go.
 | ||||||
|  | func unhex(b byte) (v byte, ok bool) { | ||||||
|  | 	switch { | ||||||
|  | 	case '0' <= b && b <= '9': | ||||||
|  | 		return b - '0', true | ||||||
|  | 	case 'a' <= b && b <= 'f': | ||||||
|  | 		return b - 'a' + 10, true | ||||||
|  | 	case 'A' <= b && b <= 'F': | ||||||
|  | 		return b - 'A' + 10, true | ||||||
|  | 	} | ||||||
|  | 	return 0, false | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // 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.<unknown field name>", 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]".
 | ||||||
|  | 	for { | ||||||
|  | 		tok := p.next() | ||||||
|  | 		if tok.err != nil { | ||||||
|  | 			return tok.err | ||||||
|  | 		} | ||||||
|  | 		if tok.value == terminator { | ||||||
|  | 			break | ||||||
|  | 		} | ||||||
|  | 		if tok.value == "[" { | ||||||
|  | 			// Looks like an extension.
 | ||||||
|  | 			//
 | ||||||
|  | 			// TODO: Check whether we need to handle
 | ||||||
|  | 			// namespace rooted names (e.g. ".something.Foo").
 | ||||||
|  | 			tok = p.next() | ||||||
|  | 			if tok.err != nil { | ||||||
|  | 				return tok.err | ||||||
|  | 			} | ||||||
|  | 			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 == tok.value { | ||||||
|  | 					desc = d | ||||||
|  | 					break | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
|  | 			if desc == nil { | ||||||
|  | 				return p.errorf("unrecognized extension %q", tok.value) | ||||||
|  | 			} | ||||||
|  | 			// Check the extension terminator.
 | ||||||
|  | 			tok = p.next() | ||||||
|  | 			if tok.err != nil { | ||||||
|  | 				return tok.err | ||||||
|  | 			} | ||||||
|  | 			if tok.value != "]" { | ||||||
|  | 				return p.errorf("unrecognized extension terminator %q", tok.value) | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
|  | 			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().(extendableProto) | ||||||
|  | 			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) | ||||||
|  | 			sv.Field(oop.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 >
 | ||||||
|  | 			// Technically the "key" and "value" could come in any order,
 | ||||||
|  | 			// but in practice they won't.
 | ||||||
|  | 
 | ||||||
|  | 			tok := p.next() | ||||||
|  | 			var terminator string | ||||||
|  | 			switch tok.value { | ||||||
|  | 			case "<": | ||||||
|  | 				terminator = ">" | ||||||
|  | 			case "{": | ||||||
|  | 				terminator = "}" | ||||||
|  | 			default: | ||||||
|  | 				return p.errorf("expected '{' or '<', found %q", tok.value) | ||||||
|  | 			} | ||||||
|  | 			if err := p.consumeToken("key"); err != nil { | ||||||
|  | 				return err | ||||||
|  | 			} | ||||||
|  | 			if err := p.consumeToken(":"); err != nil { | ||||||
|  | 				return err | ||||||
|  | 			} | ||||||
|  | 			if err := p.readAny(key, props.mkeyprop); err != nil { | ||||||
|  | 				return err | ||||||
|  | 			} | ||||||
|  | 			if err := p.consumeOptionalSeparator(); err != nil { | ||||||
|  | 				return err | ||||||
|  | 			} | ||||||
|  | 			if err := p.consumeToken("value"); err != nil { | ||||||
|  | 				return err | ||||||
|  | 			} | ||||||
|  | 			if err := p.checkForColon(props.mvalprop, dst.Type().Elem()); err != nil { | ||||||
|  | 				return err | ||||||
|  | 			} | ||||||
|  | 			if err := p.readAny(val, props.mvalprop); err != nil { | ||||||
|  | 				return err | ||||||
|  | 			} | ||||||
|  | 			if err := p.consumeOptionalSeparator(); err != nil { | ||||||
|  | 				return err | ||||||
|  | 			} | ||||||
|  | 			if err := p.consumeToken(terminator); err != nil { | ||||||
|  | 				return err | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
|  | 			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 | ||||||
|  | 		} else if props.Required { | ||||||
|  | 			reqCount-- | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		if err := p.consumeOptionalSeparator(); err != nil { | ||||||
|  | 			return err | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if reqCount > 0 { | ||||||
|  | 		return p.missingRequiredFieldError(sv) | ||||||
|  | 	} | ||||||
|  | 	return reqFieldErr | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // 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: | ||||||
|  | 		// Either "true", "false", 1 or 0.
 | ||||||
|  | 		switch tok.value { | ||||||
|  | 		case "true", "1": | ||||||
|  | 			fv.SetBool(true) | ||||||
|  | 			return nil | ||||||
|  | 		case "false", "0": | ||||||
|  | 			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 { | ||||||
|  | 		err := um.UnmarshalText([]byte(s)) | ||||||
|  | 		return err | ||||||
|  | 	} | ||||||
|  | 	pb.Reset() | ||||||
|  | 	v := reflect.ValueOf(pb) | ||||||
|  | 	if pe := newTextParser(s).readStruct(v.Elem(), ""); pe != nil { | ||||||
|  | 		return pe | ||||||
|  | 	} | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
							
								
								
									
										340
									
								
								vendor/github.com/google/go-github/LICENSE
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										340
									
								
								vendor/github.com/google/go-github/LICENSE
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,340 @@ | |||||||
|  | Copyright (c) 2013 The go-github 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. | ||||||
|  | 
 | ||||||
|  | ---------- | ||||||
|  | 
 | ||||||
|  | Some documentation is taken from the GitHub Developer site | ||||||
|  | <http://developer.github.com/>, which is available under a Creative Commons | ||||||
|  | Attribution 3.0 License: | ||||||
|  | 
 | ||||||
|  | THE WORK (AS DEFINED BELOW) IS PROVIDED UNDER THE TERMS OF THIS CREATIVE | ||||||
|  | COMMONS PUBLIC LICENSE ("CCPL" OR "LICENSE"). THE WORK IS PROTECTED BY | ||||||
|  | COPYRIGHT AND/OR OTHER APPLICABLE LAW. ANY USE OF THE WORK OTHER THAN AS | ||||||
|  | AUTHORIZED UNDER THIS LICENSE OR COPYRIGHT LAW IS PROHIBITED. | ||||||
|  | 
 | ||||||
|  | BY EXERCISING ANY RIGHTS TO THE WORK PROVIDED HERE, YOU ACCEPT AND AGREE | ||||||
|  | TO BE BOUND BY THE TERMS OF THIS LICENSE. TO THE EXTENT THIS LICENSE MAY | ||||||
|  | BE CONSIDERED TO BE A CONTRACT, THE LICENSOR GRANTS YOU THE RIGHTS | ||||||
|  | CONTAINED HERE IN CONSIDERATION OF YOUR ACCEPTANCE OF SUCH TERMS AND | ||||||
|  | CONDITIONS. | ||||||
|  | 
 | ||||||
|  | 1. Definitions | ||||||
|  | 
 | ||||||
|  |  a. "Adaptation" means a work based upon the Work, or upon the Work and | ||||||
|  |     other pre-existing works, such as a translation, adaptation, | ||||||
|  |     derivative work, arrangement of music or other alterations of a | ||||||
|  |     literary or artistic work, or phonogram or performance and includes | ||||||
|  |     cinematographic adaptations or any other form in which the Work may be | ||||||
|  |     recast, transformed, or adapted including in any form recognizably | ||||||
|  |     derived from the original, except that a work that constitutes a | ||||||
|  |     Collection will not be considered an Adaptation for the purpose of | ||||||
|  |     this License. For the avoidance of doubt, where the Work is a musical | ||||||
|  |     work, performance or phonogram, the synchronization of the Work in | ||||||
|  |     timed-relation with a moving image ("synching") will be considered an | ||||||
|  |     Adaptation for the purpose of this License. | ||||||
|  |  b. "Collection" means a collection of literary or artistic works, such as | ||||||
|  |     encyclopedias and anthologies, or performances, phonograms or | ||||||
|  |     broadcasts, or other works or subject matter other than works listed | ||||||
|  |     in Section 1(f) below, which, by reason of the selection and | ||||||
|  |     arrangement of their contents, constitute intellectual creations, in | ||||||
|  |     which the Work is included in its entirety in unmodified form along | ||||||
|  |     with one or more other contributions, each constituting separate and | ||||||
|  |     independent works in themselves, which together are assembled into a | ||||||
|  |     collective whole. A work that constitutes a Collection will not be | ||||||
|  |     considered an Adaptation (as defined above) for the purposes of this | ||||||
|  |     License. | ||||||
|  |  c. "Distribute" means to make available to the public the original and | ||||||
|  |     copies of the Work or Adaptation, as appropriate, through sale or | ||||||
|  |     other transfer of ownership. | ||||||
|  |  d. "Licensor" means the individual, individuals, entity or entities that | ||||||
|  |     offer(s) the Work under the terms of this License. | ||||||
|  |  e. "Original Author" means, in the case of a literary or artistic work, | ||||||
|  |     the individual, individuals, entity or entities who created the Work | ||||||
|  |     or if no individual or entity can be identified, the publisher; and in | ||||||
|  |     addition (i) in the case of a performance the actors, singers, | ||||||
|  |     musicians, dancers, and other persons who act, sing, deliver, declaim, | ||||||
|  |     play in, interpret or otherwise perform literary or artistic works or | ||||||
|  |     expressions of folklore; (ii) in the case of a phonogram the producer | ||||||
|  |     being the person or legal entity who first fixes the sounds of a | ||||||
|  |     performance or other sounds; and, (iii) in the case of broadcasts, the | ||||||
|  |     organization that transmits the broadcast. | ||||||
|  |  f. "Work" means the literary and/or artistic work offered under the terms | ||||||
|  |     of this License including without limitation any production in the | ||||||
|  |     literary, scientific and artistic domain, whatever may be the mode or | ||||||
|  |     form of its expression including digital form, such as a book, | ||||||
|  |     pamphlet and other writing; a lecture, address, sermon or other work | ||||||
|  |     of the same nature; a dramatic or dramatico-musical work; a | ||||||
|  |     choreographic work or entertainment in dumb show; a musical | ||||||
|  |     composition with or without words; a cinematographic work to which are | ||||||
|  |     assimilated works expressed by a process analogous to cinematography; | ||||||
|  |     a work of drawing, painting, architecture, sculpture, engraving or | ||||||
|  |     lithography; a photographic work to which are assimilated works | ||||||
|  |     expressed by a process analogous to photography; a work of applied | ||||||
|  |     art; an illustration, map, plan, sketch or three-dimensional work | ||||||
|  |     relative to geography, topography, architecture or science; a | ||||||
|  |     performance; a broadcast; a phonogram; a compilation of data to the | ||||||
|  |     extent it is protected as a copyrightable work; or a work performed by | ||||||
|  |     a variety or circus performer to the extent it is not otherwise | ||||||
|  |     considered a literary or artistic work. | ||||||
|  |  g. "You" means an individual or entity exercising rights under this | ||||||
|  |     License who has not previously violated the terms of this License with | ||||||
|  |     respect to the Work, or who has received express permission from the | ||||||
|  |     Licensor to exercise rights under this License despite a previous | ||||||
|  |     violation. | ||||||
|  |  h. "Publicly Perform" means to perform public recitations of the Work and | ||||||
|  |     to communicate to the public those public recitations, by any means or | ||||||
|  |     process, including by wire or wireless means or public digital | ||||||
|  |     performances; to make available to the public Works in such a way that | ||||||
|  |     members of the public may access these Works from a place and at a | ||||||
|  |     place individually chosen by them; to perform the Work to the public | ||||||
|  |     by any means or process and the communication to the public of the | ||||||
|  |     performances of the Work, including by public digital performance; to | ||||||
|  |     broadcast and rebroadcast the Work by any means including signs, | ||||||
|  |     sounds or images. | ||||||
|  |  i. "Reproduce" means to make copies of the Work by any means including | ||||||
|  |     without limitation by sound or visual recordings and the right of | ||||||
|  |     fixation and reproducing fixations of the Work, including storage of a | ||||||
|  |     protected performance or phonogram in digital form or other electronic | ||||||
|  |     medium. | ||||||
|  | 
 | ||||||
|  | 2. Fair Dealing Rights. Nothing in this License is intended to reduce, | ||||||
|  | limit, or restrict any uses free from copyright or rights arising from | ||||||
|  | limitations or exceptions that are provided for in connection with the | ||||||
|  | copyright protection under copyright law or other applicable laws. | ||||||
|  | 
 | ||||||
|  | 3. License Grant. Subject to the terms and conditions of this License, | ||||||
|  | Licensor hereby grants You a worldwide, royalty-free, non-exclusive, | ||||||
|  | perpetual (for the duration of the applicable copyright) license to | ||||||
|  | exercise the rights in the Work as stated below: | ||||||
|  | 
 | ||||||
|  |  a. to Reproduce the Work, to incorporate the Work into one or more | ||||||
|  |     Collections, and to Reproduce the Work as incorporated in the | ||||||
|  |     Collections; | ||||||
|  |  b. to create and Reproduce Adaptations provided that any such Adaptation, | ||||||
|  |     including any translation in any medium, takes reasonable steps to | ||||||
|  |     clearly label, demarcate or otherwise identify that changes were made | ||||||
|  |     to the original Work. For example, a translation could be marked "The | ||||||
|  |     original work was translated from English to Spanish," or a | ||||||
|  |     modification could indicate "The original work has been modified."; | ||||||
|  |  c. to Distribute and Publicly Perform the Work including as incorporated | ||||||
|  |     in Collections; and, | ||||||
|  |  d. to Distribute and Publicly Perform Adaptations. | ||||||
|  |  e. For the avoidance of doubt: | ||||||
|  | 
 | ||||||
|  |      i. Non-waivable Compulsory License Schemes. In those jurisdictions in | ||||||
|  |         which the right to collect royalties through any statutory or | ||||||
|  |         compulsory licensing scheme cannot be waived, the Licensor | ||||||
|  |         reserves the exclusive right to collect such royalties for any | ||||||
|  |         exercise by You of the rights granted under this License; | ||||||
|  |     ii. Waivable Compulsory License Schemes. In those jurisdictions in | ||||||
|  |         which the right to collect royalties through any statutory or | ||||||
|  |         compulsory licensing scheme can be waived, the Licensor waives the | ||||||
|  |         exclusive right to collect such royalties for any exercise by You | ||||||
|  |         of the rights granted under this License; and, | ||||||
|  |    iii. Voluntary License Schemes. The Licensor waives the right to | ||||||
|  |         collect royalties, whether individually or, in the event that the | ||||||
|  |         Licensor is a member of a collecting society that administers | ||||||
|  |         voluntary licensing schemes, via that society, from any exercise | ||||||
|  |         by You of the rights granted under this License. | ||||||
|  | 
 | ||||||
|  | The above rights may be exercised in all media and formats whether now | ||||||
|  | known or hereafter devised. The above rights include the right to make | ||||||
|  | such modifications as are technically necessary to exercise the rights in | ||||||
|  | other media and formats. Subject to Section 8(f), all rights not expressly | ||||||
|  | granted by Licensor are hereby reserved. | ||||||
|  | 
 | ||||||
|  | 4. Restrictions. The license granted in Section 3 above is expressly made | ||||||
|  | subject to and limited by the following restrictions: | ||||||
|  | 
 | ||||||
|  |  a. You may Distribute or Publicly Perform the Work only under the terms | ||||||
|  |     of this License. You must include a copy of, or the Uniform Resource | ||||||
|  |     Identifier (URI) for, this License with every copy of the Work You | ||||||
|  |     Distribute or Publicly Perform. You may not offer or impose any terms | ||||||
|  |     on the Work that restrict the terms of this License or the ability of | ||||||
|  |     the recipient of the Work to exercise the rights granted to that | ||||||
|  |     recipient under the terms of the License. You may not sublicense the | ||||||
|  |     Work. You must keep intact all notices that refer to this License and | ||||||
|  |     to the disclaimer of warranties with every copy of the Work You | ||||||
|  |     Distribute or Publicly Perform. When You Distribute or Publicly | ||||||
|  |     Perform the Work, You may not impose any effective technological | ||||||
|  |     measures on the Work that restrict the ability of a recipient of the | ||||||
|  |     Work from You to exercise the rights granted to that recipient under | ||||||
|  |     the terms of the License. This Section 4(a) applies to the Work as | ||||||
|  |     incorporated in a Collection, but this does not require the Collection | ||||||
|  |     apart from the Work itself to be made subject to the terms of this | ||||||
|  |     License. If You create a Collection, upon notice from any Licensor You | ||||||
|  |     must, to the extent practicable, remove from the Collection any credit | ||||||
|  |     as required by Section 4(b), as requested. If You create an | ||||||
|  |     Adaptation, upon notice from any Licensor You must, to the extent | ||||||
|  |     practicable, remove from the Adaptation any credit as required by | ||||||
|  |     Section 4(b), as requested. | ||||||
|  |  b. If You Distribute, or Publicly Perform the Work or any Adaptations or | ||||||
|  |     Collections, You must, unless a request has been made pursuant to | ||||||
|  |     Section 4(a), keep intact all copyright notices for the Work and | ||||||
|  |     provide, reasonable to the medium or means You are utilizing: (i) the | ||||||
|  |     name of the Original Author (or pseudonym, if applicable) if supplied, | ||||||
|  |     and/or if the Original Author and/or Licensor designate another party | ||||||
|  |     or parties (e.g., a sponsor institute, publishing entity, journal) for | ||||||
|  |     attribution ("Attribution Parties") in Licensor's copyright notice, | ||||||
|  |     terms of service or by other reasonable means, the name of such party | ||||||
|  |     or parties; (ii) the title of the Work if supplied; (iii) to the | ||||||
|  |     extent reasonably practicable, the URI, if any, that Licensor | ||||||
|  |     specifies to be associated with the Work, unless such URI does not | ||||||
|  |     refer to the copyright notice or licensing information for the Work; | ||||||
|  |     and (iv) , consistent with Section 3(b), in the case of an Adaptation, | ||||||
|  |     a credit identifying the use of the Work in the Adaptation (e.g., | ||||||
|  |     "French translation of the Work by Original Author," or "Screenplay | ||||||
|  |     based on original Work by Original Author"). The credit required by | ||||||
|  |     this Section 4 (b) may be implemented in any reasonable manner; | ||||||
|  |     provided, however, that in the case of a Adaptation or Collection, at | ||||||
|  |     a minimum such credit will appear, if a credit for all contributing | ||||||
|  |     authors of the Adaptation or Collection appears, then as part of these | ||||||
|  |     credits and in a manner at least as prominent as the credits for the | ||||||
|  |     other contributing authors. For the avoidance of doubt, You may only | ||||||
|  |     use the credit required by this Section for the purpose of attribution | ||||||
|  |     in the manner set out above and, by exercising Your rights under this | ||||||
|  |     License, You may not implicitly or explicitly assert or imply any | ||||||
|  |     connection with, sponsorship or endorsement by the Original Author, | ||||||
|  |     Licensor and/or Attribution Parties, as appropriate, of You or Your | ||||||
|  |     use of the Work, without the separate, express prior written | ||||||
|  |     permission of the Original Author, Licensor and/or Attribution | ||||||
|  |     Parties. | ||||||
|  |  c. Except as otherwise agreed in writing by the Licensor or as may be | ||||||
|  |     otherwise permitted by applicable law, if You Reproduce, Distribute or | ||||||
|  |     Publicly Perform the Work either by itself or as part of any | ||||||
|  |     Adaptations or Collections, You must not distort, mutilate, modify or | ||||||
|  |     take other derogatory action in relation to the Work which would be | ||||||
|  |     prejudicial to the Original Author's honor or reputation. Licensor | ||||||
|  |     agrees that in those jurisdictions (e.g. Japan), in which any exercise | ||||||
|  |     of the right granted in Section 3(b) of this License (the right to | ||||||
|  |     make Adaptations) would be deemed to be a distortion, mutilation, | ||||||
|  |     modification or other derogatory action prejudicial to the Original | ||||||
|  |     Author's honor and reputation, the Licensor will waive or not assert, | ||||||
|  |     as appropriate, this Section, to the fullest extent permitted by the | ||||||
|  |     applicable national law, to enable You to reasonably exercise Your | ||||||
|  |     right under Section 3(b) of this License (right to make Adaptations) | ||||||
|  |     but not otherwise. | ||||||
|  | 
 | ||||||
|  | 5. Representations, Warranties and Disclaimer | ||||||
|  | 
 | ||||||
|  | UNLESS OTHERWISE MUTUALLY AGREED TO BY THE PARTIES IN WRITING, LICENSOR | ||||||
|  | OFFERS THE WORK AS-IS AND MAKES NO REPRESENTATIONS OR WARRANTIES OF ANY | ||||||
|  | KIND CONCERNING THE WORK, EXPRESS, IMPLIED, STATUTORY OR OTHERWISE, | ||||||
|  | INCLUDING, WITHOUT LIMITATION, WARRANTIES OF TITLE, MERCHANTIBILITY, | ||||||
|  | FITNESS FOR A PARTICULAR PURPOSE, NONINFRINGEMENT, OR THE ABSENCE OF | ||||||
|  | LATENT OR OTHER DEFECTS, ACCURACY, OR THE PRESENCE OF ABSENCE OF ERRORS, | ||||||
|  | WHETHER OR NOT DISCOVERABLE. SOME JURISDICTIONS DO NOT ALLOW THE EXCLUSION | ||||||
|  | OF IMPLIED WARRANTIES, SO SUCH EXCLUSION MAY NOT APPLY TO YOU. | ||||||
|  | 
 | ||||||
|  | 6. Limitation on Liability. EXCEPT TO THE EXTENT REQUIRED BY APPLICABLE | ||||||
|  | LAW, IN NO EVENT WILL LICENSOR BE LIABLE TO YOU ON ANY LEGAL THEORY FOR | ||||||
|  | ANY SPECIAL, INCIDENTAL, CONSEQUENTIAL, PUNITIVE OR EXEMPLARY DAMAGES | ||||||
|  | ARISING OUT OF THIS LICENSE OR THE USE OF THE WORK, EVEN IF LICENSOR HAS | ||||||
|  | BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. | ||||||
|  | 
 | ||||||
|  | 7. Termination | ||||||
|  | 
 | ||||||
|  |  a. This License and the rights granted hereunder will terminate | ||||||
|  |     automatically upon any breach by You of the terms of this License. | ||||||
|  |     Individuals or entities who have received Adaptations or Collections | ||||||
|  |     from You under this License, however, will not have their licenses | ||||||
|  |     terminated provided such individuals or entities remain in full | ||||||
|  |     compliance with those licenses. Sections 1, 2, 5, 6, 7, and 8 will | ||||||
|  |     survive any termination of this License. | ||||||
|  |  b. Subject to the above terms and conditions, the license granted here is | ||||||
|  |     perpetual (for the duration of the applicable copyright in the Work). | ||||||
|  |     Notwithstanding the above, Licensor reserves the right to release the | ||||||
|  |     Work under different license terms or to stop distributing the Work at | ||||||
|  |     any time; provided, however that any such election will not serve to | ||||||
|  |     withdraw this License (or any other license that has been, or is | ||||||
|  |     required to be, granted under the terms of this License), and this | ||||||
|  |     License will continue in full force and effect unless terminated as | ||||||
|  |     stated above. | ||||||
|  | 
 | ||||||
|  | 8. Miscellaneous | ||||||
|  | 
 | ||||||
|  |  a. Each time You Distribute or Publicly Perform the Work or a Collection, | ||||||
|  |     the Licensor offers to the recipient a license to the Work on the same | ||||||
|  |     terms and conditions as the license granted to You under this License. | ||||||
|  |  b. Each time You Distribute or Publicly Perform an Adaptation, Licensor | ||||||
|  |     offers to the recipient a license to the original Work on the same | ||||||
|  |     terms and conditions as the license granted to You under this License. | ||||||
|  |  c. If any provision of this License is invalid or unenforceable under | ||||||
|  |     applicable law, it shall not affect the validity or enforceability of | ||||||
|  |     the remainder of the terms of this License, and without further action | ||||||
|  |     by the parties to this agreement, such provision shall be reformed to | ||||||
|  |     the minimum extent necessary to make such provision valid and | ||||||
|  |     enforceable. | ||||||
|  |  d. No term or provision of this License shall be deemed waived and no | ||||||
|  |     breach consented to unless such waiver or consent shall be in writing | ||||||
|  |     and signed by the party to be charged with such waiver or consent. | ||||||
|  |  e. This License constitutes the entire agreement between the parties with | ||||||
|  |     respect to the Work licensed here. There are no understandings, | ||||||
|  |     agreements or representations with respect to the Work not specified | ||||||
|  |     here. Licensor shall not be bound by any additional provisions that | ||||||
|  |     may appear in any communication from You. This License may not be | ||||||
|  |     modified without the mutual written agreement of the Licensor and You. | ||||||
|  |  f. The rights granted under, and the subject matter referenced, in this | ||||||
|  |     License were drafted utilizing the terminology of the Berne Convention | ||||||
|  |     for the Protection of Literary and Artistic Works (as amended on | ||||||
|  |     September 28, 1979), the Rome Convention of 1961, the WIPO Copyright | ||||||
|  |     Treaty of 1996, the WIPO Performances and Phonograms Treaty of 1996 | ||||||
|  |     and the Universal Copyright Convention (as revised on July 24, 1971). | ||||||
|  |     These rights and subject matter take effect in the relevant | ||||||
|  |     jurisdiction in which the License terms are sought to be enforced | ||||||
|  |     according to the corresponding provisions of the implementation of | ||||||
|  |     those treaty provisions in the applicable national law. If the | ||||||
|  |     standard suite of rights granted under applicable copyright law | ||||||
|  |     includes additional rights not granted under this License, such | ||||||
|  |     additional rights are deemed to be included in the License; this | ||||||
|  |     License is not intended to restrict the license of any rights under | ||||||
|  |     applicable law. | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | Creative Commons Notice | ||||||
|  | 
 | ||||||
|  |     Creative Commons is not a party to this License, and makes no warranty | ||||||
|  |     whatsoever in connection with the Work. Creative Commons will not be | ||||||
|  |     liable to You or any party on any legal theory for any damages | ||||||
|  |     whatsoever, including without limitation any general, special, | ||||||
|  |     incidental or consequential damages arising in connection to this | ||||||
|  |     license. Notwithstanding the foregoing two (2) sentences, if Creative | ||||||
|  |     Commons has expressly identified itself as the Licensor hereunder, it | ||||||
|  |     shall have all rights and obligations of Licensor. | ||||||
|  | 
 | ||||||
|  |     Except for the limited purpose of indicating to the public that the | ||||||
|  |     Work is licensed under the CCPL, Creative Commons does not authorize | ||||||
|  |     the use by either party of the trademark "Creative Commons" or any | ||||||
|  |     related trademark or logo of Creative Commons without the prior | ||||||
|  |     written consent of Creative Commons. Any permitted use will be in | ||||||
|  |     compliance with Creative Commons' then-current trademark usage | ||||||
|  |     guidelines, as may be published on its website or otherwise made | ||||||
|  |     available upon request from time to time. For the avoidance of doubt, | ||||||
|  |     this trademark restriction does not form part of this License. | ||||||
|  | 
 | ||||||
|  |     Creative Commons may be contacted at http://creativecommons.org/. | ||||||
							
								
								
									
										14
									
								
								vendor/github.com/google/go-github/github/activity.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								vendor/github.com/google/go-github/github/activity.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,14 @@ | |||||||
|  | // Copyright 2013 The go-github 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 github | ||||||
|  | 
 | ||||||
|  | // ActivityService handles communication with the activity related
 | ||||||
|  | // methods of the GitHub API.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: http://developer.github.com/v3/activity/
 | ||||||
|  | type ActivityService struct { | ||||||
|  | 	client *Client | ||||||
|  | } | ||||||
							
								
								
									
										305
									
								
								vendor/github.com/google/go-github/github/activity_events.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										305
									
								
								vendor/github.com/google/go-github/github/activity_events.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,305 @@ | |||||||
|  | // Copyright 2013 The go-github 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 github | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  | 	"encoding/json" | ||||||
|  | 	"fmt" | ||||||
|  | 	"time" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | // Event represents a GitHub event.
 | ||||||
|  | type Event struct { | ||||||
|  | 	Type       *string          `json:"type,omitempty"` | ||||||
|  | 	Public     *bool            `json:"public"` | ||||||
|  | 	RawPayload *json.RawMessage `json:"payload,omitempty"` | ||||||
|  | 	Repo       *Repository      `json:"repo,omitempty"` | ||||||
|  | 	Actor      *User            `json:"actor,omitempty"` | ||||||
|  | 	Org        *Organization    `json:"org,omitempty"` | ||||||
|  | 	CreatedAt  *time.Time       `json:"created_at,omitempty"` | ||||||
|  | 	ID         *string          `json:"id,omitempty"` | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (e Event) String() string { | ||||||
|  | 	return Stringify(e) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Payload returns the parsed event payload. For recognized event types
 | ||||||
|  | // (PushEvent), a value of the corresponding struct type will be returned.
 | ||||||
|  | func (e *Event) Payload() (payload interface{}) { | ||||||
|  | 	switch *e.Type { | ||||||
|  | 	case "PushEvent": | ||||||
|  | 		payload = &PushEvent{} | ||||||
|  | 	} | ||||||
|  | 	if err := json.Unmarshal(*e.RawPayload, &payload); err != nil { | ||||||
|  | 		panic(err.Error()) | ||||||
|  | 	} | ||||||
|  | 	return payload | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // PushEvent represents a git push to a GitHub repository.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: http://developer.github.com/v3/activity/events/types/#pushevent
 | ||||||
|  | type PushEvent struct { | ||||||
|  | 	PushID  *int              `json:"push_id,omitempty"` | ||||||
|  | 	Head    *string           `json:"head,omitempty"` | ||||||
|  | 	Ref     *string           `json:"ref,omitempty"` | ||||||
|  | 	Size    *int              `json:"size,omitempty"` | ||||||
|  | 	Commits []PushEventCommit `json:"commits,omitempty"` | ||||||
|  | 	Repo    *Repository       `json:"repository,omitempty"` | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (p PushEvent) String() string { | ||||||
|  | 	return Stringify(p) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // PushEventCommit represents a git commit in a GitHub PushEvent.
 | ||||||
|  | type PushEventCommit struct { | ||||||
|  | 	SHA      *string       `json:"sha,omitempty"` | ||||||
|  | 	Message  *string       `json:"message,omitempty"` | ||||||
|  | 	Author   *CommitAuthor `json:"author,omitempty"` | ||||||
|  | 	URL      *string       `json:"url,omitempty"` | ||||||
|  | 	Distinct *bool         `json:"distinct,omitempty"` | ||||||
|  | 	Added    []string      `json:"added,omitempty"` | ||||||
|  | 	Removed  []string      `json:"removed,omitempty"` | ||||||
|  | 	Modified []string      `json:"modified,omitempty"` | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (p PushEventCommit) String() string { | ||||||
|  | 	return Stringify(p) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | //PullRequestEvent represents the payload delivered by PullRequestEvent webhook
 | ||||||
|  | type PullRequestEvent struct { | ||||||
|  | 	Action      *string      `json:"action,omitempty"` | ||||||
|  | 	Number      *int         `json:"number,omitempty"` | ||||||
|  | 	PullRequest *PullRequest `json:"pull_request,omitempty"` | ||||||
|  | 	Repo        *Repository  `json:"repository,omitempty"` | ||||||
|  | 	Sender      *User        `json:"sender,omitempty"` | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // IssueActivityEvent represents the payload delivered by Issue webhook
 | ||||||
|  | type IssueActivityEvent struct { | ||||||
|  | 	Action *string     `json:"action,omitempty"` | ||||||
|  | 	Issue  *Issue      `json:"issue,omitempty"` | ||||||
|  | 	Repo   *Repository `json:"repository,omitempty"` | ||||||
|  | 	Sender *User       `json:"sender,omitempty"` | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // IssueCommentEvent represents the payload delivered by IssueComment webhook
 | ||||||
|  | //
 | ||||||
|  | // This webhook also gets fired for comments on pull requests
 | ||||||
|  | type IssueCommentEvent struct { | ||||||
|  | 	Action  *string       `json:"action,omitempty"` | ||||||
|  | 	Issue   *Issue        `json:"issue,omitempty"` | ||||||
|  | 	Comment *IssueComment `json:"comment,omitempty"` | ||||||
|  | 	Repo    *Repository   `json:"repository,omitempty"` | ||||||
|  | 	Sender  *User         `json:"sender,omitempty"` | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ListEvents drinks from the firehose of all public events across GitHub.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: http://developer.github.com/v3/activity/events/#list-public-events
 | ||||||
|  | func (s *ActivityService) ListEvents(opt *ListOptions) ([]Event, *Response, error) { | ||||||
|  | 	u, err := addOptions("events", opt) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	req, err := s.client.NewRequest("GET", u, nil) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	events := new([]Event) | ||||||
|  | 	resp, err := s.client.Do(req, events) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, resp, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return *events, resp, err | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ListRepositoryEvents lists events for a repository.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: http://developer.github.com/v3/activity/events/#list-repository-events
 | ||||||
|  | func (s *ActivityService) ListRepositoryEvents(owner, repo string, opt *ListOptions) ([]Event, *Response, error) { | ||||||
|  | 	u := fmt.Sprintf("repos/%v/%v/events", owner, repo) | ||||||
|  | 	u, err := addOptions(u, opt) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	req, err := s.client.NewRequest("GET", u, nil) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	events := new([]Event) | ||||||
|  | 	resp, err := s.client.Do(req, events) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, resp, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return *events, resp, err | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ListIssueEventsForRepository lists issue events for a repository.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: http://developer.github.com/v3/activity/events/#list-issue-events-for-a-repository
 | ||||||
|  | func (s *ActivityService) ListIssueEventsForRepository(owner, repo string, opt *ListOptions) ([]Event, *Response, error) { | ||||||
|  | 	u := fmt.Sprintf("repos/%v/%v/issues/events", owner, repo) | ||||||
|  | 	u, err := addOptions(u, opt) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	req, err := s.client.NewRequest("GET", u, nil) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	events := new([]Event) | ||||||
|  | 	resp, err := s.client.Do(req, events) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, resp, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return *events, resp, err | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ListEventsForRepoNetwork lists public events for a network of repositories.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: http://developer.github.com/v3/activity/events/#list-public-events-for-a-network-of-repositories
 | ||||||
|  | func (s *ActivityService) ListEventsForRepoNetwork(owner, repo string, opt *ListOptions) ([]Event, *Response, error) { | ||||||
|  | 	u := fmt.Sprintf("networks/%v/%v/events", owner, repo) | ||||||
|  | 	u, err := addOptions(u, opt) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	req, err := s.client.NewRequest("GET", u, nil) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	events := new([]Event) | ||||||
|  | 	resp, err := s.client.Do(req, events) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, resp, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return *events, resp, err | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ListEventsForOrganization lists public events for an organization.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: http://developer.github.com/v3/activity/events/#list-public-events-for-an-organization
 | ||||||
|  | func (s *ActivityService) ListEventsForOrganization(org string, opt *ListOptions) ([]Event, *Response, error) { | ||||||
|  | 	u := fmt.Sprintf("orgs/%v/events", org) | ||||||
|  | 	u, err := addOptions(u, opt) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	req, err := s.client.NewRequest("GET", u, nil) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	events := new([]Event) | ||||||
|  | 	resp, err := s.client.Do(req, events) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, resp, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return *events, resp, err | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ListEventsPerformedByUser lists the events performed by a user. If publicOnly is
 | ||||||
|  | // true, only public events will be returned.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: http://developer.github.com/v3/activity/events/#list-events-performed-by-a-user
 | ||||||
|  | func (s *ActivityService) ListEventsPerformedByUser(user string, publicOnly bool, opt *ListOptions) ([]Event, *Response, error) { | ||||||
|  | 	var u string | ||||||
|  | 	if publicOnly { | ||||||
|  | 		u = fmt.Sprintf("users/%v/events/public", user) | ||||||
|  | 	} else { | ||||||
|  | 		u = fmt.Sprintf("users/%v/events", user) | ||||||
|  | 	} | ||||||
|  | 	u, err := addOptions(u, opt) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	req, err := s.client.NewRequest("GET", u, nil) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	events := new([]Event) | ||||||
|  | 	resp, err := s.client.Do(req, events) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, resp, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return *events, resp, err | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ListEventsReceivedByUser lists the events received by a user. If publicOnly is
 | ||||||
|  | // true, only public events will be returned.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: http://developer.github.com/v3/activity/events/#list-events-that-a-user-has-received
 | ||||||
|  | func (s *ActivityService) ListEventsReceivedByUser(user string, publicOnly bool, opt *ListOptions) ([]Event, *Response, error) { | ||||||
|  | 	var u string | ||||||
|  | 	if publicOnly { | ||||||
|  | 		u = fmt.Sprintf("users/%v/received_events/public", user) | ||||||
|  | 	} else { | ||||||
|  | 		u = fmt.Sprintf("users/%v/received_events", user) | ||||||
|  | 	} | ||||||
|  | 	u, err := addOptions(u, opt) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	req, err := s.client.NewRequest("GET", u, nil) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	events := new([]Event) | ||||||
|  | 	resp, err := s.client.Do(req, events) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, resp, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return *events, resp, err | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ListUserEventsForOrganization provides the user’s organization dashboard. You
 | ||||||
|  | // must be authenticated as the user to view this.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: http://developer.github.com/v3/activity/events/#list-events-for-an-organization
 | ||||||
|  | func (s *ActivityService) ListUserEventsForOrganization(org, user string, opt *ListOptions) ([]Event, *Response, error) { | ||||||
|  | 	u := fmt.Sprintf("users/%v/events/orgs/%v", user, org) | ||||||
|  | 	u, err := addOptions(u, opt) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	req, err := s.client.NewRequest("GET", u, nil) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	events := new([]Event) | ||||||
|  | 	resp, err := s.client.Do(req, events) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, resp, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return *events, resp, err | ||||||
|  | } | ||||||
							
								
								
									
										225
									
								
								vendor/github.com/google/go-github/github/activity_notifications.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										225
									
								
								vendor/github.com/google/go-github/github/activity_notifications.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,225 @@ | |||||||
|  | // Copyright 2014 The go-github 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 github | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  | 	"fmt" | ||||||
|  | 	"time" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | // Notification identifies a GitHub notification for a user.
 | ||||||
|  | type Notification struct { | ||||||
|  | 	ID         *string              `json:"id,omitempty"` | ||||||
|  | 	Repository *Repository          `json:"repository,omitempty"` | ||||||
|  | 	Subject    *NotificationSubject `json:"subject,omitempty"` | ||||||
|  | 
 | ||||||
|  | 	// Reason identifies the event that triggered the notification.
 | ||||||
|  | 	//
 | ||||||
|  | 	// GitHub API Docs: https://developer.github.com/v3/activity/notifications/#notification-reasons
 | ||||||
|  | 	Reason *string `json:"reason,omitempty"` | ||||||
|  | 
 | ||||||
|  | 	Unread     *bool      `json:"unread,omitempty"` | ||||||
|  | 	UpdatedAt  *time.Time `json:"updated_at,omitempty"` | ||||||
|  | 	LastReadAt *time.Time `json:"last_read_at,omitempty"` | ||||||
|  | 	URL        *string    `json:"url,omitempty"` | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // NotificationSubject identifies the subject of a notification.
 | ||||||
|  | type NotificationSubject struct { | ||||||
|  | 	Title            *string `json:"title,omitempty"` | ||||||
|  | 	URL              *string `json:"url,omitempty"` | ||||||
|  | 	LatestCommentURL *string `json:"latest_comment_url,omitempty"` | ||||||
|  | 	Type             *string `json:"type,omitempty"` | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // NotificationListOptions specifies the optional parameters to the
 | ||||||
|  | // ActivityService.ListNotifications method.
 | ||||||
|  | type NotificationListOptions struct { | ||||||
|  | 	All           bool      `url:"all,omitempty"` | ||||||
|  | 	Participating bool      `url:"participating,omitempty"` | ||||||
|  | 	Since         time.Time `url:"since,omitempty"` | ||||||
|  | 	Before        time.Time `url:"before,omitempty"` | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ListNotifications lists all notifications for the authenticated user.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API Docs: https://developer.github.com/v3/activity/notifications/#list-your-notifications
 | ||||||
|  | func (s *ActivityService) ListNotifications(opt *NotificationListOptions) ([]Notification, *Response, error) { | ||||||
|  | 	u := fmt.Sprintf("notifications") | ||||||
|  | 	u, err := addOptions(u, opt) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	req, err := s.client.NewRequest("GET", u, nil) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	var notifications []Notification | ||||||
|  | 	resp, err := s.client.Do(req, ¬ifications) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, resp, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return notifications, resp, err | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ListRepositoryNotifications lists all notifications in a given repository
 | ||||||
|  | // for the authenticated user.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API Docs: https://developer.github.com/v3/activity/notifications/#list-your-notifications-in-a-repository
 | ||||||
|  | func (s *ActivityService) ListRepositoryNotifications(owner, repo string, opt *NotificationListOptions) ([]Notification, *Response, error) { | ||||||
|  | 	u := fmt.Sprintf("repos/%v/%v/notifications", owner, repo) | ||||||
|  | 	u, err := addOptions(u, opt) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	req, err := s.client.NewRequest("GET", u, nil) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	var notifications []Notification | ||||||
|  | 	resp, err := s.client.Do(req, ¬ifications) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, resp, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return notifications, resp, err | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | type markReadOptions struct { | ||||||
|  | 	LastReadAt time.Time `url:"last_read_at,omitempty"` | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // MarkNotificationsRead marks all notifications up to lastRead as read.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API Docs: https://developer.github.com/v3/activity/notifications/#mark-as-read
 | ||||||
|  | func (s *ActivityService) MarkNotificationsRead(lastRead time.Time) (*Response, error) { | ||||||
|  | 	u := fmt.Sprintf("notifications") | ||||||
|  | 	u, err := addOptions(u, markReadOptions{lastRead}) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	req, err := s.client.NewRequest("PUT", u, nil) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return s.client.Do(req, nil) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // MarkRepositoryNotificationsRead marks all notifications up to lastRead in
 | ||||||
|  | // the specified repository as read.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API Docs: https://developer.github.com/v3/activity/notifications/#mark-notifications-as-read-in-a-repository
 | ||||||
|  | func (s *ActivityService) MarkRepositoryNotificationsRead(owner, repo string, lastRead time.Time) (*Response, error) { | ||||||
|  | 	u := fmt.Sprintf("repos/%v/%v/notifications", owner, repo) | ||||||
|  | 	u, err := addOptions(u, markReadOptions{lastRead}) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	req, err := s.client.NewRequest("PUT", u, nil) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return s.client.Do(req, nil) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // GetThread gets the specified notification thread.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API Docs: https://developer.github.com/v3/activity/notifications/#view-a-single-thread
 | ||||||
|  | func (s *ActivityService) GetThread(id string) (*Notification, *Response, error) { | ||||||
|  | 	u := fmt.Sprintf("notifications/threads/%v", id) | ||||||
|  | 
 | ||||||
|  | 	req, err := s.client.NewRequest("GET", u, nil) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	notification := new(Notification) | ||||||
|  | 	resp, err := s.client.Do(req, notification) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, resp, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return notification, resp, err | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // MarkThreadRead marks the specified thread as read.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API Docs: https://developer.github.com/v3/activity/notifications/#mark-a-thread-as-read
 | ||||||
|  | func (s *ActivityService) MarkThreadRead(id string) (*Response, error) { | ||||||
|  | 	u := fmt.Sprintf("notifications/threads/%v", id) | ||||||
|  | 
 | ||||||
|  | 	req, err := s.client.NewRequest("PATCH", u, nil) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return s.client.Do(req, nil) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // GetThreadSubscription checks to see if the authenticated user is subscribed
 | ||||||
|  | // to a thread.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API Docs: https://developer.github.com/v3/activity/notifications/#get-a-thread-subscription
 | ||||||
|  | func (s *ActivityService) GetThreadSubscription(id string) (*Subscription, *Response, error) { | ||||||
|  | 	u := fmt.Sprintf("notifications/threads/%v/subscription", id) | ||||||
|  | 
 | ||||||
|  | 	req, err := s.client.NewRequest("GET", u, nil) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	sub := new(Subscription) | ||||||
|  | 	resp, err := s.client.Do(req, sub) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, resp, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return sub, resp, err | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // SetThreadSubscription sets the subscription for the specified thread for the
 | ||||||
|  | // authenticated user.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API Docs: https://developer.github.com/v3/activity/notifications/#set-a-thread-subscription
 | ||||||
|  | func (s *ActivityService) SetThreadSubscription(id string, subscription *Subscription) (*Subscription, *Response, error) { | ||||||
|  | 	u := fmt.Sprintf("notifications/threads/%v/subscription", id) | ||||||
|  | 
 | ||||||
|  | 	req, err := s.client.NewRequest("PUT", u, subscription) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	sub := new(Subscription) | ||||||
|  | 	resp, err := s.client.Do(req, sub) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, resp, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return sub, resp, err | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // DeleteThreadSubscription deletes the subscription for the specified thread
 | ||||||
|  | // for the authenticated user.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API Docs: https://developer.github.com/v3/activity/notifications/#delete-a-thread-subscription
 | ||||||
|  | func (s *ActivityService) DeleteThreadSubscription(id string) (*Response, error) { | ||||||
|  | 	u := fmt.Sprintf("notifications/threads/%v/subscription", id) | ||||||
|  | 	req, err := s.client.NewRequest("DELETE", u, nil) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return s.client.Do(req, nil) | ||||||
|  | } | ||||||
							
								
								
									
										123
									
								
								vendor/github.com/google/go-github/github/activity_star.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										123
									
								
								vendor/github.com/google/go-github/github/activity_star.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,123 @@ | |||||||
|  | // Copyright 2013 The go-github 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 github | ||||||
|  | 
 | ||||||
|  | import "fmt" | ||||||
|  | 
 | ||||||
|  | // StarredRepository is returned by ListStarred.
 | ||||||
|  | type StarredRepository struct { | ||||||
|  | 	StarredAt  *Timestamp  `json:"starred_at,omitempty"` | ||||||
|  | 	Repository *Repository `json:"repo,omitempty"` | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ListStargazers lists people who have starred the specified repo.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API Docs: https://developer.github.com/v3/activity/starring/#list-stargazers
 | ||||||
|  | func (s *ActivityService) ListStargazers(owner, repo string, opt *ListOptions) ([]User, *Response, error) { | ||||||
|  | 	u := fmt.Sprintf("repos/%s/%s/stargazers", owner, repo) | ||||||
|  | 	u, err := addOptions(u, opt) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	req, err := s.client.NewRequest("GET", u, nil) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	stargazers := new([]User) | ||||||
|  | 	resp, err := s.client.Do(req, stargazers) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, resp, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return *stargazers, resp, err | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ActivityListStarredOptions specifies the optional parameters to the
 | ||||||
|  | // ActivityService.ListStarred method.
 | ||||||
|  | type ActivityListStarredOptions struct { | ||||||
|  | 	// How to sort the repository list.  Possible values are: created, updated,
 | ||||||
|  | 	// pushed, full_name.  Default is "full_name".
 | ||||||
|  | 	Sort string `url:"sort,omitempty"` | ||||||
|  | 
 | ||||||
|  | 	// Direction in which to sort repositories.  Possible values are: asc, desc.
 | ||||||
|  | 	// Default is "asc" when sort is "full_name", otherwise default is "desc".
 | ||||||
|  | 	Direction string `url:"direction,omitempty"` | ||||||
|  | 
 | ||||||
|  | 	ListOptions | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ListStarred lists all the repos starred by a user.  Passing the empty string
 | ||||||
|  | // will list the starred repositories for the authenticated user.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: http://developer.github.com/v3/activity/starring/#list-repositories-being-starred
 | ||||||
|  | func (s *ActivityService) ListStarred(user string, opt *ActivityListStarredOptions) ([]StarredRepository, *Response, error) { | ||||||
|  | 	var u string | ||||||
|  | 	if user != "" { | ||||||
|  | 		u = fmt.Sprintf("users/%v/starred", user) | ||||||
|  | 	} else { | ||||||
|  | 		u = "user/starred" | ||||||
|  | 	} | ||||||
|  | 	u, err := addOptions(u, opt) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	req, err := s.client.NewRequest("GET", u, nil) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	// TODO: remove custom Accept header when this API fully launches
 | ||||||
|  | 	req.Header.Set("Accept", mediaTypeStarringPreview) | ||||||
|  | 
 | ||||||
|  | 	repos := new([]StarredRepository) | ||||||
|  | 	resp, err := s.client.Do(req, repos) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, resp, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return *repos, resp, err | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // IsStarred checks if a repository is starred by authenticated user.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: https://developer.github.com/v3/activity/starring/#check-if-you-are-starring-a-repository
 | ||||||
|  | func (s *ActivityService) IsStarred(owner, repo string) (bool, *Response, error) { | ||||||
|  | 	u := fmt.Sprintf("user/starred/%v/%v", owner, repo) | ||||||
|  | 	req, err := s.client.NewRequest("GET", u, nil) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return false, nil, err | ||||||
|  | 	} | ||||||
|  | 	resp, err := s.client.Do(req, nil) | ||||||
|  | 	starred, err := parseBoolResponse(err) | ||||||
|  | 	return starred, resp, err | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Star a repository as the authenticated user.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: https://developer.github.com/v3/activity/starring/#star-a-repository
 | ||||||
|  | func (s *ActivityService) Star(owner, repo string) (*Response, error) { | ||||||
|  | 	u := fmt.Sprintf("user/starred/%v/%v", owner, repo) | ||||||
|  | 	req, err := s.client.NewRequest("PUT", u, nil) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, err | ||||||
|  | 	} | ||||||
|  | 	return s.client.Do(req, nil) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Unstar a repository as the authenticated user.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: https://developer.github.com/v3/activity/starring/#unstar-a-repository
 | ||||||
|  | func (s *ActivityService) Unstar(owner, repo string) (*Response, error) { | ||||||
|  | 	u := fmt.Sprintf("user/starred/%v/%v", owner, repo) | ||||||
|  | 	req, err := s.client.NewRequest("DELETE", u, nil) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, err | ||||||
|  | 	} | ||||||
|  | 	return s.client.Do(req, nil) | ||||||
|  | } | ||||||
							
								
								
									
										131
									
								
								vendor/github.com/google/go-github/github/activity_watching.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										131
									
								
								vendor/github.com/google/go-github/github/activity_watching.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,131 @@ | |||||||
|  | // Copyright 2014 The go-github 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 github | ||||||
|  | 
 | ||||||
|  | import "fmt" | ||||||
|  | 
 | ||||||
|  | // Subscription identifies a repository or thread subscription.
 | ||||||
|  | type Subscription struct { | ||||||
|  | 	Subscribed *bool      `json:"subscribed,omitempty"` | ||||||
|  | 	Ignored    *bool      `json:"ignored,omitempty"` | ||||||
|  | 	Reason     *string    `json:"reason,omitempty"` | ||||||
|  | 	CreatedAt  *Timestamp `json:"created_at,omitempty"` | ||||||
|  | 	URL        *string    `json:"url,omitempty"` | ||||||
|  | 
 | ||||||
|  | 	// only populated for repository subscriptions
 | ||||||
|  | 	RepositoryURL *string `json:"repository_url,omitempty"` | ||||||
|  | 
 | ||||||
|  | 	// only populated for thread subscriptions
 | ||||||
|  | 	ThreadURL *string `json:"thread_url,omitempty"` | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ListWatchers lists watchers of a particular repo.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API Docs: http://developer.github.com/v3/activity/watching/#list-watchers
 | ||||||
|  | func (s *ActivityService) ListWatchers(owner, repo string, opt *ListOptions) ([]User, *Response, error) { | ||||||
|  | 	u := fmt.Sprintf("repos/%s/%s/subscribers", owner, repo) | ||||||
|  | 	u, err := addOptions(u, opt) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	req, err := s.client.NewRequest("GET", u, nil) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	watchers := new([]User) | ||||||
|  | 	resp, err := s.client.Do(req, watchers) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, resp, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return *watchers, resp, err | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ListWatched lists the repositories the specified user is watching.  Passing
 | ||||||
|  | // the empty string will fetch watched repos for the authenticated user.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API Docs: https://developer.github.com/v3/activity/watching/#list-repositories-being-watched
 | ||||||
|  | func (s *ActivityService) ListWatched(user string) ([]Repository, *Response, error) { | ||||||
|  | 	var u string | ||||||
|  | 	if user != "" { | ||||||
|  | 		u = fmt.Sprintf("users/%v/subscriptions", user) | ||||||
|  | 	} else { | ||||||
|  | 		u = "user/subscriptions" | ||||||
|  | 	} | ||||||
|  | 	req, err := s.client.NewRequest("GET", u, nil) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	watched := new([]Repository) | ||||||
|  | 	resp, err := s.client.Do(req, watched) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, resp, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return *watched, resp, err | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // GetRepositorySubscription returns the subscription for the specified
 | ||||||
|  | // repository for the authenticated user.  If the authenticated user is not
 | ||||||
|  | // watching the repository, a nil Subscription is returned.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API Docs: https://developer.github.com/v3/activity/watching/#get-a-repository-subscription
 | ||||||
|  | func (s *ActivityService) GetRepositorySubscription(owner, repo string) (*Subscription, *Response, error) { | ||||||
|  | 	u := fmt.Sprintf("repos/%s/%s/subscription", owner, repo) | ||||||
|  | 
 | ||||||
|  | 	req, err := s.client.NewRequest("GET", u, nil) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	sub := new(Subscription) | ||||||
|  | 	resp, err := s.client.Do(req, sub) | ||||||
|  | 	if err != nil { | ||||||
|  | 		// if it's just a 404, don't return that as an error
 | ||||||
|  | 		_, err = parseBoolResponse(err) | ||||||
|  | 		return nil, resp, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return sub, resp, err | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // SetRepositorySubscription sets the subscription for the specified repository
 | ||||||
|  | // for the authenticated user.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API Docs: https://developer.github.com/v3/activity/watching/#set-a-repository-subscription
 | ||||||
|  | func (s *ActivityService) SetRepositorySubscription(owner, repo string, subscription *Subscription) (*Subscription, *Response, error) { | ||||||
|  | 	u := fmt.Sprintf("repos/%s/%s/subscription", owner, repo) | ||||||
|  | 
 | ||||||
|  | 	req, err := s.client.NewRequest("PUT", u, subscription) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	sub := new(Subscription) | ||||||
|  | 	resp, err := s.client.Do(req, sub) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, resp, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return sub, resp, err | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // DeleteRepositorySubscription deletes the subscription for the specified
 | ||||||
|  | // repository for the authenticated user.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API Docs: https://developer.github.com/v3/activity/watching/#delete-a-repository-subscription
 | ||||||
|  | func (s *ActivityService) DeleteRepositorySubscription(owner, repo string) (*Response, error) { | ||||||
|  | 	u := fmt.Sprintf("repos/%s/%s/subscription", owner, repo) | ||||||
|  | 	req, err := s.client.NewRequest("DELETE", u, nil) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return s.client.Do(req, nil) | ||||||
|  | } | ||||||
							
								
								
									
										126
									
								
								vendor/github.com/google/go-github/github/doc.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										126
									
								
								vendor/github.com/google/go-github/github/doc.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,126 @@ | |||||||
|  | // Copyright 2013 The go-github 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 github provides a client for using the GitHub API. | ||||||
|  | 
 | ||||||
|  | Construct a new GitHub client, then use the various services on the client to | ||||||
|  | access different parts of the GitHub API. For example: | ||||||
|  | 
 | ||||||
|  | 	client := github.NewClient(nil) | ||||||
|  | 
 | ||||||
|  | 	// list all organizations for user "willnorris"
 | ||||||
|  | 	orgs, _, err := client.Organizations.List("willnorris", nil) | ||||||
|  | 
 | ||||||
|  | Set optional parameters for an API method by passing an Options object. | ||||||
|  | 
 | ||||||
|  | 	// list recently updated repositories for org "github"
 | ||||||
|  | 	opt := &github.RepositoryListByOrgOptions{Sort: "updated"} | ||||||
|  | 	repos, _, err := client.Repositories.ListByOrg("github", opt) | ||||||
|  | 
 | ||||||
|  | The services of a client divide the API into logical chunks and correspond to | ||||||
|  | the structure of the GitHub API documentation at | ||||||
|  | http://developer.github.com/v3/.
 | ||||||
|  | 
 | ||||||
|  | Authentication | ||||||
|  | 
 | ||||||
|  | The go-github library does not directly handle authentication. Instead, when | ||||||
|  | creating a new client, pass an http.Client that can handle authentication for | ||||||
|  | you. The easiest and recommended way to do this is using the golang.org/x/oauth2 | ||||||
|  | library, but you can always use any other library that provides an http.Client. | ||||||
|  | If you have an OAuth2 access token (for example, a personal API token), you can | ||||||
|  | use it with the oauth2 library using: | ||||||
|  | 
 | ||||||
|  | 	import "golang.org/x/oauth2" | ||||||
|  | 
 | ||||||
|  | 	func main() { | ||||||
|  | 		ts := oauth2.StaticTokenSource( | ||||||
|  | 			&oauth2.Token{AccessToken: "... your access token ..."}, | ||||||
|  | 		) | ||||||
|  | 		tc := oauth2.NewClient(oauth2.NoContext, ts) | ||||||
|  | 
 | ||||||
|  | 		client := github.NewClient(tc) | ||||||
|  | 
 | ||||||
|  | 		// list all repositories for the authenticated user
 | ||||||
|  | 		repos, _, err := client.Repositories.List("", nil) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | Note that when using an authenticated Client, all calls made by the client will | ||||||
|  | include the specified OAuth token. Therefore, authenticated clients should | ||||||
|  | almost never be shared between different users. | ||||||
|  | 
 | ||||||
|  | Rate Limiting | ||||||
|  | 
 | ||||||
|  | GitHub imposes a rate limit on all API clients.  Unauthenticated clients are | ||||||
|  | limited to 60 requests per hour, while authenticated clients can make up to | ||||||
|  | 5,000 requests per hour.  To receive the higher rate limit when making calls | ||||||
|  | that are not issued on behalf of a user, use the | ||||||
|  | UnauthenticatedRateLimitedTransport. | ||||||
|  | 
 | ||||||
|  | The Rate field on a client tracks the rate limit information based on the most | ||||||
|  | recent API call.  This is updated on every call, but may be out of date if it's | ||||||
|  | been some time since the last API call and other clients have made subsequent | ||||||
|  | requests since then.  You can always call RateLimit() directly to get the most | ||||||
|  | up-to-date rate limit data for the client. | ||||||
|  | 
 | ||||||
|  | Learn more about GitHub rate limiting at | ||||||
|  | http://developer.github.com/v3/#rate-limiting.
 | ||||||
|  | 
 | ||||||
|  | Conditional Requests | ||||||
|  | 
 | ||||||
|  | The GitHub API has good support for conditional requests which will help | ||||||
|  | prevent you from burning through your rate limit, as well as help speed up your | ||||||
|  | application.  go-github does not handle conditional requests directly, but is | ||||||
|  | instead designed to work with a caching http.Transport.  We recommend using | ||||||
|  | https://github.com/gregjones/httpcache, which can be used in conjuction with
 | ||||||
|  | https://github.com/sourcegraph/apiproxy to provide additional flexibility and
 | ||||||
|  | control of caching rules. | ||||||
|  | 
 | ||||||
|  | Learn more about GitHub conditional requests at | ||||||
|  | https://developer.github.com/v3/#conditional-requests.
 | ||||||
|  | 
 | ||||||
|  | Creating and Updating Resources | ||||||
|  | 
 | ||||||
|  | All structs for GitHub resources use pointer values for all non-repeated fields. | ||||||
|  | This allows distinguishing between unset fields and those set to a zero-value. | ||||||
|  | Helper functions have been provided to easily create these pointers for string, | ||||||
|  | bool, and int values.  For example: | ||||||
|  | 
 | ||||||
|  | 	// create a new private repository named "foo"
 | ||||||
|  | 	repo := &github.Repository{ | ||||||
|  | 		Name:    github.String("foo"), | ||||||
|  | 		Private: github.Bool(true), | ||||||
|  | 	} | ||||||
|  | 	client.Repositories.Create("", repo) | ||||||
|  | 
 | ||||||
|  | Users who have worked with protocol buffers should find this pattern familiar. | ||||||
|  | 
 | ||||||
|  | Pagination | ||||||
|  | 
 | ||||||
|  | All requests for resource collections (repos, pull requests, issues, etc) | ||||||
|  | support pagination. Pagination options are described in the | ||||||
|  | ListOptions struct and passed to the list methods directly or as an | ||||||
|  | embedded type of a more specific list options struct (for example | ||||||
|  | PullRequestListOptions).  Pages information is available via Response struct. | ||||||
|  | 
 | ||||||
|  | 	opt := &github.RepositoryListByOrgOptions{ | ||||||
|  | 		ListOptions: github.ListOptions{PerPage: 10}, | ||||||
|  | 	} | ||||||
|  | 	// get all pages of results
 | ||||||
|  | 	var allRepos []github.Repository | ||||||
|  | 	for { | ||||||
|  | 		repos, resp, err := client.Repositories.ListByOrg("github", opt) | ||||||
|  | 		if err != nil { | ||||||
|  | 			return err | ||||||
|  | 		} | ||||||
|  | 		allRepos = append(allRepos, repos...) | ||||||
|  | 		if resp.NextPage == 0 { | ||||||
|  | 			break | ||||||
|  | 		} | ||||||
|  | 		opt.ListOptions.Page = resp.NextPage | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | */ | ||||||
|  | package github | ||||||
							
								
								
									
										281
									
								
								vendor/github.com/google/go-github/github/gists.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										281
									
								
								vendor/github.com/google/go-github/github/gists.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,281 @@ | |||||||
|  | // Copyright 2013 The go-github AUTHORS. All rights reserved.
 | ||||||
|  | //
 | ||||||
|  | // Use of this source code is governed by BSD-style
 | ||||||
|  | // license that can be found in the LICENSE file.
 | ||||||
|  | 
 | ||||||
|  | package github | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  | 	"fmt" | ||||||
|  | 	"time" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | // GistsService handles communication with the Gist related
 | ||||||
|  | // methods of the GitHub API.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: http://developer.github.com/v3/gists/
 | ||||||
|  | type GistsService struct { | ||||||
|  | 	client *Client | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Gist represents a GitHub's gist.
 | ||||||
|  | type Gist struct { | ||||||
|  | 	ID          *string                   `json:"id,omitempty"` | ||||||
|  | 	Description *string                   `json:"description,omitempty"` | ||||||
|  | 	Public      *bool                     `json:"public,omitempty"` | ||||||
|  | 	Owner       *User                     `json:"owner,omitempty"` | ||||||
|  | 	Files       map[GistFilename]GistFile `json:"files,omitempty"` | ||||||
|  | 	Comments    *int                      `json:"comments,omitempty"` | ||||||
|  | 	HTMLURL     *string                   `json:"html_url,omitempty"` | ||||||
|  | 	GitPullURL  *string                   `json:"git_pull_url,omitempty"` | ||||||
|  | 	GitPushURL  *string                   `json:"git_push_url,omitempty"` | ||||||
|  | 	CreatedAt   *time.Time                `json:"created_at,omitempty"` | ||||||
|  | 	UpdatedAt   *time.Time                `json:"updated_at,omitempty"` | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (g Gist) String() string { | ||||||
|  | 	return Stringify(g) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // GistFilename represents filename on a gist.
 | ||||||
|  | type GistFilename string | ||||||
|  | 
 | ||||||
|  | // GistFile represents a file on a gist.
 | ||||||
|  | type GistFile struct { | ||||||
|  | 	Size     *int    `json:"size,omitempty"` | ||||||
|  | 	Filename *string `json:"filename,omitempty"` | ||||||
|  | 	RawURL   *string `json:"raw_url,omitempty"` | ||||||
|  | 	Content  *string `json:"content,omitempty"` | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (g GistFile) String() string { | ||||||
|  | 	return Stringify(g) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // GistListOptions specifies the optional parameters to the
 | ||||||
|  | // GistsService.List, GistsService.ListAll, and GistsService.ListStarred methods.
 | ||||||
|  | type GistListOptions struct { | ||||||
|  | 	// Since filters Gists by time.
 | ||||||
|  | 	Since time.Time `url:"since,omitempty"` | ||||||
|  | 
 | ||||||
|  | 	ListOptions | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // List gists for a user. Passing the empty string will list
 | ||||||
|  | // all public gists if called anonymously. However, if the call
 | ||||||
|  | // is authenticated, it will returns all gists for the authenticated
 | ||||||
|  | // user.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: http://developer.github.com/v3/gists/#list-gists
 | ||||||
|  | func (s *GistsService) List(user string, opt *GistListOptions) ([]Gist, *Response, error) { | ||||||
|  | 	var u string | ||||||
|  | 	if user != "" { | ||||||
|  | 		u = fmt.Sprintf("users/%v/gists", user) | ||||||
|  | 	} else { | ||||||
|  | 		u = "gists" | ||||||
|  | 	} | ||||||
|  | 	u, err := addOptions(u, opt) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	req, err := s.client.NewRequest("GET", u, nil) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	gists := new([]Gist) | ||||||
|  | 	resp, err := s.client.Do(req, gists) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, resp, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return *gists, resp, err | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ListAll lists all public gists.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: http://developer.github.com/v3/gists/#list-gists
 | ||||||
|  | func (s *GistsService) ListAll(opt *GistListOptions) ([]Gist, *Response, error) { | ||||||
|  | 	u, err := addOptions("gists/public", opt) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	req, err := s.client.NewRequest("GET", u, nil) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	gists := new([]Gist) | ||||||
|  | 	resp, err := s.client.Do(req, gists) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, resp, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return *gists, resp, err | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ListStarred lists starred gists of authenticated user.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: http://developer.github.com/v3/gists/#list-gists
 | ||||||
|  | func (s *GistsService) ListStarred(opt *GistListOptions) ([]Gist, *Response, error) { | ||||||
|  | 	u, err := addOptions("gists/starred", opt) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	req, err := s.client.NewRequest("GET", u, nil) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	gists := new([]Gist) | ||||||
|  | 	resp, err := s.client.Do(req, gists) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, resp, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return *gists, resp, err | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Get a single gist.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: http://developer.github.com/v3/gists/#get-a-single-gist
 | ||||||
|  | func (s *GistsService) Get(id string) (*Gist, *Response, error) { | ||||||
|  | 	u := fmt.Sprintf("gists/%v", id) | ||||||
|  | 	req, err := s.client.NewRequest("GET", u, nil) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 	gist := new(Gist) | ||||||
|  | 	resp, err := s.client.Do(req, gist) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, resp, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return gist, resp, err | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // GetRevision gets a specific revision of a gist.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: https://developer.github.com/v3/gists/#get-a-specific-revision-of-a-gist
 | ||||||
|  | func (s *GistsService) GetRevision(id, sha string) (*Gist, *Response, error) { | ||||||
|  | 	u := fmt.Sprintf("gists/%v/%v", id, sha) | ||||||
|  | 	req, err := s.client.NewRequest("GET", u, nil) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 	gist := new(Gist) | ||||||
|  | 	resp, err := s.client.Do(req, gist) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, resp, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return gist, resp, err | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Create a gist for authenticated user.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: http://developer.github.com/v3/gists/#create-a-gist
 | ||||||
|  | func (s *GistsService) Create(gist *Gist) (*Gist, *Response, error) { | ||||||
|  | 	u := "gists" | ||||||
|  | 	req, err := s.client.NewRequest("POST", u, gist) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 	g := new(Gist) | ||||||
|  | 	resp, err := s.client.Do(req, g) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, resp, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return g, resp, err | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Edit a gist.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: http://developer.github.com/v3/gists/#edit-a-gist
 | ||||||
|  | func (s *GistsService) Edit(id string, gist *Gist) (*Gist, *Response, error) { | ||||||
|  | 	u := fmt.Sprintf("gists/%v", id) | ||||||
|  | 	req, err := s.client.NewRequest("PATCH", u, gist) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 	g := new(Gist) | ||||||
|  | 	resp, err := s.client.Do(req, g) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, resp, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return g, resp, err | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Delete a gist.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: http://developer.github.com/v3/gists/#delete-a-gist
 | ||||||
|  | func (s *GistsService) Delete(id string) (*Response, error) { | ||||||
|  | 	u := fmt.Sprintf("gists/%v", id) | ||||||
|  | 	req, err := s.client.NewRequest("DELETE", u, nil) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, err | ||||||
|  | 	} | ||||||
|  | 	return s.client.Do(req, nil) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Star a gist on behalf of authenticated user.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: http://developer.github.com/v3/gists/#star-a-gist
 | ||||||
|  | func (s *GistsService) Star(id string) (*Response, error) { | ||||||
|  | 	u := fmt.Sprintf("gists/%v/star", id) | ||||||
|  | 	req, err := s.client.NewRequest("PUT", u, nil) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, err | ||||||
|  | 	} | ||||||
|  | 	return s.client.Do(req, nil) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Unstar a gist on a behalf of authenticated user.
 | ||||||
|  | //
 | ||||||
|  | // Github API docs: http://developer.github.com/v3/gists/#unstar-a-gist
 | ||||||
|  | func (s *GistsService) Unstar(id string) (*Response, error) { | ||||||
|  | 	u := fmt.Sprintf("gists/%v/star", id) | ||||||
|  | 	req, err := s.client.NewRequest("DELETE", u, nil) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, err | ||||||
|  | 	} | ||||||
|  | 	return s.client.Do(req, nil) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // IsStarred checks if a gist is starred by authenticated user.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: http://developer.github.com/v3/gists/#check-if-a-gist-is-starred
 | ||||||
|  | func (s *GistsService) IsStarred(id string) (bool, *Response, error) { | ||||||
|  | 	u := fmt.Sprintf("gists/%v/star", id) | ||||||
|  | 	req, err := s.client.NewRequest("GET", u, nil) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return false, nil, err | ||||||
|  | 	} | ||||||
|  | 	resp, err := s.client.Do(req, nil) | ||||||
|  | 	starred, err := parseBoolResponse(err) | ||||||
|  | 	return starred, resp, err | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Fork a gist.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: http://developer.github.com/v3/gists/#fork-a-gist
 | ||||||
|  | func (s *GistsService) Fork(id string) (*Gist, *Response, error) { | ||||||
|  | 	u := fmt.Sprintf("gists/%v/forks", id) | ||||||
|  | 	req, err := s.client.NewRequest("POST", u, nil) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	g := new(Gist) | ||||||
|  | 	resp, err := s.client.Do(req, g) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, resp, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return g, resp, err | ||||||
|  | } | ||||||
							
								
								
									
										118
									
								
								vendor/github.com/google/go-github/github/gists_comments.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										118
									
								
								vendor/github.com/google/go-github/github/gists_comments.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,118 @@ | |||||||
|  | // Copyright 2013 The go-github 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 github | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  | 	"fmt" | ||||||
|  | 	"time" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | // GistComment represents a Gist comment.
 | ||||||
|  | type GistComment struct { | ||||||
|  | 	ID        *int       `json:"id,omitempty"` | ||||||
|  | 	URL       *string    `json:"url,omitempty"` | ||||||
|  | 	Body      *string    `json:"body,omitempty"` | ||||||
|  | 	User      *User      `json:"user,omitempty"` | ||||||
|  | 	CreatedAt *time.Time `json:"created_at,omitempty"` | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (g GistComment) String() string { | ||||||
|  | 	return Stringify(g) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ListComments lists all comments for a gist.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: http://developer.github.com/v3/gists/comments/#list-comments-on-a-gist
 | ||||||
|  | func (s *GistsService) ListComments(gistID string, opt *ListOptions) ([]GistComment, *Response, error) { | ||||||
|  | 	u := fmt.Sprintf("gists/%v/comments", gistID) | ||||||
|  | 	u, err := addOptions(u, opt) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	req, err := s.client.NewRequest("GET", u, nil) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	comments := new([]GistComment) | ||||||
|  | 	resp, err := s.client.Do(req, comments) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, resp, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return *comments, resp, err | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // GetComment retrieves a single comment from a gist.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: http://developer.github.com/v3/gists/comments/#get-a-single-comment
 | ||||||
|  | func (s *GistsService) GetComment(gistID string, commentID int) (*GistComment, *Response, error) { | ||||||
|  | 	u := fmt.Sprintf("gists/%v/comments/%v", gistID, commentID) | ||||||
|  | 	req, err := s.client.NewRequest("GET", u, nil) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	c := new(GistComment) | ||||||
|  | 	resp, err := s.client.Do(req, c) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, resp, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return c, resp, err | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // CreateComment creates a comment for a gist.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: http://developer.github.com/v3/gists/comments/#create-a-comment
 | ||||||
|  | func (s *GistsService) CreateComment(gistID string, comment *GistComment) (*GistComment, *Response, error) { | ||||||
|  | 	u := fmt.Sprintf("gists/%v/comments", gistID) | ||||||
|  | 	req, err := s.client.NewRequest("POST", u, comment) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	c := new(GistComment) | ||||||
|  | 	resp, err := s.client.Do(req, c) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, resp, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return c, resp, err | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // EditComment edits an existing gist comment.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: http://developer.github.com/v3/gists/comments/#edit-a-comment
 | ||||||
|  | func (s *GistsService) EditComment(gistID string, commentID int, comment *GistComment) (*GistComment, *Response, error) { | ||||||
|  | 	u := fmt.Sprintf("gists/%v/comments/%v", gistID, commentID) | ||||||
|  | 	req, err := s.client.NewRequest("PATCH", u, comment) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	c := new(GistComment) | ||||||
|  | 	resp, err := s.client.Do(req, c) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, resp, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return c, resp, err | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // DeleteComment deletes a gist comment.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: http://developer.github.com/v3/gists/comments/#delete-a-comment
 | ||||||
|  | func (s *GistsService) DeleteComment(gistID string, commentID int) (*Response, error) { | ||||||
|  | 	u := fmt.Sprintf("gists/%v/comments/%v", gistID, commentID) | ||||||
|  | 	req, err := s.client.NewRequest("DELETE", u, nil) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return s.client.Do(req, nil) | ||||||
|  | } | ||||||
							
								
								
									
										14
									
								
								vendor/github.com/google/go-github/github/git.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								vendor/github.com/google/go-github/github/git.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,14 @@ | |||||||
|  | // Copyright 2013 The go-github 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 github | ||||||
|  | 
 | ||||||
|  | // GitService handles communication with the git data related
 | ||||||
|  | // methods of the GitHub API.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: http://developer.github.com/v3/git/
 | ||||||
|  | type GitService struct { | ||||||
|  | 	client *Client | ||||||
|  | } | ||||||
							
								
								
									
										47
									
								
								vendor/github.com/google/go-github/github/git_blobs.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										47
									
								
								vendor/github.com/google/go-github/github/git_blobs.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,47 @@ | |||||||
|  | // Copyright 2013 The go-github 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 github | ||||||
|  | 
 | ||||||
|  | import "fmt" | ||||||
|  | 
 | ||||||
|  | // Blob represents a blob object.
 | ||||||
|  | type Blob struct { | ||||||
|  | 	Content  *string `json:"content,omitempty"` | ||||||
|  | 	Encoding *string `json:"encoding,omitempty"` | ||||||
|  | 	SHA      *string `json:"sha,omitempty"` | ||||||
|  | 	Size     *int    `json:"size,omitempty"` | ||||||
|  | 	URL      *string `json:"url,omitempty"` | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // GetBlob fetchs a blob from a repo given a SHA.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: http://developer.github.com/v3/git/blobs/#get-a-blob
 | ||||||
|  | func (s *GitService) GetBlob(owner string, repo string, sha string) (*Blob, *Response, error) { | ||||||
|  | 	u := fmt.Sprintf("repos/%v/%v/git/blobs/%v", owner, repo, sha) | ||||||
|  | 	req, err := s.client.NewRequest("GET", u, nil) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	blob := new(Blob) | ||||||
|  | 	resp, err := s.client.Do(req, blob) | ||||||
|  | 	return blob, resp, err | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // CreateBlob creates a blob object.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: http://developer.github.com/v3/git/blobs/#create-a-blob
 | ||||||
|  | func (s *GitService) CreateBlob(owner string, repo string, blob *Blob) (*Blob, *Response, error) { | ||||||
|  | 	u := fmt.Sprintf("repos/%v/%v/git/blobs", owner, repo) | ||||||
|  | 	req, err := s.client.NewRequest("POST", u, blob) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	t := new(Blob) | ||||||
|  | 	resp, err := s.client.Do(req, t) | ||||||
|  | 	return t, resp, err | ||||||
|  | } | ||||||
							
								
								
									
										112
									
								
								vendor/github.com/google/go-github/github/git_commits.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										112
									
								
								vendor/github.com/google/go-github/github/git_commits.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,112 @@ | |||||||
|  | // Copyright 2013 The go-github 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 github | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  | 	"fmt" | ||||||
|  | 	"time" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | // Commit represents a GitHub commit.
 | ||||||
|  | type Commit struct { | ||||||
|  | 	SHA       *string       `json:"sha,omitempty"` | ||||||
|  | 	Author    *CommitAuthor `json:"author,omitempty"` | ||||||
|  | 	Committer *CommitAuthor `json:"committer,omitempty"` | ||||||
|  | 	Message   *string       `json:"message,omitempty"` | ||||||
|  | 	Tree      *Tree         `json:"tree,omitempty"` | ||||||
|  | 	Parents   []Commit      `json:"parents,omitempty"` | ||||||
|  | 	Stats     *CommitStats  `json:"stats,omitempty"` | ||||||
|  | 	URL       *string       `json:"url,omitempty"` | ||||||
|  | 
 | ||||||
|  | 	// CommentCount is the number of GitHub comments on the commit.  This
 | ||||||
|  | 	// is only populated for requests that fetch GitHub data like
 | ||||||
|  | 	// Pulls.ListCommits, Repositories.ListCommits, etc.
 | ||||||
|  | 	CommentCount *int `json:"comment_count,omitempty"` | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (c Commit) String() string { | ||||||
|  | 	return Stringify(c) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // CommitAuthor represents the author or committer of a commit.  The commit
 | ||||||
|  | // author may not correspond to a GitHub User.
 | ||||||
|  | type CommitAuthor struct { | ||||||
|  | 	Date  *time.Time `json:"date,omitempty"` | ||||||
|  | 	Name  *string    `json:"name,omitempty"` | ||||||
|  | 	Email *string    `json:"email,omitempty"` | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (c CommitAuthor) String() string { | ||||||
|  | 	return Stringify(c) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // GetCommit fetchs the Commit object for a given SHA.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: http://developer.github.com/v3/git/commits/#get-a-commit
 | ||||||
|  | func (s *GitService) GetCommit(owner string, repo string, sha string) (*Commit, *Response, error) { | ||||||
|  | 	u := fmt.Sprintf("repos/%v/%v/git/commits/%v", owner, repo, sha) | ||||||
|  | 	req, err := s.client.NewRequest("GET", u, nil) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	c := new(Commit) | ||||||
|  | 	resp, err := s.client.Do(req, c) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, resp, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return c, resp, err | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // createCommit represents the body of a CreateCommit request.
 | ||||||
|  | type createCommit struct { | ||||||
|  | 	Author    *CommitAuthor `json:"author,omitempty"` | ||||||
|  | 	Committer *CommitAuthor `json:"committer,omitempty"` | ||||||
|  | 	Message   *string       `json:"message,omitempty"` | ||||||
|  | 	Tree      *string       `json:"tree,omitempty"` | ||||||
|  | 	Parents   []string      `json:"parents,omitempty"` | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // CreateCommit creates a new commit in a repository.
 | ||||||
|  | //
 | ||||||
|  | // The commit.Committer is optional and will be filled with the commit.Author
 | ||||||
|  | // data if omitted. If the commit.Author is omitted, it will be filled in with
 | ||||||
|  | // the authenticated user’s information and the current date.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: http://developer.github.com/v3/git/commits/#create-a-commit
 | ||||||
|  | func (s *GitService) CreateCommit(owner string, repo string, commit *Commit) (*Commit, *Response, error) { | ||||||
|  | 	u := fmt.Sprintf("repos/%v/%v/git/commits", owner, repo) | ||||||
|  | 
 | ||||||
|  | 	body := &createCommit{} | ||||||
|  | 	if commit != nil { | ||||||
|  | 		parents := make([]string, len(commit.Parents)) | ||||||
|  | 		for i, parent := range commit.Parents { | ||||||
|  | 			parents[i] = *parent.SHA | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		body = &createCommit{ | ||||||
|  | 			Author:    commit.Author, | ||||||
|  | 			Committer: commit.Committer, | ||||||
|  | 			Message:   commit.Message, | ||||||
|  | 			Tree:      commit.Tree.SHA, | ||||||
|  | 			Parents:   parents, | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	req, err := s.client.NewRequest("POST", u, body) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	c := new(Commit) | ||||||
|  | 	resp, err := s.client.Do(req, c) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, resp, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return c, resp, err | ||||||
|  | } | ||||||
							
								
								
									
										162
									
								
								vendor/github.com/google/go-github/github/git_refs.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										162
									
								
								vendor/github.com/google/go-github/github/git_refs.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,162 @@ | |||||||
|  | // Copyright 2013 The go-github 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 github | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  | 	"fmt" | ||||||
|  | 	"strings" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | // Reference represents a GitHub reference.
 | ||||||
|  | type Reference struct { | ||||||
|  | 	Ref    *string    `json:"ref"` | ||||||
|  | 	URL    *string    `json:"url"` | ||||||
|  | 	Object *GitObject `json:"object"` | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (r Reference) String() string { | ||||||
|  | 	return Stringify(r) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // GitObject represents a Git object.
 | ||||||
|  | type GitObject struct { | ||||||
|  | 	Type *string `json:"type"` | ||||||
|  | 	SHA  *string `json:"sha"` | ||||||
|  | 	URL  *string `json:"url"` | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (o GitObject) String() string { | ||||||
|  | 	return Stringify(o) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // createRefRequest represents the payload for creating a reference.
 | ||||||
|  | type createRefRequest struct { | ||||||
|  | 	Ref *string `json:"ref"` | ||||||
|  | 	SHA *string `json:"sha"` | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // updateRefRequest represents the payload for updating a reference.
 | ||||||
|  | type updateRefRequest struct { | ||||||
|  | 	SHA   *string `json:"sha"` | ||||||
|  | 	Force *bool   `json:"force"` | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // GetRef fetches the Reference object for a given Git ref.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: http://developer.github.com/v3/git/refs/#get-a-reference
 | ||||||
|  | func (s *GitService) GetRef(owner string, repo string, ref string) (*Reference, *Response, error) { | ||||||
|  | 	ref = strings.TrimPrefix(ref, "refs/") | ||||||
|  | 	u := fmt.Sprintf("repos/%v/%v/git/refs/%v", owner, repo, ref) | ||||||
|  | 	req, err := s.client.NewRequest("GET", u, nil) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	r := new(Reference) | ||||||
|  | 	resp, err := s.client.Do(req, r) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, resp, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return r, resp, err | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ReferenceListOptions specifies optional parameters to the
 | ||||||
|  | // GitService.ListRefs method.
 | ||||||
|  | type ReferenceListOptions struct { | ||||||
|  | 	Type string `url:"-"` | ||||||
|  | 
 | ||||||
|  | 	ListOptions | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ListRefs lists all refs in a repository.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: http://developer.github.com/v3/git/refs/#get-all-references
 | ||||||
|  | func (s *GitService) ListRefs(owner, repo string, opt *ReferenceListOptions) ([]Reference, *Response, error) { | ||||||
|  | 	var u string | ||||||
|  | 	if opt != nil && opt.Type != "" { | ||||||
|  | 		u = fmt.Sprintf("repos/%v/%v/git/refs/%v", owner, repo, opt.Type) | ||||||
|  | 	} else { | ||||||
|  | 		u = fmt.Sprintf("repos/%v/%v/git/refs", owner, repo) | ||||||
|  | 	} | ||||||
|  | 	u, err := addOptions(u, opt) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	req, err := s.client.NewRequest("GET", u, nil) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	var rs []Reference | ||||||
|  | 	resp, err := s.client.Do(req, &rs) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, resp, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return rs, resp, err | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // CreateRef creates a new ref in a repository.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: http://developer.github.com/v3/git/refs/#create-a-reference
 | ||||||
|  | func (s *GitService) CreateRef(owner string, repo string, ref *Reference) (*Reference, *Response, error) { | ||||||
|  | 	u := fmt.Sprintf("repos/%v/%v/git/refs", owner, repo) | ||||||
|  | 	req, err := s.client.NewRequest("POST", u, &createRefRequest{ | ||||||
|  | 		// back-compat with previous behavior that didn't require 'refs/' prefix
 | ||||||
|  | 		Ref: String("refs/" + strings.TrimPrefix(*ref.Ref, "refs/")), | ||||||
|  | 		SHA: ref.Object.SHA, | ||||||
|  | 	}) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	r := new(Reference) | ||||||
|  | 	resp, err := s.client.Do(req, r) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, resp, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return r, resp, err | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // UpdateRef updates an existing ref in a repository.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: http://developer.github.com/v3/git/refs/#update-a-reference
 | ||||||
|  | func (s *GitService) UpdateRef(owner string, repo string, ref *Reference, force bool) (*Reference, *Response, error) { | ||||||
|  | 	refPath := strings.TrimPrefix(*ref.Ref, "refs/") | ||||||
|  | 	u := fmt.Sprintf("repos/%v/%v/git/refs/%v", owner, repo, refPath) | ||||||
|  | 	req, err := s.client.NewRequest("PATCH", u, &updateRefRequest{ | ||||||
|  | 		SHA:   ref.Object.SHA, | ||||||
|  | 		Force: &force, | ||||||
|  | 	}) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	r := new(Reference) | ||||||
|  | 	resp, err := s.client.Do(req, r) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, resp, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return r, resp, err | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // DeleteRef deletes a ref from a repository.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: http://developer.github.com/v3/git/refs/#delete-a-reference
 | ||||||
|  | func (s *GitService) DeleteRef(owner string, repo string, ref string) (*Response, error) { | ||||||
|  | 	ref = strings.TrimPrefix(ref, "refs/") | ||||||
|  | 	u := fmt.Sprintf("repos/%v/%v/git/refs/%v", owner, repo, ref) | ||||||
|  | 	req, err := s.client.NewRequest("DELETE", u, nil) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return s.client.Do(req, nil) | ||||||
|  | } | ||||||
							
								
								
									
										73
									
								
								vendor/github.com/google/go-github/github/git_tags.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										73
									
								
								vendor/github.com/google/go-github/github/git_tags.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,73 @@ | |||||||
|  | // Copyright 2013 The go-github 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 github | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  | 	"fmt" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | // Tag represents a tag object.
 | ||||||
|  | type Tag struct { | ||||||
|  | 	Tag     *string       `json:"tag,omitempty"` | ||||||
|  | 	SHA     *string       `json:"sha,omitempty"` | ||||||
|  | 	URL     *string       `json:"url,omitempty"` | ||||||
|  | 	Message *string       `json:"message,omitempty"` | ||||||
|  | 	Tagger  *CommitAuthor `json:"tagger,omitempty"` | ||||||
|  | 	Object  *GitObject    `json:"object,omitempty"` | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // createTagRequest represents the body of a CreateTag request.  This is mostly
 | ||||||
|  | // identical to Tag with the exception that the object SHA and Type are
 | ||||||
|  | // top-level fields, rather than being nested inside a JSON object.
 | ||||||
|  | type createTagRequest struct { | ||||||
|  | 	Tag     *string       `json:"tag,omitempty"` | ||||||
|  | 	Message *string       `json:"message,omitempty"` | ||||||
|  | 	Object  *string       `json:"object,omitempty"` | ||||||
|  | 	Type    *string       `json:"type,omitempty"` | ||||||
|  | 	Tagger  *CommitAuthor `json:"tagger,omitempty"` | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // GetTag fetchs a tag from a repo given a SHA.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: http://developer.github.com/v3/git/tags/#get-a-tag
 | ||||||
|  | func (s *GitService) GetTag(owner string, repo string, sha string) (*Tag, *Response, error) { | ||||||
|  | 	u := fmt.Sprintf("repos/%v/%v/git/tags/%v", owner, repo, sha) | ||||||
|  | 	req, err := s.client.NewRequest("GET", u, nil) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	tag := new(Tag) | ||||||
|  | 	resp, err := s.client.Do(req, tag) | ||||||
|  | 	return tag, resp, err | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // CreateTag creates a tag object.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: http://developer.github.com/v3/git/tags/#create-a-tag-object
 | ||||||
|  | func (s *GitService) CreateTag(owner string, repo string, tag *Tag) (*Tag, *Response, error) { | ||||||
|  | 	u := fmt.Sprintf("repos/%v/%v/git/tags", owner, repo) | ||||||
|  | 
 | ||||||
|  | 	// convert Tag into a createTagRequest
 | ||||||
|  | 	tagRequest := &createTagRequest{ | ||||||
|  | 		Tag:     tag.Tag, | ||||||
|  | 		Message: tag.Message, | ||||||
|  | 		Tagger:  tag.Tagger, | ||||||
|  | 	} | ||||||
|  | 	if tag.Object != nil { | ||||||
|  | 		tagRequest.Object = tag.Object.SHA | ||||||
|  | 		tagRequest.Type = tag.Object.Type | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	req, err := s.client.NewRequest("POST", u, tagRequest) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	t := new(Tag) | ||||||
|  | 	resp, err := s.client.Do(req, t) | ||||||
|  | 	return t, resp, err | ||||||
|  | } | ||||||
							
								
								
									
										89
									
								
								vendor/github.com/google/go-github/github/git_trees.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										89
									
								
								vendor/github.com/google/go-github/github/git_trees.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,89 @@ | |||||||
|  | // Copyright 2013 The go-github 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 github | ||||||
|  | 
 | ||||||
|  | import "fmt" | ||||||
|  | 
 | ||||||
|  | // Tree represents a GitHub tree.
 | ||||||
|  | type Tree struct { | ||||||
|  | 	SHA     *string     `json:"sha,omitempty"` | ||||||
|  | 	Entries []TreeEntry `json:"tree,omitempty"` | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (t Tree) String() string { | ||||||
|  | 	return Stringify(t) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // TreeEntry represents the contents of a tree structure.  TreeEntry can
 | ||||||
|  | // represent either a blob, a commit (in the case of a submodule), or another
 | ||||||
|  | // tree.
 | ||||||
|  | type TreeEntry struct { | ||||||
|  | 	SHA     *string `json:"sha,omitempty"` | ||||||
|  | 	Path    *string `json:"path,omitempty"` | ||||||
|  | 	Mode    *string `json:"mode,omitempty"` | ||||||
|  | 	Type    *string `json:"type,omitempty"` | ||||||
|  | 	Size    *int    `json:"size,omitempty"` | ||||||
|  | 	Content *string `json:"content,omitempty"` | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (t TreeEntry) String() string { | ||||||
|  | 	return Stringify(t) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // GetTree fetches the Tree object for a given sha hash from a repository.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: http://developer.github.com/v3/git/trees/#get-a-tree
 | ||||||
|  | func (s *GitService) GetTree(owner string, repo string, sha string, recursive bool) (*Tree, *Response, error) { | ||||||
|  | 	u := fmt.Sprintf("repos/%v/%v/git/trees/%v", owner, repo, sha) | ||||||
|  | 	if recursive { | ||||||
|  | 		u += "?recursive=1" | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	req, err := s.client.NewRequest("GET", u, nil) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	t := new(Tree) | ||||||
|  | 	resp, err := s.client.Do(req, t) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, resp, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return t, resp, err | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // createTree represents the body of a CreateTree request.
 | ||||||
|  | type createTree struct { | ||||||
|  | 	BaseTree string      `json:"base_tree,omitempty"` | ||||||
|  | 	Entries  []TreeEntry `json:"tree"` | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // CreateTree creates a new tree in a repository.  If both a tree and a nested
 | ||||||
|  | // path modifying that tree are specified, it will overwrite the contents of
 | ||||||
|  | // that tree with the new path contents and write a new tree out.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: http://developer.github.com/v3/git/trees/#create-a-tree
 | ||||||
|  | func (s *GitService) CreateTree(owner string, repo string, baseTree string, entries []TreeEntry) (*Tree, *Response, error) { | ||||||
|  | 	u := fmt.Sprintf("repos/%v/%v/git/trees", owner, repo) | ||||||
|  | 
 | ||||||
|  | 	body := &createTree{ | ||||||
|  | 		BaseTree: baseTree, | ||||||
|  | 		Entries:  entries, | ||||||
|  | 	} | ||||||
|  | 	req, err := s.client.NewRequest("POST", u, body) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	t := new(Tree) | ||||||
|  | 	resp, err := s.client.Do(req, t) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, resp, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return t, resp, err | ||||||
|  | } | ||||||
							
								
								
									
										588
									
								
								vendor/github.com/google/go-github/github/github.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										588
									
								
								vendor/github.com/google/go-github/github/github.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,588 @@ | |||||||
|  | // Copyright 2013 The go-github 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 github | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  | 	"bytes" | ||||||
|  | 	"encoding/json" | ||||||
|  | 	"errors" | ||||||
|  | 	"fmt" | ||||||
|  | 	"io" | ||||||
|  | 	"io/ioutil" | ||||||
|  | 	"net/http" | ||||||
|  | 	"net/url" | ||||||
|  | 	"reflect" | ||||||
|  | 	"strconv" | ||||||
|  | 	"strings" | ||||||
|  | 	"time" | ||||||
|  | 
 | ||||||
|  | 	"github.com/google/go-querystring/query" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | const ( | ||||||
|  | 	libraryVersion = "0.1" | ||||||
|  | 	defaultBaseURL = "https://api.github.com/" | ||||||
|  | 	uploadBaseURL  = "https://uploads.github.com/" | ||||||
|  | 	userAgent      = "go-github/" + libraryVersion | ||||||
|  | 
 | ||||||
|  | 	headerRateLimit     = "X-RateLimit-Limit" | ||||||
|  | 	headerRateRemaining = "X-RateLimit-Remaining" | ||||||
|  | 	headerRateReset     = "X-RateLimit-Reset" | ||||||
|  | 
 | ||||||
|  | 	mediaTypeV3      = "application/vnd.github.v3+json" | ||||||
|  | 	defaultMediaType = "application/octet-stream" | ||||||
|  | 
 | ||||||
|  | 	// Media Type values to access preview APIs
 | ||||||
|  | 
 | ||||||
|  | 	// https://developer.github.com/changes/2015-03-09-licenses-api/
 | ||||||
|  | 	mediaTypeLicensesPreview = "application/vnd.github.drax-preview+json" | ||||||
|  | 
 | ||||||
|  | 	// https://developer.github.com/changes/2014-12-09-new-attributes-for-stars-api/
 | ||||||
|  | 	mediaTypeStarringPreview = "application/vnd.github.v3.star+json" | ||||||
|  | 
 | ||||||
|  | 	// https://developer.github.com/changes/2015-06-24-api-enhancements-for-working-with-organization-permissions/
 | ||||||
|  | 	mediaTypeOrgPermissionPreview     = "application/vnd.github.ironman-preview+json" | ||||||
|  | 	mediaTypeOrgPermissionRepoPreview = "application/vnd.github.ironman-preview.repository+json" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | // A Client manages communication with the GitHub API.
 | ||||||
|  | type Client struct { | ||||||
|  | 	// HTTP client used to communicate with the API.
 | ||||||
|  | 	client *http.Client | ||||||
|  | 
 | ||||||
|  | 	// Base URL for API requests.  Defaults to the public GitHub API, but can be
 | ||||||
|  | 	// set to a domain endpoint to use with GitHub Enterprise.  BaseURL should
 | ||||||
|  | 	// always be specified with a trailing slash.
 | ||||||
|  | 	BaseURL *url.URL | ||||||
|  | 
 | ||||||
|  | 	// Base URL for uploading files.
 | ||||||
|  | 	UploadURL *url.URL | ||||||
|  | 
 | ||||||
|  | 	// User agent used when communicating with the GitHub API.
 | ||||||
|  | 	UserAgent string | ||||||
|  | 
 | ||||||
|  | 	// Rate specifies the current rate limit for the client as determined by the
 | ||||||
|  | 	// most recent API call.  If the client is used in a multi-user application,
 | ||||||
|  | 	// this rate may not always be up-to-date.  Call RateLimits() to check the
 | ||||||
|  | 	// current rate.
 | ||||||
|  | 	Rate Rate | ||||||
|  | 
 | ||||||
|  | 	// Services used for talking to different parts of the GitHub API.
 | ||||||
|  | 	Activity      *ActivityService | ||||||
|  | 	Gists         *GistsService | ||||||
|  | 	Git           *GitService | ||||||
|  | 	Gitignores    *GitignoresService | ||||||
|  | 	Issues        *IssuesService | ||||||
|  | 	Organizations *OrganizationsService | ||||||
|  | 	PullRequests  *PullRequestsService | ||||||
|  | 	Repositories  *RepositoriesService | ||||||
|  | 	Search        *SearchService | ||||||
|  | 	Users         *UsersService | ||||||
|  | 	Licenses      *LicensesService | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ListOptions specifies the optional parameters to various List methods that
 | ||||||
|  | // support pagination.
 | ||||||
|  | type ListOptions struct { | ||||||
|  | 	// For paginated result sets, page of results to retrieve.
 | ||||||
|  | 	Page int `url:"page,omitempty"` | ||||||
|  | 
 | ||||||
|  | 	// For paginated result sets, the number of results to include per page.
 | ||||||
|  | 	PerPage int `url:"per_page,omitempty"` | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // UploadOptions specifies the parameters to methods that support uploads.
 | ||||||
|  | type UploadOptions struct { | ||||||
|  | 	Name string `url:"name,omitempty"` | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // addOptions adds the parameters in opt as URL query parameters to s.  opt
 | ||||||
|  | // must be a struct whose fields may contain "url" tags.
 | ||||||
|  | func addOptions(s string, opt interface{}) (string, error) { | ||||||
|  | 	v := reflect.ValueOf(opt) | ||||||
|  | 	if v.Kind() == reflect.Ptr && v.IsNil() { | ||||||
|  | 		return s, nil | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	u, err := url.Parse(s) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return s, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	qs, err := query.Values(opt) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return s, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	u.RawQuery = qs.Encode() | ||||||
|  | 	return u.String(), nil | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // NewClient returns a new GitHub API client.  If a nil httpClient is
 | ||||||
|  | // provided, http.DefaultClient will be used.  To use API methods which require
 | ||||||
|  | // authentication, provide an http.Client that will perform the authentication
 | ||||||
|  | // for you (such as that provided by the golang.org/x/oauth2 library).
 | ||||||
|  | func NewClient(httpClient *http.Client) *Client { | ||||||
|  | 	if httpClient == nil { | ||||||
|  | 		httpClient = http.DefaultClient | ||||||
|  | 	} | ||||||
|  | 	baseURL, _ := url.Parse(defaultBaseURL) | ||||||
|  | 	uploadURL, _ := url.Parse(uploadBaseURL) | ||||||
|  | 
 | ||||||
|  | 	c := &Client{client: httpClient, BaseURL: baseURL, UserAgent: userAgent, UploadURL: uploadURL} | ||||||
|  | 	c.Activity = &ActivityService{client: c} | ||||||
|  | 	c.Gists = &GistsService{client: c} | ||||||
|  | 	c.Git = &GitService{client: c} | ||||||
|  | 	c.Gitignores = &GitignoresService{client: c} | ||||||
|  | 	c.Issues = &IssuesService{client: c} | ||||||
|  | 	c.Organizations = &OrganizationsService{client: c} | ||||||
|  | 	c.PullRequests = &PullRequestsService{client: c} | ||||||
|  | 	c.Repositories = &RepositoriesService{client: c} | ||||||
|  | 	c.Search = &SearchService{client: c} | ||||||
|  | 	c.Users = &UsersService{client: c} | ||||||
|  | 	c.Licenses = &LicensesService{client: c} | ||||||
|  | 	return c | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // NewRequest creates an API request. A relative URL can be provided in urlStr,
 | ||||||
|  | // in which case it is resolved relative to the BaseURL of the Client.
 | ||||||
|  | // Relative URLs should always be specified without a preceding slash.  If
 | ||||||
|  | // specified, the value pointed to by body is JSON encoded and included as the
 | ||||||
|  | // request body.
 | ||||||
|  | func (c *Client) NewRequest(method, urlStr string, body interface{}) (*http.Request, error) { | ||||||
|  | 	rel, err := url.Parse(urlStr) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	u := c.BaseURL.ResolveReference(rel) | ||||||
|  | 
 | ||||||
|  | 	var buf io.ReadWriter | ||||||
|  | 	if body != nil { | ||||||
|  | 		buf = new(bytes.Buffer) | ||||||
|  | 		err := json.NewEncoder(buf).Encode(body) | ||||||
|  | 		if err != nil { | ||||||
|  | 			return nil, err | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	req, err := http.NewRequest(method, u.String(), buf) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	req.Header.Add("Accept", mediaTypeV3) | ||||||
|  | 	if c.UserAgent != "" { | ||||||
|  | 		req.Header.Add("User-Agent", c.UserAgent) | ||||||
|  | 	} | ||||||
|  | 	return req, nil | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // NewUploadRequest creates an upload request. A relative URL can be provided in
 | ||||||
|  | // urlStr, in which case it is resolved relative to the UploadURL of the Client.
 | ||||||
|  | // Relative URLs should always be specified without a preceding slash.
 | ||||||
|  | func (c *Client) NewUploadRequest(urlStr string, reader io.Reader, size int64, mediaType string) (*http.Request, error) { | ||||||
|  | 	rel, err := url.Parse(urlStr) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	u := c.UploadURL.ResolveReference(rel) | ||||||
|  | 	req, err := http.NewRequest("POST", u.String(), reader) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, err | ||||||
|  | 	} | ||||||
|  | 	req.ContentLength = size | ||||||
|  | 
 | ||||||
|  | 	if len(mediaType) == 0 { | ||||||
|  | 		mediaType = defaultMediaType | ||||||
|  | 	} | ||||||
|  | 	req.Header.Add("Content-Type", mediaType) | ||||||
|  | 	req.Header.Add("Accept", mediaTypeV3) | ||||||
|  | 	req.Header.Add("User-Agent", c.UserAgent) | ||||||
|  | 	return req, nil | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Response is a GitHub API response.  This wraps the standard http.Response
 | ||||||
|  | // returned from GitHub and provides convenient access to things like
 | ||||||
|  | // pagination links.
 | ||||||
|  | type Response struct { | ||||||
|  | 	*http.Response | ||||||
|  | 
 | ||||||
|  | 	// These fields provide the page values for paginating through a set of
 | ||||||
|  | 	// results.  Any or all of these may be set to the zero value for
 | ||||||
|  | 	// responses that are not part of a paginated set, or for which there
 | ||||||
|  | 	// are no additional pages.
 | ||||||
|  | 
 | ||||||
|  | 	NextPage  int | ||||||
|  | 	PrevPage  int | ||||||
|  | 	FirstPage int | ||||||
|  | 	LastPage  int | ||||||
|  | 
 | ||||||
|  | 	Rate | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // newResponse creates a new Response for the provided http.Response.
 | ||||||
|  | func newResponse(r *http.Response) *Response { | ||||||
|  | 	response := &Response{Response: r} | ||||||
|  | 	response.populatePageValues() | ||||||
|  | 	response.populateRate() | ||||||
|  | 	return response | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // populatePageValues parses the HTTP Link response headers and populates the
 | ||||||
|  | // various pagination link values in the Reponse.
 | ||||||
|  | func (r *Response) populatePageValues() { | ||||||
|  | 	if links, ok := r.Response.Header["Link"]; ok && len(links) > 0 { | ||||||
|  | 		for _, link := range strings.Split(links[0], ",") { | ||||||
|  | 			segments := strings.Split(strings.TrimSpace(link), ";") | ||||||
|  | 
 | ||||||
|  | 			// link must at least have href and rel
 | ||||||
|  | 			if len(segments) < 2 { | ||||||
|  | 				continue | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
|  | 			// ensure href is properly formatted
 | ||||||
|  | 			if !strings.HasPrefix(segments[0], "<") || !strings.HasSuffix(segments[0], ">") { | ||||||
|  | 				continue | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
|  | 			// try to pull out page parameter
 | ||||||
|  | 			url, err := url.Parse(segments[0][1 : len(segments[0])-1]) | ||||||
|  | 			if err != nil { | ||||||
|  | 				continue | ||||||
|  | 			} | ||||||
|  | 			page := url.Query().Get("page") | ||||||
|  | 			if page == "" { | ||||||
|  | 				continue | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
|  | 			for _, segment := range segments[1:] { | ||||||
|  | 				switch strings.TrimSpace(segment) { | ||||||
|  | 				case `rel="next"`: | ||||||
|  | 					r.NextPage, _ = strconv.Atoi(page) | ||||||
|  | 				case `rel="prev"`: | ||||||
|  | 					r.PrevPage, _ = strconv.Atoi(page) | ||||||
|  | 				case `rel="first"`: | ||||||
|  | 					r.FirstPage, _ = strconv.Atoi(page) | ||||||
|  | 				case `rel="last"`: | ||||||
|  | 					r.LastPage, _ = strconv.Atoi(page) | ||||||
|  | 				} | ||||||
|  | 
 | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // populateRate parses the rate related headers and populates the response Rate.
 | ||||||
|  | func (r *Response) populateRate() { | ||||||
|  | 	if limit := r.Header.Get(headerRateLimit); limit != "" { | ||||||
|  | 		r.Rate.Limit, _ = strconv.Atoi(limit) | ||||||
|  | 	} | ||||||
|  | 	if remaining := r.Header.Get(headerRateRemaining); remaining != "" { | ||||||
|  | 		r.Rate.Remaining, _ = strconv.Atoi(remaining) | ||||||
|  | 	} | ||||||
|  | 	if reset := r.Header.Get(headerRateReset); reset != "" { | ||||||
|  | 		if v, _ := strconv.ParseInt(reset, 10, 64); v != 0 { | ||||||
|  | 			r.Rate.Reset = Timestamp{time.Unix(v, 0)} | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Do sends an API request and returns the API response.  The API response is
 | ||||||
|  | // JSON decoded and stored in the value pointed to by v, or returned as an
 | ||||||
|  | // error if an API error has occurred.  If v implements the io.Writer
 | ||||||
|  | // interface, the raw response body will be written to v, without attempting to
 | ||||||
|  | // first decode it.
 | ||||||
|  | func (c *Client) Do(req *http.Request, v interface{}) (*Response, error) { | ||||||
|  | 	resp, err := c.client.Do(req) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	defer resp.Body.Close() | ||||||
|  | 
 | ||||||
|  | 	response := newResponse(resp) | ||||||
|  | 
 | ||||||
|  | 	c.Rate = response.Rate | ||||||
|  | 
 | ||||||
|  | 	err = CheckResponse(resp) | ||||||
|  | 	if err != nil { | ||||||
|  | 		// even though there was an error, we still return the response
 | ||||||
|  | 		// in case the caller wants to inspect it further
 | ||||||
|  | 		return response, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if v != nil { | ||||||
|  | 		if w, ok := v.(io.Writer); ok { | ||||||
|  | 			io.Copy(w, resp.Body) | ||||||
|  | 		} else { | ||||||
|  | 			err = json.NewDecoder(resp.Body).Decode(v) | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	return response, err | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /* | ||||||
|  | An ErrorResponse reports one or more errors caused by an API request. | ||||||
|  | 
 | ||||||
|  | GitHub API docs: http://developer.github.com/v3/#client-errors
 | ||||||
|  | */ | ||||||
|  | type ErrorResponse struct { | ||||||
|  | 	Response *http.Response // HTTP response that caused this error
 | ||||||
|  | 	Message  string         `json:"message"` // error message
 | ||||||
|  | 	Errors   []Error        `json:"errors"`  // more detail on individual errors
 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (r *ErrorResponse) Error() string { | ||||||
|  | 	return fmt.Sprintf("%v %v: %d %v %+v", | ||||||
|  | 		r.Response.Request.Method, sanitizeURL(r.Response.Request.URL), | ||||||
|  | 		r.Response.StatusCode, r.Message, r.Errors) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // sanitizeURL redacts the client_id and client_secret tokens from the URL which
 | ||||||
|  | // may be exposed to the user, specifically in the ErrorResponse error message.
 | ||||||
|  | func sanitizeURL(uri *url.URL) *url.URL { | ||||||
|  | 	if uri == nil { | ||||||
|  | 		return nil | ||||||
|  | 	} | ||||||
|  | 	params := uri.Query() | ||||||
|  | 	if len(params.Get("client_secret")) > 0 { | ||||||
|  | 		params.Set("client_secret", "REDACTED") | ||||||
|  | 		uri.RawQuery = params.Encode() | ||||||
|  | 	} | ||||||
|  | 	return uri | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /* | ||||||
|  | An Error reports more details on an individual error in an ErrorResponse. | ||||||
|  | These are the possible validation error codes: | ||||||
|  | 
 | ||||||
|  |     missing: | ||||||
|  |         resource does not exist | ||||||
|  |     missing_field: | ||||||
|  |         a required field on a resource has not been set | ||||||
|  |     invalid: | ||||||
|  |         the formatting of a field is invalid | ||||||
|  |     already_exists: | ||||||
|  |         another resource has the same valid as this field | ||||||
|  | 
 | ||||||
|  | GitHub API docs: http://developer.github.com/v3/#client-errors
 | ||||||
|  | */ | ||||||
|  | type Error struct { | ||||||
|  | 	Resource string `json:"resource"` // resource on which the error occurred
 | ||||||
|  | 	Field    string `json:"field"`    // field on which the error occurred
 | ||||||
|  | 	Code     string `json:"code"`     // validation error code
 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (e *Error) Error() string { | ||||||
|  | 	return fmt.Sprintf("%v error caused by %v field on %v resource", | ||||||
|  | 		e.Code, e.Field, e.Resource) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // CheckResponse checks the API response for errors, and returns them if
 | ||||||
|  | // present.  A response is considered an error if it has a status code outside
 | ||||||
|  | // the 200 range.  API error responses are expected to have either no response
 | ||||||
|  | // body, or a JSON response body that maps to ErrorResponse.  Any other
 | ||||||
|  | // response body will be silently ignored.
 | ||||||
|  | func CheckResponse(r *http.Response) error { | ||||||
|  | 	if c := r.StatusCode; 200 <= c && c <= 299 { | ||||||
|  | 		return nil | ||||||
|  | 	} | ||||||
|  | 	errorResponse := &ErrorResponse{Response: r} | ||||||
|  | 	data, err := ioutil.ReadAll(r.Body) | ||||||
|  | 	if err == nil && data != nil { | ||||||
|  | 		json.Unmarshal(data, errorResponse) | ||||||
|  | 	} | ||||||
|  | 	return errorResponse | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // parseBoolResponse determines the boolean result from a GitHub API response.
 | ||||||
|  | // Several GitHub API methods return boolean responses indicated by the HTTP
 | ||||||
|  | // status code in the response (true indicated by a 204, false indicated by a
 | ||||||
|  | // 404).  This helper function will determine that result and hide the 404
 | ||||||
|  | // error if present.  Any other error will be returned through as-is.
 | ||||||
|  | func parseBoolResponse(err error) (bool, error) { | ||||||
|  | 	if err == nil { | ||||||
|  | 		return true, nil | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if err, ok := err.(*ErrorResponse); ok && err.Response.StatusCode == http.StatusNotFound { | ||||||
|  | 		// Simply false.  In this one case, we do not pass the error through.
 | ||||||
|  | 		return false, nil | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	// some other real error occurred
 | ||||||
|  | 	return false, err | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Rate represents the rate limit for the current client.
 | ||||||
|  | type Rate struct { | ||||||
|  | 	// The number of requests per hour the client is currently limited to.
 | ||||||
|  | 	Limit int `json:"limit"` | ||||||
|  | 
 | ||||||
|  | 	// The number of remaining requests the client can make this hour.
 | ||||||
|  | 	Remaining int `json:"remaining"` | ||||||
|  | 
 | ||||||
|  | 	// The time at which the current rate limit will reset.
 | ||||||
|  | 	Reset Timestamp `json:"reset"` | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (r Rate) String() string { | ||||||
|  | 	return Stringify(r) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // RateLimits represents the rate limits for the current client.
 | ||||||
|  | type RateLimits struct { | ||||||
|  | 	// The rate limit for non-search API requests.  Unauthenticated
 | ||||||
|  | 	// requests are limited to 60 per hour.  Authenticated requests are
 | ||||||
|  | 	// limited to 5,000 per hour.
 | ||||||
|  | 	Core *Rate `json:"core"` | ||||||
|  | 
 | ||||||
|  | 	// The rate limit for search API requests.  Unauthenticated requests
 | ||||||
|  | 	// are limited to 5 requests per minutes.  Authenticated requests are
 | ||||||
|  | 	// limited to 20 per minute.
 | ||||||
|  | 	//
 | ||||||
|  | 	// GitHub API docs: https://developer.github.com/v3/search/#rate-limit
 | ||||||
|  | 	Search *Rate `json:"search"` | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (r RateLimits) String() string { | ||||||
|  | 	return Stringify(r) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // RateLimit is deprecated.  Use RateLimits instead.
 | ||||||
|  | func (c *Client) RateLimit() (*Rate, *Response, error) { | ||||||
|  | 	limits, resp, err := c.RateLimits() | ||||||
|  | 	if limits == nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return limits.Core, resp, err | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // RateLimits returns the rate limits for the current client.
 | ||||||
|  | func (c *Client) RateLimits() (*RateLimits, *Response, error) { | ||||||
|  | 	req, err := c.NewRequest("GET", "rate_limit", nil) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	response := new(struct { | ||||||
|  | 		Resources *RateLimits `json:"resources"` | ||||||
|  | 	}) | ||||||
|  | 	resp, err := c.Do(req, response) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return response.Resources, resp, err | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /* | ||||||
|  | UnauthenticatedRateLimitedTransport allows you to make unauthenticated calls | ||||||
|  | that need to use a higher rate limit associated with your OAuth application. | ||||||
|  | 
 | ||||||
|  | 	t := &github.UnauthenticatedRateLimitedTransport{ | ||||||
|  | 		ClientID:     "your app's client ID", | ||||||
|  | 		ClientSecret: "your app's client secret", | ||||||
|  | 	} | ||||||
|  | 	client := github.NewClient(t.Client()) | ||||||
|  | 
 | ||||||
|  | This will append the querystring params client_id=xxx&client_secret=yyy to all | ||||||
|  | requests. | ||||||
|  | 
 | ||||||
|  | See http://developer.github.com/v3/#unauthenticated-rate-limited-requests for
 | ||||||
|  | more information. | ||||||
|  | */ | ||||||
|  | type UnauthenticatedRateLimitedTransport struct { | ||||||
|  | 	// ClientID is the GitHub OAuth client ID of the current application, which
 | ||||||
|  | 	// can be found by selecting its entry in the list at
 | ||||||
|  | 	// https://github.com/settings/applications.
 | ||||||
|  | 	ClientID string | ||||||
|  | 
 | ||||||
|  | 	// ClientSecret is the GitHub OAuth client secret of the current
 | ||||||
|  | 	// application.
 | ||||||
|  | 	ClientSecret string | ||||||
|  | 
 | ||||||
|  | 	// Transport is the underlying HTTP transport to use when making requests.
 | ||||||
|  | 	// It will default to http.DefaultTransport if nil.
 | ||||||
|  | 	Transport http.RoundTripper | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // RoundTrip implements the RoundTripper interface.
 | ||||||
|  | func (t *UnauthenticatedRateLimitedTransport) RoundTrip(req *http.Request) (*http.Response, error) { | ||||||
|  | 	if t.ClientID == "" { | ||||||
|  | 		return nil, errors.New("t.ClientID is empty") | ||||||
|  | 	} | ||||||
|  | 	if t.ClientSecret == "" { | ||||||
|  | 		return nil, errors.New("t.ClientSecret is empty") | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	// To set extra querystring params, we must make a copy of the Request so
 | ||||||
|  | 	// that we don't modify the Request we were given. This is required by the
 | ||||||
|  | 	// specification of http.RoundTripper.
 | ||||||
|  | 	req = cloneRequest(req) | ||||||
|  | 	q := req.URL.Query() | ||||||
|  | 	q.Set("client_id", t.ClientID) | ||||||
|  | 	q.Set("client_secret", t.ClientSecret) | ||||||
|  | 	req.URL.RawQuery = q.Encode() | ||||||
|  | 
 | ||||||
|  | 	// Make the HTTP request.
 | ||||||
|  | 	return t.transport().RoundTrip(req) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Client returns an *http.Client that makes requests which are subject to the
 | ||||||
|  | // rate limit of your OAuth application.
 | ||||||
|  | func (t *UnauthenticatedRateLimitedTransport) Client() *http.Client { | ||||||
|  | 	return &http.Client{Transport: t} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (t *UnauthenticatedRateLimitedTransport) transport() http.RoundTripper { | ||||||
|  | 	if t.Transport != nil { | ||||||
|  | 		return t.Transport | ||||||
|  | 	} | ||||||
|  | 	return http.DefaultTransport | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // cloneRequest returns a clone of the provided *http.Request. The clone is a
 | ||||||
|  | // shallow copy of the struct and its Header map.
 | ||||||
|  | func cloneRequest(r *http.Request) *http.Request { | ||||||
|  | 	// shallow copy of the struct
 | ||||||
|  | 	r2 := new(http.Request) | ||||||
|  | 	*r2 = *r | ||||||
|  | 	// deep copy of the Header
 | ||||||
|  | 	r2.Header = make(http.Header) | ||||||
|  | 	for k, s := range r.Header { | ||||||
|  | 		r2.Header[k] = s | ||||||
|  | 	} | ||||||
|  | 	return r2 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // 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 { | ||||||
|  | 	p := new(bool) | ||||||
|  | 	*p = v | ||||||
|  | 	return p | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // 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) *int { | ||||||
|  | 	p := new(int) | ||||||
|  | 	*p = v | ||||||
|  | 	return p | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // 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 { | ||||||
|  | 	p := new(string) | ||||||
|  | 	*p = v | ||||||
|  | 	return p | ||||||
|  | } | ||||||
							
								
								
									
										63
									
								
								vendor/github.com/google/go-github/github/gitignore.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										63
									
								
								vendor/github.com/google/go-github/github/gitignore.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,63 @@ | |||||||
|  | // Copyright 2013 The go-github 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 github | ||||||
|  | 
 | ||||||
|  | import "fmt" | ||||||
|  | 
 | ||||||
|  | // GitignoresService provides access to the gitignore related functions in the
 | ||||||
|  | // GitHub API.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: http://developer.github.com/v3/gitignore/
 | ||||||
|  | type GitignoresService struct { | ||||||
|  | 	client *Client | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Gitignore represents a .gitignore file as returned by the GitHub API.
 | ||||||
|  | type Gitignore struct { | ||||||
|  | 	Name   *string `json:"name,omitempty"` | ||||||
|  | 	Source *string `json:"source,omitempty"` | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (g Gitignore) String() string { | ||||||
|  | 	return Stringify(g) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // List all available Gitignore templates.
 | ||||||
|  | //
 | ||||||
|  | // http://developer.github.com/v3/gitignore/#listing-available-templates
 | ||||||
|  | func (s GitignoresService) List() ([]string, *Response, error) { | ||||||
|  | 	req, err := s.client.NewRequest("GET", "gitignore/templates", nil) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	availableTemplates := new([]string) | ||||||
|  | 	resp, err := s.client.Do(req, availableTemplates) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, resp, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return *availableTemplates, resp, err | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Get a Gitignore by name.
 | ||||||
|  | //
 | ||||||
|  | // http://developer.github.com/v3/gitignore/#get-a-single-template
 | ||||||
|  | func (s GitignoresService) Get(name string) (*Gitignore, *Response, error) { | ||||||
|  | 	u := fmt.Sprintf("gitignore/templates/%v", name) | ||||||
|  | 	req, err := s.client.NewRequest("GET", u, nil) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	gitignore := new(Gitignore) | ||||||
|  | 	resp, err := s.client.Do(req, gitignore) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, resp, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return gitignore, resp, err | ||||||
|  | } | ||||||
							
								
								
									
										261
									
								
								vendor/github.com/google/go-github/github/issues.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										261
									
								
								vendor/github.com/google/go-github/github/issues.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,261 @@ | |||||||
|  | // Copyright 2013 The go-github 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 github | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  | 	"fmt" | ||||||
|  | 	"time" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | // IssuesService handles communication with the issue related
 | ||||||
|  | // methods of the GitHub API.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: http://developer.github.com/v3/issues/
 | ||||||
|  | type IssuesService struct { | ||||||
|  | 	client *Client | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Issue represents a GitHub issue on a repository.
 | ||||||
|  | type Issue struct { | ||||||
|  | 	Number           *int              `json:"number,omitempty"` | ||||||
|  | 	State            *string           `json:"state,omitempty"` | ||||||
|  | 	Title            *string           `json:"title,omitempty"` | ||||||
|  | 	Body             *string           `json:"body,omitempty"` | ||||||
|  | 	User             *User             `json:"user,omitempty"` | ||||||
|  | 	Labels           []Label           `json:"labels,omitempty"` | ||||||
|  | 	Assignee         *User             `json:"assignee,omitempty"` | ||||||
|  | 	Comments         *int              `json:"comments,omitempty"` | ||||||
|  | 	ClosedAt         *time.Time        `json:"closed_at,omitempty"` | ||||||
|  | 	CreatedAt        *time.Time        `json:"created_at,omitempty"` | ||||||
|  | 	UpdatedAt        *time.Time        `json:"updated_at,omitempty"` | ||||||
|  | 	URL              *string           `json:"url,omitempty"` | ||||||
|  | 	HTMLURL          *string           `json:"html_url,omitempty"` | ||||||
|  | 	Milestone        *Milestone        `json:"milestone,omitempty"` | ||||||
|  | 	PullRequestLinks *PullRequestLinks `json:"pull_request,omitempty"` | ||||||
|  | 
 | ||||||
|  | 	// TextMatches is only populated from search results that request text matches
 | ||||||
|  | 	// See: search.go and https://developer.github.com/v3/search/#text-match-metadata
 | ||||||
|  | 	TextMatches []TextMatch `json:"text_matches,omitempty"` | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (i Issue) String() string { | ||||||
|  | 	return Stringify(i) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // IssueRequest represents a request to create/edit an issue.
 | ||||||
|  | // It is separate from Issue above because otherwise Labels
 | ||||||
|  | // and Assignee fail to serialize to the correct JSON.
 | ||||||
|  | type IssueRequest struct { | ||||||
|  | 	Title     *string   `json:"title,omitempty"` | ||||||
|  | 	Body      *string   `json:"body,omitempty"` | ||||||
|  | 	Labels    *[]string `json:"labels,omitempty"` | ||||||
|  | 	Assignee  *string   `json:"assignee,omitempty"` | ||||||
|  | 	State     *string   `json:"state,omitempty"` | ||||||
|  | 	Milestone *int      `json:"milestone,omitempty"` | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // IssueListOptions specifies the optional parameters to the IssuesService.List
 | ||||||
|  | // and IssuesService.ListByOrg methods.
 | ||||||
|  | type IssueListOptions struct { | ||||||
|  | 	// Filter specifies which issues to list.  Possible values are: assigned,
 | ||||||
|  | 	// created, mentioned, subscribed, all.  Default is "assigned".
 | ||||||
|  | 	Filter string `url:"filter,omitempty"` | ||||||
|  | 
 | ||||||
|  | 	// State filters issues based on their state.  Possible values are: open,
 | ||||||
|  | 	// closed.  Default is "open".
 | ||||||
|  | 	State string `url:"state,omitempty"` | ||||||
|  | 
 | ||||||
|  | 	// Labels filters issues based on their label.
 | ||||||
|  | 	Labels []string `url:"labels,comma,omitempty"` | ||||||
|  | 
 | ||||||
|  | 	// Sort specifies how to sort issues.  Possible values are: created, updated,
 | ||||||
|  | 	// and comments.  Default value is "created".
 | ||||||
|  | 	Sort string `url:"sort,omitempty"` | ||||||
|  | 
 | ||||||
|  | 	// Direction in which to sort issues.  Possible values are: asc, desc.
 | ||||||
|  | 	// Default is "asc".
 | ||||||
|  | 	Direction string `url:"direction,omitempty"` | ||||||
|  | 
 | ||||||
|  | 	// Since filters issues by time.
 | ||||||
|  | 	Since time.Time `url:"since,omitempty"` | ||||||
|  | 
 | ||||||
|  | 	ListOptions | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // PullRequestLinks object is added to the Issue object when it's an issue included
 | ||||||
|  | // in the IssueCommentEvent webhook payload, if the webhooks is fired by a comment on a PR
 | ||||||
|  | type PullRequestLinks struct { | ||||||
|  | 	URL      *string `json:"url,omitempty"` | ||||||
|  | 	HTMLURL  *string `json:"html_url,omitempty"` | ||||||
|  | 	DiffURL  *string `json:"diff_url,omitempty"` | ||||||
|  | 	PatchURL *string `json:"patch_url,omitempty"` | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // List the issues for the authenticated user.  If all is true, list issues
 | ||||||
|  | // across all the user's visible repositories including owned, member, and
 | ||||||
|  | // organization repositories; if false, list only owned and member
 | ||||||
|  | // repositories.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: http://developer.github.com/v3/issues/#list-issues
 | ||||||
|  | func (s *IssuesService) List(all bool, opt *IssueListOptions) ([]Issue, *Response, error) { | ||||||
|  | 	var u string | ||||||
|  | 	if all { | ||||||
|  | 		u = "issues" | ||||||
|  | 	} else { | ||||||
|  | 		u = "user/issues" | ||||||
|  | 	} | ||||||
|  | 	return s.listIssues(u, opt) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ListByOrg fetches the issues in the specified organization for the
 | ||||||
|  | // authenticated user.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: http://developer.github.com/v3/issues/#list-issues
 | ||||||
|  | func (s *IssuesService) ListByOrg(org string, opt *IssueListOptions) ([]Issue, *Response, error) { | ||||||
|  | 	u := fmt.Sprintf("orgs/%v/issues", org) | ||||||
|  | 	return s.listIssues(u, opt) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (s *IssuesService) listIssues(u string, opt *IssueListOptions) ([]Issue, *Response, error) { | ||||||
|  | 	u, err := addOptions(u, opt) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	req, err := s.client.NewRequest("GET", u, nil) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	issues := new([]Issue) | ||||||
|  | 	resp, err := s.client.Do(req, issues) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, resp, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return *issues, resp, err | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // IssueListByRepoOptions specifies the optional parameters to the
 | ||||||
|  | // IssuesService.ListByRepo method.
 | ||||||
|  | type IssueListByRepoOptions struct { | ||||||
|  | 	// Milestone limits issues for the specified milestone.  Possible values are
 | ||||||
|  | 	// a milestone number, "none" for issues with no milestone, "*" for issues
 | ||||||
|  | 	// with any milestone.
 | ||||||
|  | 	Milestone string `url:"milestone,omitempty"` | ||||||
|  | 
 | ||||||
|  | 	// State filters issues based on their state.  Possible values are: open,
 | ||||||
|  | 	// closed.  Default is "open".
 | ||||||
|  | 	State string `url:"state,omitempty"` | ||||||
|  | 
 | ||||||
|  | 	// Assignee filters issues based on their assignee.  Possible values are a
 | ||||||
|  | 	// user name, "none" for issues that are not assigned, "*" for issues with
 | ||||||
|  | 	// any assigned user.
 | ||||||
|  | 	Assignee string `url:"assignee,omitempty"` | ||||||
|  | 
 | ||||||
|  | 	// Creator filters issues based on their creator.
 | ||||||
|  | 	Creator string `url:"creator,omitempty"` | ||||||
|  | 
 | ||||||
|  | 	// Mentioned filters issues to those mentioned a specific user.
 | ||||||
|  | 	Mentioned string `url:"mentioned,omitempty"` | ||||||
|  | 
 | ||||||
|  | 	// Labels filters issues based on their label.
 | ||||||
|  | 	Labels []string `url:"labels,omitempty,comma"` | ||||||
|  | 
 | ||||||
|  | 	// Sort specifies how to sort issues.  Possible values are: created, updated,
 | ||||||
|  | 	// and comments.  Default value is "created".
 | ||||||
|  | 	Sort string `url:"sort,omitempty"` | ||||||
|  | 
 | ||||||
|  | 	// Direction in which to sort issues.  Possible values are: asc, desc.
 | ||||||
|  | 	// Default is "asc".
 | ||||||
|  | 	Direction string `url:"direction,omitempty"` | ||||||
|  | 
 | ||||||
|  | 	// Since filters issues by time.
 | ||||||
|  | 	Since time.Time `url:"since,omitempty"` | ||||||
|  | 
 | ||||||
|  | 	ListOptions | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ListByRepo lists the issues for the specified repository.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: http://developer.github.com/v3/issues/#list-issues-for-a-repository
 | ||||||
|  | func (s *IssuesService) ListByRepo(owner string, repo string, opt *IssueListByRepoOptions) ([]Issue, *Response, error) { | ||||||
|  | 	u := fmt.Sprintf("repos/%v/%v/issues", owner, repo) | ||||||
|  | 	u, err := addOptions(u, opt) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	req, err := s.client.NewRequest("GET", u, nil) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	issues := new([]Issue) | ||||||
|  | 	resp, err := s.client.Do(req, issues) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, resp, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return *issues, resp, err | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Get a single issue.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: http://developer.github.com/v3/issues/#get-a-single-issue
 | ||||||
|  | func (s *IssuesService) Get(owner string, repo string, number int) (*Issue, *Response, error) { | ||||||
|  | 	u := fmt.Sprintf("repos/%v/%v/issues/%d", owner, repo, number) | ||||||
|  | 	req, err := s.client.NewRequest("GET", u, nil) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	issue := new(Issue) | ||||||
|  | 	resp, err := s.client.Do(req, issue) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, resp, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return issue, resp, err | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Create a new issue on the specified repository.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: http://developer.github.com/v3/issues/#create-an-issue
 | ||||||
|  | func (s *IssuesService) Create(owner string, repo string, issue *IssueRequest) (*Issue, *Response, error) { | ||||||
|  | 	u := fmt.Sprintf("repos/%v/%v/issues", owner, repo) | ||||||
|  | 	req, err := s.client.NewRequest("POST", u, issue) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	i := new(Issue) | ||||||
|  | 	resp, err := s.client.Do(req, i) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, resp, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return i, resp, err | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Edit an issue.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: http://developer.github.com/v3/issues/#edit-an-issue
 | ||||||
|  | func (s *IssuesService) Edit(owner string, repo string, number int, issue *IssueRequest) (*Issue, *Response, error) { | ||||||
|  | 	u := fmt.Sprintf("repos/%v/%v/issues/%d", owner, repo, number) | ||||||
|  | 	req, err := s.client.NewRequest("PATCH", u, issue) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	i := new(Issue) | ||||||
|  | 	resp, err := s.client.Do(req, i) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, resp, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return i, resp, err | ||||||
|  | } | ||||||
							
								
								
									
										46
									
								
								vendor/github.com/google/go-github/github/issues_assignees.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								vendor/github.com/google/go-github/github/issues_assignees.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,46 @@ | |||||||
|  | // Copyright 2013 The go-github 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 github | ||||||
|  | 
 | ||||||
|  | import "fmt" | ||||||
|  | 
 | ||||||
|  | // ListAssignees fetches all available assignees (owners and collaborators) to
 | ||||||
|  | // which issues may be assigned.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: http://developer.github.com/v3/issues/assignees/#list-assignees
 | ||||||
|  | func (s *IssuesService) ListAssignees(owner string, repo string, opt *ListOptions) ([]User, *Response, error) { | ||||||
|  | 	u := fmt.Sprintf("repos/%v/%v/assignees", owner, repo) | ||||||
|  | 	u, err := addOptions(u, opt) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	req, err := s.client.NewRequest("GET", u, nil) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 	assignees := new([]User) | ||||||
|  | 	resp, err := s.client.Do(req, assignees) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, resp, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return *assignees, resp, err | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // IsAssignee checks if a user is an assignee for the specified repository.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: http://developer.github.com/v3/issues/assignees/#check-assignee
 | ||||||
|  | func (s *IssuesService) IsAssignee(owner string, repo string, user string) (bool, *Response, error) { | ||||||
|  | 	u := fmt.Sprintf("repos/%v/%v/assignees/%v", owner, repo, user) | ||||||
|  | 	req, err := s.client.NewRequest("GET", u, nil) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return false, nil, err | ||||||
|  | 	} | ||||||
|  | 	resp, err := s.client.Do(req, nil) | ||||||
|  | 	assignee, err := parseBoolResponse(err) | ||||||
|  | 	return assignee, resp, err | ||||||
|  | } | ||||||
							
								
								
									
										138
									
								
								vendor/github.com/google/go-github/github/issues_comments.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										138
									
								
								vendor/github.com/google/go-github/github/issues_comments.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,138 @@ | |||||||
|  | // Copyright 2013 The go-github 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 github | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  | 	"fmt" | ||||||
|  | 	"time" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | // IssueComment represents a comment left on an issue.
 | ||||||
|  | type IssueComment struct { | ||||||
|  | 	ID        *int       `json:"id,omitempty"` | ||||||
|  | 	Body      *string    `json:"body,omitempty"` | ||||||
|  | 	User      *User      `json:"user,omitempty"` | ||||||
|  | 	CreatedAt *time.Time `json:"created_at,omitempty"` | ||||||
|  | 	UpdatedAt *time.Time `json:"updated_at,omitempty"` | ||||||
|  | 	URL       *string    `json:"url,omitempty"` | ||||||
|  | 	HTMLURL   *string    `json:"html_url,omitempty"` | ||||||
|  | 	IssueURL  *string    `json:"issue_url,omitempty"` | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (i IssueComment) String() string { | ||||||
|  | 	return Stringify(i) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // IssueListCommentsOptions specifies the optional parameters to the
 | ||||||
|  | // IssuesService.ListComments method.
 | ||||||
|  | type IssueListCommentsOptions struct { | ||||||
|  | 	// Sort specifies how to sort comments.  Possible values are: created, updated.
 | ||||||
|  | 	Sort string `url:"sort,omitempty"` | ||||||
|  | 
 | ||||||
|  | 	// Direction in which to sort comments.  Possible values are: asc, desc.
 | ||||||
|  | 	Direction string `url:"direction,omitempty"` | ||||||
|  | 
 | ||||||
|  | 	// Since filters comments by time.
 | ||||||
|  | 	Since time.Time `url:"since,omitempty"` | ||||||
|  | 
 | ||||||
|  | 	ListOptions | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ListComments lists all comments on the specified issue.  Specifying an issue
 | ||||||
|  | // number of 0 will return all comments on all issues for the repository.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: http://developer.github.com/v3/issues/comments/#list-comments-on-an-issue
 | ||||||
|  | func (s *IssuesService) ListComments(owner string, repo string, number int, opt *IssueListCommentsOptions) ([]IssueComment, *Response, error) { | ||||||
|  | 	var u string | ||||||
|  | 	if number == 0 { | ||||||
|  | 		u = fmt.Sprintf("repos/%v/%v/issues/comments", owner, repo) | ||||||
|  | 	} else { | ||||||
|  | 		u = fmt.Sprintf("repos/%v/%v/issues/%d/comments", owner, repo, number) | ||||||
|  | 	} | ||||||
|  | 	u, err := addOptions(u, opt) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	req, err := s.client.NewRequest("GET", u, nil) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 	comments := new([]IssueComment) | ||||||
|  | 	resp, err := s.client.Do(req, comments) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, resp, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return *comments, resp, err | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // GetComment fetches the specified issue comment.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: http://developer.github.com/v3/issues/comments/#get-a-single-comment
 | ||||||
|  | func (s *IssuesService) GetComment(owner string, repo string, id int) (*IssueComment, *Response, error) { | ||||||
|  | 	u := fmt.Sprintf("repos/%v/%v/issues/comments/%d", owner, repo, id) | ||||||
|  | 
 | ||||||
|  | 	req, err := s.client.NewRequest("GET", u, nil) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 	comment := new(IssueComment) | ||||||
|  | 	resp, err := s.client.Do(req, comment) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, resp, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return comment, resp, err | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // CreateComment creates a new comment on the specified issue.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: http://developer.github.com/v3/issues/comments/#create-a-comment
 | ||||||
|  | func (s *IssuesService) CreateComment(owner string, repo string, number int, comment *IssueComment) (*IssueComment, *Response, error) { | ||||||
|  | 	u := fmt.Sprintf("repos/%v/%v/issues/%d/comments", owner, repo, number) | ||||||
|  | 	req, err := s.client.NewRequest("POST", u, comment) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 	c := new(IssueComment) | ||||||
|  | 	resp, err := s.client.Do(req, c) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, resp, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return c, resp, err | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // EditComment updates an issue comment.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: http://developer.github.com/v3/issues/comments/#edit-a-comment
 | ||||||
|  | func (s *IssuesService) EditComment(owner string, repo string, id int, comment *IssueComment) (*IssueComment, *Response, error) { | ||||||
|  | 	u := fmt.Sprintf("repos/%v/%v/issues/comments/%d", owner, repo, id) | ||||||
|  | 	req, err := s.client.NewRequest("PATCH", u, comment) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 	c := new(IssueComment) | ||||||
|  | 	resp, err := s.client.Do(req, c) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, resp, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return c, resp, err | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // DeleteComment deletes an issue comment.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: http://developer.github.com/v3/issues/comments/#delete-a-comment
 | ||||||
|  | func (s *IssuesService) DeleteComment(owner string, repo string, id int) (*Response, error) { | ||||||
|  | 	u := fmt.Sprintf("repos/%v/%v/issues/comments/%d", owner, repo, id) | ||||||
|  | 	req, err := s.client.NewRequest("DELETE", u, nil) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, err | ||||||
|  | 	} | ||||||
|  | 	return s.client.Do(req, nil) | ||||||
|  | } | ||||||
							
								
								
									
										149
									
								
								vendor/github.com/google/go-github/github/issues_events.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										149
									
								
								vendor/github.com/google/go-github/github/issues_events.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,149 @@ | |||||||
|  | // Copyright 2014 The go-github 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 github | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  | 	"fmt" | ||||||
|  | 	"time" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | // IssueEvent represents an event that occurred around an Issue or Pull Request.
 | ||||||
|  | type IssueEvent struct { | ||||||
|  | 	ID  *int    `json:"id,omitempty"` | ||||||
|  | 	URL *string `json:"url,omitempty"` | ||||||
|  | 
 | ||||||
|  | 	// The User that generated this event.
 | ||||||
|  | 	Actor *User `json:"actor,omitempty"` | ||||||
|  | 
 | ||||||
|  | 	// Event identifies the actual type of Event that occurred.  Possible
 | ||||||
|  | 	// values are:
 | ||||||
|  | 	//
 | ||||||
|  | 	//     closed
 | ||||||
|  | 	//       The Actor closed the issue.
 | ||||||
|  | 	//       If the issue was closed by commit message, CommitID holds the SHA1 hash of the commit.
 | ||||||
|  | 	//
 | ||||||
|  | 	//     merged
 | ||||||
|  | 	//       The Actor merged into master a branch containing a commit mentioning the issue.
 | ||||||
|  | 	//       CommitID holds the SHA1 of the merge commit.
 | ||||||
|  | 	//
 | ||||||
|  | 	//     referenced
 | ||||||
|  | 	//       The Actor committed to master a commit mentioning the issue in its commit message.
 | ||||||
|  | 	//       CommitID holds the SHA1 of the commit.
 | ||||||
|  | 	//
 | ||||||
|  | 	//     reopened, locked, unlocked
 | ||||||
|  | 	//       The Actor did that to the issue.
 | ||||||
|  | 	//
 | ||||||
|  | 	//     renamed
 | ||||||
|  | 	//       The Actor changed the issue title from Rename.From to Rename.To.
 | ||||||
|  | 	//
 | ||||||
|  | 	//     mentioned
 | ||||||
|  | 	//       Someone unspecified @mentioned the Actor [sic] in an issue comment body.
 | ||||||
|  | 	//
 | ||||||
|  | 	//     assigned, unassigned
 | ||||||
|  | 	//       The Actor assigned the issue to or removed the assignment from the Assignee.
 | ||||||
|  | 	//
 | ||||||
|  | 	//     labeled, unlabeled
 | ||||||
|  | 	//       The Actor added or removed the Label from the issue.
 | ||||||
|  | 	//
 | ||||||
|  | 	//     milestoned, demilestoned
 | ||||||
|  | 	//       The Actor added or removed the issue from the Milestone.
 | ||||||
|  | 	//
 | ||||||
|  | 	//     subscribed, unsubscribed
 | ||||||
|  | 	//       The Actor subscribed to or unsubscribed from notifications for an issue.
 | ||||||
|  | 	//
 | ||||||
|  | 	//     head_ref_deleted, head_ref_restored
 | ||||||
|  | 	//       The pull request’s branch was deleted or restored.
 | ||||||
|  | 	//
 | ||||||
|  | 	Event *string `json:"event,omitempty"` | ||||||
|  | 
 | ||||||
|  | 	CreatedAt *time.Time `json:"created_at,omitempty"` | ||||||
|  | 	Issue     *Issue     `json:"issue,omitempty"` | ||||||
|  | 
 | ||||||
|  | 	// Only present on certain events; see above.
 | ||||||
|  | 	Assignee  *User      `json:"assignee,omitempty"` | ||||||
|  | 	CommitID  *string    `json:"commit_id,omitempty"` | ||||||
|  | 	Milestone *Milestone `json:"milestone,omitempty"` | ||||||
|  | 	Label     *Label     `json:"label,omitempty"` | ||||||
|  | 	Rename    *Rename    `json:"rename,omitempty"` | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ListIssueEvents lists events for the specified issue.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: https://developer.github.com/v3/issues/events/#list-events-for-an-issue
 | ||||||
|  | func (s *IssuesService) ListIssueEvents(owner, repo string, number int, opt *ListOptions) ([]IssueEvent, *Response, error) { | ||||||
|  | 	u := fmt.Sprintf("repos/%v/%v/issues/%v/events", owner, repo, number) | ||||||
|  | 	u, err := addOptions(u, opt) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	req, err := s.client.NewRequest("GET", u, nil) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	var events []IssueEvent | ||||||
|  | 	resp, err := s.client.Do(req, &events) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, resp, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return events, resp, err | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ListRepositoryEvents lists events for the specified repository.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: https://developer.github.com/v3/issues/events/#list-events-for-a-repository
 | ||||||
|  | func (s *IssuesService) ListRepositoryEvents(owner, repo string, opt *ListOptions) ([]IssueEvent, *Response, error) { | ||||||
|  | 	u := fmt.Sprintf("repos/%v/%v/issues/events", owner, repo) | ||||||
|  | 	u, err := addOptions(u, opt) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	req, err := s.client.NewRequest("GET", u, nil) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	var events []IssueEvent | ||||||
|  | 	resp, err := s.client.Do(req, &events) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, resp, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return events, resp, err | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // GetEvent returns the specified issue event.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: https://developer.github.com/v3/issues/events/#get-a-single-event
 | ||||||
|  | func (s *IssuesService) GetEvent(owner, repo string, id int) (*IssueEvent, *Response, error) { | ||||||
|  | 	u := fmt.Sprintf("repos/%v/%v/issues/events/%v", owner, repo, id) | ||||||
|  | 
 | ||||||
|  | 	req, err := s.client.NewRequest("GET", u, nil) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	event := new(IssueEvent) | ||||||
|  | 	resp, err := s.client.Do(req, event) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, resp, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return event, resp, err | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Rename contains details for 'renamed' events.
 | ||||||
|  | type Rename struct { | ||||||
|  | 	From *string `json:"from,omitempty"` | ||||||
|  | 	To   *string `json:"to,omitempty"` | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (r Rename) String() string { | ||||||
|  | 	return Stringify(r) | ||||||
|  | } | ||||||
							
								
								
									
										222
									
								
								vendor/github.com/google/go-github/github/issues_labels.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										222
									
								
								vendor/github.com/google/go-github/github/issues_labels.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,222 @@ | |||||||
|  | // Copyright 2013 The go-github 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 github | ||||||
|  | 
 | ||||||
|  | import "fmt" | ||||||
|  | 
 | ||||||
|  | // Label represents a GitHub label on an Issue
 | ||||||
|  | type Label struct { | ||||||
|  | 	URL   *string `json:"url,omitempty"` | ||||||
|  | 	Name  *string `json:"name,omitempty"` | ||||||
|  | 	Color *string `json:"color,omitempty"` | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (l Label) String() string { | ||||||
|  | 	return fmt.Sprint(*l.Name) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ListLabels lists all labels for a repository.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: http://developer.github.com/v3/issues/labels/#list-all-labels-for-this-repository
 | ||||||
|  | func (s *IssuesService) ListLabels(owner string, repo string, opt *ListOptions) ([]Label, *Response, error) { | ||||||
|  | 	u := fmt.Sprintf("repos/%v/%v/labels", owner, repo) | ||||||
|  | 	u, err := addOptions(u, opt) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	req, err := s.client.NewRequest("GET", u, nil) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	labels := new([]Label) | ||||||
|  | 	resp, err := s.client.Do(req, labels) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, resp, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return *labels, resp, err | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // GetLabel gets a single label.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: http://developer.github.com/v3/issues/labels/#get-a-single-label
 | ||||||
|  | func (s *IssuesService) GetLabel(owner string, repo string, name string) (*Label, *Response, error) { | ||||||
|  | 	u := fmt.Sprintf("repos/%v/%v/labels/%v", owner, repo, name) | ||||||
|  | 	req, err := s.client.NewRequest("GET", u, nil) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	label := new(Label) | ||||||
|  | 	resp, err := s.client.Do(req, label) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, resp, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return label, resp, err | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // CreateLabel creates a new label on the specified repository.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: http://developer.github.com/v3/issues/labels/#create-a-label
 | ||||||
|  | func (s *IssuesService) CreateLabel(owner string, repo string, label *Label) (*Label, *Response, error) { | ||||||
|  | 	u := fmt.Sprintf("repos/%v/%v/labels", owner, repo) | ||||||
|  | 	req, err := s.client.NewRequest("POST", u, label) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	l := new(Label) | ||||||
|  | 	resp, err := s.client.Do(req, l) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, resp, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return l, resp, err | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // EditLabel edits a label.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: http://developer.github.com/v3/issues/labels/#update-a-label
 | ||||||
|  | func (s *IssuesService) EditLabel(owner string, repo string, name string, label *Label) (*Label, *Response, error) { | ||||||
|  | 	u := fmt.Sprintf("repos/%v/%v/labels/%v", owner, repo, name) | ||||||
|  | 	req, err := s.client.NewRequest("PATCH", u, label) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	l := new(Label) | ||||||
|  | 	resp, err := s.client.Do(req, l) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, resp, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return l, resp, err | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // DeleteLabel deletes a label.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: http://developer.github.com/v3/issues/labels/#delete-a-label
 | ||||||
|  | func (s *IssuesService) DeleteLabel(owner string, repo string, name string) (*Response, error) { | ||||||
|  | 	u := fmt.Sprintf("repos/%v/%v/labels/%v", owner, repo, name) | ||||||
|  | 	req, err := s.client.NewRequest("DELETE", u, nil) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, err | ||||||
|  | 	} | ||||||
|  | 	return s.client.Do(req, nil) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ListLabelsByIssue lists all labels for an issue.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: http://developer.github.com/v3/issues/labels/#list-all-labels-for-this-repository
 | ||||||
|  | func (s *IssuesService) ListLabelsByIssue(owner string, repo string, number int, opt *ListOptions) ([]Label, *Response, error) { | ||||||
|  | 	u := fmt.Sprintf("repos/%v/%v/issues/%d/labels", owner, repo, number) | ||||||
|  | 	u, err := addOptions(u, opt) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	req, err := s.client.NewRequest("GET", u, nil) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	labels := new([]Label) | ||||||
|  | 	resp, err := s.client.Do(req, labels) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, resp, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return *labels, resp, err | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // AddLabelsToIssue adds labels to an issue.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: http://developer.github.com/v3/issues/labels/#list-all-labels-for-this-repository
 | ||||||
|  | func (s *IssuesService) AddLabelsToIssue(owner string, repo string, number int, labels []string) ([]Label, *Response, error) { | ||||||
|  | 	u := fmt.Sprintf("repos/%v/%v/issues/%d/labels", owner, repo, number) | ||||||
|  | 	req, err := s.client.NewRequest("POST", u, labels) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	l := new([]Label) | ||||||
|  | 	resp, err := s.client.Do(req, l) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, resp, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return *l, resp, err | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // RemoveLabelForIssue removes a label for an issue.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: http://developer.github.com/v3/issues/labels/#remove-a-label-from-an-issue
 | ||||||
|  | func (s *IssuesService) RemoveLabelForIssue(owner string, repo string, number int, label string) (*Response, error) { | ||||||
|  | 	u := fmt.Sprintf("repos/%v/%v/issues/%d/labels/%v", owner, repo, number, label) | ||||||
|  | 	req, err := s.client.NewRequest("DELETE", u, nil) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, err | ||||||
|  | 	} | ||||||
|  | 	return s.client.Do(req, nil) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ReplaceLabelsForIssue replaces all labels for an issue.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: http://developer.github.com/v3/issues/labels/#replace-all-labels-for-an-issue
 | ||||||
|  | func (s *IssuesService) ReplaceLabelsForIssue(owner string, repo string, number int, labels []string) ([]Label, *Response, error) { | ||||||
|  | 	u := fmt.Sprintf("repos/%v/%v/issues/%d/labels", owner, repo, number) | ||||||
|  | 	req, err := s.client.NewRequest("PUT", u, labels) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	l := new([]Label) | ||||||
|  | 	resp, err := s.client.Do(req, l) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, resp, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return *l, resp, err | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // RemoveLabelsForIssue removes all labels for an issue.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: http://developer.github.com/v3/issues/labels/#remove-all-labels-from-an-issue
 | ||||||
|  | func (s *IssuesService) RemoveLabelsForIssue(owner string, repo string, number int) (*Response, error) { | ||||||
|  | 	u := fmt.Sprintf("repos/%v/%v/issues/%d/labels", owner, repo, number) | ||||||
|  | 	req, err := s.client.NewRequest("DELETE", u, nil) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, err | ||||||
|  | 	} | ||||||
|  | 	return s.client.Do(req, nil) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ListLabelsForMilestone lists labels for every issue in a milestone.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: http://developer.github.com/v3/issues/labels/#get-labels-for-every-issue-in-a-milestone
 | ||||||
|  | func (s *IssuesService) ListLabelsForMilestone(owner string, repo string, number int, opt *ListOptions) ([]Label, *Response, error) { | ||||||
|  | 	u := fmt.Sprintf("repos/%v/%v/milestones/%d/labels", owner, repo, number) | ||||||
|  | 	u, err := addOptions(u, opt) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	req, err := s.client.NewRequest("GET", u, nil) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	labels := new([]Label) | ||||||
|  | 	resp, err := s.client.Do(req, labels) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, resp, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return *labels, resp, err | ||||||
|  | } | ||||||
							
								
								
									
										140
									
								
								vendor/github.com/google/go-github/github/issues_milestones.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										140
									
								
								vendor/github.com/google/go-github/github/issues_milestones.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,140 @@ | |||||||
|  | // Copyright 2014 The go-github 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 github | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  | 	"fmt" | ||||||
|  | 	"time" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | // Milestone represents a Github repository milestone.
 | ||||||
|  | type Milestone struct { | ||||||
|  | 	URL          *string    `json:"url,omitempty"` | ||||||
|  | 	Number       *int       `json:"number,omitempty"` | ||||||
|  | 	State        *string    `json:"state,omitempty"` | ||||||
|  | 	Title        *string    `json:"title,omitempty"` | ||||||
|  | 	Description  *string    `json:"description,omitempty"` | ||||||
|  | 	Creator      *User      `json:"creator,omitempty"` | ||||||
|  | 	OpenIssues   *int       `json:"open_issues,omitempty"` | ||||||
|  | 	ClosedIssues *int       `json:"closed_issues,omitempty"` | ||||||
|  | 	CreatedAt    *time.Time `json:"created_at,omitempty"` | ||||||
|  | 	UpdatedAt    *time.Time `json:"updated_at,omitempty"` | ||||||
|  | 	DueOn        *time.Time `json:"due_on,omitempty"` | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (m Milestone) String() string { | ||||||
|  | 	return Stringify(m) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // MilestoneListOptions specifies the optional parameters to the
 | ||||||
|  | // IssuesService.ListMilestones method.
 | ||||||
|  | type MilestoneListOptions struct { | ||||||
|  | 	// State filters milestones based on their state. Possible values are:
 | ||||||
|  | 	// open, closed. Default is "open".
 | ||||||
|  | 	State string `url:"state,omitempty"` | ||||||
|  | 
 | ||||||
|  | 	// Sort specifies how to sort milestones. Possible values are: due_date, completeness.
 | ||||||
|  | 	// Default value is "due_date".
 | ||||||
|  | 	Sort string `url:"sort,omitempty"` | ||||||
|  | 
 | ||||||
|  | 	// Direction in which to sort milestones. Possible values are: asc, desc.
 | ||||||
|  | 	// Default is "asc".
 | ||||||
|  | 	Direction string `url:"direction,omitempty"` | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ListMilestones lists all milestones for a repository.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: https://developer.github.com/v3/issues/milestones/#list-milestones-for-a-repository
 | ||||||
|  | func (s *IssuesService) ListMilestones(owner string, repo string, opt *MilestoneListOptions) ([]Milestone, *Response, error) { | ||||||
|  | 	u := fmt.Sprintf("repos/%v/%v/milestones", owner, repo) | ||||||
|  | 	u, err := addOptions(u, opt) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	req, err := s.client.NewRequest("GET", u, nil) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	milestones := new([]Milestone) | ||||||
|  | 	resp, err := s.client.Do(req, milestones) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, resp, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return *milestones, resp, err | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // GetMilestone gets a single milestone.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: https://developer.github.com/v3/issues/milestones/#get-a-single-milestone
 | ||||||
|  | func (s *IssuesService) GetMilestone(owner string, repo string, number int) (*Milestone, *Response, error) { | ||||||
|  | 	u := fmt.Sprintf("repos/%v/%v/milestones/%d", owner, repo, number) | ||||||
|  | 	req, err := s.client.NewRequest("GET", u, nil) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	milestone := new(Milestone) | ||||||
|  | 	resp, err := s.client.Do(req, milestone) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, resp, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return milestone, resp, err | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // CreateMilestone creates a new milestone on the specified repository.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: https://developer.github.com/v3/issues/milestones/#create-a-milestone
 | ||||||
|  | func (s *IssuesService) CreateMilestone(owner string, repo string, milestone *Milestone) (*Milestone, *Response, error) { | ||||||
|  | 	u := fmt.Sprintf("repos/%v/%v/milestones", owner, repo) | ||||||
|  | 	req, err := s.client.NewRequest("POST", u, milestone) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	m := new(Milestone) | ||||||
|  | 	resp, err := s.client.Do(req, m) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, resp, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return m, resp, err | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // EditMilestone edits a milestone.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: https://developer.github.com/v3/issues/milestones/#update-a-milestone
 | ||||||
|  | func (s *IssuesService) EditMilestone(owner string, repo string, number int, milestone *Milestone) (*Milestone, *Response, error) { | ||||||
|  | 	u := fmt.Sprintf("repos/%v/%v/milestones/%d", owner, repo, number) | ||||||
|  | 	req, err := s.client.NewRequest("PATCH", u, milestone) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	m := new(Milestone) | ||||||
|  | 	resp, err := s.client.Do(req, m) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, resp, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return m, resp, err | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // DeleteMilestone deletes a milestone.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: https://developer.github.com/v3/issues/milestones/#delete-a-milestone
 | ||||||
|  | func (s *IssuesService) DeleteMilestone(owner string, repo string, number int) (*Response, error) { | ||||||
|  | 	u := fmt.Sprintf("repos/%v/%v/milestones/%d", owner, repo, number) | ||||||
|  | 	req, err := s.client.NewRequest("DELETE", u, nil) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return s.client.Do(req, nil) | ||||||
|  | } | ||||||
							
								
								
									
										81
									
								
								vendor/github.com/google/go-github/github/licenses.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										81
									
								
								vendor/github.com/google/go-github/github/licenses.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,81 @@ | |||||||
|  | // Copyright 2013 The go-github 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 github | ||||||
|  | 
 | ||||||
|  | import "fmt" | ||||||
|  | 
 | ||||||
|  | // LicensesService handles communication with the license related
 | ||||||
|  | // methods of the GitHub API.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: http://developer.github.com/v3/pulls/
 | ||||||
|  | type LicensesService struct { | ||||||
|  | 	client *Client | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // License represents an open source license.
 | ||||||
|  | type License struct { | ||||||
|  | 	Key  *string `json:"key,omitempty"` | ||||||
|  | 	Name *string `json:"name,omitempty"` | ||||||
|  | 	URL  *string `json:"url,omitempty"` | ||||||
|  | 
 | ||||||
|  | 	HTMLURL        *string   `json:"html_url,omitempty"` | ||||||
|  | 	Featured       *bool     `json:"featured,omitempty"` | ||||||
|  | 	Description    *string   `json:"description,omitempty"` | ||||||
|  | 	Category       *string   `json:"category,omitempty"` | ||||||
|  | 	Implementation *string   `json:"implementation,omitempty"` | ||||||
|  | 	Required       *[]string `json:"required,omitempty"` | ||||||
|  | 	Permitted      *[]string `json:"permitted,omitempty"` | ||||||
|  | 	Forbidden      *[]string `json:"forbidden,omitempty"` | ||||||
|  | 	Body           *string   `json:"body,omitempty"` | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (l License) String() string { | ||||||
|  | 	return Stringify(l) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // List popular open source licenses.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: https://developer.github.com/v3/licenses/#list-all-licenses
 | ||||||
|  | func (s *LicensesService) List() ([]License, *Response, error) { | ||||||
|  | 	req, err := s.client.NewRequest("GET", "licenses", nil) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	// TODO: remove custom Accept header when this API fully launches
 | ||||||
|  | 	req.Header.Set("Accept", mediaTypeLicensesPreview) | ||||||
|  | 
 | ||||||
|  | 	licenses := new([]License) | ||||||
|  | 	resp, err := s.client.Do(req, licenses) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, resp, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return *licenses, resp, err | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Get extended metadata for one license.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: https://developer.github.com/v3/licenses/#get-an-individual-license
 | ||||||
|  | func (s *LicensesService) Get(licenseName string) (*License, *Response, error) { | ||||||
|  | 	u := fmt.Sprintf("licenses/%s", licenseName) | ||||||
|  | 
 | ||||||
|  | 	req, err := s.client.NewRequest("GET", u, nil) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	// TODO: remove custom Accept header when this API fully launches
 | ||||||
|  | 	req.Header.Set("Accept", mediaTypeLicensesPreview) | ||||||
|  | 
 | ||||||
|  | 	license := new(License) | ||||||
|  | 	resp, err := s.client.Do(req, license) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, resp, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return license, resp, err | ||||||
|  | } | ||||||
							
								
								
									
										197
									
								
								vendor/github.com/google/go-github/github/misc.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										197
									
								
								vendor/github.com/google/go-github/github/misc.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,197 @@ | |||||||
|  | // Copyright 2014 The go-github 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 github | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  | 	"bytes" | ||||||
|  | 	"fmt" | ||||||
|  | 	"net/url" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | // MarkdownOptions specifies optional parameters to the Markdown method.
 | ||||||
|  | type MarkdownOptions struct { | ||||||
|  | 	// Mode identifies the rendering mode.  Possible values are:
 | ||||||
|  | 	//   markdown - render a document as plain Markdown, just like
 | ||||||
|  | 	//   README files are rendered.
 | ||||||
|  | 	//
 | ||||||
|  | 	//   gfm - to render a document as user-content, e.g. like user
 | ||||||
|  | 	//   comments or issues are rendered. In GFM mode, hard line breaks are
 | ||||||
|  | 	//   always taken into account, and issue and user mentions are linked
 | ||||||
|  | 	//   accordingly.
 | ||||||
|  | 	//
 | ||||||
|  | 	// Default is "markdown".
 | ||||||
|  | 	Mode string | ||||||
|  | 
 | ||||||
|  | 	// Context identifies the repository context.  Only taken into account
 | ||||||
|  | 	// when rendering as "gfm".
 | ||||||
|  | 	Context string | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | type markdownRequest struct { | ||||||
|  | 	Text    *string `json:"text,omitempty"` | ||||||
|  | 	Mode    *string `json:"mode,omitempty"` | ||||||
|  | 	Context *string `json:"context,omitempty"` | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Markdown renders an arbitrary Markdown document.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: https://developer.github.com/v3/markdown/
 | ||||||
|  | func (c *Client) Markdown(text string, opt *MarkdownOptions) (string, *Response, error) { | ||||||
|  | 	request := &markdownRequest{Text: String(text)} | ||||||
|  | 	if opt != nil { | ||||||
|  | 		if opt.Mode != "" { | ||||||
|  | 			request.Mode = String(opt.Mode) | ||||||
|  | 		} | ||||||
|  | 		if opt.Context != "" { | ||||||
|  | 			request.Context = String(opt.Context) | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	req, err := c.NewRequest("POST", "markdown", request) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return "", nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	buf := new(bytes.Buffer) | ||||||
|  | 	resp, err := c.Do(req, buf) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return "", resp, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return buf.String(), resp, nil | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ListEmojis returns the emojis available to use on GitHub.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: https://developer.github.com/v3/emojis/
 | ||||||
|  | func (c *Client) ListEmojis() (map[string]string, *Response, error) { | ||||||
|  | 	req, err := c.NewRequest("GET", "emojis", nil) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	var emoji map[string]string | ||||||
|  | 	resp, err := c.Do(req, &emoji) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, resp, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return emoji, resp, nil | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // APIMeta represents metadata about the GitHub API.
 | ||||||
|  | type APIMeta struct { | ||||||
|  | 	// An Array of IP addresses in CIDR format specifying the addresses
 | ||||||
|  | 	// that incoming service hooks will originate from on GitHub.com.
 | ||||||
|  | 	Hooks []string `json:"hooks,omitempty"` | ||||||
|  | 
 | ||||||
|  | 	// An Array of IP addresses in CIDR format specifying the Git servers
 | ||||||
|  | 	// for GitHub.com.
 | ||||||
|  | 	Git []string `json:"git,omitempty"` | ||||||
|  | 
 | ||||||
|  | 	// Whether authentication with username and password is supported.
 | ||||||
|  | 	// (GitHub Enterprise instances using CAS or OAuth for authentication
 | ||||||
|  | 	// will return false. Features like Basic Authentication with a
 | ||||||
|  | 	// username and password, sudo mode, and two-factor authentication are
 | ||||||
|  | 	// not supported on these servers.)
 | ||||||
|  | 	VerifiablePasswordAuthentication *bool `json:"verifiable_password_authentication,omitempty"` | ||||||
|  | 
 | ||||||
|  | 	// An array of IP addresses in CIDR format specifying the addresses
 | ||||||
|  | 	// which serve GitHub Pages websites.
 | ||||||
|  | 	Pages []string `json:"pages,omitempty"` | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // APIMeta returns information about GitHub.com, the service. Or, if you access
 | ||||||
|  | // this endpoint on your organization’s GitHub Enterprise installation, this
 | ||||||
|  | // endpoint provides information about that installation.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: https://developer.github.com/v3/meta/
 | ||||||
|  | func (c *Client) APIMeta() (*APIMeta, *Response, error) { | ||||||
|  | 	req, err := c.NewRequest("GET", "meta", nil) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	meta := new(APIMeta) | ||||||
|  | 	resp, err := c.Do(req, meta) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, resp, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return meta, resp, nil | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Octocat returns an ASCII art octocat with the specified message in a speech
 | ||||||
|  | // bubble.  If message is empty, a random zen phrase is used.
 | ||||||
|  | func (c *Client) Octocat(message string) (string, *Response, error) { | ||||||
|  | 	u := "octocat" | ||||||
|  | 	if message != "" { | ||||||
|  | 		u = fmt.Sprintf("%s?s=%s", u, url.QueryEscape(message)) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	req, err := c.NewRequest("GET", u, nil) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return "", nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	buf := new(bytes.Buffer) | ||||||
|  | 	resp, err := c.Do(req, buf) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return "", resp, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return buf.String(), resp, nil | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Zen returns a random line from The Zen of GitHub.
 | ||||||
|  | //
 | ||||||
|  | // see also: http://warpspire.com/posts/taste/
 | ||||||
|  | func (c *Client) Zen() (string, *Response, error) { | ||||||
|  | 	req, err := c.NewRequest("GET", "zen", nil) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return "", nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	buf := new(bytes.Buffer) | ||||||
|  | 	resp, err := c.Do(req, buf) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return "", resp, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return buf.String(), resp, nil | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ServiceHook represents a hook that has configuration settings, a list of
 | ||||||
|  | // available events, and default events.
 | ||||||
|  | type ServiceHook struct { | ||||||
|  | 	Name            *string    `json:"name,omitempty"` | ||||||
|  | 	Events          []string   `json:"events,omitempty"` | ||||||
|  | 	SupportedEvents []string   `json:"supported_events,omitempty"` | ||||||
|  | 	Schema          [][]string `json:"schema,omitempty"` | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (s *ServiceHook) String() string { | ||||||
|  | 	return Stringify(s) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ListServiceHooks lists all of the available service hooks.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: https://developer.github.com/webhooks/#services
 | ||||||
|  | func (c *Client) ListServiceHooks() ([]ServiceHook, *Response, error) { | ||||||
|  | 	u := "hooks" | ||||||
|  | 	req, err := c.NewRequest("GET", u, nil) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	hooks := new([]ServiceHook) | ||||||
|  | 	resp, err := c.Do(req, hooks) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, resp, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return *hooks, resp, err | ||||||
|  | } | ||||||
							
								
								
									
										137
									
								
								vendor/github.com/google/go-github/github/orgs.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										137
									
								
								vendor/github.com/google/go-github/github/orgs.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,137 @@ | |||||||
|  | // Copyright 2013 The go-github 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 github | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  | 	"fmt" | ||||||
|  | 	"time" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | // OrganizationsService provides access to the organization related functions
 | ||||||
|  | // in the GitHub API.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: http://developer.github.com/v3/orgs/
 | ||||||
|  | type OrganizationsService struct { | ||||||
|  | 	client *Client | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Organization represents a GitHub organization account.
 | ||||||
|  | type Organization struct { | ||||||
|  | 	Login             *string    `json:"login,omitempty"` | ||||||
|  | 	ID                *int       `json:"id,omitempty"` | ||||||
|  | 	AvatarURL         *string    `json:"avatar_url,omitempty"` | ||||||
|  | 	HTMLURL           *string    `json:"html_url,omitempty"` | ||||||
|  | 	Name              *string    `json:"name,omitempty"` | ||||||
|  | 	Company           *string    `json:"company,omitempty"` | ||||||
|  | 	Blog              *string    `json:"blog,omitempty"` | ||||||
|  | 	Location          *string    `json:"location,omitempty"` | ||||||
|  | 	Email             *string    `json:"email,omitempty"` | ||||||
|  | 	PublicRepos       *int       `json:"public_repos,omitempty"` | ||||||
|  | 	PublicGists       *int       `json:"public_gists,omitempty"` | ||||||
|  | 	Followers         *int       `json:"followers,omitempty"` | ||||||
|  | 	Following         *int       `json:"following,omitempty"` | ||||||
|  | 	CreatedAt         *time.Time `json:"created_at,omitempty"` | ||||||
|  | 	UpdatedAt         *time.Time `json:"updated_at,omitempty"` | ||||||
|  | 	TotalPrivateRepos *int       `json:"total_private_repos,omitempty"` | ||||||
|  | 	OwnedPrivateRepos *int       `json:"owned_private_repos,omitempty"` | ||||||
|  | 	PrivateGists      *int       `json:"private_gists,omitempty"` | ||||||
|  | 	DiskUsage         *int       `json:"disk_usage,omitempty"` | ||||||
|  | 	Collaborators     *int       `json:"collaborators,omitempty"` | ||||||
|  | 	BillingEmail      *string    `json:"billing_email,omitempty"` | ||||||
|  | 	Type              *string    `json:"type,omitempty"` | ||||||
|  | 	Plan              *Plan      `json:"plan,omitempty"` | ||||||
|  | 
 | ||||||
|  | 	// API URLs
 | ||||||
|  | 	URL              *string `json:"url,omitempty"` | ||||||
|  | 	EventsURL        *string `json:"events_url,omitempty"` | ||||||
|  | 	MembersURL       *string `json:"members_url,omitempty"` | ||||||
|  | 	PublicMembersURL *string `json:"public_members_url,omitempty"` | ||||||
|  | 	ReposURL         *string `json:"repos_url,omitempty"` | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (o Organization) String() string { | ||||||
|  | 	return Stringify(o) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Plan represents the payment plan for an account.  See plans at https://github.com/plans.
 | ||||||
|  | type Plan struct { | ||||||
|  | 	Name          *string `json:"name,omitempty"` | ||||||
|  | 	Space         *int    `json:"space,omitempty"` | ||||||
|  | 	Collaborators *int    `json:"collaborators,omitempty"` | ||||||
|  | 	PrivateRepos  *int    `json:"private_repos,omitempty"` | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (p Plan) String() string { | ||||||
|  | 	return Stringify(p) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // List the organizations for a user.  Passing the empty string will list
 | ||||||
|  | // organizations for the authenticated user.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: http://developer.github.com/v3/orgs/#list-user-organizations
 | ||||||
|  | func (s *OrganizationsService) List(user string, opt *ListOptions) ([]Organization, *Response, error) { | ||||||
|  | 	var u string | ||||||
|  | 	if user != "" { | ||||||
|  | 		u = fmt.Sprintf("users/%v/orgs", user) | ||||||
|  | 	} else { | ||||||
|  | 		u = "user/orgs" | ||||||
|  | 	} | ||||||
|  | 	u, err := addOptions(u, opt) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	req, err := s.client.NewRequest("GET", u, nil) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	orgs := new([]Organization) | ||||||
|  | 	resp, err := s.client.Do(req, orgs) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, resp, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return *orgs, resp, err | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Get fetches an organization by name.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: http://developer.github.com/v3/orgs/#get-an-organization
 | ||||||
|  | func (s *OrganizationsService) Get(org string) (*Organization, *Response, error) { | ||||||
|  | 	u := fmt.Sprintf("orgs/%v", org) | ||||||
|  | 	req, err := s.client.NewRequest("GET", u, nil) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	organization := new(Organization) | ||||||
|  | 	resp, err := s.client.Do(req, organization) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, resp, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return organization, resp, err | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Edit an organization.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: http://developer.github.com/v3/orgs/#edit-an-organization
 | ||||||
|  | func (s *OrganizationsService) Edit(name string, org *Organization) (*Organization, *Response, error) { | ||||||
|  | 	u := fmt.Sprintf("orgs/%v", name) | ||||||
|  | 	req, err := s.client.NewRequest("PATCH", u, org) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	o := new(Organization) | ||||||
|  | 	resp, err := s.client.Do(req, o) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, resp, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return o, resp, err | ||||||
|  | } | ||||||
							
								
								
									
										104
									
								
								vendor/github.com/google/go-github/github/orgs_hooks.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										104
									
								
								vendor/github.com/google/go-github/github/orgs_hooks.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,104 @@ | |||||||
|  | // Copyright 2015 The go-github 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 github | ||||||
|  | 
 | ||||||
|  | import "fmt" | ||||||
|  | 
 | ||||||
|  | // ListHooks lists all Hooks for the specified organization.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: https://developer.github.com/v3/orgs/hooks/#list-hooks
 | ||||||
|  | func (s *OrganizationsService) ListHooks(org string, opt *ListOptions) ([]Hook, *Response, error) { | ||||||
|  | 	u := fmt.Sprintf("orgs/%v/hooks", org) | ||||||
|  | 	u, err := addOptions(u, opt) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	req, err := s.client.NewRequest("GET", u, nil) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	hooks := new([]Hook) | ||||||
|  | 	resp, err := s.client.Do(req, hooks) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, resp, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return *hooks, resp, err | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // GetHook returns a single specified Hook.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: https://developer.github.com/v3/orgs/hooks/#get-single-hook
 | ||||||
|  | func (s *OrganizationsService) GetHook(org string, id int) (*Hook, *Response, error) { | ||||||
|  | 	u := fmt.Sprintf("orgs/%v/hooks/%d", org, id) | ||||||
|  | 	req, err := s.client.NewRequest("GET", u, nil) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 	hook := new(Hook) | ||||||
|  | 	resp, err := s.client.Do(req, hook) | ||||||
|  | 	return hook, resp, err | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // CreateHook creates a Hook for the specified org.
 | ||||||
|  | // Name and Config are required fields.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: https://developer.github.com/v3/orgs/hooks/#create-a-hook
 | ||||||
|  | func (s *OrganizationsService) CreateHook(org string, hook *Hook) (*Hook, *Response, error) { | ||||||
|  | 	u := fmt.Sprintf("orgs/%v/hooks", org) | ||||||
|  | 	req, err := s.client.NewRequest("POST", u, hook) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	h := new(Hook) | ||||||
|  | 	resp, err := s.client.Do(req, h) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, resp, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return h, resp, err | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // EditHook updates a specified Hook.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: https://developer.github.com/v3/orgs/hooks/#edit-a-hook
 | ||||||
|  | func (s *OrganizationsService) EditHook(org string, id int, hook *Hook) (*Hook, *Response, error) { | ||||||
|  | 	u := fmt.Sprintf("orgs/%v/hooks/%d", org, id) | ||||||
|  | 	req, err := s.client.NewRequest("PATCH", u, hook) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 	h := new(Hook) | ||||||
|  | 	resp, err := s.client.Do(req, h) | ||||||
|  | 	return h, resp, err | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // PingHook triggers a 'ping' event to be sent to the Hook.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: https://developer.github.com/v3/orgs/hooks/#ping-a-hook
 | ||||||
|  | func (s *OrganizationsService) PingHook(org string, id int) (*Response, error) { | ||||||
|  | 	u := fmt.Sprintf("orgs/%v/hooks/%d/pings", org, id) | ||||||
|  | 	req, err := s.client.NewRequest("POST", u, nil) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, err | ||||||
|  | 	} | ||||||
|  | 	return s.client.Do(req, nil) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // DeleteHook deletes a specified Hook.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: https://developer.github.com/v3/orgs/hooks/#delete-a-hook
 | ||||||
|  | func (s *OrganizationsService) DeleteHook(org string, id int) (*Response, error) { | ||||||
|  | 	u := fmt.Sprintf("orgs/%v/hooks/%d", org, id) | ||||||
|  | 	req, err := s.client.NewRequest("DELETE", u, nil) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, err | ||||||
|  | 	} | ||||||
|  | 	return s.client.Do(req, nil) | ||||||
|  | } | ||||||
							
								
								
									
										276
									
								
								vendor/github.com/google/go-github/github/orgs_members.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										276
									
								
								vendor/github.com/google/go-github/github/orgs_members.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,276 @@ | |||||||
|  | // Copyright 2013 The go-github 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 github | ||||||
|  | 
 | ||||||
|  | import "fmt" | ||||||
|  | 
 | ||||||
|  | // Membership represents the status of a user's membership in an organization or team.
 | ||||||
|  | type Membership struct { | ||||||
|  | 	URL *string `json:"url,omitempty"` | ||||||
|  | 
 | ||||||
|  | 	// State is the user's status within the organization or team.
 | ||||||
|  | 	// Possible values are: "active", "pending"
 | ||||||
|  | 	State *string `json:"state,omitempty"` | ||||||
|  | 
 | ||||||
|  | 	// Role identifies the user's role within the organization or team.
 | ||||||
|  | 	// Possible values for organization membership:
 | ||||||
|  | 	//     member - non-owner organization member
 | ||||||
|  | 	//     admin - organization owner
 | ||||||
|  | 	//
 | ||||||
|  | 	// Possible values for team membership are:
 | ||||||
|  | 	//     member - a normal member of the team
 | ||||||
|  | 	//     maintainer - a team maintainer. Able to add/remove other team
 | ||||||
|  | 	//                  members, promote other team members to team
 | ||||||
|  | 	//                  maintainer, and edit the team’s name and description
 | ||||||
|  | 	Role *string `json:"role,omitempty"` | ||||||
|  | 
 | ||||||
|  | 	// For organization membership, the API URL of the organization.
 | ||||||
|  | 	OrganizationURL *string `json:"organization_url,omitempty"` | ||||||
|  | 
 | ||||||
|  | 	// For organization membership, the organization the membership is for.
 | ||||||
|  | 	Organization *Organization `json:"organization,omitempty"` | ||||||
|  | 
 | ||||||
|  | 	// For organization membership, the user the membership is for.
 | ||||||
|  | 	User *User `json:"user,omitempty"` | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (m Membership) String() string { | ||||||
|  | 	return Stringify(m) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ListMembersOptions specifies optional parameters to the
 | ||||||
|  | // OrganizationsService.ListMembers method.
 | ||||||
|  | type ListMembersOptions struct { | ||||||
|  | 	// If true (or if the authenticated user is not an owner of the
 | ||||||
|  | 	// organization), list only publicly visible members.
 | ||||||
|  | 	PublicOnly bool `url:"-"` | ||||||
|  | 
 | ||||||
|  | 	// Filter members returned in the list.  Possible values are:
 | ||||||
|  | 	// 2fa_disabled, all.  Default is "all".
 | ||||||
|  | 	Filter string `url:"filter,omitempty"` | ||||||
|  | 
 | ||||||
|  | 	// Role filters memebers returned by their role in the organization.
 | ||||||
|  | 	// Possible values are:
 | ||||||
|  | 	//     all - all members of the organization, regardless of role
 | ||||||
|  | 	//     admin - organization owners
 | ||||||
|  | 	//     member - non-organization members
 | ||||||
|  | 	//
 | ||||||
|  | 	// Default is "all".
 | ||||||
|  | 	Role string `url:"role,omitempty"` | ||||||
|  | 
 | ||||||
|  | 	ListOptions | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ListMembers lists the members for an organization.  If the authenticated
 | ||||||
|  | // user is an owner of the organization, this will return both concealed and
 | ||||||
|  | // public members, otherwise it will only return public members.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: http://developer.github.com/v3/orgs/members/#members-list
 | ||||||
|  | func (s *OrganizationsService) ListMembers(org string, opt *ListMembersOptions) ([]User, *Response, error) { | ||||||
|  | 	var u string | ||||||
|  | 	if opt != nil && opt.PublicOnly { | ||||||
|  | 		u = fmt.Sprintf("orgs/%v/public_members", org) | ||||||
|  | 	} else { | ||||||
|  | 		u = fmt.Sprintf("orgs/%v/members", org) | ||||||
|  | 	} | ||||||
|  | 	u, err := addOptions(u, opt) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	req, err := s.client.NewRequest("GET", u, nil) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if opt != nil && opt.Role != "" { | ||||||
|  | 		req.Header.Set("Accept", mediaTypeOrgPermissionPreview) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	members := new([]User) | ||||||
|  | 	resp, err := s.client.Do(req, members) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, resp, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return *members, resp, err | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // IsMember checks if a user is a member of an organization.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: http://developer.github.com/v3/orgs/members/#check-membership
 | ||||||
|  | func (s *OrganizationsService) IsMember(org, user string) (bool, *Response, error) { | ||||||
|  | 	u := fmt.Sprintf("orgs/%v/members/%v", org, user) | ||||||
|  | 	req, err := s.client.NewRequest("GET", u, nil) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return false, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	resp, err := s.client.Do(req, nil) | ||||||
|  | 	member, err := parseBoolResponse(err) | ||||||
|  | 	return member, resp, err | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // IsPublicMember checks if a user is a public member of an organization.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: http://developer.github.com/v3/orgs/members/#check-public-membership
 | ||||||
|  | func (s *OrganizationsService) IsPublicMember(org, user string) (bool, *Response, error) { | ||||||
|  | 	u := fmt.Sprintf("orgs/%v/public_members/%v", org, user) | ||||||
|  | 	req, err := s.client.NewRequest("GET", u, nil) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return false, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	resp, err := s.client.Do(req, nil) | ||||||
|  | 	member, err := parseBoolResponse(err) | ||||||
|  | 	return member, resp, err | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // RemoveMember removes a user from all teams of an organization.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: http://developer.github.com/v3/orgs/members/#remove-a-member
 | ||||||
|  | func (s *OrganizationsService) RemoveMember(org, user string) (*Response, error) { | ||||||
|  | 	u := fmt.Sprintf("orgs/%v/members/%v", org, user) | ||||||
|  | 	req, err := s.client.NewRequest("DELETE", u, nil) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return s.client.Do(req, nil) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // PublicizeMembership publicizes a user's membership in an organization. (A
 | ||||||
|  | // user cannot publicize the membership for another user.)
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: http://developer.github.com/v3/orgs/members/#publicize-a-users-membership
 | ||||||
|  | func (s *OrganizationsService) PublicizeMembership(org, user string) (*Response, error) { | ||||||
|  | 	u := fmt.Sprintf("orgs/%v/public_members/%v", org, user) | ||||||
|  | 	req, err := s.client.NewRequest("PUT", u, nil) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return s.client.Do(req, nil) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ConcealMembership conceals a user's membership in an organization.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: http://developer.github.com/v3/orgs/members/#conceal-a-users-membership
 | ||||||
|  | func (s *OrganizationsService) ConcealMembership(org, user string) (*Response, error) { | ||||||
|  | 	u := fmt.Sprintf("orgs/%v/public_members/%v", org, user) | ||||||
|  | 	req, err := s.client.NewRequest("DELETE", u, nil) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return s.client.Do(req, nil) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ListOrgMembershipsOptions specifies optional parameters to the
 | ||||||
|  | // OrganizationsService.ListOrgMemberships method.
 | ||||||
|  | type ListOrgMembershipsOptions struct { | ||||||
|  | 	// Filter memberships to include only those with the specified state.
 | ||||||
|  | 	// Possible values are: "active", "pending".
 | ||||||
|  | 	State string `url:"state,omitempty"` | ||||||
|  | 
 | ||||||
|  | 	ListOptions | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ListOrgMemberships lists the organization memberships for the authenticated user.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: https://developer.github.com/v3/orgs/members/#list-your-organization-memberships
 | ||||||
|  | func (s *OrganizationsService) ListOrgMemberships(opt *ListOrgMembershipsOptions) ([]Membership, *Response, error) { | ||||||
|  | 	u := "user/memberships/orgs" | ||||||
|  | 	u, err := addOptions(u, opt) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	req, err := s.client.NewRequest("GET", u, nil) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	var memberships []Membership | ||||||
|  | 	resp, err := s.client.Do(req, &memberships) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, resp, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return memberships, resp, err | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // GetOrgMembership gets the membership for a user in a specified organization.
 | ||||||
|  | // Passing an empty string for user will get the membership for the
 | ||||||
|  | // authenticated user.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: https://developer.github.com/v3/orgs/members/#get-organization-membership
 | ||||||
|  | // GitHub API docs: https://developer.github.com/v3/orgs/members/#get-your-organization-membership
 | ||||||
|  | func (s *OrganizationsService) GetOrgMembership(user, org string) (*Membership, *Response, error) { | ||||||
|  | 	var u string | ||||||
|  | 	if user != "" { | ||||||
|  | 		u = fmt.Sprintf("orgs/%v/memberships/%v", org, user) | ||||||
|  | 	} else { | ||||||
|  | 		u = fmt.Sprintf("user/memberships/orgs/%v", org) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	req, err := s.client.NewRequest("GET", u, nil) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	membership := new(Membership) | ||||||
|  | 	resp, err := s.client.Do(req, membership) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, resp, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return membership, resp, err | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // EditOrgMembership edits the membership for user in specified organization.
 | ||||||
|  | // Passing an empty string for user will edit the membership for the
 | ||||||
|  | // authenticated user.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: https://developer.github.com/v3/orgs/members/#add-or-update-organization-membership
 | ||||||
|  | // GitHub API docs: https://developer.github.com/v3/orgs/members/#edit-your-organization-membership
 | ||||||
|  | func (s *OrganizationsService) EditOrgMembership(user, org string, membership *Membership) (*Membership, *Response, error) { | ||||||
|  | 	var u, method string | ||||||
|  | 	if user != "" { | ||||||
|  | 		u = fmt.Sprintf("orgs/%v/memberships/%v", org, user) | ||||||
|  | 		method = "PUT" | ||||||
|  | 	} else { | ||||||
|  | 		u = fmt.Sprintf("user/memberships/orgs/%v", org) | ||||||
|  | 		method = "PATCH" | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	req, err := s.client.NewRequest(method, u, membership) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	m := new(Membership) | ||||||
|  | 	resp, err := s.client.Do(req, m) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, resp, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return m, resp, err | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // RemoveOrgMembership removes user from the specified organization.  If the
 | ||||||
|  | // user has been invited to the organization, this will cancel their invitation.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: https://developer.github.com/v3/orgs/members/#remove-organization-membership
 | ||||||
|  | func (s *OrganizationsService) RemoveOrgMembership(user, org string) (*Response, error) { | ||||||
|  | 	u := fmt.Sprintf("orgs/%v/memberships/%v", org, user) | ||||||
|  | 	req, err := s.client.NewRequest("DELETE", u, nil) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return s.client.Do(req, nil) | ||||||
|  | } | ||||||
							
								
								
									
										396
									
								
								vendor/github.com/google/go-github/github/orgs_teams.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										396
									
								
								vendor/github.com/google/go-github/github/orgs_teams.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,396 @@ | |||||||
|  | // Copyright 2013 The go-github 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 github | ||||||
|  | 
 | ||||||
|  | import "fmt" | ||||||
|  | 
 | ||||||
|  | // Team represents a team within a GitHub organization.  Teams are used to
 | ||||||
|  | // manage access to an organization's repositories.
 | ||||||
|  | type Team struct { | ||||||
|  | 	ID   *int    `json:"id,omitempty"` | ||||||
|  | 	Name *string `json:"name,omitempty"` | ||||||
|  | 	URL  *string `json:"url,omitempty"` | ||||||
|  | 	Slug *string `json:"slug,omitempty"` | ||||||
|  | 
 | ||||||
|  | 	// Permission is deprecated when creating or editing a team in an org
 | ||||||
|  | 	// using the new GitHub permission model.  It no longer identifies the
 | ||||||
|  | 	// permission a team has on its repos, but only specifies the default
 | ||||||
|  | 	// permission a repo is initially added with.  Avoid confusion by
 | ||||||
|  | 	// specifying a permission value when calling AddTeamRepo.
 | ||||||
|  | 	Permission *string `json:"permission,omitempty"` | ||||||
|  | 
 | ||||||
|  | 	// Privacy identifies the level of privacy this team should have.
 | ||||||
|  | 	// Possible values are:
 | ||||||
|  | 	//     secret - only visible to organization owners and members of this team
 | ||||||
|  | 	//     closed - visible to all members of this organization
 | ||||||
|  | 	// Default is "secret".
 | ||||||
|  | 	Privacy *string `json:"privacy,omitempty"` | ||||||
|  | 
 | ||||||
|  | 	MembersCount *int          `json:"members_count,omitempty"` | ||||||
|  | 	ReposCount   *int          `json:"repos_count,omitempty"` | ||||||
|  | 	Organization *Organization `json:"organization,omitempty"` | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (t Team) String() string { | ||||||
|  | 	return Stringify(t) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ListTeams lists all of the teams for an organization.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: http://developer.github.com/v3/orgs/teams/#list-teams
 | ||||||
|  | func (s *OrganizationsService) ListTeams(org string, opt *ListOptions) ([]Team, *Response, error) { | ||||||
|  | 	u := fmt.Sprintf("orgs/%v/teams", org) | ||||||
|  | 	u, err := addOptions(u, opt) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	req, err := s.client.NewRequest("GET", u, nil) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	teams := new([]Team) | ||||||
|  | 	resp, err := s.client.Do(req, teams) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, resp, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return *teams, resp, err | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // GetTeam fetches a team by ID.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: http://developer.github.com/v3/orgs/teams/#get-team
 | ||||||
|  | func (s *OrganizationsService) GetTeam(team int) (*Team, *Response, error) { | ||||||
|  | 	u := fmt.Sprintf("teams/%v", team) | ||||||
|  | 	req, err := s.client.NewRequest("GET", u, nil) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	t := new(Team) | ||||||
|  | 	resp, err := s.client.Do(req, t) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, resp, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return t, resp, err | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // CreateTeam creates a new team within an organization.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: http://developer.github.com/v3/orgs/teams/#create-team
 | ||||||
|  | func (s *OrganizationsService) CreateTeam(org string, team *Team) (*Team, *Response, error) { | ||||||
|  | 	u := fmt.Sprintf("orgs/%v/teams", org) | ||||||
|  | 	req, err := s.client.NewRequest("POST", u, team) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if team.Privacy != nil { | ||||||
|  | 		req.Header.Set("Accept", mediaTypeOrgPermissionPreview) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	t := new(Team) | ||||||
|  | 	resp, err := s.client.Do(req, t) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, resp, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return t, resp, err | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // EditTeam edits a team.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: http://developer.github.com/v3/orgs/teams/#edit-team
 | ||||||
|  | func (s *OrganizationsService) EditTeam(id int, team *Team) (*Team, *Response, error) { | ||||||
|  | 	u := fmt.Sprintf("teams/%v", id) | ||||||
|  | 	req, err := s.client.NewRequest("PATCH", u, team) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if team.Privacy != nil { | ||||||
|  | 		req.Header.Set("Accept", mediaTypeOrgPermissionPreview) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	t := new(Team) | ||||||
|  | 	resp, err := s.client.Do(req, t) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, resp, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return t, resp, err | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // DeleteTeam deletes a team.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: http://developer.github.com/v3/orgs/teams/#delete-team
 | ||||||
|  | func (s *OrganizationsService) DeleteTeam(team int) (*Response, error) { | ||||||
|  | 	u := fmt.Sprintf("teams/%v", team) | ||||||
|  | 	req, err := s.client.NewRequest("DELETE", u, nil) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return s.client.Do(req, nil) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // OrganizationListTeamMembersOptions specifies the optional parameters to the
 | ||||||
|  | // OrganizationsService.ListTeamMembers method.
 | ||||||
|  | type OrganizationListTeamMembersOptions struct { | ||||||
|  | 	// Role filters members returned by their role in the team.  Possible
 | ||||||
|  | 	// values are "all", "member", "maintainer".  Default is "all".
 | ||||||
|  | 	Role string `url:"role,omitempty"` | ||||||
|  | 
 | ||||||
|  | 	ListOptions | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ListTeamMembers lists all of the users who are members of the specified
 | ||||||
|  | // team.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: http://developer.github.com/v3/orgs/teams/#list-team-members
 | ||||||
|  | func (s *OrganizationsService) ListTeamMembers(team int, opt *OrganizationListTeamMembersOptions) ([]User, *Response, error) { | ||||||
|  | 	u := fmt.Sprintf("teams/%v/members", team) | ||||||
|  | 	u, err := addOptions(u, opt) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	req, err := s.client.NewRequest("GET", u, nil) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if opt != nil && opt.Role != "" { | ||||||
|  | 		req.Header.Set("Accept", mediaTypeOrgPermissionPreview) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	members := new([]User) | ||||||
|  | 	resp, err := s.client.Do(req, members) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, resp, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return *members, resp, err | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // IsTeamMember checks if a user is a member of the specified team.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: http://developer.github.com/v3/orgs/teams/#get-team-member
 | ||||||
|  | func (s *OrganizationsService) IsTeamMember(team int, user string) (bool, *Response, error) { | ||||||
|  | 	u := fmt.Sprintf("teams/%v/members/%v", team, user) | ||||||
|  | 	req, err := s.client.NewRequest("GET", u, nil) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return false, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	resp, err := s.client.Do(req, nil) | ||||||
|  | 	member, err := parseBoolResponse(err) | ||||||
|  | 	return member, resp, err | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ListTeamRepos lists the repositories that the specified team has access to.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: http://developer.github.com/v3/orgs/teams/#list-team-repos
 | ||||||
|  | func (s *OrganizationsService) ListTeamRepos(team int, opt *ListOptions) ([]Repository, *Response, error) { | ||||||
|  | 	u := fmt.Sprintf("teams/%v/repos", team) | ||||||
|  | 	u, err := addOptions(u, opt) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	req, err := s.client.NewRequest("GET", u, nil) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	repos := new([]Repository) | ||||||
|  | 	resp, err := s.client.Do(req, repos) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, resp, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return *repos, resp, err | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // IsTeamRepo checks if a team manages the specified repository.  If the
 | ||||||
|  | // repository is managed by team, a Repository is returned which includes the
 | ||||||
|  | // permissions team has for that repo.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: http://developer.github.com/v3/orgs/teams/#get-team-repo
 | ||||||
|  | func (s *OrganizationsService) IsTeamRepo(team int, owner string, repo string) (*Repository, *Response, error) { | ||||||
|  | 	u := fmt.Sprintf("teams/%v/repos/%v/%v", team, owner, repo) | ||||||
|  | 	req, err := s.client.NewRequest("GET", u, nil) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	req.Header.Set("Accept", mediaTypeOrgPermissionRepoPreview) | ||||||
|  | 
 | ||||||
|  | 	repository := new(Repository) | ||||||
|  | 	resp, err := s.client.Do(req, repository) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, resp, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return repository, resp, err | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // OrganizationAddTeamRepoOptions specifies the optional parameters to the
 | ||||||
|  | // OrganizationsService.AddTeamRepo method.
 | ||||||
|  | type OrganizationAddTeamRepoOptions struct { | ||||||
|  | 	// Permission specifies the permission to grant the team on this repository.
 | ||||||
|  | 	// Possible values are:
 | ||||||
|  | 	//     pull - team members can pull, but not push to or administer this repository
 | ||||||
|  | 	//     push - team members can pull and push, but not administer this repository
 | ||||||
|  | 	//     admin - team members can pull, push and administer this repository
 | ||||||
|  | 	//
 | ||||||
|  | 	// If not specified, the team's permission attribute will be used.
 | ||||||
|  | 	Permission string `json:"permission,omitempty"` | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // AddTeamRepo adds a repository to be managed by the specified team.  The
 | ||||||
|  | // specified repository must be owned by the organization to which the team
 | ||||||
|  | // belongs, or a direct fork of a repository owned by the organization.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: http://developer.github.com/v3/orgs/teams/#add-team-repo
 | ||||||
|  | func (s *OrganizationsService) AddTeamRepo(team int, owner string, repo string, opt *OrganizationAddTeamRepoOptions) (*Response, error) { | ||||||
|  | 	u := fmt.Sprintf("teams/%v/repos/%v/%v", team, owner, repo) | ||||||
|  | 	req, err := s.client.NewRequest("PUT", u, opt) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if opt != nil { | ||||||
|  | 		req.Header.Set("Accept", mediaTypeOrgPermissionPreview) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return s.client.Do(req, nil) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // RemoveTeamRepo removes a repository from being managed by the specified
 | ||||||
|  | // team.  Note that this does not delete the repository, it just removes it
 | ||||||
|  | // from the team.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: http://developer.github.com/v3/orgs/teams/#remove-team-repo
 | ||||||
|  | func (s *OrganizationsService) RemoveTeamRepo(team int, owner string, repo string) (*Response, error) { | ||||||
|  | 	u := fmt.Sprintf("teams/%v/repos/%v/%v", team, owner, repo) | ||||||
|  | 	req, err := s.client.NewRequest("DELETE", u, nil) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return s.client.Do(req, nil) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ListUserTeams lists a user's teams
 | ||||||
|  | // GitHub API docs: https://developer.github.com/v3/orgs/teams/#list-user-teams
 | ||||||
|  | func (s *OrganizationsService) ListUserTeams(opt *ListOptions) ([]Team, *Response, error) { | ||||||
|  | 	u := "user/teams" | ||||||
|  | 	u, err := addOptions(u, opt) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	req, err := s.client.NewRequest("GET", u, nil) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	teams := new([]Team) | ||||||
|  | 	resp, err := s.client.Do(req, teams) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, resp, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return *teams, resp, err | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // GetTeamMembership returns the membership status for a user in a team.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: https://developer.github.com/v3/orgs/teams/#get-team-membership
 | ||||||
|  | func (s *OrganizationsService) GetTeamMembership(team int, user string) (*Membership, *Response, error) { | ||||||
|  | 	u := fmt.Sprintf("teams/%v/memberships/%v", team, user) | ||||||
|  | 	req, err := s.client.NewRequest("GET", u, nil) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	t := new(Membership) | ||||||
|  | 	resp, err := s.client.Do(req, t) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, resp, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return t, resp, err | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // OrganizationAddTeamMembershipOptions does stuff specifies the optional
 | ||||||
|  | // parameters to the OrganizationsService.AddTeamMembership method.
 | ||||||
|  | type OrganizationAddTeamMembershipOptions struct { | ||||||
|  | 	// Role specifies the role the user should have in the team.  Possible
 | ||||||
|  | 	// values are:
 | ||||||
|  | 	//     member - a normal member of the team
 | ||||||
|  | 	//     maintainer - a team maintainer. Able to add/remove other team
 | ||||||
|  | 	//                  members, promote other team members to team
 | ||||||
|  | 	//                  maintainer, and edit the team’s name and description
 | ||||||
|  | 	//
 | ||||||
|  | 	// Default value is "member".
 | ||||||
|  | 	Role string `json:"role,omitempty"` | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // AddTeamMembership adds or invites a user to a team.
 | ||||||
|  | //
 | ||||||
|  | // In order to add a membership between a user and a team, the authenticated
 | ||||||
|  | // user must have 'admin' permissions to the team or be an owner of the
 | ||||||
|  | // organization that the team is associated with.
 | ||||||
|  | //
 | ||||||
|  | // If the user is already a part of the team's organization (meaning they're on
 | ||||||
|  | // at least one other team in the organization), this endpoint will add the
 | ||||||
|  | // user to the team.
 | ||||||
|  | //
 | ||||||
|  | // If the user is completely unaffiliated with the team's organization (meaning
 | ||||||
|  | // they're on none of the organization's teams), this endpoint will send an
 | ||||||
|  | // invitation to the user via email. This newly-created membership will be in
 | ||||||
|  | // the "pending" state until the user accepts the invitation, at which point
 | ||||||
|  | // the membership will transition to the "active" state and the user will be
 | ||||||
|  | // added as a member of the team.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: https://developer.github.com/v3/orgs/teams/#add-team-membership
 | ||||||
|  | func (s *OrganizationsService) AddTeamMembership(team int, user string, opt *OrganizationAddTeamMembershipOptions) (*Membership, *Response, error) { | ||||||
|  | 	u := fmt.Sprintf("teams/%v/memberships/%v", team, user) | ||||||
|  | 	req, err := s.client.NewRequest("PUT", u, opt) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if opt != nil { | ||||||
|  | 		req.Header.Set("Accept", mediaTypeOrgPermissionPreview) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	t := new(Membership) | ||||||
|  | 	resp, err := s.client.Do(req, t) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, resp, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return t, resp, err | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // RemoveTeamMembership removes a user from a team.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: https://developer.github.com/v3/orgs/teams/#remove-team-membership
 | ||||||
|  | func (s *OrganizationsService) RemoveTeamMembership(team int, user string) (*Response, error) { | ||||||
|  | 	u := fmt.Sprintf("teams/%v/memberships/%v", team, user) | ||||||
|  | 	req, err := s.client.NewRequest("DELETE", u, nil) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return s.client.Do(req, nil) | ||||||
|  | } | ||||||
							
								
								
									
										275
									
								
								vendor/github.com/google/go-github/github/pulls.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										275
									
								
								vendor/github.com/google/go-github/github/pulls.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,275 @@ | |||||||
|  | // Copyright 2013 The go-github 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 github | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  | 	"fmt" | ||||||
|  | 	"time" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | // PullRequestsService handles communication with the pull request related
 | ||||||
|  | // methods of the GitHub API.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: http://developer.github.com/v3/pulls/
 | ||||||
|  | type PullRequestsService struct { | ||||||
|  | 	client *Client | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // PullRequest represents a GitHub pull request on a repository.
 | ||||||
|  | type PullRequest struct { | ||||||
|  | 	Number       *int       `json:"number,omitempty"` | ||||||
|  | 	State        *string    `json:"state,omitempty"` | ||||||
|  | 	Title        *string    `json:"title,omitempty"` | ||||||
|  | 	Body         *string    `json:"body,omitempty"` | ||||||
|  | 	CreatedAt    *time.Time `json:"created_at,omitempty"` | ||||||
|  | 	UpdatedAt    *time.Time `json:"updated_at,omitempty"` | ||||||
|  | 	ClosedAt     *time.Time `json:"closed_at,omitempty"` | ||||||
|  | 	MergedAt     *time.Time `json:"merged_at,omitempty"` | ||||||
|  | 	User         *User      `json:"user,omitempty"` | ||||||
|  | 	Merged       *bool      `json:"merged,omitempty"` | ||||||
|  | 	Mergeable    *bool      `json:"mergeable,omitempty"` | ||||||
|  | 	MergedBy     *User      `json:"merged_by,omitempty"` | ||||||
|  | 	Comments     *int       `json:"comments,omitempty"` | ||||||
|  | 	Commits      *int       `json:"commits,omitempty"` | ||||||
|  | 	Additions    *int       `json:"additions,omitempty"` | ||||||
|  | 	Deletions    *int       `json:"deletions,omitempty"` | ||||||
|  | 	ChangedFiles *int       `json:"changed_files,omitempty"` | ||||||
|  | 	URL          *string    `json:"url,omitempty"` | ||||||
|  | 	HTMLURL      *string    `json:"html_url,omitempty"` | ||||||
|  | 	IssueURL     *string    `json:"issue_url,omitempty"` | ||||||
|  | 	StatusesURL  *string    `json:"statuses_url,omitempty"` | ||||||
|  | 	DiffURL      *string    `json:"diff_url,omitempty"` | ||||||
|  | 	PatchURL     *string    `json:"patch_url,omitempty"` | ||||||
|  | 
 | ||||||
|  | 	Head *PullRequestBranch `json:"head,omitempty"` | ||||||
|  | 	Base *PullRequestBranch `json:"base,omitempty"` | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (p PullRequest) String() string { | ||||||
|  | 	return Stringify(p) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // PullRequestBranch represents a base or head branch in a GitHub pull request.
 | ||||||
|  | type PullRequestBranch struct { | ||||||
|  | 	Label *string     `json:"label,omitempty"` | ||||||
|  | 	Ref   *string     `json:"ref,omitempty"` | ||||||
|  | 	SHA   *string     `json:"sha,omitempty"` | ||||||
|  | 	Repo  *Repository `json:"repo,omitempty"` | ||||||
|  | 	User  *User       `json:"user,omitempty"` | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // PullRequestListOptions specifies the optional parameters to the
 | ||||||
|  | // PullRequestsService.List method.
 | ||||||
|  | type PullRequestListOptions struct { | ||||||
|  | 	// State filters pull requests based on their state.  Possible values are:
 | ||||||
|  | 	// open, closed.  Default is "open".
 | ||||||
|  | 	State string `url:"state,omitempty"` | ||||||
|  | 
 | ||||||
|  | 	// Head filters pull requests by head user and branch name in the format of:
 | ||||||
|  | 	// "user:ref-name".
 | ||||||
|  | 	Head string `url:"head,omitempty"` | ||||||
|  | 
 | ||||||
|  | 	// Base filters pull requests by base branch name.
 | ||||||
|  | 	Base string `url:"base,omitempty"` | ||||||
|  | 
 | ||||||
|  | 	// Sort specifies how to sort pull requests. Possible values are: created,
 | ||||||
|  | 	// updated, popularity, long-running. Default is "created".
 | ||||||
|  | 	Sort string `url:"sort,omitempty"` | ||||||
|  | 
 | ||||||
|  | 	// Direction in which to sort pull requests. Possible values are: asc, desc.
 | ||||||
|  | 	// If Sort is "created" or not specified, Default is "desc", otherwise Default
 | ||||||
|  | 	// is "asc"
 | ||||||
|  | 	Direction string `url:"direction,omitempty"` | ||||||
|  | 
 | ||||||
|  | 	ListOptions | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // List the pull requests for the specified repository.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: http://developer.github.com/v3/pulls/#list-pull-requests
 | ||||||
|  | func (s *PullRequestsService) List(owner string, repo string, opt *PullRequestListOptions) ([]PullRequest, *Response, error) { | ||||||
|  | 	u := fmt.Sprintf("repos/%v/%v/pulls", owner, repo) | ||||||
|  | 	u, err := addOptions(u, opt) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	req, err := s.client.NewRequest("GET", u, nil) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	pulls := new([]PullRequest) | ||||||
|  | 	resp, err := s.client.Do(req, pulls) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, resp, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return *pulls, resp, err | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Get a single pull request.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: https://developer.github.com/v3/pulls/#get-a-single-pull-request
 | ||||||
|  | func (s *PullRequestsService) Get(owner string, repo string, number int) (*PullRequest, *Response, error) { | ||||||
|  | 	u := fmt.Sprintf("repos/%v/%v/pulls/%d", owner, repo, number) | ||||||
|  | 	req, err := s.client.NewRequest("GET", u, nil) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	pull := new(PullRequest) | ||||||
|  | 	resp, err := s.client.Do(req, pull) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, resp, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return pull, resp, err | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // NewPullRequest represents a new pull request to be created.
 | ||||||
|  | type NewPullRequest struct { | ||||||
|  | 	Title *string `json:"title,omitempty"` | ||||||
|  | 	Head  *string `json:"head,omitempty"` | ||||||
|  | 	Base  *string `json:"base,omitempty"` | ||||||
|  | 	Body  *string `json:"body,omitempty"` | ||||||
|  | 	Issue *int    `json:"issue,omitempty"` | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Create a new pull request on the specified repository.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: https://developer.github.com/v3/pulls/#create-a-pull-request
 | ||||||
|  | func (s *PullRequestsService) Create(owner string, repo string, pull *NewPullRequest) (*PullRequest, *Response, error) { | ||||||
|  | 	u := fmt.Sprintf("repos/%v/%v/pulls", owner, repo) | ||||||
|  | 	req, err := s.client.NewRequest("POST", u, pull) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	p := new(PullRequest) | ||||||
|  | 	resp, err := s.client.Do(req, p) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, resp, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return p, resp, err | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Edit a pull request.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: https://developer.github.com/v3/pulls/#update-a-pull-request
 | ||||||
|  | func (s *PullRequestsService) Edit(owner string, repo string, number int, pull *PullRequest) (*PullRequest, *Response, error) { | ||||||
|  | 	u := fmt.Sprintf("repos/%v/%v/pulls/%d", owner, repo, number) | ||||||
|  | 	req, err := s.client.NewRequest("PATCH", u, pull) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	p := new(PullRequest) | ||||||
|  | 	resp, err := s.client.Do(req, p) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, resp, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return p, resp, err | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ListCommits lists the commits in a pull request.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: https://developer.github.com/v3/pulls/#list-commits-on-a-pull-request
 | ||||||
|  | func (s *PullRequestsService) ListCommits(owner string, repo string, number int, opt *ListOptions) ([]RepositoryCommit, *Response, error) { | ||||||
|  | 	u := fmt.Sprintf("repos/%v/%v/pulls/%d/commits", owner, repo, number) | ||||||
|  | 	u, err := addOptions(u, opt) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	req, err := s.client.NewRequest("GET", u, nil) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	commits := new([]RepositoryCommit) | ||||||
|  | 	resp, err := s.client.Do(req, commits) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, resp, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return *commits, resp, err | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ListFiles lists the files in a pull request.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: https://developer.github.com/v3/pulls/#list-pull-requests-files
 | ||||||
|  | func (s *PullRequestsService) ListFiles(owner string, repo string, number int, opt *ListOptions) ([]CommitFile, *Response, error) { | ||||||
|  | 	u := fmt.Sprintf("repos/%v/%v/pulls/%d/files", owner, repo, number) | ||||||
|  | 	u, err := addOptions(u, opt) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	req, err := s.client.NewRequest("GET", u, nil) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	commitFiles := new([]CommitFile) | ||||||
|  | 	resp, err := s.client.Do(req, commitFiles) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, resp, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return *commitFiles, resp, err | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // IsMerged checks if a pull request has been merged.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: https://developer.github.com/v3/pulls/#get-if-a-pull-request-has-been-merged
 | ||||||
|  | func (s *PullRequestsService) IsMerged(owner string, repo string, number int) (bool, *Response, error) { | ||||||
|  | 	u := fmt.Sprintf("repos/%v/%v/pulls/%d/merge", owner, repo, number) | ||||||
|  | 	req, err := s.client.NewRequest("GET", u, nil) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return false, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	resp, err := s.client.Do(req, nil) | ||||||
|  | 	merged, err := parseBoolResponse(err) | ||||||
|  | 	return merged, resp, err | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // PullRequestMergeResult represents the result of merging a pull request.
 | ||||||
|  | type PullRequestMergeResult struct { | ||||||
|  | 	SHA     *string `json:"sha,omitempty"` | ||||||
|  | 	Merged  *bool   `json:"merged,omitempty"` | ||||||
|  | 	Message *string `json:"message,omitempty"` | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | type pullRequestMergeRequest struct { | ||||||
|  | 	CommitMessage *string `json:"commit_message"` | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Merge a pull request (Merge Button™).
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: https://developer.github.com/v3/pulls/#merge-a-pull-request-merge-buttontrade
 | ||||||
|  | func (s *PullRequestsService) Merge(owner string, repo string, number int, commitMessage string) (*PullRequestMergeResult, *Response, error) { | ||||||
|  | 	u := fmt.Sprintf("repos/%v/%v/pulls/%d/merge", owner, repo, number) | ||||||
|  | 
 | ||||||
|  | 	req, err := s.client.NewRequest("PUT", u, &pullRequestMergeRequest{ | ||||||
|  | 		CommitMessage: &commitMessage, | ||||||
|  | 	}) | ||||||
|  | 
 | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	mergeResult := new(PullRequestMergeResult) | ||||||
|  | 	resp, err := s.client.Do(req, mergeResult) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, resp, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return mergeResult, resp, err | ||||||
|  | } | ||||||
							
								
								
									
										145
									
								
								vendor/github.com/google/go-github/github/pulls_comments.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										145
									
								
								vendor/github.com/google/go-github/github/pulls_comments.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,145 @@ | |||||||
|  | // Copyright 2013 The go-github 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 github | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  | 	"fmt" | ||||||
|  | 	"time" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | // PullRequestComment represents a comment left on a pull request.
 | ||||||
|  | type PullRequestComment struct { | ||||||
|  | 	ID               *int       `json:"id,omitempty"` | ||||||
|  | 	Body             *string    `json:"body,omitempty"` | ||||||
|  | 	Path             *string    `json:"path,omitempty"` | ||||||
|  | 	DiffHunk         *string    `json:"diff_hunk,omitempty"` | ||||||
|  | 	Position         *int       `json:"position,omitempty"` | ||||||
|  | 	OriginalPosition *int       `json:"original_position,omitempty"` | ||||||
|  | 	CommitID         *string    `json:"commit_id,omitempty"` | ||||||
|  | 	OriginalCommitID *string    `json:"original_commit_id,omitempty"` | ||||||
|  | 	User             *User      `json:"user,omitempty"` | ||||||
|  | 	CreatedAt        *time.Time `json:"created_at,omitempty"` | ||||||
|  | 	UpdatedAt        *time.Time `json:"updated_at,omitempty"` | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (p PullRequestComment) String() string { | ||||||
|  | 	return Stringify(p) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // PullRequestListCommentsOptions specifies the optional parameters to the
 | ||||||
|  | // PullRequestsService.ListComments method.
 | ||||||
|  | type PullRequestListCommentsOptions struct { | ||||||
|  | 	// Sort specifies how to sort comments.  Possible values are: created, updated.
 | ||||||
|  | 	Sort string `url:"sort,omitempty"` | ||||||
|  | 
 | ||||||
|  | 	// Direction in which to sort comments.  Possible values are: asc, desc.
 | ||||||
|  | 	Direction string `url:"direction,omitempty"` | ||||||
|  | 
 | ||||||
|  | 	// Since filters comments by time.
 | ||||||
|  | 	Since time.Time `url:"since,omitempty"` | ||||||
|  | 
 | ||||||
|  | 	ListOptions | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ListComments lists all comments on the specified pull request.  Specifying a
 | ||||||
|  | // pull request number of 0 will return all comments on all pull requests for
 | ||||||
|  | // the repository.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: https://developer.github.com/v3/pulls/comments/#list-comments-on-a-pull-request
 | ||||||
|  | func (s *PullRequestsService) ListComments(owner string, repo string, number int, opt *PullRequestListCommentsOptions) ([]PullRequestComment, *Response, error) { | ||||||
|  | 	var u string | ||||||
|  | 	if number == 0 { | ||||||
|  | 		u = fmt.Sprintf("repos/%v/%v/pulls/comments", owner, repo) | ||||||
|  | 	} else { | ||||||
|  | 		u = fmt.Sprintf("repos/%v/%v/pulls/%d/comments", owner, repo, number) | ||||||
|  | 	} | ||||||
|  | 	u, err := addOptions(u, opt) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	req, err := s.client.NewRequest("GET", u, nil) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	comments := new([]PullRequestComment) | ||||||
|  | 	resp, err := s.client.Do(req, comments) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, resp, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return *comments, resp, err | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // GetComment fetches the specified pull request comment.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: https://developer.github.com/v3/pulls/comments/#get-a-single-comment
 | ||||||
|  | func (s *PullRequestsService) GetComment(owner string, repo string, number int) (*PullRequestComment, *Response, error) { | ||||||
|  | 	u := fmt.Sprintf("repos/%v/%v/pulls/comments/%d", owner, repo, number) | ||||||
|  | 	req, err := s.client.NewRequest("GET", u, nil) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	comment := new(PullRequestComment) | ||||||
|  | 	resp, err := s.client.Do(req, comment) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, resp, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return comment, resp, err | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // CreateComment creates a new comment on the specified pull request.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: https://developer.github.com/v3/pulls/comments/#create-a-comment
 | ||||||
|  | func (s *PullRequestsService) CreateComment(owner string, repo string, number int, comment *PullRequestComment) (*PullRequestComment, *Response, error) { | ||||||
|  | 	u := fmt.Sprintf("repos/%v/%v/pulls/%d/comments", owner, repo, number) | ||||||
|  | 	req, err := s.client.NewRequest("POST", u, comment) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	c := new(PullRequestComment) | ||||||
|  | 	resp, err := s.client.Do(req, c) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, resp, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return c, resp, err | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // EditComment updates a pull request comment.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: https://developer.github.com/v3/pulls/comments/#edit-a-comment
 | ||||||
|  | func (s *PullRequestsService) EditComment(owner string, repo string, number int, comment *PullRequestComment) (*PullRequestComment, *Response, error) { | ||||||
|  | 	u := fmt.Sprintf("repos/%v/%v/pulls/comments/%d", owner, repo, number) | ||||||
|  | 	req, err := s.client.NewRequest("PATCH", u, comment) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	c := new(PullRequestComment) | ||||||
|  | 	resp, err := s.client.Do(req, c) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, resp, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return c, resp, err | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // DeleteComment deletes a pull request comment.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: https://developer.github.com/v3/pulls/comments/#delete-a-comment
 | ||||||
|  | func (s *PullRequestsService) DeleteComment(owner string, repo string, number int) (*Response, error) { | ||||||
|  | 	u := fmt.Sprintf("repos/%v/%v/pulls/comments/%d", owner, repo, number) | ||||||
|  | 	req, err := s.client.NewRequest("DELETE", u, nil) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, err | ||||||
|  | 	} | ||||||
|  | 	return s.client.Do(req, nil) | ||||||
|  | } | ||||||
							
								
								
									
										496
									
								
								vendor/github.com/google/go-github/github/repos.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										496
									
								
								vendor/github.com/google/go-github/github/repos.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,496 @@ | |||||||
|  | // Copyright 2013 The go-github 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 github | ||||||
|  | 
 | ||||||
|  | import "fmt" | ||||||
|  | 
 | ||||||
|  | // RepositoriesService handles communication with the repository related
 | ||||||
|  | // methods of the GitHub API.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: http://developer.github.com/v3/repos/
 | ||||||
|  | type RepositoriesService struct { | ||||||
|  | 	client *Client | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Repository represents a GitHub repository.
 | ||||||
|  | type Repository struct { | ||||||
|  | 	ID               *int             `json:"id,omitempty"` | ||||||
|  | 	Owner            *User            `json:"owner,omitempty"` | ||||||
|  | 	Name             *string          `json:"name,omitempty"` | ||||||
|  | 	FullName         *string          `json:"full_name,omitempty"` | ||||||
|  | 	Description      *string          `json:"description,omitempty"` | ||||||
|  | 	Homepage         *string          `json:"homepage,omitempty"` | ||||||
|  | 	DefaultBranch    *string          `json:"default_branch,omitempty"` | ||||||
|  | 	MasterBranch     *string          `json:"master_branch,omitempty"` | ||||||
|  | 	CreatedAt        *Timestamp       `json:"created_at,omitempty"` | ||||||
|  | 	PushedAt         *Timestamp       `json:"pushed_at,omitempty"` | ||||||
|  | 	UpdatedAt        *Timestamp       `json:"updated_at,omitempty"` | ||||||
|  | 	HTMLURL          *string          `json:"html_url,omitempty"` | ||||||
|  | 	CloneURL         *string          `json:"clone_url,omitempty"` | ||||||
|  | 	GitURL           *string          `json:"git_url,omitempty"` | ||||||
|  | 	MirrorURL        *string          `json:"mirror_url,omitempty"` | ||||||
|  | 	SSHURL           *string          `json:"ssh_url,omitempty"` | ||||||
|  | 	SVNURL           *string          `json:"svn_url,omitempty"` | ||||||
|  | 	Language         *string          `json:"language,omitempty"` | ||||||
|  | 	Fork             *bool            `json:"fork"` | ||||||
|  | 	ForksCount       *int             `json:"forks_count,omitempty"` | ||||||
|  | 	NetworkCount     *int             `json:"network_count,omitempty"` | ||||||
|  | 	OpenIssuesCount  *int             `json:"open_issues_count,omitempty"` | ||||||
|  | 	StargazersCount  *int             `json:"stargazers_count,omitempty"` | ||||||
|  | 	SubscribersCount *int             `json:"subscribers_count,omitempty"` | ||||||
|  | 	WatchersCount    *int             `json:"watchers_count,omitempty"` | ||||||
|  | 	Size             *int             `json:"size,omitempty"` | ||||||
|  | 	AutoInit         *bool            `json:"auto_init,omitempty"` | ||||||
|  | 	Parent           *Repository      `json:"parent,omitempty"` | ||||||
|  | 	Source           *Repository      `json:"source,omitempty"` | ||||||
|  | 	Organization     *Organization    `json:"organization,omitempty"` | ||||||
|  | 	Permissions      *map[string]bool `json:"permissions,omitempty"` | ||||||
|  | 
 | ||||||
|  | 	// Only provided when using RepositoriesService.Get while in preview
 | ||||||
|  | 	License *License `json:"license,omitempty"` | ||||||
|  | 
 | ||||||
|  | 	// Additional mutable fields when creating and editing a repository
 | ||||||
|  | 	Private      *bool `json:"private"` | ||||||
|  | 	HasIssues    *bool `json:"has_issues"` | ||||||
|  | 	HasWiki      *bool `json:"has_wiki"` | ||||||
|  | 	HasDownloads *bool `json:"has_downloads"` | ||||||
|  | 	// Creating an organization repository. Required for non-owners.
 | ||||||
|  | 	TeamID *int `json:"team_id"` | ||||||
|  | 
 | ||||||
|  | 	// API URLs
 | ||||||
|  | 	URL              *string `json:"url,omitempty"` | ||||||
|  | 	ArchiveURL       *string `json:"archive_url,omitempty"` | ||||||
|  | 	AssigneesURL     *string `json:"assignees_url,omitempty"` | ||||||
|  | 	BlobsURL         *string `json:"blobs_url,omitempty"` | ||||||
|  | 	BranchesURL      *string `json:"branches_url,omitempty"` | ||||||
|  | 	CollaboratorsURL *string `json:"collaborators_url,omitempty"` | ||||||
|  | 	CommentsURL      *string `json:"comments_url,omitempty"` | ||||||
|  | 	CommitsURL       *string `json:"commits_url,omitempty"` | ||||||
|  | 	CompareURL       *string `json:"compare_url,omitempty"` | ||||||
|  | 	ContentsURL      *string `json:"contents_url,omitempty"` | ||||||
|  | 	ContributorsURL  *string `json:"contributors_url,omitempty"` | ||||||
|  | 	DownloadsURL     *string `json:"downloads_url,omitempty"` | ||||||
|  | 	EventsURL        *string `json:"events_url,omitempty"` | ||||||
|  | 	ForksURL         *string `json:"forks_url,omitempty"` | ||||||
|  | 	GitCommitsURL    *string `json:"git_commits_url,omitempty"` | ||||||
|  | 	GitRefsURL       *string `json:"git_refs_url,omitempty"` | ||||||
|  | 	GitTagsURL       *string `json:"git_tags_url,omitempty"` | ||||||
|  | 	HooksURL         *string `json:"hooks_url,omitempty"` | ||||||
|  | 	IssueCommentURL  *string `json:"issue_comment_url,omitempty"` | ||||||
|  | 	IssueEventsURL   *string `json:"issue_events_url,omitempty"` | ||||||
|  | 	IssuesURL        *string `json:"issues_url,omitempty"` | ||||||
|  | 	KeysURL          *string `json:"keys_url,omitempty"` | ||||||
|  | 	LabelsURL        *string `json:"labels_url,omitempty"` | ||||||
|  | 	LanguagesURL     *string `json:"languages_url,omitempty"` | ||||||
|  | 	MergesURL        *string `json:"merges_url,omitempty"` | ||||||
|  | 	MilestonesURL    *string `json:"milestones_url,omitempty"` | ||||||
|  | 	NotificationsURL *string `json:"notifications_url,omitempty"` | ||||||
|  | 	PullsURL         *string `json:"pulls_url,omitempty"` | ||||||
|  | 	ReleasesURL      *string `json:"releases_url,omitempty"` | ||||||
|  | 	StargazersURL    *string `json:"stargazers_url,omitempty"` | ||||||
|  | 	StatusesURL      *string `json:"statuses_url,omitempty"` | ||||||
|  | 	SubscribersURL   *string `json:"subscribers_url,omitempty"` | ||||||
|  | 	SubscriptionURL  *string `json:"subscription_url,omitempty"` | ||||||
|  | 	TagsURL          *string `json:"tags_url,omitempty"` | ||||||
|  | 	TreesURL         *string `json:"trees_url,omitempty"` | ||||||
|  | 	TeamsURL         *string `json:"teams_url,omitempty"` | ||||||
|  | 
 | ||||||
|  | 	// TextMatches is only populated from search results that request text matches
 | ||||||
|  | 	// See: search.go and https://developer.github.com/v3/search/#text-match-metadata
 | ||||||
|  | 	TextMatches []TextMatch `json:"text_matches,omitempty"` | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (r Repository) String() string { | ||||||
|  | 	return Stringify(r) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // RepositoryListOptions specifies the optional parameters to the
 | ||||||
|  | // RepositoriesService.List method.
 | ||||||
|  | type RepositoryListOptions struct { | ||||||
|  | 	// Type of repositories to list.  Possible values are: all, owner, public,
 | ||||||
|  | 	// private, member.  Default is "all".
 | ||||||
|  | 	Type string `url:"type,omitempty"` | ||||||
|  | 
 | ||||||
|  | 	// How to sort the repository list.  Possible values are: created, updated,
 | ||||||
|  | 	// pushed, full_name.  Default is "full_name".
 | ||||||
|  | 	Sort string `url:"sort,omitempty"` | ||||||
|  | 
 | ||||||
|  | 	// Direction in which to sort repositories.  Possible values are: asc, desc.
 | ||||||
|  | 	// Default is "asc" when sort is "full_name", otherwise default is "desc".
 | ||||||
|  | 	Direction string `url:"direction,omitempty"` | ||||||
|  | 
 | ||||||
|  | 	ListOptions | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // List the repositories for a user.  Passing the empty string will list
 | ||||||
|  | // repositories for the authenticated user.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: http://developer.github.com/v3/repos/#list-user-repositories
 | ||||||
|  | func (s *RepositoriesService) List(user string, opt *RepositoryListOptions) ([]Repository, *Response, error) { | ||||||
|  | 	var u string | ||||||
|  | 	if user != "" { | ||||||
|  | 		u = fmt.Sprintf("users/%v/repos", user) | ||||||
|  | 	} else { | ||||||
|  | 		u = "user/repos" | ||||||
|  | 	} | ||||||
|  | 	u, err := addOptions(u, opt) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	req, err := s.client.NewRequest("GET", u, nil) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	// TODO: remove custom Accept header when license support fully launches
 | ||||||
|  | 	req.Header.Set("Accept", mediaTypeLicensesPreview) | ||||||
|  | 
 | ||||||
|  | 	repos := new([]Repository) | ||||||
|  | 	resp, err := s.client.Do(req, repos) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, resp, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return *repos, resp, err | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // RepositoryListByOrgOptions specifies the optional parameters to the
 | ||||||
|  | // RepositoriesService.ListByOrg method.
 | ||||||
|  | type RepositoryListByOrgOptions struct { | ||||||
|  | 	// Type of repositories to list.  Possible values are: all, public, private,
 | ||||||
|  | 	// forks, sources, member.  Default is "all".
 | ||||||
|  | 	Type string `url:"type,omitempty"` | ||||||
|  | 
 | ||||||
|  | 	ListOptions | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ListByOrg lists the repositories for an organization.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: http://developer.github.com/v3/repos/#list-organization-repositories
 | ||||||
|  | func (s *RepositoriesService) ListByOrg(org string, opt *RepositoryListByOrgOptions) ([]Repository, *Response, error) { | ||||||
|  | 	u := fmt.Sprintf("orgs/%v/repos", org) | ||||||
|  | 	u, err := addOptions(u, opt) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	req, err := s.client.NewRequest("GET", u, nil) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	// TODO: remove custom Accept header when license support fully launches
 | ||||||
|  | 	req.Header.Set("Accept", mediaTypeLicensesPreview) | ||||||
|  | 
 | ||||||
|  | 	repos := new([]Repository) | ||||||
|  | 	resp, err := s.client.Do(req, repos) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, resp, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return *repos, resp, err | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // RepositoryListAllOptions specifies the optional parameters to the
 | ||||||
|  | // RepositoriesService.ListAll method.
 | ||||||
|  | type RepositoryListAllOptions struct { | ||||||
|  | 	// ID of the last repository seen
 | ||||||
|  | 	Since int `url:"since,omitempty"` | ||||||
|  | 
 | ||||||
|  | 	ListOptions | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ListAll lists all GitHub repositories in the order that they were created.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: http://developer.github.com/v3/repos/#list-all-public-repositories
 | ||||||
|  | func (s *RepositoriesService) ListAll(opt *RepositoryListAllOptions) ([]Repository, *Response, error) { | ||||||
|  | 	u, err := addOptions("repositories", opt) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	req, err := s.client.NewRequest("GET", u, nil) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	repos := new([]Repository) | ||||||
|  | 	resp, err := s.client.Do(req, repos) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, resp, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return *repos, resp, err | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Create a new repository.  If an organization is specified, the new
 | ||||||
|  | // repository will be created under that org.  If the empty string is
 | ||||||
|  | // specified, it will be created for the authenticated user.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: http://developer.github.com/v3/repos/#create
 | ||||||
|  | func (s *RepositoriesService) Create(org string, repo *Repository) (*Repository, *Response, error) { | ||||||
|  | 	var u string | ||||||
|  | 	if org != "" { | ||||||
|  | 		u = fmt.Sprintf("orgs/%v/repos", org) | ||||||
|  | 	} else { | ||||||
|  | 		u = "user/repos" | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	req, err := s.client.NewRequest("POST", u, repo) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	r := new(Repository) | ||||||
|  | 	resp, err := s.client.Do(req, r) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, resp, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return r, resp, err | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Get fetches a repository.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: http://developer.github.com/v3/repos/#get
 | ||||||
|  | func (s *RepositoriesService) Get(owner, repo string) (*Repository, *Response, error) { | ||||||
|  | 	u := fmt.Sprintf("repos/%v/%v", owner, repo) | ||||||
|  | 	req, err := s.client.NewRequest("GET", u, nil) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	// TODO: remove custom Accept header when the license support fully launches
 | ||||||
|  | 	// https://developer.github.com/v3/licenses/#get-a-repositorys-license
 | ||||||
|  | 	req.Header.Set("Accept", mediaTypeLicensesPreview) | ||||||
|  | 
 | ||||||
|  | 	repository := new(Repository) | ||||||
|  | 	resp, err := s.client.Do(req, repository) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, resp, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return repository, resp, err | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Edit updates a repository.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: http://developer.github.com/v3/repos/#edit
 | ||||||
|  | func (s *RepositoriesService) Edit(owner, repo string, repository *Repository) (*Repository, *Response, error) { | ||||||
|  | 	u := fmt.Sprintf("repos/%v/%v", owner, repo) | ||||||
|  | 	req, err := s.client.NewRequest("PATCH", u, repository) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	r := new(Repository) | ||||||
|  | 	resp, err := s.client.Do(req, r) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, resp, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return r, resp, err | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Delete a repository.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: https://developer.github.com/v3/repos/#delete-a-repository
 | ||||||
|  | func (s *RepositoriesService) Delete(owner, repo string) (*Response, error) { | ||||||
|  | 	u := fmt.Sprintf("repos/%v/%v", owner, repo) | ||||||
|  | 	req, err := s.client.NewRequest("DELETE", u, nil) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return s.client.Do(req, nil) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Contributor represents a repository contributor
 | ||||||
|  | type Contributor struct { | ||||||
|  | 	Login             *string `json:"login,omitempty"` | ||||||
|  | 	ID                *int    `json:"id,omitempty"` | ||||||
|  | 	AvatarURL         *string `json:"avatar_url,omitempty"` | ||||||
|  | 	GravatarID        *string `json:"gravatar_id,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"` | ||||||
|  | 	Contributions     *int    `json:"contributions,omitempty"` | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ListContributorsOptions specifies the optional parameters to the
 | ||||||
|  | // RepositoriesService.ListContributors method.
 | ||||||
|  | type ListContributorsOptions struct { | ||||||
|  | 	// Include anonymous contributors in results or not
 | ||||||
|  | 	Anon string `url:"anon,omitempty"` | ||||||
|  | 
 | ||||||
|  | 	ListOptions | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ListContributors lists contributors for a repository.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: http://developer.github.com/v3/repos/#list-contributors
 | ||||||
|  | func (s *RepositoriesService) ListContributors(owner string, repository string, opt *ListContributorsOptions) ([]Contributor, *Response, error) { | ||||||
|  | 	u := fmt.Sprintf("repos/%v/%v/contributors", owner, repository) | ||||||
|  | 	u, err := addOptions(u, opt) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	req, err := s.client.NewRequest("GET", u, nil) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	contributor := new([]Contributor) | ||||||
|  | 	resp, err := s.client.Do(req, contributor) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return *contributor, resp, err | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ListLanguages lists languages for the specified repository. The returned map
 | ||||||
|  | // specifies the languages and the number of bytes of code written in that
 | ||||||
|  | // language. For example:
 | ||||||
|  | //
 | ||||||
|  | //     {
 | ||||||
|  | //       "C": 78769,
 | ||||||
|  | //       "Python": 7769
 | ||||||
|  | //     }
 | ||||||
|  | //
 | ||||||
|  | // GitHub API Docs: http://developer.github.com/v3/repos/#list-languages
 | ||||||
|  | func (s *RepositoriesService) ListLanguages(owner string, repo string) (map[string]int, *Response, error) { | ||||||
|  | 	u := fmt.Sprintf("repos/%v/%v/languages", owner, repo) | ||||||
|  | 	req, err := s.client.NewRequest("GET", u, nil) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	languages := make(map[string]int) | ||||||
|  | 	resp, err := s.client.Do(req, &languages) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, resp, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return languages, resp, err | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ListTeams lists the teams for the specified repository.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: https://developer.github.com/v3/repos/#list-teams
 | ||||||
|  | func (s *RepositoriesService) ListTeams(owner string, repo string, opt *ListOptions) ([]Team, *Response, error) { | ||||||
|  | 	u := fmt.Sprintf("repos/%v/%v/teams", owner, repo) | ||||||
|  | 	u, err := addOptions(u, opt) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	req, err := s.client.NewRequest("GET", u, nil) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	teams := new([]Team) | ||||||
|  | 	resp, err := s.client.Do(req, teams) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, resp, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return *teams, resp, err | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // RepositoryTag represents a repository tag.
 | ||||||
|  | type RepositoryTag struct { | ||||||
|  | 	Name       *string `json:"name,omitempty"` | ||||||
|  | 	Commit     *Commit `json:"commit,omitempty"` | ||||||
|  | 	ZipballURL *string `json:"zipball_url,omitempty"` | ||||||
|  | 	TarballURL *string `json:"tarball_url,omitempty"` | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ListTags lists tags for the specified repository.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: https://developer.github.com/v3/repos/#list-tags
 | ||||||
|  | func (s *RepositoriesService) ListTags(owner string, repo string, opt *ListOptions) ([]RepositoryTag, *Response, error) { | ||||||
|  | 	u := fmt.Sprintf("repos/%v/%v/tags", owner, repo) | ||||||
|  | 	u, err := addOptions(u, opt) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	req, err := s.client.NewRequest("GET", u, nil) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	tags := new([]RepositoryTag) | ||||||
|  | 	resp, err := s.client.Do(req, tags) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, resp, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return *tags, resp, err | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Branch represents a repository branch
 | ||||||
|  | type Branch struct { | ||||||
|  | 	Name   *string `json:"name,omitempty"` | ||||||
|  | 	Commit *Commit `json:"commit,omitempty"` | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ListBranches lists branches for the specified repository.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: http://developer.github.com/v3/repos/#list-branches
 | ||||||
|  | func (s *RepositoriesService) ListBranches(owner string, repo string, opt *ListOptions) ([]Branch, *Response, error) { | ||||||
|  | 	u := fmt.Sprintf("repos/%v/%v/branches", owner, repo) | ||||||
|  | 	u, err := addOptions(u, opt) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	req, err := s.client.NewRequest("GET", u, nil) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	branches := new([]Branch) | ||||||
|  | 	resp, err := s.client.Do(req, branches) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, resp, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return *branches, resp, err | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // GetBranch gets the specified branch for a repository.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: https://developer.github.com/v3/repos/#get-branch
 | ||||||
|  | func (s *RepositoriesService) GetBranch(owner, repo, branch string) (*Branch, *Response, error) { | ||||||
|  | 	u := fmt.Sprintf("repos/%v/%v/branches/%v", owner, repo, branch) | ||||||
|  | 	req, err := s.client.NewRequest("GET", u, nil) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	b := new(Branch) | ||||||
|  | 	resp, err := s.client.Do(req, b) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, resp, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return b, resp, err | ||||||
|  | } | ||||||
							
								
								
									
										95
									
								
								vendor/github.com/google/go-github/github/repos_collaborators.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										95
									
								
								vendor/github.com/google/go-github/github/repos_collaborators.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,95 @@ | |||||||
|  | // Copyright 2013 The go-github 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 github | ||||||
|  | 
 | ||||||
|  | import "fmt" | ||||||
|  | 
 | ||||||
|  | // ListCollaborators lists the Github users that have access to the repository.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: http://developer.github.com/v3/repos/collaborators/#list
 | ||||||
|  | func (s *RepositoriesService) ListCollaborators(owner, repo string, opt *ListOptions) ([]User, *Response, error) { | ||||||
|  | 	u := fmt.Sprintf("repos/%v/%v/collaborators", owner, repo) | ||||||
|  | 	u, err := addOptions(u, opt) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	req, err := s.client.NewRequest("GET", u, nil) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	req.Header.Set("Accept", mediaTypeOrgPermissionPreview) | ||||||
|  | 
 | ||||||
|  | 	users := new([]User) | ||||||
|  | 	resp, err := s.client.Do(req, users) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, resp, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return *users, resp, err | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // IsCollaborator checks whether the specified Github user has collaborator
 | ||||||
|  | // access to the given repo.
 | ||||||
|  | // Note: This will return false if the user is not a collaborator OR the user
 | ||||||
|  | // is not a GitHub user.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: http://developer.github.com/v3/repos/collaborators/#get
 | ||||||
|  | func (s *RepositoriesService) IsCollaborator(owner, repo, user string) (bool, *Response, error) { | ||||||
|  | 	u := fmt.Sprintf("repos/%v/%v/collaborators/%v", owner, repo, user) | ||||||
|  | 	req, err := s.client.NewRequest("GET", u, nil) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return false, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	resp, err := s.client.Do(req, nil) | ||||||
|  | 	isCollab, err := parseBoolResponse(err) | ||||||
|  | 	return isCollab, resp, err | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // RepositoryAddCollaboratorOptions specifies the optional parameters to the
 | ||||||
|  | // RepositoriesService.AddCollaborator method.
 | ||||||
|  | type RepositoryAddCollaboratorOptions struct { | ||||||
|  | 	// Permission specifies the permission to grant the user on this repository.
 | ||||||
|  | 	// Possible values are:
 | ||||||
|  | 	//     pull - team members can pull, but not push to or administer this repository
 | ||||||
|  | 	//     push - team members can pull and push, but not administer this repository
 | ||||||
|  | 	//     admin - team members can pull, push and administer this repository
 | ||||||
|  | 	//
 | ||||||
|  | 	// Default value is "pull".  This option is only valid for organization-owned repositories.
 | ||||||
|  | 	Permission string `json:"permission,omitempty"` | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // AddCollaborator adds the specified Github user as collaborator to the given repo.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: http://developer.github.com/v3/repos/collaborators/#add-collaborator
 | ||||||
|  | func (s *RepositoriesService) AddCollaborator(owner, repo, user string, opt *RepositoryAddCollaboratorOptions) (*Response, error) { | ||||||
|  | 	u := fmt.Sprintf("repos/%v/%v/collaborators/%v", owner, repo, user) | ||||||
|  | 	req, err := s.client.NewRequest("PUT", u, opt) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if opt != nil { | ||||||
|  | 		req.Header.Set("Accept", mediaTypeOrgPermissionPreview) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return s.client.Do(req, nil) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // RemoveCollaborator removes the specified Github user as collaborator from the given repo.
 | ||||||
|  | // Note: Does not return error if a valid user that is not a collaborator is removed.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: http://developer.github.com/v3/repos/collaborators/#remove-collaborator
 | ||||||
|  | func (s *RepositoriesService) RemoveCollaborator(owner, repo, user string) (*Response, error) { | ||||||
|  | 	u := fmt.Sprintf("repos/%v/%v/collaborators/%v", owner, repo, user) | ||||||
|  | 	req, err := s.client.NewRequest("DELETE", u, nil) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, err | ||||||
|  | 	} | ||||||
|  | 	return s.client.Do(req, nil) | ||||||
|  | } | ||||||
							
								
								
									
										150
									
								
								vendor/github.com/google/go-github/github/repos_comments.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										150
									
								
								vendor/github.com/google/go-github/github/repos_comments.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,150 @@ | |||||||
|  | // Copyright 2013 The go-github 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 github | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  | 	"fmt" | ||||||
|  | 	"time" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | // RepositoryComment represents a comment for a commit, file, or line in a repository.
 | ||||||
|  | type RepositoryComment struct { | ||||||
|  | 	HTMLURL   *string    `json:"html_url,omitempty"` | ||||||
|  | 	URL       *string    `json:"url,omitempty"` | ||||||
|  | 	ID        *int       `json:"id,omitempty"` | ||||||
|  | 	CommitID  *string    `json:"commit_id,omitempty"` | ||||||
|  | 	User      *User      `json:"user,omitempty"` | ||||||
|  | 	CreatedAt *time.Time `json:"created_at,omitempty"` | ||||||
|  | 	UpdatedAt *time.Time `json:"updated_at,omitempty"` | ||||||
|  | 
 | ||||||
|  | 	// User-mutable fields
 | ||||||
|  | 	Body *string `json:"body"` | ||||||
|  | 	// User-initialized fields
 | ||||||
|  | 	Path     *string `json:"path,omitempty"` | ||||||
|  | 	Position *int    `json:"position,omitempty"` | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (r RepositoryComment) String() string { | ||||||
|  | 	return Stringify(r) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ListComments lists all the comments for the repository.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: http://developer.github.com/v3/repos/comments/#list-commit-comments-for-a-repository
 | ||||||
|  | func (s *RepositoriesService) ListComments(owner, repo string, opt *ListOptions) ([]RepositoryComment, *Response, error) { | ||||||
|  | 	u := fmt.Sprintf("repos/%v/%v/comments", owner, repo) | ||||||
|  | 	u, err := addOptions(u, opt) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	req, err := s.client.NewRequest("GET", u, nil) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	comments := new([]RepositoryComment) | ||||||
|  | 	resp, err := s.client.Do(req, comments) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, resp, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return *comments, resp, err | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ListCommitComments lists all the comments for a given commit SHA.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: http://developer.github.com/v3/repos/comments/#list-comments-for-a-single-commit
 | ||||||
|  | func (s *RepositoriesService) ListCommitComments(owner, repo, sha string, opt *ListOptions) ([]RepositoryComment, *Response, error) { | ||||||
|  | 	u := fmt.Sprintf("repos/%v/%v/commits/%v/comments", owner, repo, sha) | ||||||
|  | 	u, err := addOptions(u, opt) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	req, err := s.client.NewRequest("GET", u, nil) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	comments := new([]RepositoryComment) | ||||||
|  | 	resp, err := s.client.Do(req, comments) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, resp, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return *comments, resp, err | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // CreateComment creates a comment for the given commit.
 | ||||||
|  | // Note: GitHub allows for comments to be created for non-existing files and positions.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: http://developer.github.com/v3/repos/comments/#create-a-commit-comment
 | ||||||
|  | func (s *RepositoriesService) CreateComment(owner, repo, sha string, comment *RepositoryComment) (*RepositoryComment, *Response, error) { | ||||||
|  | 	u := fmt.Sprintf("repos/%v/%v/commits/%v/comments", owner, repo, sha) | ||||||
|  | 	req, err := s.client.NewRequest("POST", u, comment) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	c := new(RepositoryComment) | ||||||
|  | 	resp, err := s.client.Do(req, c) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, resp, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return c, resp, err | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // GetComment gets a single comment from a repository.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: http://developer.github.com/v3/repos/comments/#get-a-single-commit-comment
 | ||||||
|  | func (s *RepositoriesService) GetComment(owner, repo string, id int) (*RepositoryComment, *Response, error) { | ||||||
|  | 	u := fmt.Sprintf("repos/%v/%v/comments/%v", owner, repo, id) | ||||||
|  | 	req, err := s.client.NewRequest("GET", u, nil) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	c := new(RepositoryComment) | ||||||
|  | 	resp, err := s.client.Do(req, c) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, resp, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return c, resp, err | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // UpdateComment updates the body of a single comment.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: http://developer.github.com/v3/repos/comments/#update-a-commit-comment
 | ||||||
|  | func (s *RepositoriesService) UpdateComment(owner, repo string, id int, comment *RepositoryComment) (*RepositoryComment, *Response, error) { | ||||||
|  | 	u := fmt.Sprintf("repos/%v/%v/comments/%v", owner, repo, id) | ||||||
|  | 	req, err := s.client.NewRequest("PATCH", u, comment) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	c := new(RepositoryComment) | ||||||
|  | 	resp, err := s.client.Do(req, c) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, resp, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return c, resp, err | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // DeleteComment deletes a single comment from a repository.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: http://developer.github.com/v3/repos/comments/#delete-a-commit-comment
 | ||||||
|  | func (s *RepositoriesService) DeleteComment(owner, repo string, id int) (*Response, error) { | ||||||
|  | 	u := fmt.Sprintf("repos/%v/%v/comments/%v", owner, repo, id) | ||||||
|  | 	req, err := s.client.NewRequest("DELETE", u, nil) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, err | ||||||
|  | 	} | ||||||
|  | 	return s.client.Do(req, nil) | ||||||
|  | } | ||||||
							
								
								
									
										168
									
								
								vendor/github.com/google/go-github/github/repos_commits.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										168
									
								
								vendor/github.com/google/go-github/github/repos_commits.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,168 @@ | |||||||
|  | // Copyright 2013 The go-github 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 github | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  | 	"fmt" | ||||||
|  | 	"time" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | // RepositoryCommit represents a commit in a repo.
 | ||||||
|  | // Note that it's wrapping a Commit, so author/committer information is in two places,
 | ||||||
|  | // but contain different details about them: in RepositoryCommit "github details", in Commit - "git details".
 | ||||||
|  | type RepositoryCommit struct { | ||||||
|  | 	SHA       *string  `json:"sha,omitempty"` | ||||||
|  | 	Commit    *Commit  `json:"commit,omitempty"` | ||||||
|  | 	Author    *User    `json:"author,omitempty"` | ||||||
|  | 	Committer *User    `json:"committer,omitempty"` | ||||||
|  | 	Parents   []Commit `json:"parents,omitempty"` | ||||||
|  | 	Message   *string  `json:"message,omitempty"` | ||||||
|  | 	HTMLURL   *string  `json:"html_url,omitempty"` | ||||||
|  | 
 | ||||||
|  | 	// Details about how many changes were made in this commit. Only filled in during GetCommit!
 | ||||||
|  | 	Stats *CommitStats `json:"stats,omitempty"` | ||||||
|  | 	// Details about which files, and how this commit touched. Only filled in during GetCommit!
 | ||||||
|  | 	Files []CommitFile `json:"files,omitempty"` | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (r RepositoryCommit) String() string { | ||||||
|  | 	return Stringify(r) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // CommitStats represents the number of additions / deletions from a file in a given RepositoryCommit.
 | ||||||
|  | type CommitStats struct { | ||||||
|  | 	Additions *int `json:"additions,omitempty"` | ||||||
|  | 	Deletions *int `json:"deletions,omitempty"` | ||||||
|  | 	Total     *int `json:"total,omitempty"` | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (c CommitStats) String() string { | ||||||
|  | 	return Stringify(c) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // CommitFile represents a file modified in a commit.
 | ||||||
|  | type CommitFile struct { | ||||||
|  | 	SHA       *string `json:"sha,omitempty"` | ||||||
|  | 	Filename  *string `json:"filename,omitempty"` | ||||||
|  | 	Additions *int    `json:"additions,omitempty"` | ||||||
|  | 	Deletions *int    `json:"deletions,omitempty"` | ||||||
|  | 	Changes   *int    `json:"changes,omitempty"` | ||||||
|  | 	Status    *string `json:"status,omitempty"` | ||||||
|  | 	Patch     *string `json:"patch,omitempty"` | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (c CommitFile) String() string { | ||||||
|  | 	return Stringify(c) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // CommitsComparison is the result of comparing two commits.
 | ||||||
|  | // See CompareCommits() for details.
 | ||||||
|  | type CommitsComparison struct { | ||||||
|  | 	BaseCommit      *RepositoryCommit `json:"base_commit,omitempty"` | ||||||
|  | 	MergeBaseCommit *RepositoryCommit `json:"merge_base_commit,omitempty"` | ||||||
|  | 
 | ||||||
|  | 	// Head can be 'behind' or 'ahead'
 | ||||||
|  | 	Status       *string `json:"status,omitempty"` | ||||||
|  | 	AheadBy      *int    `json:"ahead_by,omitempty"` | ||||||
|  | 	BehindBy     *int    `json:"behind_by,omitempty"` | ||||||
|  | 	TotalCommits *int    `json:"total_commits,omitempty"` | ||||||
|  | 
 | ||||||
|  | 	Commits []RepositoryCommit `json:"commits,omitempty"` | ||||||
|  | 
 | ||||||
|  | 	Files []CommitFile `json:"files,omitempty"` | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (c CommitsComparison) String() string { | ||||||
|  | 	return Stringify(c) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // CommitsListOptions specifies the optional parameters to the
 | ||||||
|  | // RepositoriesService.ListCommits method.
 | ||||||
|  | type CommitsListOptions struct { | ||||||
|  | 	// SHA or branch to start listing Commits from.
 | ||||||
|  | 	SHA string `url:"sha,omitempty"` | ||||||
|  | 
 | ||||||
|  | 	// Path that should be touched by the returned Commits.
 | ||||||
|  | 	Path string `url:"path,omitempty"` | ||||||
|  | 
 | ||||||
|  | 	// Author of by which to filter Commits.
 | ||||||
|  | 	Author string `url:"author,omitempty"` | ||||||
|  | 
 | ||||||
|  | 	// Since when should Commits be included in the response.
 | ||||||
|  | 	Since time.Time `url:"since,omitempty"` | ||||||
|  | 
 | ||||||
|  | 	// Until when should Commits be included in the response.
 | ||||||
|  | 	Until time.Time `url:"until,omitempty"` | ||||||
|  | 
 | ||||||
|  | 	ListOptions | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ListCommits lists the commits of a repository.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: http://developer.github.com/v3/repos/commits/#list
 | ||||||
|  | func (s *RepositoriesService) ListCommits(owner, repo string, opt *CommitsListOptions) ([]RepositoryCommit, *Response, error) { | ||||||
|  | 	u := fmt.Sprintf("repos/%v/%v/commits", owner, repo) | ||||||
|  | 	u, err := addOptions(u, opt) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	req, err := s.client.NewRequest("GET", u, nil) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	commits := new([]RepositoryCommit) | ||||||
|  | 	resp, err := s.client.Do(req, commits) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, resp, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return *commits, resp, err | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // GetCommit fetches the specified commit, including all details about it.
 | ||||||
|  | // todo: support media formats - https://github.com/google/go-github/issues/6
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: http://developer.github.com/v3/repos/commits/#get-a-single-commit
 | ||||||
|  | // See also: http://developer.github.com//v3/git/commits/#get-a-single-commit provides the same functionality
 | ||||||
|  | func (s *RepositoriesService) GetCommit(owner, repo, sha string) (*RepositoryCommit, *Response, error) { | ||||||
|  | 	u := fmt.Sprintf("repos/%v/%v/commits/%v", owner, repo, sha) | ||||||
|  | 
 | ||||||
|  | 	req, err := s.client.NewRequest("GET", u, nil) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	commit := new(RepositoryCommit) | ||||||
|  | 	resp, err := s.client.Do(req, commit) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, resp, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return commit, resp, err | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // CompareCommits compares a range of commits with each other.
 | ||||||
|  | // todo: support media formats - https://github.com/google/go-github/issues/6
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: http://developer.github.com/v3/repos/commits/index.html#compare-two-commits
 | ||||||
|  | func (s *RepositoriesService) CompareCommits(owner, repo string, base, head string) (*CommitsComparison, *Response, error) { | ||||||
|  | 	u := fmt.Sprintf("repos/%v/%v/compare/%v...%v", owner, repo, base, head) | ||||||
|  | 
 | ||||||
|  | 	req, err := s.client.NewRequest("GET", u, nil) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	comp := new(CommitsComparison) | ||||||
|  | 	resp, err := s.client.Do(req, comp) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, resp, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return comp, resp, err | ||||||
|  | } | ||||||
							
								
								
									
										248
									
								
								vendor/github.com/google/go-github/github/repos_contents.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										248
									
								
								vendor/github.com/google/go-github/github/repos_contents.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,248 @@ | |||||||
|  | // Copyright 2013 The go-github AUTHORS. All rights reserved.
 | ||||||
|  | //
 | ||||||
|  | // Use of this source code is governed by a BSD-style
 | ||||||
|  | // license that can be found in the LICENSE file.
 | ||||||
|  | 
 | ||||||
|  | // Repository contents API methods.
 | ||||||
|  | // http://developer.github.com/v3/repos/contents/
 | ||||||
|  | 
 | ||||||
|  | package github | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  | 	"encoding/base64" | ||||||
|  | 	"encoding/json" | ||||||
|  | 	"errors" | ||||||
|  | 	"fmt" | ||||||
|  | 	"io" | ||||||
|  | 	"net/http" | ||||||
|  | 	"net/url" | ||||||
|  | 	"path" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | // RepositoryContent represents a file or directory in a github repository.
 | ||||||
|  | type RepositoryContent struct { | ||||||
|  | 	Type        *string `json:"type,omitempty"` | ||||||
|  | 	Encoding    *string `json:"encoding,omitempty"` | ||||||
|  | 	Size        *int    `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"` | ||||||
|  | 	GitURL      *string `json:"git_url,omitempty"` | ||||||
|  | 	HTMLURL     *string `json:"html_url,omitempty"` | ||||||
|  | 	DownloadURL *string `json:"download_url,omitempty"` | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // RepositoryContentResponse holds the parsed response from CreateFile, UpdateFile, and DeleteFile.
 | ||||||
|  | type RepositoryContentResponse struct { | ||||||
|  | 	Content *RepositoryContent `json:"content,omitempty"` | ||||||
|  | 	Commit  `json:"commit,omitempty"` | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // RepositoryContentFileOptions specifies optional parameters for CreateFile, UpdateFile, and DeleteFile.
 | ||||||
|  | type RepositoryContentFileOptions struct { | ||||||
|  | 	Message   *string       `json:"message,omitempty"` | ||||||
|  | 	Content   []byte        `json:"content,omitempty"` | ||||||
|  | 	SHA       *string       `json:"sha,omitempty"` | ||||||
|  | 	Branch    *string       `json:"branch,omitempty"` | ||||||
|  | 	Author    *CommitAuthor `json:"author,omitempty"` | ||||||
|  | 	Committer *CommitAuthor `json:"committer,omitempty"` | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // RepositoryContentGetOptions represents an optional ref parameter, which can be a SHA,
 | ||||||
|  | // branch, or tag
 | ||||||
|  | type RepositoryContentGetOptions struct { | ||||||
|  | 	Ref string `url:"ref,omitempty"` | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (r RepositoryContent) String() string { | ||||||
|  | 	return Stringify(r) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Decode decodes the file content if it is base64 encoded.
 | ||||||
|  | func (r *RepositoryContent) Decode() ([]byte, error) { | ||||||
|  | 	if *r.Encoding != "base64" { | ||||||
|  | 		return nil, errors.New("cannot decode non-base64") | ||||||
|  | 	} | ||||||
|  | 	o, err := base64.StdEncoding.DecodeString(*r.Content) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, err | ||||||
|  | 	} | ||||||
|  | 	return o, nil | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // GetReadme gets the Readme file for the repository.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: http://developer.github.com/v3/repos/contents/#get-the-readme
 | ||||||
|  | func (s *RepositoriesService) GetReadme(owner, repo string, opt *RepositoryContentGetOptions) (*RepositoryContent, *Response, error) { | ||||||
|  | 	u := fmt.Sprintf("repos/%v/%v/readme", owner, repo) | ||||||
|  | 	u, err := addOptions(u, opt) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 	req, err := s.client.NewRequest("GET", u, nil) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 	readme := new(RepositoryContent) | ||||||
|  | 	resp, err := s.client.Do(req, readme) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, resp, err | ||||||
|  | 	} | ||||||
|  | 	return readme, resp, err | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // DownloadContents returns an io.ReadCloser that reads the contents of the
 | ||||||
|  | // specified file. This function will work with files of any size, as opposed
 | ||||||
|  | // to GetContents which is limited to 1 Mb files. It is the caller's
 | ||||||
|  | // responsibility to close the ReadCloser.
 | ||||||
|  | func (s *RepositoriesService) DownloadContents(owner, repo, filepath string, opt *RepositoryContentGetOptions) (io.ReadCloser, error) { | ||||||
|  | 	dir := path.Dir(filepath) | ||||||
|  | 	filename := path.Base(filepath) | ||||||
|  | 	_, dirContents, _, err := s.GetContents(owner, repo, dir, opt) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, err | ||||||
|  | 	} | ||||||
|  | 	for _, contents := range dirContents { | ||||||
|  | 		if *contents.Name == filename { | ||||||
|  | 			if contents.DownloadURL == nil || *contents.DownloadURL == "" { | ||||||
|  | 				return nil, fmt.Errorf("No download link found for %s", filepath) | ||||||
|  | 			} | ||||||
|  | 			resp, err := s.client.client.Get(*contents.DownloadURL) | ||||||
|  | 			if err != nil { | ||||||
|  | 				return nil, err | ||||||
|  | 			} | ||||||
|  | 			return resp.Body, nil | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	return nil, fmt.Errorf("No file named %s found in %s", filename, dir) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // GetContents can return either the metadata and content of a single file
 | ||||||
|  | // (when path references a file) or the metadata of all the files and/or
 | ||||||
|  | // subdirectories of a directory (when path references a directory). To make it
 | ||||||
|  | // easy to distinguish between both result types and to mimic the API as much
 | ||||||
|  | // as possible, both result types will be returned but only one will contain a
 | ||||||
|  | // value and the other will be nil.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: http://developer.github.com/v3/repos/contents/#get-contents
 | ||||||
|  | func (s *RepositoriesService) GetContents(owner, repo, path string, opt *RepositoryContentGetOptions) (fileContent *RepositoryContent, | ||||||
|  | 	directoryContent []*RepositoryContent, resp *Response, err error) { | ||||||
|  | 	u := fmt.Sprintf("repos/%s/%s/contents/%s", owner, repo, path) | ||||||
|  | 	u, err = addOptions(u, opt) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, nil, err | ||||||
|  | 	} | ||||||
|  | 	req, err := s.client.NewRequest("GET", u, nil) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, nil, err | ||||||
|  | 	} | ||||||
|  | 	var rawJSON json.RawMessage | ||||||
|  | 	resp, err = s.client.Do(req, &rawJSON) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, resp, err | ||||||
|  | 	} | ||||||
|  | 	fileUnmarshalError := json.Unmarshal(rawJSON, &fileContent) | ||||||
|  | 	if fileUnmarshalError == nil { | ||||||
|  | 		return fileContent, nil, resp, fileUnmarshalError | ||||||
|  | 	} | ||||||
|  | 	directoryUnmarshalError := json.Unmarshal(rawJSON, &directoryContent) | ||||||
|  | 	if directoryUnmarshalError == nil { | ||||||
|  | 		return nil, directoryContent, resp, directoryUnmarshalError | ||||||
|  | 	} | ||||||
|  | 	return nil, nil, resp, fmt.Errorf("unmarshalling failed for both file and directory content: %s and %s ", fileUnmarshalError, directoryUnmarshalError) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // CreateFile creates a new file in a repository at the given path and returns
 | ||||||
|  | // the commit and file metadata.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: http://developer.github.com/v3/repos/contents/#create-a-file
 | ||||||
|  | func (s *RepositoriesService) CreateFile(owner, repo, path string, opt *RepositoryContentFileOptions) (*RepositoryContentResponse, *Response, error) { | ||||||
|  | 	u := fmt.Sprintf("repos/%s/%s/contents/%s", owner, repo, path) | ||||||
|  | 	req, err := s.client.NewRequest("PUT", u, opt) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 	createResponse := new(RepositoryContentResponse) | ||||||
|  | 	resp, err := s.client.Do(req, createResponse) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, resp, err | ||||||
|  | 	} | ||||||
|  | 	return createResponse, resp, err | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // UpdateFile updates a file in a repository at the given path and returns the
 | ||||||
|  | // commit and file metadata. Requires the blob SHA of the file being updated.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: http://developer.github.com/v3/repos/contents/#update-a-file
 | ||||||
|  | func (s *RepositoriesService) UpdateFile(owner, repo, path string, opt *RepositoryContentFileOptions) (*RepositoryContentResponse, *Response, error) { | ||||||
|  | 	u := fmt.Sprintf("repos/%s/%s/contents/%s", owner, repo, path) | ||||||
|  | 	req, err := s.client.NewRequest("PUT", u, opt) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 	updateResponse := new(RepositoryContentResponse) | ||||||
|  | 	resp, err := s.client.Do(req, updateResponse) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, resp, err | ||||||
|  | 	} | ||||||
|  | 	return updateResponse, resp, err | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // DeleteFile deletes a file from a repository and returns the commit.
 | ||||||
|  | // Requires the blob SHA of the file to be deleted.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: http://developer.github.com/v3/repos/contents/#delete-a-file
 | ||||||
|  | func (s *RepositoriesService) DeleteFile(owner, repo, path string, opt *RepositoryContentFileOptions) (*RepositoryContentResponse, *Response, error) { | ||||||
|  | 	u := fmt.Sprintf("repos/%s/%s/contents/%s", owner, repo, path) | ||||||
|  | 	req, err := s.client.NewRequest("DELETE", u, opt) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 	deleteResponse := new(RepositoryContentResponse) | ||||||
|  | 	resp, err := s.client.Do(req, deleteResponse) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, resp, err | ||||||
|  | 	} | ||||||
|  | 	return deleteResponse, resp, err | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // archiveFormat is used to define the archive type when calling GetArchiveLink.
 | ||||||
|  | type archiveFormat string | ||||||
|  | 
 | ||||||
|  | const ( | ||||||
|  | 	// Tarball specifies an archive in gzipped tar format.
 | ||||||
|  | 	Tarball archiveFormat = "tarball" | ||||||
|  | 
 | ||||||
|  | 	// Zipball specifies an archive in zip format.
 | ||||||
|  | 	Zipball archiveFormat = "zipball" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | // GetArchiveLink returns an URL to download a tarball or zipball archive for a
 | ||||||
|  | // repository. The archiveFormat can be specified by either the github.Tarball
 | ||||||
|  | // or github.Zipball constant.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: http://developer.github.com/v3/repos/contents/#get-archive-link
 | ||||||
|  | func (s *RepositoriesService) GetArchiveLink(owner, repo string, archiveformat archiveFormat, opt *RepositoryContentGetOptions) (*url.URL, *Response, error) { | ||||||
|  | 	u := fmt.Sprintf("repos/%s/%s/%s", owner, repo, archiveformat) | ||||||
|  | 	if opt != nil && opt.Ref != "" { | ||||||
|  | 		u += fmt.Sprintf("/%s", opt.Ref) | ||||||
|  | 	} | ||||||
|  | 	req, err := s.client.NewRequest("GET", u, nil) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 	var resp *http.Response | ||||||
|  | 	// Use http.DefaultTransport if no custom Transport is configured
 | ||||||
|  | 	if s.client.client.Transport == nil { | ||||||
|  | 		resp, err = http.DefaultTransport.RoundTrip(req) | ||||||
|  | 	} else { | ||||||
|  | 		resp, err = s.client.client.Transport.RoundTrip(req) | ||||||
|  | 	} | ||||||
|  | 	if err != nil || resp.StatusCode != http.StatusFound { | ||||||
|  | 		return nil, newResponse(resp), err | ||||||
|  | 	} | ||||||
|  | 	parsedURL, err := url.Parse(resp.Header.Get("Location")) | ||||||
|  | 	return parsedURL, newResponse(resp), err | ||||||
|  | } | ||||||
							
								
								
									
										162
									
								
								vendor/github.com/google/go-github/github/repos_deployments.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										162
									
								
								vendor/github.com/google/go-github/github/repos_deployments.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,162 @@ | |||||||
|  | // Copyright 2014 The go-github 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 github | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  | 	"encoding/json" | ||||||
|  | 	"fmt" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | // Deployment represents a deployment in a repo
 | ||||||
|  | type Deployment struct { | ||||||
|  | 	URL         *string         `json:"url,omitempty"` | ||||||
|  | 	ID          *int            `json:"id,omitempty"` | ||||||
|  | 	SHA         *string         `json:"sha,omitempty"` | ||||||
|  | 	Ref         *string         `json:"ref,omitempty"` | ||||||
|  | 	Task        *string         `json:"task,omitempty"` | ||||||
|  | 	Payload     json.RawMessage `json:"payload,omitempty"` | ||||||
|  | 	Environment *string         `json:"environment,omitempty"` | ||||||
|  | 	Description *string         `json:"description,omitempty"` | ||||||
|  | 	Creator     *User           `json:"creator,omitempty"` | ||||||
|  | 	CreatedAt   *Timestamp      `json:"created_at,omitempty"` | ||||||
|  | 	UpdatedAt   *Timestamp      `json:"pushed_at,omitempty"` | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // DeploymentRequest represents a deployment request
 | ||||||
|  | type DeploymentRequest struct { | ||||||
|  | 	Ref              *string   `json:"ref,omitempty"` | ||||||
|  | 	Task             *string   `json:"task,omitempty"` | ||||||
|  | 	AutoMerge        *bool     `json:"auto_merge,omitempty"` | ||||||
|  | 	RequiredContexts *[]string `json:"required_contexts,omitempty"` | ||||||
|  | 	Payload          *string   `json:"payload,omitempty"` | ||||||
|  | 	Environment      *string   `json:"environment,omitempty"` | ||||||
|  | 	Description      *string   `json:"description,omitempty"` | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // DeploymentsListOptions specifies the optional parameters to the
 | ||||||
|  | // RepositoriesService.ListDeployments method.
 | ||||||
|  | type DeploymentsListOptions struct { | ||||||
|  | 	// SHA of the Deployment.
 | ||||||
|  | 	SHA string `url:"sha,omitempty"` | ||||||
|  | 
 | ||||||
|  | 	// List deployments for a given ref.
 | ||||||
|  | 	Ref string `url:"ref,omitempty"` | ||||||
|  | 
 | ||||||
|  | 	// List deployments for a given task.
 | ||||||
|  | 	Task string `url:"task,omitempty"` | ||||||
|  | 
 | ||||||
|  | 	// List deployments for a given environment.
 | ||||||
|  | 	Environment string `url:"environment,omitempty"` | ||||||
|  | 
 | ||||||
|  | 	ListOptions | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ListDeployments lists the deployments of a repository.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: https://developer.github.com/v3/repos/deployments/#list-deployments
 | ||||||
|  | func (s *RepositoriesService) ListDeployments(owner, repo string, opt *DeploymentsListOptions) ([]Deployment, *Response, error) { | ||||||
|  | 	u := fmt.Sprintf("repos/%v/%v/deployments", owner, repo) | ||||||
|  | 	u, err := addOptions(u, opt) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	req, err := s.client.NewRequest("GET", u, nil) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	deployments := new([]Deployment) | ||||||
|  | 	resp, err := s.client.Do(req, deployments) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, resp, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return *deployments, resp, err | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // CreateDeployment creates a new deployment for a repository.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: https://developer.github.com/v3/repos/deployments/#create-a-deployment
 | ||||||
|  | func (s *RepositoriesService) CreateDeployment(owner, repo string, request *DeploymentRequest) (*Deployment, *Response, error) { | ||||||
|  | 	u := fmt.Sprintf("repos/%v/%v/deployments", owner, repo) | ||||||
|  | 
 | ||||||
|  | 	req, err := s.client.NewRequest("POST", u, request) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	d := new(Deployment) | ||||||
|  | 	resp, err := s.client.Do(req, d) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, resp, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return d, resp, err | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // DeploymentStatus represents the status of a
 | ||||||
|  | // particular deployment.
 | ||||||
|  | type DeploymentStatus struct { | ||||||
|  | 	ID          *int       `json:"id,omitempty"` | ||||||
|  | 	State       *string    `json:"state,omitempty"` | ||||||
|  | 	Creator     *User      `json:"creator,omitempty"` | ||||||
|  | 	Description *string    `json:"description,omitempty"` | ||||||
|  | 	TargetURL   *string    `json:"target_url,omitempty"` | ||||||
|  | 	CreatedAt   *Timestamp `json:"created_at,omitempty"` | ||||||
|  | 	UpdatedAt   *Timestamp `json:"pushed_at,omitempty"` | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // DeploymentStatusRequest represents a deployment request
 | ||||||
|  | type DeploymentStatusRequest struct { | ||||||
|  | 	State       *string `json:"state,omitempty"` | ||||||
|  | 	TargetURL   *string `json:"target_url,omitempty"` | ||||||
|  | 	Description *string `json:"description,omitempty"` | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ListDeploymentStatuses lists the statuses of a given deployment of a repository.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: https://developer.github.com/v3/repos/deployments/#list-deployment-statuses
 | ||||||
|  | func (s *RepositoriesService) ListDeploymentStatuses(owner, repo string, deployment int, opt *ListOptions) ([]DeploymentStatus, *Response, error) { | ||||||
|  | 	u := fmt.Sprintf("repos/%v/%v/deployments/%v/statuses", owner, repo, deployment) | ||||||
|  | 	u, err := addOptions(u, opt) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	req, err := s.client.NewRequest("GET", u, nil) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	statuses := new([]DeploymentStatus) | ||||||
|  | 	resp, err := s.client.Do(req, statuses) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, resp, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return *statuses, resp, err | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // CreateDeploymentStatus creates a new status for a deployment.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: https://developer.github.com/v3/repos/deployments/#create-a-deployment-status
 | ||||||
|  | func (s *RepositoriesService) CreateDeploymentStatus(owner, repo string, deployment int, request *DeploymentStatusRequest) (*DeploymentStatus, *Response, error) { | ||||||
|  | 	u := fmt.Sprintf("repos/%v/%v/deployments/%v/statuses", owner, repo, deployment) | ||||||
|  | 
 | ||||||
|  | 	req, err := s.client.NewRequest("POST", u, request) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	d := new(DeploymentStatus) | ||||||
|  | 	resp, err := s.client.Do(req, d) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, resp, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return d, resp, err | ||||||
|  | } | ||||||
							
								
								
									
										73
									
								
								vendor/github.com/google/go-github/github/repos_forks.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										73
									
								
								vendor/github.com/google/go-github/github/repos_forks.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,73 @@ | |||||||
|  | // Copyright 2013 The go-github 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 github | ||||||
|  | 
 | ||||||
|  | import "fmt" | ||||||
|  | 
 | ||||||
|  | // RepositoryListForksOptions specifies the optional parameters to the
 | ||||||
|  | // RepositoriesService.ListForks method.
 | ||||||
|  | type RepositoryListForksOptions struct { | ||||||
|  | 	// How to sort the forks list.  Possible values are: newest, oldest,
 | ||||||
|  | 	// watchers.  Default is "newest".
 | ||||||
|  | 	Sort string `url:"sort,omitempty"` | ||||||
|  | 
 | ||||||
|  | 	ListOptions | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ListForks lists the forks of the specified repository.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: http://developer.github.com/v3/repos/forks/#list-forks
 | ||||||
|  | func (s *RepositoriesService) ListForks(owner, repo string, opt *RepositoryListForksOptions) ([]Repository, *Response, error) { | ||||||
|  | 	u := fmt.Sprintf("repos/%v/%v/forks", owner, repo) | ||||||
|  | 	u, err := addOptions(u, opt) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	req, err := s.client.NewRequest("GET", u, nil) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	repos := new([]Repository) | ||||||
|  | 	resp, err := s.client.Do(req, repos) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, resp, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return *repos, resp, err | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // RepositoryCreateForkOptions specifies the optional parameters to the
 | ||||||
|  | // RepositoriesService.CreateFork method.
 | ||||||
|  | type RepositoryCreateForkOptions struct { | ||||||
|  | 	// The organization to fork the repository into.
 | ||||||
|  | 	Organization string `url:"organization,omitempty"` | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // CreateFork creates a fork of the specified repository.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: http://developer.github.com/v3/repos/forks/#list-forks
 | ||||||
|  | func (s *RepositoriesService) CreateFork(owner, repo string, opt *RepositoryCreateForkOptions) (*Repository, *Response, error) { | ||||||
|  | 	u := fmt.Sprintf("repos/%v/%v/forks", owner, repo) | ||||||
|  | 	u, err := addOptions(u, opt) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	req, err := s.client.NewRequest("POST", u, nil) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	fork := new(Repository) | ||||||
|  | 	resp, err := s.client.Do(req, fork) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, resp, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return fork, resp, err | ||||||
|  | } | ||||||
							
								
								
									
										194
									
								
								vendor/github.com/google/go-github/github/repos_hooks.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										194
									
								
								vendor/github.com/google/go-github/github/repos_hooks.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,194 @@ | |||||||
|  | // Copyright 2013 The go-github 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 github | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  | 	"fmt" | ||||||
|  | 	"time" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | // WebHookPayload represents the data that is received from GitHub when a push
 | ||||||
|  | // event hook is triggered.  The format of these payloads pre-date most of the
 | ||||||
|  | // GitHub v3 API, so there are lots of minor incompatibilities with the types
 | ||||||
|  | // defined in the rest of the API.  Therefore, several types are duplicated
 | ||||||
|  | // here to account for these differences.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: https://help.github.com/articles/post-receive-hooks
 | ||||||
|  | type WebHookPayload struct { | ||||||
|  | 	After      *string         `json:"after,omitempty"` | ||||||
|  | 	Before     *string         `json:"before,omitempty"` | ||||||
|  | 	Commits    []WebHookCommit `json:"commits,omitempty"` | ||||||
|  | 	Compare    *string         `json:"compare,omitempty"` | ||||||
|  | 	Created    *bool           `json:"created,omitempty"` | ||||||
|  | 	Deleted    *bool           `json:"deleted,omitempty"` | ||||||
|  | 	Forced     *bool           `json:"forced,omitempty"` | ||||||
|  | 	HeadCommit *WebHookCommit  `json:"head_commit,omitempty"` | ||||||
|  | 	Pusher     *User           `json:"pusher,omitempty"` | ||||||
|  | 	Ref        *string         `json:"ref,omitempty"` | ||||||
|  | 	Repo       *Repository     `json:"repository,omitempty"` | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (w WebHookPayload) String() string { | ||||||
|  | 	return Stringify(w) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // WebHookCommit represents the commit variant we receive from GitHub in a
 | ||||||
|  | // WebHookPayload.
 | ||||||
|  | type WebHookCommit struct { | ||||||
|  | 	Added     []string       `json:"added,omitempty"` | ||||||
|  | 	Author    *WebHookAuthor `json:"author,omitempty"` | ||||||
|  | 	Committer *WebHookAuthor `json:"committer,omitempty"` | ||||||
|  | 	Distinct  *bool          `json:"distinct,omitempty"` | ||||||
|  | 	ID        *string        `json:"id,omitempty"` | ||||||
|  | 	Message   *string        `json:"message,omitempty"` | ||||||
|  | 	Modified  []string       `json:"modified,omitempty"` | ||||||
|  | 	Removed   []string       `json:"removed,omitempty"` | ||||||
|  | 	Timestamp *time.Time     `json:"timestamp,omitempty"` | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (w WebHookCommit) String() string { | ||||||
|  | 	return Stringify(w) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // WebHookAuthor represents the author or committer of a commit, as specified
 | ||||||
|  | // in a WebHookCommit.  The commit author may not correspond to a GitHub User.
 | ||||||
|  | type WebHookAuthor struct { | ||||||
|  | 	Email    *string `json:"email,omitempty"` | ||||||
|  | 	Name     *string `json:"name,omitempty"` | ||||||
|  | 	Username *string `json:"username,omitempty"` | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (w WebHookAuthor) String() string { | ||||||
|  | 	return Stringify(w) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Hook represents a GitHub (web and service) hook for a repository.
 | ||||||
|  | type Hook struct { | ||||||
|  | 	CreatedAt *time.Time             `json:"created_at,omitempty"` | ||||||
|  | 	UpdatedAt *time.Time             `json:"updated_at,omitempty"` | ||||||
|  | 	Name      *string                `json:"name,omitempty"` | ||||||
|  | 	Events    []string               `json:"events,omitempty"` | ||||||
|  | 	Active    *bool                  `json:"active,omitempty"` | ||||||
|  | 	Config    map[string]interface{} `json:"config,omitempty"` | ||||||
|  | 	ID        *int                   `json:"id,omitempty"` | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (h Hook) String() string { | ||||||
|  | 	return Stringify(h) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // CreateHook creates a Hook for the specified repository.
 | ||||||
|  | // Name and Config are required fields.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: http://developer.github.com/v3/repos/hooks/#create-a-hook
 | ||||||
|  | func (s *RepositoriesService) CreateHook(owner, repo string, hook *Hook) (*Hook, *Response, error) { | ||||||
|  | 	u := fmt.Sprintf("repos/%v/%v/hooks", owner, repo) | ||||||
|  | 	req, err := s.client.NewRequest("POST", u, hook) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	h := new(Hook) | ||||||
|  | 	resp, err := s.client.Do(req, h) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, resp, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return h, resp, err | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ListHooks lists all Hooks for the specified repository.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: http://developer.github.com/v3/repos/hooks/#list
 | ||||||
|  | func (s *RepositoriesService) ListHooks(owner, repo string, opt *ListOptions) ([]Hook, *Response, error) { | ||||||
|  | 	u := fmt.Sprintf("repos/%v/%v/hooks", owner, repo) | ||||||
|  | 	u, err := addOptions(u, opt) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	req, err := s.client.NewRequest("GET", u, nil) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	hooks := new([]Hook) | ||||||
|  | 	resp, err := s.client.Do(req, hooks) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, resp, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return *hooks, resp, err | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // GetHook returns a single specified Hook.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: http://developer.github.com/v3/repos/hooks/#get-single-hook
 | ||||||
|  | func (s *RepositoriesService) GetHook(owner, repo string, id int) (*Hook, *Response, error) { | ||||||
|  | 	u := fmt.Sprintf("repos/%v/%v/hooks/%d", owner, repo, id) | ||||||
|  | 	req, err := s.client.NewRequest("GET", u, nil) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 	hook := new(Hook) | ||||||
|  | 	resp, err := s.client.Do(req, hook) | ||||||
|  | 	return hook, resp, err | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // EditHook updates a specified Hook.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: http://developer.github.com/v3/repos/hooks/#edit-a-hook
 | ||||||
|  | func (s *RepositoriesService) EditHook(owner, repo string, id int, hook *Hook) (*Hook, *Response, error) { | ||||||
|  | 	u := fmt.Sprintf("repos/%v/%v/hooks/%d", owner, repo, id) | ||||||
|  | 	req, err := s.client.NewRequest("PATCH", u, hook) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 	h := new(Hook) | ||||||
|  | 	resp, err := s.client.Do(req, h) | ||||||
|  | 	return h, resp, err | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // DeleteHook deletes a specified Hook.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: http://developer.github.com/v3/repos/hooks/#delete-a-hook
 | ||||||
|  | func (s *RepositoriesService) DeleteHook(owner, repo string, id int) (*Response, error) { | ||||||
|  | 	u := fmt.Sprintf("repos/%v/%v/hooks/%d", owner, repo, id) | ||||||
|  | 	req, err := s.client.NewRequest("DELETE", u, nil) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, err | ||||||
|  | 	} | ||||||
|  | 	return s.client.Do(req, nil) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // PingHook triggers a 'ping' event to be sent to the Hook.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: https://developer.github.com/v3/repos/hooks/#ping-a-hook
 | ||||||
|  | func (s *RepositoriesService) PingHook(owner, repo string, id int) (*Response, error) { | ||||||
|  | 	u := fmt.Sprintf("repos/%v/%v/hooks/%d/pings", owner, repo, id) | ||||||
|  | 	req, err := s.client.NewRequest("POST", u, nil) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, err | ||||||
|  | 	} | ||||||
|  | 	return s.client.Do(req, nil) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // TestHook triggers a test Hook by github.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: http://developer.github.com/v3/repos/hooks/#test-a-push-hook
 | ||||||
|  | func (s *RepositoriesService) TestHook(owner, repo string, id int) (*Response, error) { | ||||||
|  | 	u := fmt.Sprintf("repos/%v/%v/hooks/%d/tests", owner, repo, id) | ||||||
|  | 	req, err := s.client.NewRequest("POST", u, nil) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, err | ||||||
|  | 	} | ||||||
|  | 	return s.client.Do(req, nil) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ListServiceHooks is deprecated.  Use Client.ListServiceHooks instead.
 | ||||||
|  | func (s *RepositoriesService) ListServiceHooks() ([]ServiceHook, *Response, error) { | ||||||
|  | 	return s.client.ListServiceHooks() | ||||||
|  | } | ||||||
							
								
								
									
										108
									
								
								vendor/github.com/google/go-github/github/repos_keys.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										108
									
								
								vendor/github.com/google/go-github/github/repos_keys.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,108 @@ | |||||||
|  | // Copyright 2013 The go-github 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 github | ||||||
|  | 
 | ||||||
|  | import "fmt" | ||||||
|  | 
 | ||||||
|  | // The Key type is defined in users_keys.go
 | ||||||
|  | 
 | ||||||
|  | // ListKeys lists the deploy keys for a repository.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: http://developer.github.com/v3/repos/keys/#list
 | ||||||
|  | func (s *RepositoriesService) ListKeys(owner string, repo string, opt *ListOptions) ([]Key, *Response, error) { | ||||||
|  | 	u := fmt.Sprintf("repos/%v/%v/keys", owner, repo) | ||||||
|  | 	u, err := addOptions(u, opt) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	req, err := s.client.NewRequest("GET", u, nil) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	keys := new([]Key) | ||||||
|  | 	resp, err := s.client.Do(req, keys) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, resp, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return *keys, resp, err | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // GetKey fetches a single deploy key.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: http://developer.github.com/v3/repos/keys/#get
 | ||||||
|  | func (s *RepositoriesService) GetKey(owner string, repo string, id int) (*Key, *Response, error) { | ||||||
|  | 	u := fmt.Sprintf("repos/%v/%v/keys/%v", owner, repo, id) | ||||||
|  | 
 | ||||||
|  | 	req, err := s.client.NewRequest("GET", u, nil) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	key := new(Key) | ||||||
|  | 	resp, err := s.client.Do(req, key) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, resp, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return key, resp, err | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // CreateKey adds a deploy key for a repository.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: http://developer.github.com/v3/repos/keys/#create
 | ||||||
|  | func (s *RepositoriesService) CreateKey(owner string, repo string, key *Key) (*Key, *Response, error) { | ||||||
|  | 	u := fmt.Sprintf("repos/%v/%v/keys", owner, repo) | ||||||
|  | 
 | ||||||
|  | 	req, err := s.client.NewRequest("POST", u, key) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	k := new(Key) | ||||||
|  | 	resp, err := s.client.Do(req, k) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, resp, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return k, resp, err | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // EditKey edits a deploy key.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: http://developer.github.com/v3/repos/keys/#edit
 | ||||||
|  | func (s *RepositoriesService) EditKey(owner string, repo string, id int, key *Key) (*Key, *Response, error) { | ||||||
|  | 	u := fmt.Sprintf("repos/%v/%v/keys/%v", owner, repo, id) | ||||||
|  | 
 | ||||||
|  | 	req, err := s.client.NewRequest("PATCH", u, key) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	k := new(Key) | ||||||
|  | 	resp, err := s.client.Do(req, k) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, resp, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return k, resp, err | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // DeleteKey deletes a deploy key.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: http://developer.github.com/v3/repos/keys/#delete
 | ||||||
|  | func (s *RepositoriesService) DeleteKey(owner string, repo string, id int) (*Response, error) { | ||||||
|  | 	u := fmt.Sprintf("repos/%v/%v/keys/%v", owner, repo, id) | ||||||
|  | 
 | ||||||
|  | 	req, err := s.client.NewRequest("DELETE", u, nil) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return s.client.Do(req, nil) | ||||||
|  | } | ||||||
							
								
								
									
										37
									
								
								vendor/github.com/google/go-github/github/repos_merging.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								vendor/github.com/google/go-github/github/repos_merging.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,37 @@ | |||||||
|  | // Copyright 2014 The go-github 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 github | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  | 	"fmt" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | // RepositoryMergeRequest represents a request to merge a branch in a
 | ||||||
|  | // repository.
 | ||||||
|  | type RepositoryMergeRequest struct { | ||||||
|  | 	Base          *string `json:"base,omitempty"` | ||||||
|  | 	Head          *string `json:"head,omitempty"` | ||||||
|  | 	CommitMessage *string `json:"commit_message,omitempty"` | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Merge a branch in the specified repository.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: https://developer.github.com/v3/repos/merging/#perform-a-merge
 | ||||||
|  | func (s *RepositoriesService) Merge(owner, repo string, request *RepositoryMergeRequest) (*RepositoryCommit, *Response, error) { | ||||||
|  | 	u := fmt.Sprintf("repos/%v/%v/merges", owner, repo) | ||||||
|  | 	req, err := s.client.NewRequest("POST", u, request) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	commit := new(RepositoryCommit) | ||||||
|  | 	resp, err := s.client.Do(req, commit) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, resp, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return commit, resp, err | ||||||
|  | } | ||||||
							
								
								
									
										90
									
								
								vendor/github.com/google/go-github/github/repos_pages.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										90
									
								
								vendor/github.com/google/go-github/github/repos_pages.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,90 @@ | |||||||
|  | // Copyright 2014 The go-github 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 github | ||||||
|  | 
 | ||||||
|  | import "fmt" | ||||||
|  | 
 | ||||||
|  | // Pages represents a GitHub Pages site configuration.
 | ||||||
|  | type Pages struct { | ||||||
|  | 	URL       *string `json:"url,omitempty"` | ||||||
|  | 	Status    *string `json:"status,omitempty"` | ||||||
|  | 	CNAME     *string `json:"cname,omitempty"` | ||||||
|  | 	Custom404 *bool   `json:"custom_404,omitempty"` | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // PagesError represents a build error for a GitHub Pages site.
 | ||||||
|  | type PagesError struct { | ||||||
|  | 	Message *string `json:"message,omitempty"` | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // PagesBuild represents the build information for a GitHub Pages site.
 | ||||||
|  | type PagesBuild struct { | ||||||
|  | 	URL       *string     `json:"url,omitempty"` | ||||||
|  | 	Status    *string     `json:"status,omitempty"` | ||||||
|  | 	Error     *PagesError `json:"error,omitempty"` | ||||||
|  | 	Pusher    *User       `json:"pusher,omitempty"` | ||||||
|  | 	Commit    *string     `json:"commit,omitempty"` | ||||||
|  | 	Duration  *int        `json:"duration,omitempty"` | ||||||
|  | 	CreatedAt *Timestamp  `json:"created_at,omitempty"` | ||||||
|  | 	UpdatedAt *Timestamp  `json:"created_at,omitempty"` | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // GetPagesInfo fetches information about a GitHub Pages site.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: https://developer.github.com/v3/repos/pages/#get-information-about-a-pages-site
 | ||||||
|  | func (s *RepositoriesService) GetPagesInfo(owner string, repo string) (*Pages, *Response, error) { | ||||||
|  | 	u := fmt.Sprintf("repos/%v/%v/pages", owner, repo) | ||||||
|  | 	req, err := s.client.NewRequest("GET", u, nil) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	site := new(Pages) | ||||||
|  | 	resp, err := s.client.Do(req, site) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, resp, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return site, resp, err | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ListPagesBuilds lists the builds for a GitHub Pages site.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: https://developer.github.com/v3/repos/pages/#list-pages-builds
 | ||||||
|  | func (s *RepositoriesService) ListPagesBuilds(owner string, repo string) ([]PagesBuild, *Response, error) { | ||||||
|  | 	u := fmt.Sprintf("repos/%v/%v/pages/builds", owner, repo) | ||||||
|  | 	req, err := s.client.NewRequest("GET", u, nil) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	var pages []PagesBuild | ||||||
|  | 	resp, err := s.client.Do(req, &pages) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, resp, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return pages, resp, err | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // GetLatestPagesBuild fetches the latest build information for a GitHub pages site.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: https://developer.github.com/v3/repos/pages/#list-latest-pages-build
 | ||||||
|  | func (s *RepositoriesService) GetLatestPagesBuild(owner string, repo string) (*PagesBuild, *Response, error) { | ||||||
|  | 	u := fmt.Sprintf("repos/%v/%v/pages/builds/latest", owner, repo) | ||||||
|  | 	req, err := s.client.NewRequest("GET", u, nil) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	build := new(PagesBuild) | ||||||
|  | 	resp, err := s.client.Do(req, build) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, resp, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return build, resp, err | ||||||
|  | } | ||||||
							
								
								
									
										301
									
								
								vendor/github.com/google/go-github/github/repos_releases.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										301
									
								
								vendor/github.com/google/go-github/github/repos_releases.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,301 @@ | |||||||
|  | // Copyright 2013 The go-github 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 github | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  | 	"errors" | ||||||
|  | 	"fmt" | ||||||
|  | 	"io" | ||||||
|  | 	"mime" | ||||||
|  | 	"os" | ||||||
|  | 	"path/filepath" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | // RepositoryRelease represents a GitHub release in a repository.
 | ||||||
|  | type RepositoryRelease struct { | ||||||
|  | 	ID              *int           `json:"id,omitempty"` | ||||||
|  | 	TagName         *string        `json:"tag_name,omitempty"` | ||||||
|  | 	TargetCommitish *string        `json:"target_commitish,omitempty"` | ||||||
|  | 	Name            *string        `json:"name,omitempty"` | ||||||
|  | 	Body            *string        `json:"body,omitempty"` | ||||||
|  | 	Draft           *bool          `json:"draft,omitempty"` | ||||||
|  | 	Prerelease      *bool          `json:"prerelease,omitempty"` | ||||||
|  | 	CreatedAt       *Timestamp     `json:"created_at,omitempty"` | ||||||
|  | 	PublishedAt     *Timestamp     `json:"published_at,omitempty"` | ||||||
|  | 	URL             *string        `json:"url,omitempty"` | ||||||
|  | 	HTMLURL         *string        `json:"html_url,omitempty"` | ||||||
|  | 	AssetsURL       *string        `json:"assets_url,omitempty"` | ||||||
|  | 	Assets          []ReleaseAsset `json:"assets,omitempty"` | ||||||
|  | 	UploadURL       *string        `json:"upload_url,omitempty"` | ||||||
|  | 	ZipballURL      *string        `json:"zipball_url,omitempty"` | ||||||
|  | 	TarballURL      *string        `json:"tarball_url,omitempty"` | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (r RepositoryRelease) String() string { | ||||||
|  | 	return Stringify(r) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ReleaseAsset represents a Github release asset in a repository.
 | ||||||
|  | type ReleaseAsset struct { | ||||||
|  | 	ID                 *int       `json:"id,omitempty"` | ||||||
|  | 	URL                *string    `json:"url,omitempty"` | ||||||
|  | 	Name               *string    `json:"name,omitempty"` | ||||||
|  | 	Label              *string    `json:"label,omitempty"` | ||||||
|  | 	State              *string    `json:"state,omitempty"` | ||||||
|  | 	ContentType        *string    `json:"content_type,omitempty"` | ||||||
|  | 	Size               *int       `json:"size,omitempty"` | ||||||
|  | 	DownloadCount      *int       `json:"download_count,omitempty"` | ||||||
|  | 	CreatedAt          *Timestamp `json:"created_at,omitempty"` | ||||||
|  | 	UpdatedAt          *Timestamp `json:"updated_at,omitempty"` | ||||||
|  | 	BrowserDownloadURL *string    `json:"browser_download_url,omitempty"` | ||||||
|  | 	Uploader           *User      `json:"uploader,omitempty"` | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (r ReleaseAsset) String() string { | ||||||
|  | 	return Stringify(r) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ListReleases lists the releases for a repository.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: http://developer.github.com/v3/repos/releases/#list-releases-for-a-repository
 | ||||||
|  | func (s *RepositoriesService) ListReleases(owner, repo string, opt *ListOptions) ([]RepositoryRelease, *Response, error) { | ||||||
|  | 	u := fmt.Sprintf("repos/%s/%s/releases", owner, repo) | ||||||
|  | 	u, err := addOptions(u, opt) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	req, err := s.client.NewRequest("GET", u, nil) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	releases := new([]RepositoryRelease) | ||||||
|  | 	resp, err := s.client.Do(req, releases) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, resp, err | ||||||
|  | 	} | ||||||
|  | 	return *releases, resp, err | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // GetRelease fetches a single release.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: http://developer.github.com/v3/repos/releases/#get-a-single-release
 | ||||||
|  | func (s *RepositoriesService) GetRelease(owner, repo string, id int) (*RepositoryRelease, *Response, error) { | ||||||
|  | 	u := fmt.Sprintf("repos/%s/%s/releases/%d", owner, repo, id) | ||||||
|  | 	return s.getSingleRelease(u) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // GetLatestRelease fetches the latest published release for the repository.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: https://developer.github.com/v3/repos/releases/#get-the-latest-release
 | ||||||
|  | func (s *RepositoriesService) GetLatestRelease(owner, repo string) (*RepositoryRelease, *Response, error) { | ||||||
|  | 	u := fmt.Sprintf("repos/%s/%s/releases/latest", owner, repo) | ||||||
|  | 	return s.getSingleRelease(u) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // GetReleaseByTag fetches a release with the specified tag.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: https://developer.github.com/v3/repos/releases/#get-a-release-by-tag-name
 | ||||||
|  | func (s *RepositoriesService) GetReleaseByTag(owner, repo, tag string) (*RepositoryRelease, *Response, error) { | ||||||
|  | 	u := fmt.Sprintf("repos/%s/%s/releases/tags/%s", owner, repo, tag) | ||||||
|  | 	return s.getSingleRelease(u) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (s *RepositoriesService) getSingleRelease(url string) (*RepositoryRelease, *Response, error) { | ||||||
|  | 	req, err := s.client.NewRequest("GET", url, nil) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	release := new(RepositoryRelease) | ||||||
|  | 	resp, err := s.client.Do(req, release) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, resp, err | ||||||
|  | 	} | ||||||
|  | 	return release, resp, err | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // CreateRelease adds a new release for a repository.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs : http://developer.github.com/v3/repos/releases/#create-a-release
 | ||||||
|  | func (s *RepositoriesService) CreateRelease(owner, repo string, release *RepositoryRelease) (*RepositoryRelease, *Response, error) { | ||||||
|  | 	u := fmt.Sprintf("repos/%s/%s/releases", owner, repo) | ||||||
|  | 
 | ||||||
|  | 	req, err := s.client.NewRequest("POST", u, release) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	r := new(RepositoryRelease) | ||||||
|  | 	resp, err := s.client.Do(req, r) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, resp, err | ||||||
|  | 	} | ||||||
|  | 	return r, resp, err | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // EditRelease edits a repository release.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs : http://developer.github.com/v3/repos/releases/#edit-a-release
 | ||||||
|  | func (s *RepositoriesService) EditRelease(owner, repo string, id int, release *RepositoryRelease) (*RepositoryRelease, *Response, error) { | ||||||
|  | 	u := fmt.Sprintf("repos/%s/%s/releases/%d", owner, repo, id) | ||||||
|  | 
 | ||||||
|  | 	req, err := s.client.NewRequest("PATCH", u, release) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	r := new(RepositoryRelease) | ||||||
|  | 	resp, err := s.client.Do(req, r) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, resp, err | ||||||
|  | 	} | ||||||
|  | 	return r, resp, err | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // DeleteRelease delete a single release from a repository.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs : http://developer.github.com/v3/repos/releases/#delete-a-release
 | ||||||
|  | func (s *RepositoriesService) DeleteRelease(owner, repo string, id int) (*Response, error) { | ||||||
|  | 	u := fmt.Sprintf("repos/%s/%s/releases/%d", owner, repo, id) | ||||||
|  | 
 | ||||||
|  | 	req, err := s.client.NewRequest("DELETE", u, nil) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, err | ||||||
|  | 	} | ||||||
|  | 	return s.client.Do(req, nil) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ListReleaseAssets lists the release's assets.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs : http://developer.github.com/v3/repos/releases/#list-assets-for-a-release
 | ||||||
|  | func (s *RepositoriesService) ListReleaseAssets(owner, repo string, id int, opt *ListOptions) ([]ReleaseAsset, *Response, error) { | ||||||
|  | 	u := fmt.Sprintf("repos/%s/%s/releases/%d/assets", owner, repo, id) | ||||||
|  | 	u, err := addOptions(u, opt) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	req, err := s.client.NewRequest("GET", u, nil) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	assets := new([]ReleaseAsset) | ||||||
|  | 	resp, err := s.client.Do(req, assets) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, resp, nil | ||||||
|  | 	} | ||||||
|  | 	return *assets, resp, err | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // GetReleaseAsset fetches a single release asset.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs : http://developer.github.com/v3/repos/releases/#get-a-single-release-asset
 | ||||||
|  | func (s *RepositoriesService) GetReleaseAsset(owner, repo string, id int) (*ReleaseAsset, *Response, error) { | ||||||
|  | 	u := fmt.Sprintf("repos/%s/%s/releases/assets/%d", owner, repo, id) | ||||||
|  | 
 | ||||||
|  | 	req, err := s.client.NewRequest("GET", u, nil) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	asset := new(ReleaseAsset) | ||||||
|  | 	resp, err := s.client.Do(req, asset) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, resp, nil | ||||||
|  | 	} | ||||||
|  | 	return asset, resp, err | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // DownloadReleaseAsset downloads a release asset.
 | ||||||
|  | //
 | ||||||
|  | // DownloadReleaseAsset returns an io.ReadCloser that reads the contents of the
 | ||||||
|  | // specified release asset. It is the caller's responsibility to close the ReadCloser.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs : http://developer.github.com/v3/repos/releases/#get-a-single-release-asset
 | ||||||
|  | func (s *RepositoriesService) DownloadReleaseAsset(owner, repo string, id int) (io.ReadCloser, error) { | ||||||
|  | 	u := fmt.Sprintf("repos/%s/%s/releases/assets/%d", owner, repo, id) | ||||||
|  | 
 | ||||||
|  | 	req, err := s.client.NewRequest("GET", u, nil) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, err | ||||||
|  | 	} | ||||||
|  | 	req.Header.Set("Accept", defaultMediaType) | ||||||
|  | 
 | ||||||
|  | 	resp, err := s.client.client.Do(req) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return resp.Body, nil | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // EditReleaseAsset edits a repository release asset.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs : http://developer.github.com/v3/repos/releases/#edit-a-release-asset
 | ||||||
|  | func (s *RepositoriesService) EditReleaseAsset(owner, repo string, id int, release *ReleaseAsset) (*ReleaseAsset, *Response, error) { | ||||||
|  | 	u := fmt.Sprintf("repos/%s/%s/releases/assets/%d", owner, repo, id) | ||||||
|  | 
 | ||||||
|  | 	req, err := s.client.NewRequest("PATCH", u, release) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	asset := new(ReleaseAsset) | ||||||
|  | 	resp, err := s.client.Do(req, asset) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, resp, err | ||||||
|  | 	} | ||||||
|  | 	return asset, resp, err | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // DeleteReleaseAsset delete a single release asset from a repository.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs : http://developer.github.com/v3/repos/releases/#delete-a-release-asset
 | ||||||
|  | func (s *RepositoriesService) DeleteReleaseAsset(owner, repo string, id int) (*Response, error) { | ||||||
|  | 	u := fmt.Sprintf("repos/%s/%s/releases/assets/%d", owner, repo, id) | ||||||
|  | 
 | ||||||
|  | 	req, err := s.client.NewRequest("DELETE", u, nil) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, err | ||||||
|  | 	} | ||||||
|  | 	return s.client.Do(req, nil) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // UploadReleaseAsset creates an asset by uploading a file into a release repository.
 | ||||||
|  | // To upload assets that cannot be represented by an os.File, call NewUploadRequest directly.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs : http://developer.github.com/v3/repos/releases/#upload-a-release-asset
 | ||||||
|  | func (s *RepositoriesService) UploadReleaseAsset(owner, repo string, id int, opt *UploadOptions, file *os.File) (*ReleaseAsset, *Response, error) { | ||||||
|  | 	u := fmt.Sprintf("repos/%s/%s/releases/%d/assets", owner, repo, id) | ||||||
|  | 	u, err := addOptions(u, opt) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	stat, err := file.Stat() | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 	if stat.IsDir() { | ||||||
|  | 		return nil, nil, errors.New("the asset to upload can't be a directory") | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	mediaType := mime.TypeByExtension(filepath.Ext(file.Name())) | ||||||
|  | 	req, err := s.client.NewUploadRequest(u, file, stat.Size(), mediaType) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	asset := new(ReleaseAsset) | ||||||
|  | 	resp, err := s.client.Do(req, asset) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, resp, err | ||||||
|  | 	} | ||||||
|  | 	return asset, resp, err | ||||||
|  | } | ||||||
							
								
								
									
										214
									
								
								vendor/github.com/google/go-github/github/repos_stats.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										214
									
								
								vendor/github.com/google/go-github/github/repos_stats.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,214 @@ | |||||||
|  | // Copyright 2014 The go-github 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 github | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  | 	"fmt" | ||||||
|  | 	"time" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | // ContributorStats represents a contributor to a repository and their
 | ||||||
|  | // weekly contributions to a given repo.
 | ||||||
|  | type ContributorStats struct { | ||||||
|  | 	Author *Contributor  `json:"author,omitempty"` | ||||||
|  | 	Total  *int          `json:"total,omitempty"` | ||||||
|  | 	Weeks  []WeeklyStats `json:"weeks,omitempty"` | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (c ContributorStats) String() string { | ||||||
|  | 	return Stringify(c) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // WeeklyStats represents the number of additions, deletions and commits
 | ||||||
|  | // a Contributor made in a given week.
 | ||||||
|  | type WeeklyStats struct { | ||||||
|  | 	Week      *Timestamp `json:"w,omitempty"` | ||||||
|  | 	Additions *int       `json:"a,omitempty"` | ||||||
|  | 	Deletions *int       `json:"d,omitempty"` | ||||||
|  | 	Commits   *int       `json:"c,omitempty"` | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (w WeeklyStats) String() string { | ||||||
|  | 	return Stringify(w) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ListContributorsStats gets a repo's contributor list with additions,
 | ||||||
|  | // deletions and commit counts.
 | ||||||
|  | //
 | ||||||
|  | // If this is the first time these statistics are requested for the given
 | ||||||
|  | // repository, this method will return a non-nil error and a status code of
 | ||||||
|  | // 202. This is because this is the status that github returns to signify that
 | ||||||
|  | // it is now computing the requested statistics. A follow up request, after a
 | ||||||
|  | // delay of a second or so, should result in a successful request.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API Docs: https://developer.github.com/v3/repos/statistics/#contributors
 | ||||||
|  | func (s *RepositoriesService) ListContributorsStats(owner, repo string) ([]ContributorStats, *Response, error) { | ||||||
|  | 	u := fmt.Sprintf("repos/%v/%v/stats/contributors", owner, repo) | ||||||
|  | 	req, err := s.client.NewRequest("GET", u, nil) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	var contributorStats []ContributorStats | ||||||
|  | 	resp, err := s.client.Do(req, &contributorStats) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, resp, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return contributorStats, resp, err | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // WeeklyCommitActivity represents the weekly commit activity for a repository.
 | ||||||
|  | // The days array is a group of commits per day, starting on Sunday.
 | ||||||
|  | type WeeklyCommitActivity struct { | ||||||
|  | 	Days  []int      `json:"days,omitempty"` | ||||||
|  | 	Total *int       `json:"total,omitempty"` | ||||||
|  | 	Week  *Timestamp `json:"week,omitempty"` | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (w WeeklyCommitActivity) String() string { | ||||||
|  | 	return Stringify(w) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ListCommitActivity returns the last year of commit activity
 | ||||||
|  | // grouped by week. The days array is a group of commits per day,
 | ||||||
|  | // starting on Sunday.
 | ||||||
|  | //
 | ||||||
|  | // If this is the first time these statistics are requested for the given
 | ||||||
|  | // repository, this method will return a non-nil error and a status code of
 | ||||||
|  | // 202. This is because this is the status that github returns to signify that
 | ||||||
|  | // it is now computing the requested statistics. A follow up request, after a
 | ||||||
|  | // delay of a second or so, should result in a successful request.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API Docs: https://developer.github.com/v3/repos/statistics/#commit-activity
 | ||||||
|  | func (s *RepositoriesService) ListCommitActivity(owner, repo string) ([]WeeklyCommitActivity, *Response, error) { | ||||||
|  | 	u := fmt.Sprintf("repos/%v/%v/stats/commit_activity", owner, repo) | ||||||
|  | 	req, err := s.client.NewRequest("GET", u, nil) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	var weeklyCommitActivity []WeeklyCommitActivity | ||||||
|  | 	resp, err := s.client.Do(req, &weeklyCommitActivity) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, resp, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return weeklyCommitActivity, resp, err | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ListCodeFrequency returns a weekly aggregate of the number of additions and
 | ||||||
|  | // deletions pushed to a repository.  Returned WeeklyStats will contain
 | ||||||
|  | // additiona and deletions, but not total commits.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API Docs: https://developer.github.com/v3/repos/statistics/#code-frequency
 | ||||||
|  | func (s *RepositoriesService) ListCodeFrequency(owner, repo string) ([]WeeklyStats, *Response, error) { | ||||||
|  | 	u := fmt.Sprintf("repos/%v/%v/stats/code_frequency", owner, repo) | ||||||
|  | 	req, err := s.client.NewRequest("GET", u, nil) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	var weeks [][]int | ||||||
|  | 	resp, err := s.client.Do(req, &weeks) | ||||||
|  | 
 | ||||||
|  | 	// convert int slices into WeeklyStats
 | ||||||
|  | 	var stats []WeeklyStats | ||||||
|  | 	for _, week := range weeks { | ||||||
|  | 		if len(week) != 3 { | ||||||
|  | 			continue | ||||||
|  | 		} | ||||||
|  | 		stat := WeeklyStats{ | ||||||
|  | 			Week:      &Timestamp{time.Unix(int64(week[0]), 0)}, | ||||||
|  | 			Additions: Int(week[1]), | ||||||
|  | 			Deletions: Int(week[2]), | ||||||
|  | 		} | ||||||
|  | 		stats = append(stats, stat) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return stats, resp, err | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // RepositoryParticipation is the number of commits by everyone
 | ||||||
|  | // who has contributed to the repository (including the owner)
 | ||||||
|  | // as well as the number of commits by the owner themself.
 | ||||||
|  | type RepositoryParticipation struct { | ||||||
|  | 	All   []int `json:"all,omitempty"` | ||||||
|  | 	Owner []int `json:"owner,omitempty"` | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (r RepositoryParticipation) String() string { | ||||||
|  | 	return Stringify(r) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ListParticipation returns the total commit counts for the 'owner'
 | ||||||
|  | // and total commit counts in 'all'. 'all' is everyone combined,
 | ||||||
|  | // including the 'owner' in the last 52 weeks. If you’d like to get
 | ||||||
|  | // the commit counts for non-owners, you can subtract 'all' from 'owner'.
 | ||||||
|  | //
 | ||||||
|  | // The array order is oldest week (index 0) to most recent week.
 | ||||||
|  | //
 | ||||||
|  | // If this is the first time these statistics are requested for the given
 | ||||||
|  | // repository, this method will return a non-nil error and a status code
 | ||||||
|  | // of 202. This is because this is the status that github returns to
 | ||||||
|  | // signify that it is now computing the requested statistics. A follow
 | ||||||
|  | // up request, after a delay of a second or so, should result in a
 | ||||||
|  | // successful request.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API Docs: https://developer.github.com/v3/repos/statistics/#participation
 | ||||||
|  | func (s *RepositoriesService) ListParticipation(owner, repo string) (*RepositoryParticipation, *Response, error) { | ||||||
|  | 	u := fmt.Sprintf("repos/%v/%v/stats/participation", owner, repo) | ||||||
|  | 	req, err := s.client.NewRequest("GET", u, nil) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	participation := new(RepositoryParticipation) | ||||||
|  | 	resp, err := s.client.Do(req, participation) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, resp, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return participation, resp, err | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // PunchCard respresents the number of commits made during a given hour of a
 | ||||||
|  | // day of thew eek.
 | ||||||
|  | type PunchCard struct { | ||||||
|  | 	Day     *int // Day of the week (0-6: =Sunday - Saturday).
 | ||||||
|  | 	Hour    *int // Hour of day (0-23).
 | ||||||
|  | 	Commits *int // Number of commits.
 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ListPunchCard returns the number of commits per hour in each day.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API Docs: https://developer.github.com/v3/repos/statistics/#punch-card
 | ||||||
|  | func (s *RepositoriesService) ListPunchCard(owner, repo string) ([]PunchCard, *Response, error) { | ||||||
|  | 	u := fmt.Sprintf("repos/%v/%v/stats/punch_card", owner, repo) | ||||||
|  | 	req, err := s.client.NewRequest("GET", u, nil) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	var results [][]int | ||||||
|  | 	resp, err := s.client.Do(req, &results) | ||||||
|  | 
 | ||||||
|  | 	// convert int slices into Punchcards
 | ||||||
|  | 	var cards []PunchCard | ||||||
|  | 	for _, result := range results { | ||||||
|  | 		if len(result) != 3 { | ||||||
|  | 			continue | ||||||
|  | 		} | ||||||
|  | 		card := PunchCard{ | ||||||
|  | 			Day:     Int(result[0]), | ||||||
|  | 			Hour:    Int(result[1]), | ||||||
|  | 			Commits: Int(result[2]), | ||||||
|  | 		} | ||||||
|  | 		cards = append(cards, card) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return cards, resp, err | ||||||
|  | } | ||||||
							
								
								
									
										128
									
								
								vendor/github.com/google/go-github/github/repos_statuses.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										128
									
								
								vendor/github.com/google/go-github/github/repos_statuses.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,128 @@ | |||||||
|  | // Copyright 2013 The go-github 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 github | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  | 	"fmt" | ||||||
|  | 	"time" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | // RepoStatus represents the status of a repository at a particular reference.
 | ||||||
|  | type RepoStatus struct { | ||||||
|  | 	ID  *int    `json:"id,omitempty"` | ||||||
|  | 	URL *string `json:"url,omitempty"` | ||||||
|  | 
 | ||||||
|  | 	// State is the current state of the repository.  Possible values are:
 | ||||||
|  | 	// pending, success, error, or failure.
 | ||||||
|  | 	State *string `json:"state,omitempty"` | ||||||
|  | 
 | ||||||
|  | 	// TargetURL is the URL of the page representing this status.  It will be
 | ||||||
|  | 	// linked from the GitHub UI to allow users to see the source of the status.
 | ||||||
|  | 	TargetURL *string `json:"target_url,omitempty"` | ||||||
|  | 
 | ||||||
|  | 	// Description is a short high level summary of the status.
 | ||||||
|  | 	Description *string `json:"description,omitempty"` | ||||||
|  | 
 | ||||||
|  | 	// A string label to differentiate this status from the statuses of other systems.
 | ||||||
|  | 	Context *string `json:"context,omitempty"` | ||||||
|  | 
 | ||||||
|  | 	Creator   *User      `json:"creator,omitempty"` | ||||||
|  | 	CreatedAt *time.Time `json:"created_at,omitempty"` | ||||||
|  | 	UpdatedAt *time.Time `json:"updated_at,omitempty"` | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (r RepoStatus) String() string { | ||||||
|  | 	return Stringify(r) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ListStatuses lists the statuses of a repository at the specified
 | ||||||
|  | // reference.  ref can be a SHA, a branch name, or a tag name.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: http://developer.github.com/v3/repos/statuses/#list-statuses-for-a-specific-ref
 | ||||||
|  | func (s *RepositoriesService) ListStatuses(owner, repo, ref string, opt *ListOptions) ([]RepoStatus, *Response, error) { | ||||||
|  | 	u := fmt.Sprintf("repos/%v/%v/commits/%v/statuses", owner, repo, ref) | ||||||
|  | 	u, err := addOptions(u, opt) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	req, err := s.client.NewRequest("GET", u, nil) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	statuses := new([]RepoStatus) | ||||||
|  | 	resp, err := s.client.Do(req, statuses) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, resp, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return *statuses, resp, err | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // CreateStatus creates a new status for a repository at the specified
 | ||||||
|  | // reference.  Ref can be a SHA, a branch name, or a tag name.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: http://developer.github.com/v3/repos/statuses/#create-a-status
 | ||||||
|  | func (s *RepositoriesService) CreateStatus(owner, repo, ref string, status *RepoStatus) (*RepoStatus, *Response, error) { | ||||||
|  | 	u := fmt.Sprintf("repos/%v/%v/statuses/%v", owner, repo, ref) | ||||||
|  | 	req, err := s.client.NewRequest("POST", u, status) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	repoStatus := new(RepoStatus) | ||||||
|  | 	resp, err := s.client.Do(req, repoStatus) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, resp, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return repoStatus, resp, err | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // CombinedStatus represents the combined status of a repository at a particular reference.
 | ||||||
|  | type CombinedStatus struct { | ||||||
|  | 	// State is the combined state of the repository.  Possible values are:
 | ||||||
|  | 	// failture, pending, or success.
 | ||||||
|  | 	State *string `json:"state,omitempty"` | ||||||
|  | 
 | ||||||
|  | 	Name       *string      `json:"name,omitempty"` | ||||||
|  | 	SHA        *string      `json:"sha,omitempty"` | ||||||
|  | 	TotalCount *int         `json:"total_count,omitempty"` | ||||||
|  | 	Statuses   []RepoStatus `json:"statuses,omitempty"` | ||||||
|  | 
 | ||||||
|  | 	CommitURL     *string `json:"commit_url,omitempty"` | ||||||
|  | 	RepositoryURL *string `json:"repository_url,omitempty"` | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (s CombinedStatus) String() string { | ||||||
|  | 	return Stringify(s) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // GetCombinedStatus returns the combined status of a repository at the specified
 | ||||||
|  | // reference.  ref can be a SHA, a branch name, or a tag name.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: https://developer.github.com/v3/repos/statuses/#get-the-combined-status-for-a-specific-ref
 | ||||||
|  | func (s *RepositoriesService) GetCombinedStatus(owner, repo, ref string, opt *ListOptions) (*CombinedStatus, *Response, error) { | ||||||
|  | 	u := fmt.Sprintf("repos/%v/%v/commits/%v/status", owner, repo, ref) | ||||||
|  | 	u, err := addOptions(u, opt) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	req, err := s.client.NewRequest("GET", u, nil) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	status := new(CombinedStatus) | ||||||
|  | 	resp, err := s.client.Do(req, status) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, resp, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return status, resp, err | ||||||
|  | } | ||||||
							
								
								
									
										158
									
								
								vendor/github.com/google/go-github/github/search.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										158
									
								
								vendor/github.com/google/go-github/github/search.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,158 @@ | |||||||
|  | // Copyright 2013 The go-github 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 github | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  | 	"fmt" | ||||||
|  | 
 | ||||||
|  | 	qs "github.com/google/go-querystring/query" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | // SearchService provides access to the search related functions
 | ||||||
|  | // in the GitHub API.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: http://developer.github.com/v3/search/
 | ||||||
|  | type SearchService struct { | ||||||
|  | 	client *Client | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // SearchOptions specifies optional parameters to the SearchService methods.
 | ||||||
|  | type SearchOptions struct { | ||||||
|  | 	// How to sort the search results.  Possible values are:
 | ||||||
|  | 	//   - for repositories: stars, fork, updated
 | ||||||
|  | 	//   - for code: indexed
 | ||||||
|  | 	//   - for issues: comments, created, updated
 | ||||||
|  | 	//   - for users: followers, repositories, joined
 | ||||||
|  | 	//
 | ||||||
|  | 	// Default is to sort by best match.
 | ||||||
|  | 	Sort string `url:"sort,omitempty"` | ||||||
|  | 
 | ||||||
|  | 	// Sort order if sort parameter is provided. Possible values are: asc,
 | ||||||
|  | 	// desc. Default is desc.
 | ||||||
|  | 	Order string `url:"order,omitempty"` | ||||||
|  | 
 | ||||||
|  | 	// Whether to retrieve text match metadata with a query
 | ||||||
|  | 	TextMatch bool `url:"-"` | ||||||
|  | 
 | ||||||
|  | 	ListOptions | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // RepositoriesSearchResult represents the result of a repositories search.
 | ||||||
|  | type RepositoriesSearchResult struct { | ||||||
|  | 	Total        *int         `json:"total_count,omitempty"` | ||||||
|  | 	Repositories []Repository `json:"items,omitempty"` | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Repositories searches repositories via various criteria.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: http://developer.github.com/v3/search/#search-repositories
 | ||||||
|  | func (s *SearchService) Repositories(query string, opt *SearchOptions) (*RepositoriesSearchResult, *Response, error) { | ||||||
|  | 	result := new(RepositoriesSearchResult) | ||||||
|  | 	resp, err := s.search("repositories", query, opt, result) | ||||||
|  | 	return result, resp, err | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // IssuesSearchResult represents the result of an issues search.
 | ||||||
|  | type IssuesSearchResult struct { | ||||||
|  | 	Total  *int    `json:"total_count,omitempty"` | ||||||
|  | 	Issues []Issue `json:"items,omitempty"` | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Issues searches issues via various criteria.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: http://developer.github.com/v3/search/#search-issues
 | ||||||
|  | func (s *SearchService) Issues(query string, opt *SearchOptions) (*IssuesSearchResult, *Response, error) { | ||||||
|  | 	result := new(IssuesSearchResult) | ||||||
|  | 	resp, err := s.search("issues", query, opt, result) | ||||||
|  | 	return result, resp, err | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // UsersSearchResult represents the result of an issues search.
 | ||||||
|  | type UsersSearchResult struct { | ||||||
|  | 	Total *int   `json:"total_count,omitempty"` | ||||||
|  | 	Users []User `json:"items,omitempty"` | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Users searches users via various criteria.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: http://developer.github.com/v3/search/#search-users
 | ||||||
|  | func (s *SearchService) Users(query string, opt *SearchOptions) (*UsersSearchResult, *Response, error) { | ||||||
|  | 	result := new(UsersSearchResult) | ||||||
|  | 	resp, err := s.search("users", query, opt, result) | ||||||
|  | 	return result, resp, err | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Match represents a single text match.
 | ||||||
|  | type Match struct { | ||||||
|  | 	Text    *string `json:"text,omitempty"` | ||||||
|  | 	Indices []int   `json:"indices,omitempty"` | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // TextMatch represents a text match for a SearchResult
 | ||||||
|  | type TextMatch struct { | ||||||
|  | 	ObjectURL  *string `json:"object_url,omitempty"` | ||||||
|  | 	ObjectType *string `json:"object_type,omitempty"` | ||||||
|  | 	Property   *string `json:"property,omitempty"` | ||||||
|  | 	Fragment   *string `json:"fragment,omitempty"` | ||||||
|  | 	Matches    []Match `json:"matches,omitempty"` | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (tm TextMatch) String() string { | ||||||
|  | 	return Stringify(tm) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // CodeSearchResult represents the result of an code search.
 | ||||||
|  | type CodeSearchResult struct { | ||||||
|  | 	Total       *int         `json:"total_count,omitempty"` | ||||||
|  | 	CodeResults []CodeResult `json:"items,omitempty"` | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // CodeResult represents a single search result.
 | ||||||
|  | type CodeResult struct { | ||||||
|  | 	Name        *string     `json:"name,omitempty"` | ||||||
|  | 	Path        *string     `json:"path,omitempty"` | ||||||
|  | 	SHA         *string     `json:"sha,omitempty"` | ||||||
|  | 	HTMLURL     *string     `json:"html_url,omitempty"` | ||||||
|  | 	Repository  *Repository `json:"repository,omitempty"` | ||||||
|  | 	TextMatches []TextMatch `json:"text_matches,omitempty"` | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (c CodeResult) String() string { | ||||||
|  | 	return Stringify(c) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Code searches code via various criteria.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: http://developer.github.com/v3/search/#search-code
 | ||||||
|  | func (s *SearchService) Code(query string, opt *SearchOptions) (*CodeSearchResult, *Response, error) { | ||||||
|  | 	result := new(CodeSearchResult) | ||||||
|  | 	resp, err := s.search("code", query, opt, result) | ||||||
|  | 	return result, resp, err | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Helper function that executes search queries against different
 | ||||||
|  | // GitHub search types (repositories, code, issues, users)
 | ||||||
|  | func (s *SearchService) search(searchType string, query string, opt *SearchOptions, result interface{}) (*Response, error) { | ||||||
|  | 	params, err := qs.Values(opt) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, err | ||||||
|  | 	} | ||||||
|  | 	params.Add("q", query) | ||||||
|  | 	u := fmt.Sprintf("search/%s?%s", searchType, params.Encode()) | ||||||
|  | 
 | ||||||
|  | 	req, err := s.client.NewRequest("GET", u, nil) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if opt.TextMatch { | ||||||
|  | 		// Accept header defaults to "application/vnd.github.v3+json"
 | ||||||
|  | 		// We change it here to fetch back text-match metadata
 | ||||||
|  | 		req.Header.Set("Accept", "application/vnd.github.v3.text-match+json") | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return s.client.Do(req, result) | ||||||
|  | } | ||||||
							
								
								
									
										93
									
								
								vendor/github.com/google/go-github/github/strings.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										93
									
								
								vendor/github.com/google/go-github/github/strings.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,93 @@ | |||||||
|  | // Copyright 2013 The go-github 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 github | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  | 	"bytes" | ||||||
|  | 	"fmt" | ||||||
|  | 	"io" | ||||||
|  | 
 | ||||||
|  | 	"reflect" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | var timestampType = reflect.TypeOf(Timestamp{}) | ||||||
|  | 
 | ||||||
|  | // Stringify attempts to create a reasonable string representation of types in
 | ||||||
|  | // the GitHub library.  It does things like resolve pointers to their values
 | ||||||
|  | // and omits struct fields with nil values.
 | ||||||
|  | func Stringify(message interface{}) string { | ||||||
|  | 	var buf bytes.Buffer | ||||||
|  | 	v := reflect.ValueOf(message) | ||||||
|  | 	stringifyValue(&buf, v) | ||||||
|  | 	return buf.String() | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // stringifyValue was heavily inspired by the goprotobuf library.
 | ||||||
|  | 
 | ||||||
|  | func stringifyValue(w io.Writer, val reflect.Value) { | ||||||
|  | 	if val.Kind() == reflect.Ptr && val.IsNil() { | ||||||
|  | 		w.Write([]byte("<nil>")) | ||||||
|  | 		return | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	v := reflect.Indirect(val) | ||||||
|  | 
 | ||||||
|  | 	switch v.Kind() { | ||||||
|  | 	case reflect.String: | ||||||
|  | 		fmt.Fprintf(w, `"%s"`, v) | ||||||
|  | 	case reflect.Slice: | ||||||
|  | 		w.Write([]byte{'['}) | ||||||
|  | 		for i := 0; i < v.Len(); i++ { | ||||||
|  | 			if i > 0 { | ||||||
|  | 				w.Write([]byte{' '}) | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
|  | 			stringifyValue(w, v.Index(i)) | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		w.Write([]byte{']'}) | ||||||
|  | 		return | ||||||
|  | 	case reflect.Struct: | ||||||
|  | 		if v.Type().Name() != "" { | ||||||
|  | 			w.Write([]byte(v.Type().String())) | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		// special handling of Timestamp values
 | ||||||
|  | 		if v.Type() == timestampType { | ||||||
|  | 			fmt.Fprintf(w, "{%s}", v.Interface()) | ||||||
|  | 			return | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		w.Write([]byte{'{'}) | ||||||
|  | 
 | ||||||
|  | 		var sep bool | ||||||
|  | 		for i := 0; i < v.NumField(); i++ { | ||||||
|  | 			fv := v.Field(i) | ||||||
|  | 			if fv.Kind() == reflect.Ptr && fv.IsNil() { | ||||||
|  | 				continue | ||||||
|  | 			} | ||||||
|  | 			if fv.Kind() == reflect.Slice && fv.IsNil() { | ||||||
|  | 				continue | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
|  | 			if sep { | ||||||
|  | 				w.Write([]byte(", ")) | ||||||
|  | 			} else { | ||||||
|  | 				sep = true | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
|  | 			w.Write([]byte(v.Type().Field(i).Name)) | ||||||
|  | 			w.Write([]byte{':'}) | ||||||
|  | 			stringifyValue(w, fv) | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		w.Write([]byte{'}'}) | ||||||
|  | 	default: | ||||||
|  | 		if v.CanInterface() { | ||||||
|  | 			fmt.Fprint(w, v.Interface()) | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | } | ||||||
							
								
								
									
										41
									
								
								vendor/github.com/google/go-github/github/timestamp.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										41
									
								
								vendor/github.com/google/go-github/github/timestamp.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,41 @@ | |||||||
|  | // Copyright 2013 The go-github 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 github | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  | 	"strconv" | ||||||
|  | 	"time" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | // Timestamp represents a time that can be unmarshalled from a JSON string
 | ||||||
|  | // formatted as either an RFC3339 or Unix timestamp. This is necessary for some
 | ||||||
|  | // fields since the GitHub API is inconsistent in how it represents times. All
 | ||||||
|  | // exported methods of time.Time can be called on Timestamp.
 | ||||||
|  | type Timestamp struct { | ||||||
|  | 	time.Time | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (t Timestamp) String() string { | ||||||
|  | 	return t.Time.String() | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // UnmarshalJSON implements the json.Unmarshaler interface.
 | ||||||
|  | // Time is expected in RFC3339 or Unix format.
 | ||||||
|  | func (t *Timestamp) UnmarshalJSON(data []byte) (err error) { | ||||||
|  | 	str := string(data) | ||||||
|  | 	i, err := strconv.ParseInt(str, 10, 64) | ||||||
|  | 	if err == nil { | ||||||
|  | 		(*t).Time = time.Unix(i, 0) | ||||||
|  | 	} else { | ||||||
|  | 		(*t).Time, err = time.Parse(`"`+time.RFC3339+`"`, str) | ||||||
|  | 	} | ||||||
|  | 	return | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Equal reports whether t and u are equal based on time.Equal
 | ||||||
|  | func (t Timestamp) Equal(u Timestamp) bool { | ||||||
|  | 	return t.Time.Equal(u.Time) | ||||||
|  | } | ||||||
							
								
								
									
										144
									
								
								vendor/github.com/google/go-github/github/users.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										144
									
								
								vendor/github.com/google/go-github/github/users.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,144 @@ | |||||||
|  | // Copyright 2013 The go-github 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 github | ||||||
|  | 
 | ||||||
|  | import "fmt" | ||||||
|  | 
 | ||||||
|  | // UsersService handles communication with the user related
 | ||||||
|  | // methods of the GitHub API.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: http://developer.github.com/v3/users/
 | ||||||
|  | type UsersService struct { | ||||||
|  | 	client *Client | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // User represents a GitHub user.
 | ||||||
|  | type User struct { | ||||||
|  | 	Login             *string    `json:"login,omitempty"` | ||||||
|  | 	ID                *int       `json:"id,omitempty"` | ||||||
|  | 	AvatarURL         *string    `json:"avatar_url,omitempty"` | ||||||
|  | 	HTMLURL           *string    `json:"html_url,omitempty"` | ||||||
|  | 	GravatarID        *string    `json:"gravatar_id,omitempty"` | ||||||
|  | 	Name              *string    `json:"name,omitempty"` | ||||||
|  | 	Company           *string    `json:"company,omitempty"` | ||||||
|  | 	Blog              *string    `json:"blog,omitempty"` | ||||||
|  | 	Location          *string    `json:"location,omitempty"` | ||||||
|  | 	Email             *string    `json:"email,omitempty"` | ||||||
|  | 	Hireable          *bool      `json:"hireable,omitempty"` | ||||||
|  | 	Bio               *string    `json:"bio,omitempty"` | ||||||
|  | 	PublicRepos       *int       `json:"public_repos,omitempty"` | ||||||
|  | 	PublicGists       *int       `json:"public_gists,omitempty"` | ||||||
|  | 	Followers         *int       `json:"followers,omitempty"` | ||||||
|  | 	Following         *int       `json:"following,omitempty"` | ||||||
|  | 	CreatedAt         *Timestamp `json:"created_at,omitempty"` | ||||||
|  | 	UpdatedAt         *Timestamp `json:"updated_at,omitempty"` | ||||||
|  | 	Type              *string    `json:"type,omitempty"` | ||||||
|  | 	SiteAdmin         *bool      `json:"site_admin,omitempty"` | ||||||
|  | 	TotalPrivateRepos *int       `json:"total_private_repos,omitempty"` | ||||||
|  | 	OwnedPrivateRepos *int       `json:"owned_private_repos,omitempty"` | ||||||
|  | 	PrivateGists      *int       `json:"private_gists,omitempty"` | ||||||
|  | 	DiskUsage         *int       `json:"disk_usage,omitempty"` | ||||||
|  | 	Collaborators     *int       `json:"collaborators,omitempty"` | ||||||
|  | 	Plan              *Plan      `json:"plan,omitempty"` | ||||||
|  | 
 | ||||||
|  | 	// API URLs
 | ||||||
|  | 	URL               *string `json:"url,omitempty"` | ||||||
|  | 	EventsURL         *string `json:"events_url,omitempty"` | ||||||
|  | 	FollowingURL      *string `json:"following_url,omitempty"` | ||||||
|  | 	FollowersURL      *string `json:"followers_url,omitempty"` | ||||||
|  | 	GistsURL          *string `json:"gists_url,omitempty"` | ||||||
|  | 	OrganizationsURL  *string `json:"organizations_url,omitempty"` | ||||||
|  | 	ReceivedEventsURL *string `json:"received_events_url,omitempty"` | ||||||
|  | 	ReposURL          *string `json:"repos_url,omitempty"` | ||||||
|  | 	StarredURL        *string `json:"starred_url,omitempty"` | ||||||
|  | 	SubscriptionsURL  *string `json:"subscriptions_url,omitempty"` | ||||||
|  | 
 | ||||||
|  | 	// TextMatches is only populated from search results that request text matches
 | ||||||
|  | 	// See: search.go and https://developer.github.com/v3/search/#text-match-metadata
 | ||||||
|  | 	TextMatches []TextMatch `json:"text_matches,omitempty"` | ||||||
|  | 
 | ||||||
|  | 	// Permissions identifies the permissions that a user has on a given
 | ||||||
|  | 	// repository. This is only populated when calling Repositories.ListCollaborators.
 | ||||||
|  | 	Permissions *map[string]bool `json:"permissions,omitempty"` | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (u User) String() string { | ||||||
|  | 	return Stringify(u) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Get fetches a user.  Passing the empty string will fetch the authenticated
 | ||||||
|  | // user.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: http://developer.github.com/v3/users/#get-a-single-user
 | ||||||
|  | func (s *UsersService) Get(user string) (*User, *Response, error) { | ||||||
|  | 	var u string | ||||||
|  | 	if user != "" { | ||||||
|  | 		u = fmt.Sprintf("users/%v", user) | ||||||
|  | 	} else { | ||||||
|  | 		u = "user" | ||||||
|  | 	} | ||||||
|  | 	req, err := s.client.NewRequest("GET", u, nil) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	uResp := new(User) | ||||||
|  | 	resp, err := s.client.Do(req, uResp) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, resp, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return uResp, resp, err | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Edit the authenticated user.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: http://developer.github.com/v3/users/#update-the-authenticated-user
 | ||||||
|  | func (s *UsersService) Edit(user *User) (*User, *Response, error) { | ||||||
|  | 	u := "user" | ||||||
|  | 	req, err := s.client.NewRequest("PATCH", u, user) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	uResp := new(User) | ||||||
|  | 	resp, err := s.client.Do(req, uResp) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, resp, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return uResp, resp, err | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // UserListOptions specifies optional parameters to the UsersService.ListAll
 | ||||||
|  | // method.
 | ||||||
|  | type UserListOptions struct { | ||||||
|  | 	// ID of the last user seen
 | ||||||
|  | 	Since int `url:"since,omitempty"` | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ListAll lists all GitHub users.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: http://developer.github.com/v3/users/#get-all-users
 | ||||||
|  | func (s *UsersService) ListAll(opt *UserListOptions) ([]User, *Response, error) { | ||||||
|  | 	u, err := addOptions("users", opt) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	req, err := s.client.NewRequest("GET", u, nil) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	users := new([]User) | ||||||
|  | 	resp, err := s.client.Do(req, users) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, resp, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return *users, resp, err | ||||||
|  | } | ||||||
							
								
								
									
										64
									
								
								vendor/github.com/google/go-github/github/users_administration.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										64
									
								
								vendor/github.com/google/go-github/github/users_administration.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,64 @@ | |||||||
|  | // Copyright 2014 The go-github 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 github | ||||||
|  | 
 | ||||||
|  | import "fmt" | ||||||
|  | 
 | ||||||
|  | // PromoteSiteAdmin promotes a user to a site administrator of a GitHub Enterprise instance.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: https://developer.github.com/v3/users/administration/#promote-an-ordinary-user-to-a-site-administrator
 | ||||||
|  | func (s *UsersService) PromoteSiteAdmin(user string) (*Response, error) { | ||||||
|  | 	u := fmt.Sprintf("users/%v/site_admin", user) | ||||||
|  | 
 | ||||||
|  | 	req, err := s.client.NewRequest("PUT", u, nil) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return s.client.Do(req, nil) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // DemoteSiteAdmin demotes a user from site administrator of a GitHub Enterprise instance.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: https://developer.github.com/v3/users/administration/#demote-a-site-administrator-to-an-ordinary-user
 | ||||||
|  | func (s *UsersService) DemoteSiteAdmin(user string) (*Response, error) { | ||||||
|  | 	u := fmt.Sprintf("users/%v/site_admin", user) | ||||||
|  | 
 | ||||||
|  | 	req, err := s.client.NewRequest("DELETE", u, nil) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return s.client.Do(req, nil) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Suspend a user on a GitHub Enterprise instance.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: https://developer.github.com/v3/users/administration/#suspend-a-user
 | ||||||
|  | func (s *UsersService) Suspend(user string) (*Response, error) { | ||||||
|  | 	u := fmt.Sprintf("users/%v/suspended", user) | ||||||
|  | 
 | ||||||
|  | 	req, err := s.client.NewRequest("PUT", u, nil) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return s.client.Do(req, nil) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Unsuspend a user on a GitHub Enterprise instance.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: https://developer.github.com/v3/users/administration/#unsuspend-a-user
 | ||||||
|  | func (s *UsersService) Unsuspend(user string) (*Response, error) { | ||||||
|  | 	u := fmt.Sprintf("users/%v/suspended", user) | ||||||
|  | 
 | ||||||
|  | 	req, err := s.client.NewRequest("DELETE", u, nil) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return s.client.Do(req, nil) | ||||||
|  | } | ||||||
							
								
								
									
										69
									
								
								vendor/github.com/google/go-github/github/users_emails.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										69
									
								
								vendor/github.com/google/go-github/github/users_emails.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,69 @@ | |||||||
|  | // Copyright 2013 The go-github 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 github | ||||||
|  | 
 | ||||||
|  | // UserEmail represents user's email address
 | ||||||
|  | type UserEmail struct { | ||||||
|  | 	Email    *string `json:"email,omitempty"` | ||||||
|  | 	Primary  *bool   `json:"primary,omitempty"` | ||||||
|  | 	Verified *bool   `json:"verified,omitempty"` | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ListEmails lists all email addresses for the authenticated user.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: http://developer.github.com/v3/users/emails/#list-email-addresses-for-a-user
 | ||||||
|  | func (s *UsersService) ListEmails(opt *ListOptions) ([]UserEmail, *Response, error) { | ||||||
|  | 	u := "user/emails" | ||||||
|  | 	u, err := addOptions(u, opt) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	req, err := s.client.NewRequest("GET", u, nil) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	emails := new([]UserEmail) | ||||||
|  | 	resp, err := s.client.Do(req, emails) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, resp, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return *emails, resp, err | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // AddEmails adds email addresses of the authenticated user.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: http://developer.github.com/v3/users/emails/#add-email-addresses
 | ||||||
|  | func (s *UsersService) AddEmails(emails []string) ([]UserEmail, *Response, error) { | ||||||
|  | 	u := "user/emails" | ||||||
|  | 	req, err := s.client.NewRequest("POST", u, emails) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	e := new([]UserEmail) | ||||||
|  | 	resp, err := s.client.Do(req, e) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, resp, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return *e, resp, err | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // DeleteEmails deletes email addresses from authenticated user.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: http://developer.github.com/v3/users/emails/#delete-email-addresses
 | ||||||
|  | func (s *UsersService) DeleteEmails(emails []string) (*Response, error) { | ||||||
|  | 	u := "user/emails" | ||||||
|  | 	req, err := s.client.NewRequest("DELETE", u, emails) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return s.client.Do(req, nil) | ||||||
|  | } | ||||||
							
								
								
									
										116
									
								
								vendor/github.com/google/go-github/github/users_followers.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										116
									
								
								vendor/github.com/google/go-github/github/users_followers.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,116 @@ | |||||||
|  | // Copyright 2013 The go-github 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 github | ||||||
|  | 
 | ||||||
|  | import "fmt" | ||||||
|  | 
 | ||||||
|  | // ListFollowers lists the followers for a user.  Passing the empty string will
 | ||||||
|  | // fetch followers for the authenticated user.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: http://developer.github.com/v3/users/followers/#list-followers-of-a-user
 | ||||||
|  | func (s *UsersService) ListFollowers(user string, opt *ListOptions) ([]User, *Response, error) { | ||||||
|  | 	var u string | ||||||
|  | 	if user != "" { | ||||||
|  | 		u = fmt.Sprintf("users/%v/followers", user) | ||||||
|  | 	} else { | ||||||
|  | 		u = "user/followers" | ||||||
|  | 	} | ||||||
|  | 	u, err := addOptions(u, opt) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	req, err := s.client.NewRequest("GET", u, nil) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	users := new([]User) | ||||||
|  | 	resp, err := s.client.Do(req, users) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, resp, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return *users, resp, err | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ListFollowing lists the people that a user is following.  Passing the empty
 | ||||||
|  | // string will list people the authenticated user is following.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: http://developer.github.com/v3/users/followers/#list-users-followed-by-another-user
 | ||||||
|  | func (s *UsersService) ListFollowing(user string, opt *ListOptions) ([]User, *Response, error) { | ||||||
|  | 	var u string | ||||||
|  | 	if user != "" { | ||||||
|  | 		u = fmt.Sprintf("users/%v/following", user) | ||||||
|  | 	} else { | ||||||
|  | 		u = "user/following" | ||||||
|  | 	} | ||||||
|  | 	u, err := addOptions(u, opt) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	req, err := s.client.NewRequest("GET", u, nil) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	users := new([]User) | ||||||
|  | 	resp, err := s.client.Do(req, users) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, resp, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return *users, resp, err | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // IsFollowing checks if "user" is following "target".  Passing the empty
 | ||||||
|  | // string for "user" will check if the authenticated user is following "target".
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: http://developer.github.com/v3/users/followers/#check-if-you-are-following-a-user
 | ||||||
|  | func (s *UsersService) IsFollowing(user, target string) (bool, *Response, error) { | ||||||
|  | 	var u string | ||||||
|  | 	if user != "" { | ||||||
|  | 		u = fmt.Sprintf("users/%v/following/%v", user, target) | ||||||
|  | 	} else { | ||||||
|  | 		u = fmt.Sprintf("user/following/%v", target) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	req, err := s.client.NewRequest("GET", u, nil) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return false, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	resp, err := s.client.Do(req, nil) | ||||||
|  | 	following, err := parseBoolResponse(err) | ||||||
|  | 	return following, resp, err | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Follow will cause the authenticated user to follow the specified user.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: http://developer.github.com/v3/users/followers/#follow-a-user
 | ||||||
|  | func (s *UsersService) Follow(user string) (*Response, error) { | ||||||
|  | 	u := fmt.Sprintf("user/following/%v", user) | ||||||
|  | 	req, err := s.client.NewRequest("PUT", u, nil) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return s.client.Do(req, nil) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Unfollow will cause the authenticated user to unfollow the specified user.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: http://developer.github.com/v3/users/followers/#unfollow-a-user
 | ||||||
|  | func (s *UsersService) Unfollow(user string) (*Response, error) { | ||||||
|  | 	u := fmt.Sprintf("user/following/%v", user) | ||||||
|  | 	req, err := s.client.NewRequest("DELETE", u, nil) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return s.client.Do(req, nil) | ||||||
|  | } | ||||||
							
								
								
									
										104
									
								
								vendor/github.com/google/go-github/github/users_keys.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										104
									
								
								vendor/github.com/google/go-github/github/users_keys.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,104 @@ | |||||||
|  | // Copyright 2013 The go-github 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 github | ||||||
|  | 
 | ||||||
|  | import "fmt" | ||||||
|  | 
 | ||||||
|  | // Key represents a public SSH key used to authenticate a user or deploy script.
 | ||||||
|  | type Key struct { | ||||||
|  | 	ID    *int    `json:"id,omitempty"` | ||||||
|  | 	Key   *string `json:"key,omitempty"` | ||||||
|  | 	URL   *string `json:"url,omitempty"` | ||||||
|  | 	Title *string `json:"title,omitempty"` | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (k Key) String() string { | ||||||
|  | 	return Stringify(k) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ListKeys lists the verified public keys for a user.  Passing the empty
 | ||||||
|  | // string will fetch keys for the authenticated user.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: http://developer.github.com/v3/users/keys/#list-public-keys-for-a-user
 | ||||||
|  | func (s *UsersService) ListKeys(user string, opt *ListOptions) ([]Key, *Response, error) { | ||||||
|  | 	var u string | ||||||
|  | 	if user != "" { | ||||||
|  | 		u = fmt.Sprintf("users/%v/keys", user) | ||||||
|  | 	} else { | ||||||
|  | 		u = "user/keys" | ||||||
|  | 	} | ||||||
|  | 	u, err := addOptions(u, opt) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	req, err := s.client.NewRequest("GET", u, nil) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	keys := new([]Key) | ||||||
|  | 	resp, err := s.client.Do(req, keys) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, resp, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return *keys, resp, err | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // GetKey fetches a single public key.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: http://developer.github.com/v3/users/keys/#get-a-single-public-key
 | ||||||
|  | func (s *UsersService) GetKey(id int) (*Key, *Response, error) { | ||||||
|  | 	u := fmt.Sprintf("user/keys/%v", id) | ||||||
|  | 
 | ||||||
|  | 	req, err := s.client.NewRequest("GET", u, nil) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	key := new(Key) | ||||||
|  | 	resp, err := s.client.Do(req, key) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, resp, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return key, resp, err | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // CreateKey adds a public key for the authenticated user.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: http://developer.github.com/v3/users/keys/#create-a-public-key
 | ||||||
|  | func (s *UsersService) CreateKey(key *Key) (*Key, *Response, error) { | ||||||
|  | 	u := "user/keys" | ||||||
|  | 
 | ||||||
|  | 	req, err := s.client.NewRequest("POST", u, key) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	k := new(Key) | ||||||
|  | 	resp, err := s.client.Do(req, k) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, resp, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return k, resp, err | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // DeleteKey deletes a public key.
 | ||||||
|  | //
 | ||||||
|  | // GitHub API docs: http://developer.github.com/v3/users/keys/#delete-a-public-key
 | ||||||
|  | func (s *UsersService) DeleteKey(id int) (*Response, error) { | ||||||
|  | 	u := fmt.Sprintf("user/keys/%v", id) | ||||||
|  | 
 | ||||||
|  | 	req, err := s.client.NewRequest("DELETE", u, nil) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return s.client.Do(req, nil) | ||||||
|  | } | ||||||
							
								
								
									
										27
									
								
								vendor/github.com/google/go-querystring/LICENSE
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								vendor/github.com/google/go-querystring/LICENSE
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,27 @@ | |||||||
|  | Copyright (c) 2013 Google. 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. | ||||||
Some files were not shown because too many files have changed in this diff Show More
		Loading…
	
		Reference in New Issue
	
	Block a user