├── .gitignore ├── LICENSE ├── Makefile ├── README.md ├── bigquery ├── client.go ├── dataset.go ├── load.go └── table.go ├── bqshift.go ├── config.example.yml ├── config.go ├── main.go ├── redshift ├── client.go ├── config.go ├── table.go └── unload.go ├── storage └── transfer.go ├── util └── retry.go └── vendor ├── github.com ├── alecthomas │ ├── template │ │ ├── LICENSE │ │ ├── README.md │ │ ├── doc.go │ │ ├── exec.go │ │ ├── funcs.go │ │ ├── helper.go │ │ ├── parse │ │ │ ├── lex.go │ │ │ ├── node.go │ │ │ └── parse.go │ │ └── template.go │ └── units │ │ ├── COPYING │ │ ├── README.md │ │ ├── bytes.go │ │ ├── doc.go │ │ ├── si.go │ │ └── util.go ├── cenk │ └── backoff │ │ ├── LICENSE │ │ ├── README.md │ │ ├── backoff.go │ │ ├── exponential.go │ │ ├── retry.go │ │ └── ticker.go └── lib │ └── pq │ ├── CONTRIBUTING.md │ ├── LICENSE.md │ ├── README.md │ ├── array.go │ ├── buf.go │ ├── conn.go │ ├── copy.go │ ├── doc.go │ ├── encode.go │ ├── error.go │ ├── notify.go │ ├── oid │ ├── doc.go │ ├── gen.go │ └── types.go │ ├── url.go │ ├── user_posix.go │ └── user_windows.go ├── golang.org └── x │ ├── net │ ├── LICENSE │ ├── PATENTS │ └── context │ │ ├── context.go │ │ ├── ctxhttp │ │ ├── cancelreq.go │ │ ├── cancelreq_go14.go │ │ └── ctxhttp.go │ │ ├── go17.go │ │ └── pre_go17.go │ └── oauth2 │ ├── AUTHORS │ ├── CONTRIBUTING.md │ ├── CONTRIBUTORS │ ├── LICENSE │ ├── README.md │ ├── client_appengine.go │ ├── google │ ├── appengine.go │ ├── appengine_hook.go │ ├── appenginevm_hook.go │ ├── default.go │ ├── google.go │ ├── jwt.go │ └── sdk.go │ ├── internal │ ├── oauth2.go │ ├── token.go │ └── transport.go │ ├── jws │ └── jws.go │ ├── jwt │ └── jwt.go │ ├── oauth2.go │ ├── token.go │ └── transport.go ├── google.golang.org ├── api │ ├── LICENSE │ ├── bigquery │ │ └── v2 │ │ │ ├── bigquery-api.json │ │ │ └── bigquery-gen.go │ ├── gensupport │ │ ├── backoff.go │ │ ├── buffer.go │ │ ├── doc.go │ │ ├── json.go │ │ ├── media.go │ │ ├── params.go │ │ ├── resumable.go │ │ ├── retry.go │ │ └── send.go │ ├── googleapi │ │ ├── googleapi.go │ │ ├── internal │ │ │ └── uritemplates │ │ │ │ ├── LICENSE │ │ │ │ ├── uritemplates.go │ │ │ │ └── utils.go │ │ └── types.go │ └── storagetransfer │ │ └── v1 │ │ ├── storagetransfer-api.json │ │ └── storagetransfer-gen.go └── cloud │ ├── LICENSE │ ├── compute │ └── metadata │ │ └── metadata.go │ └── internal │ └── cloud.go ├── gopkg.in ├── alecthomas │ └── kingpin.v2 │ │ ├── COPYING │ │ ├── README.md │ │ ├── actions.go │ │ ├── app.go │ │ ├── args.go │ │ ├── cmd.go │ │ ├── completions.go │ │ ├── doc.go │ │ ├── flags.go │ │ ├── global.go │ │ ├── guesswidth.go │ │ ├── guesswidth_unix.go │ │ ├── model.go │ │ ├── parser.go │ │ ├── parsers.go │ │ ├── templates.go │ │ ├── usage.go │ │ ├── values.go │ │ ├── values.json │ │ └── values_generated.go └── yaml.v2 │ ├── LICENSE │ ├── LICENSE.libyaml │ ├── README.md │ ├── apic.go │ ├── decode.go │ ├── emitterc.go │ ├── encode.go │ ├── parserc.go │ ├── readerc.go │ ├── resolve.go │ ├── scannerc.go │ ├── sorter.go │ ├── writerc.go │ ├── yaml.go │ ├── yamlh.go │ └── yamlprivateh.go └── vendor.json /.gitignore: -------------------------------------------------------------------------------- 1 | config.yml 2 | release/ 3 | target/ 4 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2016, uSwitch 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are met: 6 | 7 | * Redistributions of source code must retain the above copyright notice, 8 | this list of conditions and the following disclaimer. 9 | * Redistributions in binary form must reproduce the above copyright 10 | notice, this list of conditions and the following disclaimer in the 11 | documentation and/or other materials provided with the distribution. 12 | * Neither the name of uSwitch nor the names of its contributors may be 13 | used to endorse or promote products derived from this software without 14 | specific prior written permission. 15 | 16 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 17 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 20 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 21 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 22 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 23 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 24 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 25 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26 | POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | .PHONY: release,clean,gh-release 2 | 3 | MAC = GOOS=darwin GOARCH=amd64 4 | LINUX = GOOS=linux GOARCH=amd64 5 | SOURCES = $(wildcard *.go) $(wildcard bigquery/*.go) $(wildcard redshift/*.go) $(wildcard storage/*.go) $(wildcard util/*.go) $(wildcard vendor/*.go) 6 | 7 | ifndef VERSION 8 | $(error VERSION is not set) 9 | endif 10 | 11 | SHA = $(shell git rev-parse --short HEAD) 12 | FLAGS = -ldflags "-X main.versionNumber=${VERSION} -X main.sha=${SHA}" 13 | 14 | release: release/bqshift-${VERSION}.tar.gz 15 | 16 | release/bqshift-${VERSION}.tar.gz: target/mac/bqshift target/linux/bqshift 17 | rm -rf release/ 18 | mkdir -p release/ 19 | tar -zcf release/bqshift-${VERSION}.tar.gz -C target/ . 20 | 21 | target/mac/bqshift: $(SOURCES) 22 | ${MAC} go build ${FLAGS} -o target/mac/bqshift . 23 | 24 | target/linux/bqshift: $(SOURCES) 25 | ${LINUX} go build ${FLAGS} -o target/linux/bqshift . 26 | 27 | gh-release: release/bqshift-${VERSION}.tar.gz 28 | gh-release create uswitch/bqshift ${VERSION} 29 | 30 | clean: 31 | rm -rf release/ 32 | rm -rf target/ -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # bqshift 2 | 3 | Automate copy of [Redshift](https://aws.amazon.com/redshift/) data to [BigQuery](https://cloud.google.com/bigquery/). 4 | 5 | ## Building 6 | 7 | ``` 8 | $ go get github.com/uswitch/bqshift 9 | $ go install github.com/uswitch/bqshift 10 | ``` 11 | 12 | ## Running 13 | 14 | ``` 15 | $ export GCLOUD_PROJECT=project-id 16 | $ export GOOGLE_APPLICATION_CREDENTIALS=/path/to/creds.json 17 | $ bqshift --config=config.example.yml 18 | ``` 19 | 20 | ### Time Partitioned Tables 21 | 22 | BigQuery supports [Partitioned Tables](https://cloud.google.com/bigquery/docs/partitioned-tables). 23 | 24 | > By dividing a large table into smaller partitions, you can improve query performance and reduce the number of bytes billed by restricting the amount of data scanned. BigQuery enables you to partition tables by date. 25 | 26 | bqshift can load partitioned data as long as the source data has date information stored, the destination table in BigQuery must also have been declared as time partitioned when it was created. bqshift can automatically create the correct table if it hasn't already been created. 27 | 28 | For example, to create a partitioned table from a table that has a `TIMESTAMP` column called `ts`, and to load data into the `2016-09-27` partition you can use the following command: 29 | 30 | ``` 31 | $ bqshift --partition --date-expression="CAST(ts as DATE)" --date=2016-09-27 --config=config.example.yml 32 | ``` 33 | 34 | #### Overwriting Partitioned Data 35 | 36 | It's possible to replace/update an existing partition by adding the `--overwrite` flag. 37 | 38 | ``` 39 | $ bqshift --overwrite --partition --date-expression="CAST(ts as DATE)" --date=2016-09-27 --config=config.example.yml 40 | ``` 41 | 42 | Note that you can _only_ update data that was already part of a partition. For example, if you were to create a partitioned table and load a bulk set of historical/archived data when you use `--overwrite` and `--date` you'll overwrite all data in the table. Instead I would suggest having a separate `_archive` table from the partitioned tables. 43 | 44 | ## Notes 45 | 46 | As part of the unloading process bqshift generates SQL for Redshift; this is _not_ protected against SQL injection attacks so beware of using this tool with user-generated input. 47 | 48 | ## Releasing 49 | 50 | We use [https://github.com/progrium/gh-release](https://github.com/progrium/gh-release) to tag and release artifacts. Install with: 51 | 52 | ``` 53 | $ go get github.com/progrium/gh-release 54 | ``` 55 | 56 | Then to release use: 57 | 58 | ``` 59 | $ VERSION=<...> make gh-release 60 | ``` 61 | 62 | ## License 63 | 64 | Copyright (c) 2016, uSwitch 65 | All rights reserved. 66 | 67 | Redistribution and use in source and binary forms, with or without 68 | modification, are permitted provided that the following conditions are met: 69 | 70 | * Redistributions of source code must retain the above copyright notice, 71 | this list of conditions and the following disclaimer. 72 | * Redistributions in binary form must reproduce the above copyright 73 | notice, this list of conditions and the following disclaimer in the 74 | documentation and/or other materials provided with the distribution. 75 | * Neither the name of uSwitch nor the names of its contributors may be 76 | used to endorse or promote products derived from this software without 77 | specific prior written permission. 78 | 79 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 80 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 81 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 82 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 83 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 84 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 85 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 86 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 87 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 88 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 89 | POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- /bigquery/client.go: -------------------------------------------------------------------------------- 1 | package bigquery 2 | 3 | import ( 4 | "golang.org/x/net/context" 5 | "golang.org/x/oauth2/google" 6 | bq "google.golang.org/api/bigquery/v2" 7 | ) 8 | 9 | type Client struct { 10 | service *bq.Service 11 | } 12 | 13 | func NewClient() (*Client, error) { 14 | ctx := context.Background() 15 | client, err := google.DefaultClient(ctx, bq.BigqueryScope) 16 | svc, err := bq.New(client) 17 | if err != nil { 18 | return nil, err 19 | } 20 | 21 | return &Client{svc}, nil 22 | } 23 | -------------------------------------------------------------------------------- /bigquery/dataset.go: -------------------------------------------------------------------------------- 1 | package bigquery 2 | 3 | import ( 4 | "github.com/uswitch/bqshift/util" 5 | bigquery "google.golang.org/api/bigquery/v2" 6 | ) 7 | 8 | func (c *Client) DatasetExists(ref *DatasetReference) (bool, error) { 9 | resp, err := util.RetryOp(func() (interface{}, error) { 10 | return c.service.Datasets.List(ref.ProjectID).All(false).Do() 11 | }) 12 | 13 | if err != nil { 14 | return false, err 15 | } 16 | 17 | list := resp.(*bigquery.DatasetList) 18 | 19 | for _, dataset := range list.Datasets { 20 | if dataset.DatasetReference.DatasetId == ref.DatasetID { 21 | return true, nil 22 | } 23 | } 24 | 25 | return false, nil 26 | } 27 | -------------------------------------------------------------------------------- /bigquery/load.go: -------------------------------------------------------------------------------- 1 | package bigquery 2 | 3 | import ( 4 | "fmt" 5 | "github.com/uswitch/bqshift/redshift" 6 | "github.com/uswitch/bqshift/util" 7 | bq "google.golang.org/api/bigquery/v2" 8 | "log" 9 | "time" 10 | ) 11 | 12 | func sourcePattern(bucket, prefix string) string { 13 | return fmt.Sprintf("gs://%s/%s/*", bucket, prefix) 14 | } 15 | 16 | type LoadSpec struct { 17 | TableReference *TableReference 18 | BucketName string 19 | ObjectPrefix string 20 | Overwrite bool 21 | Schema *bq.TableSchema 22 | Partitioned bool 23 | } 24 | 25 | type LoadCompleted struct { 26 | Error error 27 | } 28 | 29 | const StateDone = "DONE" 30 | 31 | func (c *Client) blockForJobCompletion(projectId string, createdJob *bq.Job) error { 32 | for { 33 | resp, err := util.RetryOp(func() (interface{}, error) { 34 | return c.service.Jobs.Get(projectId, createdJob.JobReference.JobId).Do() 35 | }) 36 | 37 | if err != nil { 38 | return err 39 | } 40 | 41 | job := resp.(*bq.Job) 42 | 43 | if job.Status.State == StateDone { 44 | if job.Status.ErrorResult == nil { 45 | return nil 46 | } else { 47 | return fmt.Errorf("Load job failed. Location: %s; Reason: %s. %s", job.Status.ErrorResult.Location, job.Status.ErrorResult.Reason, job.Status.ErrorResult.Message) 48 | } 49 | } 50 | 51 | log.Printf("load status %s. waiting 30s.\n", job.Status.State) 52 | time.Sleep(30 * time.Second) 53 | } 54 | } 55 | 56 | func (c *Client) LoadTable(spec *LoadSpec) error { 57 | pattern := sourcePattern(spec.BucketName, spec.ObjectPrefix) 58 | 59 | load := &bq.JobConfigurationLoad{ 60 | CreateDisposition: "CREATE_IF_NEEDED", 61 | WriteDisposition: "WRITE_EMPTY", 62 | FieldDelimiter: redshift.DefaultDelimiter(), 63 | IgnoreUnknownValues: false, 64 | SourceFormat: "CSV", 65 | SourceUris: []string{pattern}, 66 | Schema: spec.Schema, 67 | DestinationTable: spec.TableReference.ToGoogleReference(), 68 | } 69 | 70 | config := &bq.JobConfiguration{ 71 | Load: load, 72 | } 73 | 74 | if spec.Overwrite { 75 | config.Load.WriteDisposition = "WRITE_TRUNCATE" 76 | } 77 | 78 | resp, err := util.RetryOp(func() (interface{}, error) { 79 | return c.service.Jobs.Insert(spec.TableReference.ProjectID, &bq.Job{Configuration: config}).Do() 80 | }) 81 | 82 | if err != nil { 83 | return err 84 | } 85 | 86 | job := resp.(*bq.Job) 87 | log.Println("created load job, waiting for completion.") 88 | 89 | return c.blockForJobCompletion(spec.TableReference.ProjectID, job) 90 | } 91 | -------------------------------------------------------------------------------- /bigquery/table.go: -------------------------------------------------------------------------------- 1 | package bigquery 2 | 3 | import ( 4 | "fmt" 5 | "github.com/uswitch/bqshift/util" 6 | bq "google.golang.org/api/bigquery/v2" 7 | "log" 8 | "time" 9 | ) 10 | 11 | type TableReference struct { 12 | ProjectID string 13 | DatasetID string 14 | TableID string 15 | DayPartition *time.Time 16 | } 17 | 18 | func (c *Client) EnsureTableExists(ref *TableReference, partition bool) error { 19 | resp, err := util.RetryOp(func() (interface{}, error) { 20 | return c.service.Tables.List(ref.ProjectID, ref.DatasetID).Do() 21 | }) 22 | 23 | if err != nil { 24 | return err 25 | } 26 | 27 | list := resp.(*bq.TableList) 28 | for _, table := range list.Tables { 29 | if table.TableReference.TableId == ref.TableID { 30 | return nil 31 | } 32 | } 33 | 34 | newTable := &bq.Table{ 35 | Description: "bqshift created table", 36 | TableReference: ref.ToUndecoratedGoogleReference(), 37 | } 38 | 39 | if partition { 40 | newTable.TimePartitioning = &bq.TimePartitioning{ 41 | Type: "DAY", 42 | } 43 | } 44 | _, err = util.RetryOp(func() (interface{}, error) { 45 | return c.service.Tables.Insert(ref.ProjectID, ref.DatasetID, newTable).Do() 46 | }) 47 | 48 | if err != nil { 49 | return err 50 | } 51 | 52 | log.Println("created bigquery table.") 53 | 54 | return nil 55 | } 56 | 57 | type DatasetReference struct { 58 | ProjectID string 59 | DatasetID string 60 | } 61 | 62 | func (ref *TableReference) DatasetReference() *DatasetReference { 63 | return &DatasetReference{ref.ProjectID, ref.DatasetID} 64 | } 65 | 66 | func NewTableReference(projectId, dataset, table string) *TableReference { 67 | return &TableReference{ 68 | ProjectID: projectId, 69 | DatasetID: dataset, 70 | TableID: table, 71 | } 72 | } 73 | 74 | func bqfmt(t time.Time) string { 75 | return t.Format("20060102") 76 | } 77 | 78 | func (ref *TableReference) ToGoogleReference() *bq.TableReference { 79 | return &bq.TableReference{ 80 | DatasetId: ref.DatasetID, 81 | ProjectId: ref.ProjectID, 82 | TableId: ref.googleTableID(), 83 | } 84 | } 85 | 86 | func (ref *TableReference) ToUndecoratedGoogleReference() *bq.TableReference { 87 | return &bq.TableReference{ 88 | DatasetId: ref.DatasetID, 89 | ProjectId: ref.ProjectID, 90 | TableId: ref.TableID, 91 | } 92 | } 93 | 94 | func (ref *TableReference) googleTableID() string { 95 | if ref.DayPartition == nil { 96 | return ref.TableID 97 | } 98 | 99 | return fmt.Sprintf("%s$%s", ref.TableID, bqfmt(*ref.DayPartition)) 100 | } 101 | 102 | func (ref *TableReference) String() string { 103 | return fmt.Sprintf("%s:%s.%s", ref.ProjectID, ref.DatasetID, ref.TableID) 104 | } 105 | -------------------------------------------------------------------------------- /bqshift.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "github.com/uswitch/bqshift/bigquery" 6 | "github.com/uswitch/bqshift/redshift" 7 | "github.com/uswitch/bqshift/storage" 8 | "log" 9 | ) 10 | 11 | type shifter struct { 12 | redshift *redshift.Client 13 | config *Configuration 14 | } 15 | 16 | func (s *shifter) Run(table string, partition *redshift.DatePartition, tableRef *bigquery.TableReference) error { 17 | storageClient, err := storage.NewClient(tableRef, s.config.AWS.S3) 18 | if err != nil { 19 | return err 20 | } 21 | 22 | bq, err := bigquery.NewClient() 23 | exists, err := bq.DatasetExists(tableRef.DatasetReference()) 24 | if err != nil { 25 | return fmt.Errorf("error checking dataset: %s", err.Error()) 26 | } 27 | 28 | if !exists { 29 | return fmt.Errorf("dataset doesn't exist: %s", tableRef.DatasetID) 30 | } 31 | 32 | err = bq.EnsureTableExists(tableRef, s.config.DayPartition) 33 | 34 | if err != nil { 35 | return fmt.Errorf("error creating bigquery client: %s", err.Error()) 36 | } 37 | 38 | log.Println("unloading to s3") 39 | unloaded, err := s.redshift.Unload(table, partition, s.config.WhereClause) 40 | if err != nil { 41 | return fmt.Errorf("error unloading: %s", err.Error()) 42 | } 43 | 44 | log.Println("transferring to cloud storage") 45 | stored, err := storageClient.TransferToCloudStorage(unloaded) 46 | if err != nil { 47 | return fmt.Errorf("error transferring to cloud storage: %s", err.Error()) 48 | } 49 | 50 | sourceSchema, err := s.redshift.ExtractSchema(table) 51 | if err != nil { 52 | return fmt.Errorf("error extracting source schema: %s", err.Error()) 53 | } 54 | destSchema, err := sourceSchema.ToBigQuerySchema() 55 | if err != nil { 56 | return fmt.Errorf("error translating redshift schema to bigquery: %s", err.Error()) 57 | } 58 | 59 | log.Println("loading into bigquery") 60 | spec := &bigquery.LoadSpec{ 61 | Partitioned: s.config.DayPartition, 62 | TableReference: tableRef, 63 | BucketName: stored.BucketName, 64 | ObjectPrefix: stored.Prefix, 65 | Overwrite: s.config.OverwriteBigQuery, 66 | Schema: destSchema, 67 | } 68 | 69 | err = bq.LoadTable(spec) 70 | if err != nil { 71 | return fmt.Errorf("error loading data into table: %s", err.Error()) 72 | } 73 | 74 | return nil 75 | } 76 | 77 | func NewShifter(config *Configuration) (*shifter, error) { 78 | client, err := redshift.NewClient(config.AWS) 79 | if err != nil { 80 | return nil, err 81 | } 82 | 83 | return &shifter{client, config}, nil 84 | } 85 | -------------------------------------------------------------------------------- /config.example.yml: -------------------------------------------------------------------------------- 1 | redshift: 2 | host: xxx.redshift.amazonaws.com 3 | port: 5439 4 | user: user 5 | password: pass 6 | db: something 7 | s3: 8 | bucket: mybucket 9 | -------------------------------------------------------------------------------- /config.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "github.com/uswitch/bqshift/redshift" 5 | ) 6 | 7 | type Configuration struct { 8 | OverwriteBigQuery bool 9 | DayPartition bool 10 | AWS *redshift.AWSConfiguration 11 | WhereClause string 12 | } 13 | -------------------------------------------------------------------------------- /main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "github.com/uswitch/bqshift/bigquery" 6 | "github.com/uswitch/bqshift/redshift" 7 | "gopkg.in/alecthomas/kingpin.v2" 8 | "log" 9 | "time" 10 | ) 11 | 12 | var ( 13 | config = kingpin.Flag("config", "Configuration file with S3 and Redshift credentials").Required().File() 14 | accessKey = kingpin.Flag("access-key", "AWS access key. Defaults to $AWS_ACCESS_KEY_ID").OverrideDefaultFromEnvar("AWS_ACCESS_KEY_ID").Required().String() 15 | secretKey = kingpin.Flag("secret-access-key", "AWS secret access key. Defaults to $AWS_SECRET_").OverrideDefaultFromEnvar("AWS_SECRET_ACCESS_KEY").Required().String() 16 | project = kingpin.Flag("project", "Google Project ID").OverrideDefaultFromEnvar("GCLOUD_PROJECT").Required().String() 17 | overwrite = kingpin.Flag("overwrite", "Overwrite BigQuery table").Bool() 18 | usePartitionedTables = kingpin.Flag("partition", "Create time partitioned BigQuery tables.").Bool() 19 | dateExpression = kingpin.Flag("date-expression", "Redshift SQL expression to return row date. e.g. CAST(inserted as DATE)").String() 20 | dateFilter = kingpin.Flag("date", "Date (YYYY-MM-DD) of partition to filter and load. e.g. 2016-09-30.").String() 21 | where = kingpin.Flag("where", "Redshift WHERE clause. Cannot be used with --date/--date-expression. e.g.: CAST(inserted as DATE) < 2016-09-30").String() 22 | dataset = kingpin.Arg("dataset", "Destination BigQuery dataset").Required().String() 23 | table = kingpin.Arg("table", "Redshift table name").Required().String() 24 | destinationTable = kingpin.Arg("destination-table", "BigQuery table name. Defaults to Redshift table name").String() 25 | ) 26 | 27 | var versionNumber string 28 | var sha string 29 | 30 | func version() string { 31 | if versionNumber == "" { 32 | return "DEVELOPMENT" 33 | } 34 | return fmt.Sprintf("%s (%s)", versionNumber, sha) 35 | } 36 | 37 | func partitionFromArgs() (*redshift.DatePartition, error) { 38 | if *dateExpression == "" { 39 | return nil, nil 40 | } 41 | if *dateFilter == "" { 42 | return nil, nil 43 | } 44 | 45 | t, err := time.Parse("2006-01-02", *dateFilter) 46 | if err != nil { 47 | return nil, err 48 | } 49 | 50 | return redshift.NewDatePartition(*dateExpression, t), nil 51 | } 52 | 53 | func destinationTableID() string { 54 | if *destinationTable == "" { 55 | return *table 56 | } 57 | return *destinationTable 58 | } 59 | 60 | func main() { 61 | kingpin.Version(version()) 62 | kingpin.Parse() 63 | 64 | awsConfig, err := redshift.ParseAWSConfiguration(*config) 65 | if err != nil { 66 | log.Fatalln("error parsing redshift configuration:", err.Error()) 67 | } 68 | awsConfig.S3.AccessKey = *accessKey 69 | awsConfig.S3.SecretKey = *secretKey 70 | 71 | config := &Configuration{ 72 | AWS: awsConfig, 73 | OverwriteBigQuery: *overwrite, 74 | DayPartition: *usePartitionedTables, 75 | WhereClause: *where, 76 | } 77 | shifter, err := NewShifter(config) 78 | if err != nil { 79 | log.Fatalln(err.Error()) 80 | } 81 | 82 | bq := bigquery.NewTableReference(*project, *dataset, destinationTableID()) 83 | partition, err := partitionFromArgs() 84 | if err != nil { 85 | log.Fatalln(err.Error()) 86 | } 87 | 88 | if partition != nil { 89 | bq.DayPartition = &partition.DateFilter 90 | } 91 | 92 | err = shifter.Run(*table, partition, bq) 93 | if err != nil { 94 | log.Fatalln(err.Error()) 95 | } 96 | 97 | log.Println("finished") 98 | } 99 | -------------------------------------------------------------------------------- /redshift/client.go: -------------------------------------------------------------------------------- 1 | package redshift 2 | 3 | import ( 4 | "database/sql" 5 | "fmt" 6 | ) 7 | 8 | type Client struct { 9 | aws *AWSConfiguration 10 | db *sql.DB 11 | } 12 | 13 | func NewClient(config *AWSConfiguration) (*Client, error) { 14 | client := &Client{config, nil} 15 | client.Connect() 16 | 17 | return client, nil 18 | } 19 | 20 | func (c *Client) Connect() error { 21 | db, err := sql.Open("postgres", c.aws.Redshift.URLString()) 22 | if err != nil { 23 | return fmt.Errorf("error connecting to redshift: %s", err.Error()) 24 | } 25 | c.db = db 26 | return nil 27 | } 28 | 29 | func (c *Client) Close() error { 30 | return c.db.Close() 31 | } 32 | 33 | func (c *Client) query(query string, args ...interface{}) (*sql.Rows, error) { 34 | return c.db.Query(query, args...) 35 | } 36 | 37 | func (c *Client) execute(statement string, args ...interface{}) (sql.Result, error) { 38 | return c.db.Exec(statement, args...) 39 | } 40 | 41 | func (c *Client) doUnload(source *RedshiftSource) (*UnloadResult, error) { 42 | return newUnloadOperation(c, c.aws, source).execute() 43 | } 44 | 45 | func (c *Client) Unload(table string, partition *DatePartition, whereClause string) (*UnloadResult, error) { 46 | schema, err := c.ExtractSchema(table) 47 | if err != nil { 48 | return nil, fmt.Errorf("error extracting table schema: %s", err.Error()) 49 | } 50 | source := &RedshiftSource{ 51 | Table: table, 52 | Schema: schema, 53 | Partition: partition, 54 | WhereClause: whereClause, 55 | } 56 | return c.doUnload(source) 57 | } 58 | -------------------------------------------------------------------------------- /redshift/config.go: -------------------------------------------------------------------------------- 1 | package redshift 2 | 3 | import ( 4 | "bytes" 5 | "fmt" 6 | "gopkg.in/yaml.v2" 7 | "io/ioutil" 8 | "os" 9 | "strings" 10 | "time" 11 | ) 12 | 13 | type AWSConfiguration struct { 14 | Redshift *RedshiftConnectionDetails `yaml:"redshift"` 15 | S3 *S3Configuration `yaml:"s3"` 16 | } 17 | 18 | func ParseAWSConfiguration(file *os.File) (*AWSConfiguration, error) { 19 | contents, err := ioutil.ReadAll(file) 20 | if err != nil { 21 | return nil, err 22 | } 23 | 24 | var c AWSConfiguration 25 | err = yaml.Unmarshal(contents, &c) 26 | if err != nil { 27 | return nil, err 28 | } 29 | 30 | return &c, nil 31 | } 32 | 33 | type DatePartition struct { 34 | DateExpression string // expression used to extract relevant date for each row 35 | DateFilter time.Time // current partition date 36 | } 37 | 38 | func NewDatePartition(expression string, t time.Time) *DatePartition { 39 | return &DatePartition{expression, t} 40 | } 41 | 42 | type RedshiftSource struct { 43 | Table string 44 | Schema *TableSchema 45 | Partition *DatePartition 46 | WhereClause string 47 | } 48 | 49 | func (s *RedshiftSource) isPartitioned() bool { 50 | return s.Partition != nil 51 | } 52 | 53 | func escape(s string) string { 54 | return strings.Replace(s, "'", "\\'", -1) 55 | } 56 | 57 | func (s *RedshiftSource) where() string { 58 | if s.WhereClause == "" { 59 | return "" 60 | } 61 | 62 | return fmt.Sprintf("WHERE %s", escape(s.WhereClause)) 63 | } 64 | 65 | const SQLDateFormat = "2006-01-02" 66 | 67 | func (s *RedshiftSource) SelectClause() string { 68 | var columns bytes.Buffer 69 | for i := 0; i < len(s.Schema.Columns); i++ { 70 | if i > 0 { 71 | columns.WriteString(",") 72 | } 73 | columns.WriteString(s.Schema.Columns[i].Name) 74 | } 75 | if !s.isPartitioned() { 76 | return fmt.Sprintf("SELECT %s FROM %s %s", columns.String(), s.Table, s.where()) 77 | } 78 | 79 | return fmt.Sprintf("SELECT %s FROM %s WHERE %s = \\'%s\\'", columns.String(), s.Table, s.Partition.DateExpression, s.Partition.DateFilter.Format(SQLDateFormat)) 80 | } 81 | 82 | type RedshiftConnectionDetails struct { 83 | Host string `yaml:"host"` 84 | Port int `yaml:"port"` 85 | User string `yaml:"user"` 86 | Database string `yaml:"db"` 87 | Password string `yaml:"password"` 88 | } 89 | 90 | type S3Configuration struct { 91 | Bucket string `yaml:"bucket"` 92 | AccessKey string `yaml:"access_key"` 93 | SecretKey string `yaml:"secret_key"` 94 | } 95 | 96 | func (c S3Configuration) ToRedshiftCredentialsClause() string { 97 | return fmt.Sprintf("aws_access_key_id=%s;aws_secret_access_key=%s", c.AccessKey, c.SecretKey) 98 | } 99 | 100 | func (c *RedshiftConnectionDetails) URLString() string { 101 | return fmt.Sprintf("postgres://%s:%s@%s:%d/%s", c.User, c.Password, c.Host, c.Port, c.Database) 102 | } 103 | -------------------------------------------------------------------------------- /redshift/table.go: -------------------------------------------------------------------------------- 1 | package redshift 2 | 3 | import ( 4 | "fmt" 5 | _ "github.com/lib/pq" 6 | bq "google.golang.org/api/bigquery/v2" 7 | "strings" 8 | ) 9 | 10 | const ( 11 | SMALLINT = iota 12 | INTEGER = iota 13 | BIGINT = iota 14 | DECIMAL = iota 15 | DOUBLE = iota 16 | BOOLEAN = iota 17 | CHAR = iota 18 | VARCHAR = iota 19 | DATE = iota 20 | TIMESTAMP = iota 21 | ) 22 | 23 | type Column struct { 24 | Name string 25 | Type int 26 | } 27 | 28 | func (c *Column) String() string { 29 | return c.Name 30 | } 31 | 32 | type TableSchema struct { 33 | Columns []*Column 34 | } 35 | 36 | func (in *TableSchema) ToBigQuerySchema() (*bq.TableSchema, error) { 37 | fields := make([]*bq.TableFieldSchema, len(in.Columns)) 38 | 39 | for _, column := range in.Columns { 40 | t, err := bigqueryColumnType(column.Type) 41 | if err != nil { 42 | return nil, fmt.Errorf("couldn't map column %s: %s", column.Name, err.Error()) 43 | } 44 | field := &bq.TableFieldSchema{ 45 | Name: column.Name, 46 | Type: t, 47 | } 48 | fields = append(fields, field) 49 | } 50 | 51 | return &bq.TableSchema{ 52 | Fields: fields, 53 | }, nil 54 | } 55 | 56 | func bigqueryColumnType(t int) (string, error) { 57 | if t == SMALLINT || t == INTEGER || t == BIGINT { 58 | return "INTEGER", nil 59 | } 60 | if t == DECIMAL || t == DOUBLE { 61 | return "FLOAT", nil 62 | } 63 | if t == BOOLEAN { 64 | return "BOOLEAN", nil 65 | } 66 | if t == CHAR || t == VARCHAR { 67 | return "STRING", nil 68 | } 69 | if t == DATE { 70 | return "STRING", nil 71 | } 72 | if t == TIMESTAMP { 73 | return "TIMESTAMP", nil 74 | } 75 | 76 | return "", fmt.Errorf("unexpected column type: %d", t) 77 | } 78 | 79 | func (t *TableSchema) String() string { 80 | return fmt.Sprintf("%+v", t.Columns) 81 | } 82 | 83 | func (c *Client) ExtractSchema(table string) (*TableSchema, error) { 84 | rows, err := c.query(fmt.Sprintf("SELECT \"column\", \"type\" FROM pg_table_def WHERE tablename = '%s'", table)) 85 | if err != nil { 86 | return nil, err 87 | } 88 | 89 | cols := make([]*Column, 0) 90 | defer rows.Close() 91 | for rows.Next() { 92 | var name string 93 | var t string 94 | err = rows.Scan(&name, &t) 95 | if err != nil { 96 | return nil, err 97 | } 98 | colType, err := columnType(t) 99 | if err != nil { 100 | return nil, err 101 | } 102 | cols = append(cols, &Column{name, colType}) 103 | } 104 | 105 | return &TableSchema{cols}, nil 106 | } 107 | 108 | func columnType(t string) (int, error) { 109 | if strings.HasPrefix(t, "timestamp") { 110 | return TIMESTAMP, nil 111 | } 112 | if strings.HasPrefix(t, "text") { 113 | return VARCHAR, nil 114 | } 115 | if strings.HasPrefix(t, "character varying") { 116 | return VARCHAR, nil 117 | } 118 | if strings.HasPrefix(t, "character") { 119 | return CHAR, nil 120 | } 121 | if strings.HasPrefix(t, "date") { 122 | return DATE, nil 123 | } 124 | if strings.HasPrefix(t, "double") { 125 | return DOUBLE, nil 126 | } 127 | if strings.HasPrefix(t, "integer") { 128 | return INTEGER, nil 129 | } 130 | if strings.HasPrefix(t, "bigint") { 131 | return INTEGER, nil 132 | } 133 | if strings.HasPrefix(t, "smallint") { 134 | return SMALLINT, nil 135 | } 136 | if strings.HasPrefix(t, "boolean") { 137 | return BOOLEAN, nil 138 | } 139 | if strings.HasPrefix(t, "numeric") { 140 | return DECIMAL, nil 141 | } 142 | return 0, fmt.Errorf("unexpected col type: %s", t) 143 | } 144 | -------------------------------------------------------------------------------- /redshift/unload.go: -------------------------------------------------------------------------------- 1 | package redshift 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | type unloadOperation struct { 8 | client *Client 9 | config *AWSConfiguration 10 | source *RedshiftSource 11 | } 12 | 13 | type UnloadResult struct { 14 | Bucket string 15 | ObjectPrefix string 16 | } 17 | 18 | func newUnloadOperation(client *Client, config *AWSConfiguration, source *RedshiftSource) *unloadOperation { 19 | return &unloadOperation{client, config, source} 20 | } 21 | 22 | func (op *unloadOperation) execute() (*UnloadResult, error) { 23 | statement := op.unloadStatement() 24 | 25 | _, err := op.client.execute(statement) 26 | if err != nil { 27 | return nil, err 28 | } 29 | 30 | result := &UnloadResult{op.config.S3.Bucket, op.source.Table} 31 | 32 | return result, nil 33 | } 34 | 35 | func (op *unloadOperation) unloadStatement() string { 36 | return fmt.Sprintf("UNLOAD ('%s') TO '%s' WITH CREDENTIALS '%s' %s", op.source.SelectClause(), op.staging(), op.credentials(), op.options()) 37 | } 38 | 39 | func (op *unloadOperation) options() string { 40 | return fmt.Sprintf("ALLOWOVERWRITE GZIP ESCAPE DELIMITER AS '%s'", op.delimiter()) 41 | } 42 | 43 | func DefaultDelimiter() string { 44 | return "|" 45 | } 46 | 47 | func (op *unloadOperation) delimiter() string { 48 | return DefaultDelimiter() 49 | } 50 | 51 | func (op *unloadOperation) staging() string { 52 | return fmt.Sprintf("s3://%s/%s/", op.config.S3.Bucket, op.source.Table) 53 | } 54 | 55 | func (op *unloadOperation) credentials() string { 56 | return op.config.S3.ToRedshiftCredentialsClause() 57 | } 58 | -------------------------------------------------------------------------------- /storage/transfer.go: -------------------------------------------------------------------------------- 1 | package storage 2 | 3 | import ( 4 | "encoding/json" 5 | "fmt" 6 | bq "github.com/uswitch/bqshift/bigquery" 7 | "github.com/uswitch/bqshift/redshift" 8 | "github.com/uswitch/bqshift/util" 9 | "golang.org/x/net/context" 10 | "golang.org/x/oauth2/google" 11 | transfer "google.golang.org/api/storagetransfer/v1" 12 | "log" 13 | "time" 14 | ) 15 | 16 | type Client struct { 17 | service *transfer.Service 18 | table *bq.TableReference 19 | s3config *redshift.S3Configuration 20 | } 21 | 22 | func NewClient(config *bq.TableReference, s3 *redshift.S3Configuration) (*Client, error) { 23 | ctx := context.Background() 24 | client, err := google.DefaultClient(ctx, transfer.CloudPlatformScope) 25 | if err != nil { 26 | return nil, err 27 | } 28 | svc, err := transfer.New(client) 29 | if err != nil { 30 | return nil, err 31 | } 32 | 33 | c := &Client{svc, config, s3} 34 | return c, nil 35 | } 36 | 37 | func filterString(projectId, jobName string) (string, error) { 38 | m := make(map[string]interface{}) 39 | m["project_id"] = projectId 40 | names := make([]string, 1) 41 | names[0] = jobName 42 | m["job_names"] = names 43 | bs, err := json.Marshal(m) 44 | if err != nil { 45 | return "", err 46 | } 47 | return string(bs), nil 48 | } 49 | 50 | func (c *Client) blockForJobCompletion(createdJob *transfer.TransferJob) error { 51 | filter, err := filterString(createdJob.ProjectId, createdJob.Name) 52 | if err != nil { 53 | fmt.Errorf("error creating list filter: %s", err.Error()) 54 | } 55 | ticks := time.Tick(30 * time.Second) 56 | 57 | for _ = range ticks { 58 | resp, err := util.RetryOp(func() (interface{}, error) { 59 | return c.service.TransferOperations.List("transferOperations").Filter(filter).Do() 60 | }) 61 | 62 | if err != nil { 63 | return fmt.Errorf("error listing operations: %s", err.Error()) 64 | } 65 | 66 | ops := resp.(*transfer.ListOperationsResponse) 67 | if len(ops.Operations) != 1 { 68 | log.Println("waiting another 30s for transfer operation.") 69 | continue 70 | } 71 | 72 | op := ops.Operations[0] 73 | if op.Done { 74 | if op.Error != nil { 75 | return fmt.Errorf("transfer operation failed: %s", op.Error.Message) 76 | } 77 | return nil 78 | } else { 79 | log.Println("transfer in progress. waiting 30s.") 80 | } 81 | } 82 | 83 | return nil 84 | } 85 | 86 | type StoredResult struct { 87 | BucketName string 88 | Prefix string 89 | } 90 | 91 | func (c *Client) TransferToCloudStorage(source *redshift.UnloadResult) (*StoredResult, error) { 92 | startTime := time.Now().Add(1 * time.Minute).UTC() 93 | 94 | startDate := &transfer.Date{ 95 | Day: int64(startTime.Day()), 96 | Month: int64(startTime.Month()), 97 | Year: int64(startTime.Year()), 98 | } 99 | 100 | destinationBucket := source.Bucket 101 | 102 | job := &transfer.TransferJob{ 103 | Description: fmt.Sprintf("bqshift %s", source.ObjectPrefix), 104 | Status: "ENABLED", 105 | ProjectId: c.table.ProjectID, 106 | Schedule: &transfer.Schedule{ 107 | ScheduleEndDate: startDate, 108 | ScheduleStartDate: startDate, 109 | StartTimeOfDay: &transfer.TimeOfDay{ 110 | Hours: int64(startTime.Hour()), 111 | Minutes: int64(startTime.Minute()), 112 | }, 113 | }, 114 | TransferSpec: &transfer.TransferSpec{ 115 | TransferOptions: &transfer.TransferOptions{ 116 | DeleteObjectsFromSourceAfterTransfer: true, 117 | OverwriteObjectsAlreadyExistingInSink: true, 118 | }, 119 | AwsS3DataSource: &transfer.AwsS3Data{ 120 | AwsAccessKey: &transfer.AwsAccessKey{ 121 | AccessKeyId: c.s3config.AccessKey, 122 | SecretAccessKey: c.s3config.SecretKey, 123 | }, 124 | BucketName: source.Bucket, 125 | }, 126 | GcsDataSink: &transfer.GcsData{ 127 | BucketName: destinationBucket, 128 | }, 129 | ObjectConditions: &transfer.ObjectConditions{ 130 | IncludePrefixes: []string{source.ObjectPrefix}, 131 | }, 132 | }, 133 | } 134 | 135 | created, err := util.RetryOp(func() (interface{}, error) { 136 | return c.service.TransferJobs.Create(job).Do() 137 | }) 138 | if err != nil { 139 | return nil, err 140 | } 141 | 142 | log.Println("transfer requested, this may take a while.") 143 | err = c.blockForJobCompletion(created.(*transfer.TransferJob)) 144 | if err != nil { 145 | return nil, err 146 | } 147 | 148 | return &StoredResult{BucketName: destinationBucket, Prefix: source.ObjectPrefix}, nil 149 | } 150 | -------------------------------------------------------------------------------- /util/retry.go: -------------------------------------------------------------------------------- 1 | package util 2 | 3 | import ( 4 | "github.com/cenk/backoff" 5 | "log" 6 | ) 7 | 8 | func RetryOp(op func() (interface{}, error)) (interface{}, error) { 9 | resultch := make(chan interface{}, 1) 10 | 11 | retryOp := func() error { 12 | result, err := op() 13 | if err != nil { 14 | log.Println("error executing operation. will retry.", err.Error()) 15 | return err 16 | } 17 | resultch <- result 18 | return nil 19 | } 20 | 21 | err := backoff.Retry(retryOp, backoff.NewExponentialBackOff()) 22 | 23 | if err != nil { 24 | return nil, err 25 | } 26 | 27 | return <-resultch, err 28 | } 29 | -------------------------------------------------------------------------------- /vendor/github.com/alecthomas/template/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2012 The Go Authors. All rights reserved. 2 | 3 | Redistribution and use in source and binary forms, with or without 4 | modification, are permitted provided that the following conditions are 5 | met: 6 | 7 | * Redistributions of source code must retain the above copyright 8 | notice, this list of conditions and the following disclaimer. 9 | * Redistributions in binary form must reproduce the above 10 | copyright notice, this list of conditions and the following disclaimer 11 | in the documentation and/or other materials provided with the 12 | distribution. 13 | * Neither the name of Google Inc. nor the names of its 14 | contributors may be used to endorse or promote products derived from 15 | this software without specific prior written permission. 16 | 17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 20 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 21 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 23 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | -------------------------------------------------------------------------------- /vendor/github.com/alecthomas/template/README.md: -------------------------------------------------------------------------------- 1 | # Go's `text/template` package with newline elision 2 | 3 | This is a fork of Go 1.4's [text/template](http://golang.org/pkg/text/template/) package with one addition: a backslash immediately after a closing delimiter will delete all subsequent newlines until a non-newline. 4 | 5 | eg. 6 | 7 | ``` 8 | {{if true}}\ 9 | hello 10 | {{end}}\ 11 | ``` 12 | 13 | Will result in: 14 | 15 | ``` 16 | hello\n 17 | ``` 18 | 19 | Rather than: 20 | 21 | ``` 22 | \n 23 | hello\n 24 | \n 25 | ``` 26 | -------------------------------------------------------------------------------- /vendor/github.com/alecthomas/template/helper.go: -------------------------------------------------------------------------------- 1 | // Copyright 2011 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // Helper functions to make constructing templates easier. 6 | 7 | package template 8 | 9 | import ( 10 | "fmt" 11 | "io/ioutil" 12 | "path/filepath" 13 | ) 14 | 15 | // Functions and methods to parse templates. 16 | 17 | // Must is a helper that wraps a call to a function returning (*Template, error) 18 | // and panics if the error is non-nil. It is intended for use in variable 19 | // initializations such as 20 | // var t = template.Must(template.New("name").Parse("text")) 21 | func Must(t *Template, err error) *Template { 22 | if err != nil { 23 | panic(err) 24 | } 25 | return t 26 | } 27 | 28 | // ParseFiles creates a new Template and parses the template definitions from 29 | // the named files. The returned template's name will have the (base) name and 30 | // (parsed) contents of the first file. There must be at least one file. 31 | // If an error occurs, parsing stops and the returned *Template is nil. 32 | func ParseFiles(filenames ...string) (*Template, error) { 33 | return parseFiles(nil, filenames...) 34 | } 35 | 36 | // ParseFiles parses the named files and associates the resulting templates with 37 | // t. If an error occurs, parsing stops and the returned template is nil; 38 | // otherwise it is t. There must be at least one file. 39 | func (t *Template) ParseFiles(filenames ...string) (*Template, error) { 40 | return parseFiles(t, filenames...) 41 | } 42 | 43 | // parseFiles is the helper for the method and function. If the argument 44 | // template is nil, it is created from the first file. 45 | func parseFiles(t *Template, filenames ...string) (*Template, error) { 46 | if len(filenames) == 0 { 47 | // Not really a problem, but be consistent. 48 | return nil, fmt.Errorf("template: no files named in call to ParseFiles") 49 | } 50 | for _, filename := range filenames { 51 | b, err := ioutil.ReadFile(filename) 52 | if err != nil { 53 | return nil, err 54 | } 55 | s := string(b) 56 | name := filepath.Base(filename) 57 | // First template becomes return value if not already defined, 58 | // and we use that one for subsequent New calls to associate 59 | // all the templates together. Also, if this file has the same name 60 | // as t, this file becomes the contents of t, so 61 | // t, err := New(name).Funcs(xxx).ParseFiles(name) 62 | // works. Otherwise we create a new template associated with t. 63 | var tmpl *Template 64 | if t == nil { 65 | t = New(name) 66 | } 67 | if name == t.Name() { 68 | tmpl = t 69 | } else { 70 | tmpl = t.New(name) 71 | } 72 | _, err = tmpl.Parse(s) 73 | if err != nil { 74 | return nil, err 75 | } 76 | } 77 | return t, nil 78 | } 79 | 80 | // ParseGlob creates a new Template and parses the template definitions from the 81 | // files identified by the pattern, which must match at least one file. The 82 | // returned template will have the (base) name and (parsed) contents of the 83 | // first file matched by the pattern. ParseGlob is equivalent to calling 84 | // ParseFiles with the list of files matched by the pattern. 85 | func ParseGlob(pattern string) (*Template, error) { 86 | return parseGlob(nil, pattern) 87 | } 88 | 89 | // ParseGlob parses the template definitions in the files identified by the 90 | // pattern and associates the resulting templates with t. The pattern is 91 | // processed by filepath.Glob and must match at least one file. ParseGlob is 92 | // equivalent to calling t.ParseFiles with the list of files matched by the 93 | // pattern. 94 | func (t *Template) ParseGlob(pattern string) (*Template, error) { 95 | return parseGlob(t, pattern) 96 | } 97 | 98 | // parseGlob is the implementation of the function and method ParseGlob. 99 | func parseGlob(t *Template, pattern string) (*Template, error) { 100 | filenames, err := filepath.Glob(pattern) 101 | if err != nil { 102 | return nil, err 103 | } 104 | if len(filenames) == 0 { 105 | return nil, fmt.Errorf("template: pattern matches no files: %#q", pattern) 106 | } 107 | return parseFiles(t, filenames...) 108 | } 109 | -------------------------------------------------------------------------------- /vendor/github.com/alecthomas/units/COPYING: -------------------------------------------------------------------------------- 1 | Copyright (C) 2014 Alec Thomas 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of 4 | this software and associated documentation files (the "Software"), to deal in 5 | the Software without restriction, including without limitation the rights to 6 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 7 | of the Software, and to permit persons to whom the Software is furnished to do 8 | so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 19 | SOFTWARE. 20 | -------------------------------------------------------------------------------- /vendor/github.com/alecthomas/units/README.md: -------------------------------------------------------------------------------- 1 | # Units - Helpful unit multipliers and functions for Go 2 | 3 | The goal of this package is to have functionality similar to the [time](http://golang.org/pkg/time/) package. 4 | 5 | It allows for code like this: 6 | 7 | ```go 8 | n, err := ParseBase2Bytes("1KB") 9 | // n == 1024 10 | n = units.Mebibyte * 512 11 | ``` 12 | -------------------------------------------------------------------------------- /vendor/github.com/alecthomas/units/bytes.go: -------------------------------------------------------------------------------- 1 | package units 2 | 3 | // Base2Bytes is the old non-SI power-of-2 byte scale (1024 bytes in a kilobyte, 4 | // etc.). 5 | type Base2Bytes int64 6 | 7 | // Base-2 byte units. 8 | const ( 9 | Kibibyte Base2Bytes = 1024 10 | KiB = Kibibyte 11 | Mebibyte = Kibibyte * 1024 12 | MiB = Mebibyte 13 | Gibibyte = Mebibyte * 1024 14 | GiB = Gibibyte 15 | Tebibyte = Gibibyte * 1024 16 | TiB = Tebibyte 17 | Pebibyte = Tebibyte * 1024 18 | PiB = Pebibyte 19 | Exbibyte = Pebibyte * 1024 20 | EiB = Exbibyte 21 | ) 22 | 23 | var ( 24 | bytesUnitMap = MakeUnitMap("iB", "B", 1024) 25 | oldBytesUnitMap = MakeUnitMap("B", "B", 1024) 26 | ) 27 | 28 | // ParseBase2Bytes supports both iB and B in base-2 multipliers. That is, KB 29 | // and KiB are both 1024. 30 | func ParseBase2Bytes(s string) (Base2Bytes, error) { 31 | n, err := ParseUnit(s, bytesUnitMap) 32 | if err != nil { 33 | n, err = ParseUnit(s, oldBytesUnitMap) 34 | } 35 | return Base2Bytes(n), err 36 | } 37 | 38 | func (b Base2Bytes) String() string { 39 | return ToString(int64(b), 1024, "iB", "B") 40 | } 41 | 42 | var ( 43 | metricBytesUnitMap = MakeUnitMap("B", "B", 1000) 44 | ) 45 | 46 | // MetricBytes are SI byte units (1000 bytes in a kilobyte). 47 | type MetricBytes SI 48 | 49 | // SI base-10 byte units. 50 | const ( 51 | Kilobyte MetricBytes = 1000 52 | KB = Kilobyte 53 | Megabyte = Kilobyte * 1000 54 | MB = Megabyte 55 | Gigabyte = Megabyte * 1000 56 | GB = Gigabyte 57 | Terabyte = Gigabyte * 1000 58 | TB = Terabyte 59 | Petabyte = Terabyte * 1000 60 | PB = Petabyte 61 | Exabyte = Petabyte * 1000 62 | EB = Exabyte 63 | ) 64 | 65 | // ParseMetricBytes parses base-10 metric byte units. That is, KB is 1000 bytes. 66 | func ParseMetricBytes(s string) (MetricBytes, error) { 67 | n, err := ParseUnit(s, metricBytesUnitMap) 68 | return MetricBytes(n), err 69 | } 70 | 71 | func (m MetricBytes) String() string { 72 | return ToString(int64(m), 1000, "B", "B") 73 | } 74 | 75 | // ParseStrictBytes supports both iB and B suffixes for base 2 and metric, 76 | // respectively. That is, KiB represents 1024 and KB represents 1000. 77 | func ParseStrictBytes(s string) (int64, error) { 78 | n, err := ParseUnit(s, bytesUnitMap) 79 | if err != nil { 80 | n, err = ParseUnit(s, metricBytesUnitMap) 81 | } 82 | return int64(n), err 83 | } 84 | -------------------------------------------------------------------------------- /vendor/github.com/alecthomas/units/doc.go: -------------------------------------------------------------------------------- 1 | // Package units provides helpful unit multipliers and functions for Go. 2 | // 3 | // The goal of this package is to have functionality similar to the time [1] package. 4 | // 5 | // 6 | // [1] http://golang.org/pkg/time/ 7 | // 8 | // It allows for code like this: 9 | // 10 | // n, err := ParseBase2Bytes("1KB") 11 | // // n == 1024 12 | // n = units.Mebibyte * 512 13 | package units 14 | -------------------------------------------------------------------------------- /vendor/github.com/alecthomas/units/si.go: -------------------------------------------------------------------------------- 1 | package units 2 | 3 | // SI units. 4 | type SI int64 5 | 6 | // SI unit multiples. 7 | const ( 8 | Kilo SI = 1000 9 | Mega = Kilo * 1000 10 | Giga = Mega * 1000 11 | Tera = Giga * 1000 12 | Peta = Tera * 1000 13 | Exa = Peta * 1000 14 | ) 15 | 16 | func MakeUnitMap(suffix, shortSuffix string, scale int64) map[string]float64 { 17 | return map[string]float64{ 18 | shortSuffix: 1, 19 | "K" + suffix: float64(scale), 20 | "M" + suffix: float64(scale * scale), 21 | "G" + suffix: float64(scale * scale * scale), 22 | "T" + suffix: float64(scale * scale * scale * scale), 23 | "P" + suffix: float64(scale * scale * scale * scale * scale), 24 | "E" + suffix: float64(scale * scale * scale * scale * scale * scale), 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /vendor/github.com/alecthomas/units/util.go: -------------------------------------------------------------------------------- 1 | package units 2 | 3 | import ( 4 | "errors" 5 | "fmt" 6 | "strings" 7 | ) 8 | 9 | var ( 10 | siUnits = []string{"", "K", "M", "G", "T", "P", "E"} 11 | ) 12 | 13 | func ToString(n int64, scale int64, suffix, baseSuffix string) string { 14 | mn := len(siUnits) 15 | out := make([]string, mn) 16 | for i, m := range siUnits { 17 | if n%scale != 0 || i == 0 && n == 0 { 18 | s := suffix 19 | if i == 0 { 20 | s = baseSuffix 21 | } 22 | out[mn-1-i] = fmt.Sprintf("%d%s%s", n%scale, m, s) 23 | } 24 | n /= scale 25 | if n == 0 { 26 | break 27 | } 28 | } 29 | return strings.Join(out, "") 30 | } 31 | 32 | // Below code ripped straight from http://golang.org/src/pkg/time/format.go?s=33392:33438#L1123 33 | var errLeadingInt = errors.New("units: bad [0-9]*") // never printed 34 | 35 | // leadingInt consumes the leading [0-9]* from s. 36 | func leadingInt(s string) (x int64, rem string, err error) { 37 | i := 0 38 | for ; i < len(s); i++ { 39 | c := s[i] 40 | if c < '0' || c > '9' { 41 | break 42 | } 43 | if x >= (1<<63-10)/10 { 44 | // overflow 45 | return 0, "", errLeadingInt 46 | } 47 | x = x*10 + int64(c) - '0' 48 | } 49 | return x, s[i:], nil 50 | } 51 | 52 | func ParseUnit(s string, unitMap map[string]float64) (int64, error) { 53 | // [-+]?([0-9]*(\.[0-9]*)?[a-z]+)+ 54 | orig := s 55 | f := float64(0) 56 | neg := false 57 | 58 | // Consume [-+]? 59 | if s != "" { 60 | c := s[0] 61 | if c == '-' || c == '+' { 62 | neg = c == '-' 63 | s = s[1:] 64 | } 65 | } 66 | // Special case: if all that is left is "0", this is zero. 67 | if s == "0" { 68 | return 0, nil 69 | } 70 | if s == "" { 71 | return 0, errors.New("units: invalid " + orig) 72 | } 73 | for s != "" { 74 | g := float64(0) // this element of the sequence 75 | 76 | var x int64 77 | var err error 78 | 79 | // The next character must be [0-9.] 80 | if !(s[0] == '.' || ('0' <= s[0] && s[0] <= '9')) { 81 | return 0, errors.New("units: invalid " + orig) 82 | } 83 | // Consume [0-9]* 84 | pl := len(s) 85 | x, s, err = leadingInt(s) 86 | if err != nil { 87 | return 0, errors.New("units: invalid " + orig) 88 | } 89 | g = float64(x) 90 | pre := pl != len(s) // whether we consumed anything before a period 91 | 92 | // Consume (\.[0-9]*)? 93 | post := false 94 | if s != "" && s[0] == '.' { 95 | s = s[1:] 96 | pl := len(s) 97 | x, s, err = leadingInt(s) 98 | if err != nil { 99 | return 0, errors.New("units: invalid " + orig) 100 | } 101 | scale := 1.0 102 | for n := pl - len(s); n > 0; n-- { 103 | scale *= 10 104 | } 105 | g += float64(x) / scale 106 | post = pl != len(s) 107 | } 108 | if !pre && !post { 109 | // no digits (e.g. ".s" or "-.s") 110 | return 0, errors.New("units: invalid " + orig) 111 | } 112 | 113 | // Consume unit. 114 | i := 0 115 | for ; i < len(s); i++ { 116 | c := s[i] 117 | if c == '.' || ('0' <= c && c <= '9') { 118 | break 119 | } 120 | } 121 | u := s[:i] 122 | s = s[i:] 123 | unit, ok := unitMap[u] 124 | if !ok { 125 | return 0, errors.New("units: unknown unit " + u + " in " + orig) 126 | } 127 | 128 | f += g * unit 129 | } 130 | 131 | if neg { 132 | f = -f 133 | } 134 | if f < float64(-1<<63) || f > float64(1<<63-1) { 135 | return 0, errors.New("units: overflow parsing unit") 136 | } 137 | return int64(f), nil 138 | } 139 | -------------------------------------------------------------------------------- /vendor/github.com/cenk/backoff/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 Cenk Altı 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | this software and associated documentation files (the "Software"), to deal in 7 | the Software without restriction, including without limitation the rights to 8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software is furnished to do so, 10 | subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /vendor/github.com/cenk/backoff/README.md: -------------------------------------------------------------------------------- 1 | # Exponential Backoff [![GoDoc][godoc image]][godoc] [![Build Status][travis image]][travis] [![Coverage Status][coveralls image]][coveralls] 2 | 3 | This is a Go port of the exponential backoff algorithm from [Google's HTTP Client Library for Java][google-http-java-client]. 4 | 5 | [Exponential backoff][exponential backoff wiki] 6 | is an algorithm that uses feedback to multiplicatively decrease the rate of some process, 7 | in order to gradually find an acceptable rate. 8 | The retries exponentially increase and stop increasing when a certain threshold is met. 9 | 10 | ## Usage 11 | 12 | See https://godoc.org/github.com/cenk/backoff#pkg-examples 13 | 14 | ## Contributing 15 | 16 | * I would like to keep this library as small as possible. 17 | * Please don't send a PR without opening an issue and discussing it first. 18 | * If proposed change is not a common use case, I will probably not accept it. 19 | 20 | [godoc]: https://godoc.org/github.com/cenk/backoff 21 | [godoc image]: https://godoc.org/github.com/cenk/backoff?status.png 22 | [travis]: https://travis-ci.org/cenk/backoff 23 | [travis image]: https://travis-ci.org/cenk/backoff.png?branch=master 24 | [coveralls]: https://coveralls.io/github/cenk/backoff?branch=master 25 | [coveralls image]: https://coveralls.io/repos/github/cenk/backoff/badge.svg?branch=master 26 | 27 | [google-http-java-client]: https://github.com/google/google-http-java-client 28 | [exponential backoff wiki]: http://en.wikipedia.org/wiki/Exponential_backoff 29 | 30 | [advanced example]: https://godoc.org/github.com/cenk/backoff#example_ 31 | -------------------------------------------------------------------------------- /vendor/github.com/cenk/backoff/backoff.go: -------------------------------------------------------------------------------- 1 | // Package backoff implements backoff algorithms for retrying operations. 2 | // 3 | // Use Retry function for retrying operations that may fail. 4 | // If Retry does not meet your needs, 5 | // copy/paste the function into your project and modify as you wish. 6 | // 7 | // There is also Ticker type similar to time.Ticker. 8 | // You can use it if you need to work with channels. 9 | // 10 | // See Examples section below for usage examples. 11 | package backoff 12 | 13 | import "time" 14 | 15 | // BackOff is a backoff policy for retrying an operation. 16 | type BackOff interface { 17 | // NextBackOff returns the duration to wait before retrying the operation, 18 | // or backoff.Stop to indicate that no more retries should be made. 19 | // 20 | // Example usage: 21 | // 22 | // duration := backoff.NextBackOff(); 23 | // if (duration == backoff.Stop) { 24 | // // Do not retry operation. 25 | // } else { 26 | // // Sleep for duration and retry operation. 27 | // } 28 | // 29 | NextBackOff() time.Duration 30 | 31 | // Reset to initial state. 32 | Reset() 33 | } 34 | 35 | // Stop indicates that no more retries should be made for use in NextBackOff(). 36 | const Stop time.Duration = -1 37 | 38 | // ZeroBackOff is a fixed backoff policy whose backoff time is always zero, 39 | // meaning that the operation is retried immediately without waiting, indefinitely. 40 | type ZeroBackOff struct{} 41 | 42 | func (b *ZeroBackOff) Reset() {} 43 | 44 | func (b *ZeroBackOff) NextBackOff() time.Duration { return 0 } 45 | 46 | // StopBackOff is a fixed backoff policy that always returns backoff.Stop for 47 | // NextBackOff(), meaning that the operation should never be retried. 48 | type StopBackOff struct{} 49 | 50 | func (b *StopBackOff) Reset() {} 51 | 52 | func (b *StopBackOff) NextBackOff() time.Duration { return Stop } 53 | 54 | // ConstantBackOff is a backoff policy that always returns the same backoff delay. 55 | // This is in contrast to an exponential backoff policy, 56 | // which returns a delay that grows longer as you call NextBackOff() over and over again. 57 | type ConstantBackOff struct { 58 | Interval time.Duration 59 | } 60 | 61 | func (b *ConstantBackOff) Reset() {} 62 | func (b *ConstantBackOff) NextBackOff() time.Duration { return b.Interval } 63 | 64 | func NewConstantBackOff(d time.Duration) *ConstantBackOff { 65 | return &ConstantBackOff{Interval: d} 66 | } 67 | -------------------------------------------------------------------------------- /vendor/github.com/cenk/backoff/retry.go: -------------------------------------------------------------------------------- 1 | package backoff 2 | 3 | import "time" 4 | 5 | // An Operation is executing by Retry() or RetryNotify(). 6 | // The operation will be retried using a backoff policy if it returns an error. 7 | type Operation func() error 8 | 9 | // Notify is a notify-on-error function. It receives an operation error and 10 | // backoff delay if the operation failed (with an error). 11 | // 12 | // NOTE that if the backoff policy stated to stop retrying, 13 | // the notify function isn't called. 14 | type Notify func(error, time.Duration) 15 | 16 | // Retry the operation o until it does not return error or BackOff stops. 17 | // o is guaranteed to be run at least once. 18 | // It is the caller's responsibility to reset b after Retry returns. 19 | // 20 | // Retry sleeps the goroutine for the duration returned by BackOff after a 21 | // failed operation returns. 22 | func Retry(o Operation, b BackOff) error { return RetryNotify(o, b, nil) } 23 | 24 | // RetryNotify calls notify function with the error and wait duration 25 | // for each failed attempt before sleep. 26 | func RetryNotify(operation Operation, b BackOff, notify Notify) error { 27 | var err error 28 | var next time.Duration 29 | 30 | b.Reset() 31 | for { 32 | if err = operation(); err == nil { 33 | return nil 34 | } 35 | 36 | if next = b.NextBackOff(); next == Stop { 37 | return err 38 | } 39 | 40 | if notify != nil { 41 | notify(err, next) 42 | } 43 | 44 | time.Sleep(next) 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /vendor/github.com/cenk/backoff/ticker.go: -------------------------------------------------------------------------------- 1 | package backoff 2 | 3 | import ( 4 | "runtime" 5 | "sync" 6 | "time" 7 | ) 8 | 9 | // Ticker holds a channel that delivers `ticks' of a clock at times reported by a BackOff. 10 | // 11 | // Ticks will continue to arrive when the previous operation is still running, 12 | // so operations that take a while to fail could run in quick succession. 13 | type Ticker struct { 14 | C <-chan time.Time 15 | c chan time.Time 16 | b BackOff 17 | stop chan struct{} 18 | stopOnce sync.Once 19 | } 20 | 21 | // NewTicker returns a new Ticker containing a channel that will send the time at times 22 | // specified by the BackOff argument. Ticker is guaranteed to tick at least once. 23 | // The channel is closed when Stop method is called or BackOff stops. 24 | func NewTicker(b BackOff) *Ticker { 25 | c := make(chan time.Time) 26 | t := &Ticker{ 27 | C: c, 28 | c: c, 29 | b: b, 30 | stop: make(chan struct{}), 31 | } 32 | go t.run() 33 | runtime.SetFinalizer(t, (*Ticker).Stop) 34 | return t 35 | } 36 | 37 | // Stop turns off a ticker. After Stop, no more ticks will be sent. 38 | func (t *Ticker) Stop() { 39 | t.stopOnce.Do(func() { close(t.stop) }) 40 | } 41 | 42 | func (t *Ticker) run() { 43 | c := t.c 44 | defer close(c) 45 | t.b.Reset() 46 | 47 | // Ticker is guaranteed to tick at least once. 48 | afterC := t.send(time.Now()) 49 | 50 | for { 51 | if afterC == nil { 52 | return 53 | } 54 | 55 | select { 56 | case tick := <-afterC: 57 | afterC = t.send(tick) 58 | case <-t.stop: 59 | t.c = nil // Prevent future ticks from being sent to the channel. 60 | return 61 | } 62 | } 63 | } 64 | 65 | func (t *Ticker) send(tick time.Time) <-chan time.Time { 66 | select { 67 | case t.c <- tick: 68 | case <-t.stop: 69 | return nil 70 | } 71 | 72 | next := t.b.NextBackOff() 73 | if next == Stop { 74 | t.Stop() 75 | return nil 76 | } 77 | 78 | return time.After(next) 79 | } 80 | -------------------------------------------------------------------------------- /vendor/github.com/lib/pq/CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | ## Contributing to pq 2 | 3 | `pq` has a backlog of pull requests, but contributions are still very 4 | much welcome. You can help with patch review, submitting bug reports, 5 | or adding new functionality. There is no formal style guide, but 6 | please conform to the style of existing code and general Go formatting 7 | conventions when submitting patches. 8 | 9 | ### Patch review 10 | 11 | Help review existing open pull requests by commenting on the code or 12 | proposed functionality. 13 | 14 | ### Bug reports 15 | 16 | We appreciate any bug reports, but especially ones with self-contained 17 | (doesn't depend on code outside of pq), minimal (can't be simplified 18 | further) test cases. It's especially helpful if you can submit a pull 19 | request with just the failing test case (you'll probably want to 20 | pattern it after the tests in 21 | [conn_test.go](https://github.com/lib/pq/blob/master/conn_test.go). 22 | 23 | ### New functionality 24 | 25 | There are a number of pending patches for new functionality, so 26 | additional feature patches will take a while to merge. Still, patches 27 | are generally reviewed based on usefulness and complexity in addition 28 | to time-in-queue, so if you have a knockout idea, take a shot. Feel 29 | free to open an issue discussion your proposed patch beforehand. 30 | -------------------------------------------------------------------------------- /vendor/github.com/lib/pq/LICENSE.md: -------------------------------------------------------------------------------- 1 | Copyright (c) 2011-2013, 'pq' Contributors 2 | Portions Copyright (C) 2011 Blake Mizerany 3 | 4 | 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: 5 | 6 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 7 | 8 | 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. 9 | -------------------------------------------------------------------------------- /vendor/github.com/lib/pq/README.md: -------------------------------------------------------------------------------- 1 | # pq - A pure Go postgres driver for Go's database/sql package 2 | 3 | [![Build Status](https://travis-ci.org/lib/pq.png?branch=master)](https://travis-ci.org/lib/pq) 4 | 5 | ## Install 6 | 7 | go get github.com/lib/pq 8 | 9 | ## Docs 10 | 11 | For detailed documentation and basic usage examples, please see the package 12 | documentation at . 13 | 14 | ## Tests 15 | 16 | `go test` is used for testing. A running PostgreSQL server is 17 | required, with the ability to log in. The default database to connect 18 | to test with is "pqgotest," but it can be overridden using environment 19 | variables. 20 | 21 | Example: 22 | 23 | PGHOST=/run/postgresql go test github.com/lib/pq 24 | 25 | Optionally, a benchmark suite can be run as part of the tests: 26 | 27 | PGHOST=/run/postgresql go test -bench . 28 | 29 | ## Features 30 | 31 | * SSL 32 | * Handles bad connections for `database/sql` 33 | * Scan `time.Time` correctly (i.e. `timestamp[tz]`, `time[tz]`, `date`) 34 | * Scan binary blobs correctly (i.e. `bytea`) 35 | * Package for `hstore` support 36 | * COPY FROM support 37 | * pq.ParseURL for converting urls to connection strings for sql.Open. 38 | * Many libpq compatible environment variables 39 | * Unix socket support 40 | * Notifications: `LISTEN`/`NOTIFY` 41 | * pgpass support 42 | 43 | ## Future / Things you can help with 44 | 45 | * Better COPY FROM / COPY TO (see discussion in #181) 46 | 47 | ## Thank you (alphabetical) 48 | 49 | Some of these contributors are from the original library `bmizerany/pq.go` whose 50 | code still exists in here. 51 | 52 | * Andy Balholm (andybalholm) 53 | * Ben Berkert (benburkert) 54 | * Benjamin Heatwole (bheatwole) 55 | * Bill Mill (llimllib) 56 | * Bjørn Madsen (aeons) 57 | * Blake Gentry (bgentry) 58 | * Brad Fitzpatrick (bradfitz) 59 | * Charlie Melbye (cmelbye) 60 | * Chris Bandy (cbandy) 61 | * Chris Gilling (cgilling) 62 | * Chris Walsh (cwds) 63 | * Dan Sosedoff (sosedoff) 64 | * Daniel Farina (fdr) 65 | * Eric Chlebek (echlebek) 66 | * Eric Garrido (minusnine) 67 | * Eric Urban (hydrogen18) 68 | * Everyone at The Go Team 69 | * Evan Shaw (edsrzf) 70 | * Ewan Chou (coocood) 71 | * Fazal Majid (fazalmajid) 72 | * Federico Romero (federomero) 73 | * Fumin (fumin) 74 | * Gary Burd (garyburd) 75 | * Heroku (heroku) 76 | * James Pozdena (jpoz) 77 | * Jason McVetta (jmcvetta) 78 | * Jeremy Jay (pbnjay) 79 | * Joakim Sernbrant (serbaut) 80 | * John Gallagher (jgallagher) 81 | * Jonathan Rudenberg (titanous) 82 | * Joël Stemmer (jstemmer) 83 | * Kamil Kisiel (kisielk) 84 | * Kelly Dunn (kellydunn) 85 | * Keith Rarick (kr) 86 | * Kir Shatrov (kirs) 87 | * Lann Martin (lann) 88 | * Maciek Sakrejda (uhoh-itsmaciek) 89 | * Marc Brinkmann (mbr) 90 | * Marko Tiikkaja (johto) 91 | * Matt Newberry (MattNewberry) 92 | * Matt Robenolt (mattrobenolt) 93 | * Martin Olsen (martinolsen) 94 | * Mike Lewis (mikelikespie) 95 | * Nicolas Patry (Narsil) 96 | * Oliver Tonnhofer (olt) 97 | * Patrick Hayes (phayes) 98 | * Paul Hammond (paulhammond) 99 | * Ryan Smith (ryandotsmith) 100 | * Samuel Stauffer (samuel) 101 | * Timothée Peignier (cyberdelia) 102 | * Travis Cline (tmc) 103 | * TruongSinh Tran-Nguyen (truongsinh) 104 | * Yaismel Miranda (ympons) 105 | * notedit (notedit) 106 | -------------------------------------------------------------------------------- /vendor/github.com/lib/pq/buf.go: -------------------------------------------------------------------------------- 1 | package pq 2 | 3 | import ( 4 | "bytes" 5 | "encoding/binary" 6 | 7 | "github.com/lib/pq/oid" 8 | ) 9 | 10 | type readBuf []byte 11 | 12 | func (b *readBuf) int32() (n int) { 13 | n = int(int32(binary.BigEndian.Uint32(*b))) 14 | *b = (*b)[4:] 15 | return 16 | } 17 | 18 | func (b *readBuf) oid() (n oid.Oid) { 19 | n = oid.Oid(binary.BigEndian.Uint32(*b)) 20 | *b = (*b)[4:] 21 | return 22 | } 23 | 24 | // N.B: this is actually an unsigned 16-bit integer, unlike int32 25 | func (b *readBuf) int16() (n int) { 26 | n = int(binary.BigEndian.Uint16(*b)) 27 | *b = (*b)[2:] 28 | return 29 | } 30 | 31 | func (b *readBuf) string() string { 32 | i := bytes.IndexByte(*b, 0) 33 | if i < 0 { 34 | errorf("invalid message format; expected string terminator") 35 | } 36 | s := (*b)[:i] 37 | *b = (*b)[i+1:] 38 | return string(s) 39 | } 40 | 41 | func (b *readBuf) next(n int) (v []byte) { 42 | v = (*b)[:n] 43 | *b = (*b)[n:] 44 | return 45 | } 46 | 47 | func (b *readBuf) byte() byte { 48 | return b.next(1)[0] 49 | } 50 | 51 | type writeBuf struct { 52 | buf []byte 53 | pos int 54 | } 55 | 56 | func (b *writeBuf) int32(n int) { 57 | x := make([]byte, 4) 58 | binary.BigEndian.PutUint32(x, uint32(n)) 59 | b.buf = append(b.buf, x...) 60 | } 61 | 62 | func (b *writeBuf) int16(n int) { 63 | x := make([]byte, 2) 64 | binary.BigEndian.PutUint16(x, uint16(n)) 65 | b.buf = append(b.buf, x...) 66 | } 67 | 68 | func (b *writeBuf) string(s string) { 69 | b.buf = append(b.buf, (s + "\000")...) 70 | } 71 | 72 | func (b *writeBuf) byte(c byte) { 73 | b.buf = append(b.buf, c) 74 | } 75 | 76 | func (b *writeBuf) bytes(v []byte) { 77 | b.buf = append(b.buf, v...) 78 | } 79 | 80 | func (b *writeBuf) wrap() []byte { 81 | p := b.buf[b.pos:] 82 | binary.BigEndian.PutUint32(p, uint32(len(p))) 83 | return b.buf 84 | } 85 | 86 | func (b *writeBuf) next(c byte) { 87 | p := b.buf[b.pos:] 88 | binary.BigEndian.PutUint32(p, uint32(len(p))) 89 | b.pos = len(b.buf) + 1 90 | b.buf = append(b.buf, c, 0, 0, 0, 0) 91 | } 92 | -------------------------------------------------------------------------------- /vendor/github.com/lib/pq/oid/doc.go: -------------------------------------------------------------------------------- 1 | // Package oid contains OID constants 2 | // as defined by the Postgres server. 3 | package oid 4 | 5 | // Oid is a Postgres Object ID. 6 | type Oid uint32 7 | -------------------------------------------------------------------------------- /vendor/github.com/lib/pq/oid/gen.go: -------------------------------------------------------------------------------- 1 | // +build ignore 2 | 3 | // Generate the table of OID values 4 | // Run with 'go run gen.go'. 5 | package main 6 | 7 | import ( 8 | "database/sql" 9 | "fmt" 10 | "log" 11 | "os" 12 | "os/exec" 13 | 14 | _ "github.com/lib/pq" 15 | ) 16 | 17 | func main() { 18 | datname := os.Getenv("PGDATABASE") 19 | sslmode := os.Getenv("PGSSLMODE") 20 | 21 | if datname == "" { 22 | os.Setenv("PGDATABASE", "pqgotest") 23 | } 24 | 25 | if sslmode == "" { 26 | os.Setenv("PGSSLMODE", "disable") 27 | } 28 | 29 | db, err := sql.Open("postgres", "") 30 | if err != nil { 31 | log.Fatal(err) 32 | } 33 | cmd := exec.Command("gofmt") 34 | cmd.Stderr = os.Stderr 35 | w, err := cmd.StdinPipe() 36 | if err != nil { 37 | log.Fatal(err) 38 | } 39 | f, err := os.Create("types.go") 40 | if err != nil { 41 | log.Fatal(err) 42 | } 43 | cmd.Stdout = f 44 | err = cmd.Start() 45 | if err != nil { 46 | log.Fatal(err) 47 | } 48 | fmt.Fprintln(w, "// generated by 'go run gen.go'; do not edit") 49 | fmt.Fprintln(w, "\npackage oid") 50 | fmt.Fprintln(w, "const (") 51 | rows, err := db.Query(` 52 | SELECT typname, oid 53 | FROM pg_type WHERE oid < 10000 54 | ORDER BY oid; 55 | `) 56 | if err != nil { 57 | log.Fatal(err) 58 | } 59 | var name string 60 | var oid int 61 | for rows.Next() { 62 | err = rows.Scan(&name, &oid) 63 | if err != nil { 64 | log.Fatal(err) 65 | } 66 | fmt.Fprintf(w, "T_%s Oid = %d\n", name, oid) 67 | } 68 | if err = rows.Err(); err != nil { 69 | log.Fatal(err) 70 | } 71 | fmt.Fprintln(w, ")") 72 | w.Close() 73 | cmd.Wait() 74 | } 75 | -------------------------------------------------------------------------------- /vendor/github.com/lib/pq/oid/types.go: -------------------------------------------------------------------------------- 1 | // generated by 'go run gen.go'; do not edit 2 | 3 | package oid 4 | 5 | const ( 6 | T_bool Oid = 16 7 | T_bytea Oid = 17 8 | T_char Oid = 18 9 | T_name Oid = 19 10 | T_int8 Oid = 20 11 | T_int2 Oid = 21 12 | T_int2vector Oid = 22 13 | T_int4 Oid = 23 14 | T_regproc Oid = 24 15 | T_text Oid = 25 16 | T_oid Oid = 26 17 | T_tid Oid = 27 18 | T_xid Oid = 28 19 | T_cid Oid = 29 20 | T_oidvector Oid = 30 21 | T_pg_type Oid = 71 22 | T_pg_attribute Oid = 75 23 | T_pg_proc Oid = 81 24 | T_pg_class Oid = 83 25 | T_json Oid = 114 26 | T_xml Oid = 142 27 | T__xml Oid = 143 28 | T_pg_node_tree Oid = 194 29 | T__json Oid = 199 30 | T_smgr Oid = 210 31 | T_point Oid = 600 32 | T_lseg Oid = 601 33 | T_path Oid = 602 34 | T_box Oid = 603 35 | T_polygon Oid = 604 36 | T_line Oid = 628 37 | T__line Oid = 629 38 | T_cidr Oid = 650 39 | T__cidr Oid = 651 40 | T_float4 Oid = 700 41 | T_float8 Oid = 701 42 | T_abstime Oid = 702 43 | T_reltime Oid = 703 44 | T_tinterval Oid = 704 45 | T_unknown Oid = 705 46 | T_circle Oid = 718 47 | T__circle Oid = 719 48 | T_money Oid = 790 49 | T__money Oid = 791 50 | T_macaddr Oid = 829 51 | T_inet Oid = 869 52 | T__bool Oid = 1000 53 | T__bytea Oid = 1001 54 | T__char Oid = 1002 55 | T__name Oid = 1003 56 | T__int2 Oid = 1005 57 | T__int2vector Oid = 1006 58 | T__int4 Oid = 1007 59 | T__regproc Oid = 1008 60 | T__text Oid = 1009 61 | T__tid Oid = 1010 62 | T__xid Oid = 1011 63 | T__cid Oid = 1012 64 | T__oidvector Oid = 1013 65 | T__bpchar Oid = 1014 66 | T__varchar Oid = 1015 67 | T__int8 Oid = 1016 68 | T__point Oid = 1017 69 | T__lseg Oid = 1018 70 | T__path Oid = 1019 71 | T__box Oid = 1020 72 | T__float4 Oid = 1021 73 | T__float8 Oid = 1022 74 | T__abstime Oid = 1023 75 | T__reltime Oid = 1024 76 | T__tinterval Oid = 1025 77 | T__polygon Oid = 1027 78 | T__oid Oid = 1028 79 | T_aclitem Oid = 1033 80 | T__aclitem Oid = 1034 81 | T__macaddr Oid = 1040 82 | T__inet Oid = 1041 83 | T_bpchar Oid = 1042 84 | T_varchar Oid = 1043 85 | T_date Oid = 1082 86 | T_time Oid = 1083 87 | T_timestamp Oid = 1114 88 | T__timestamp Oid = 1115 89 | T__date Oid = 1182 90 | T__time Oid = 1183 91 | T_timestamptz Oid = 1184 92 | T__timestamptz Oid = 1185 93 | T_interval Oid = 1186 94 | T__interval Oid = 1187 95 | T__numeric Oid = 1231 96 | T_pg_database Oid = 1248 97 | T__cstring Oid = 1263 98 | T_timetz Oid = 1266 99 | T__timetz Oid = 1270 100 | T_bit Oid = 1560 101 | T__bit Oid = 1561 102 | T_varbit Oid = 1562 103 | T__varbit Oid = 1563 104 | T_numeric Oid = 1700 105 | T_refcursor Oid = 1790 106 | T__refcursor Oid = 2201 107 | T_regprocedure Oid = 2202 108 | T_regoper Oid = 2203 109 | T_regoperator Oid = 2204 110 | T_regclass Oid = 2205 111 | T_regtype Oid = 2206 112 | T__regprocedure Oid = 2207 113 | T__regoper Oid = 2208 114 | T__regoperator Oid = 2209 115 | T__regclass Oid = 2210 116 | T__regtype Oid = 2211 117 | T_record Oid = 2249 118 | T_cstring Oid = 2275 119 | T_any Oid = 2276 120 | T_anyarray Oid = 2277 121 | T_void Oid = 2278 122 | T_trigger Oid = 2279 123 | T_language_handler Oid = 2280 124 | T_internal Oid = 2281 125 | T_opaque Oid = 2282 126 | T_anyelement Oid = 2283 127 | T__record Oid = 2287 128 | T_anynonarray Oid = 2776 129 | T_pg_authid Oid = 2842 130 | T_pg_auth_members Oid = 2843 131 | T__txid_snapshot Oid = 2949 132 | T_uuid Oid = 2950 133 | T__uuid Oid = 2951 134 | T_txid_snapshot Oid = 2970 135 | T_fdw_handler Oid = 3115 136 | T_anyenum Oid = 3500 137 | T_tsvector Oid = 3614 138 | T_tsquery Oid = 3615 139 | T_gtsvector Oid = 3642 140 | T__tsvector Oid = 3643 141 | T__gtsvector Oid = 3644 142 | T__tsquery Oid = 3645 143 | T_regconfig Oid = 3734 144 | T__regconfig Oid = 3735 145 | T_regdictionary Oid = 3769 146 | T__regdictionary Oid = 3770 147 | T_anyrange Oid = 3831 148 | T_event_trigger Oid = 3838 149 | T_int4range Oid = 3904 150 | T__int4range Oid = 3905 151 | T_numrange Oid = 3906 152 | T__numrange Oid = 3907 153 | T_tsrange Oid = 3908 154 | T__tsrange Oid = 3909 155 | T_tstzrange Oid = 3910 156 | T__tstzrange Oid = 3911 157 | T_daterange Oid = 3912 158 | T__daterange Oid = 3913 159 | T_int8range Oid = 3926 160 | T__int8range Oid = 3927 161 | ) 162 | -------------------------------------------------------------------------------- /vendor/github.com/lib/pq/url.go: -------------------------------------------------------------------------------- 1 | package pq 2 | 3 | import ( 4 | "fmt" 5 | "net" 6 | nurl "net/url" 7 | "sort" 8 | "strings" 9 | ) 10 | 11 | // ParseURL no longer needs to be used by clients of this library since supplying a URL as a 12 | // connection string to sql.Open() is now supported: 13 | // 14 | // sql.Open("postgres", "postgres://bob:secret@1.2.3.4:5432/mydb?sslmode=verify-full") 15 | // 16 | // It remains exported here for backwards-compatibility. 17 | // 18 | // ParseURL converts a url to a connection string for driver.Open. 19 | // Example: 20 | // 21 | // "postgres://bob:secret@1.2.3.4:5432/mydb?sslmode=verify-full" 22 | // 23 | // converts to: 24 | // 25 | // "user=bob password=secret host=1.2.3.4 port=5432 dbname=mydb sslmode=verify-full" 26 | // 27 | // A minimal example: 28 | // 29 | // "postgres://" 30 | // 31 | // This will be blank, causing driver.Open to use all of the defaults 32 | func ParseURL(url string) (string, error) { 33 | u, err := nurl.Parse(url) 34 | if err != nil { 35 | return "", err 36 | } 37 | 38 | if u.Scheme != "postgres" && u.Scheme != "postgresql" { 39 | return "", fmt.Errorf("invalid connection protocol: %s", u.Scheme) 40 | } 41 | 42 | var kvs []string 43 | escaper := strings.NewReplacer(` `, `\ `, `'`, `\'`, `\`, `\\`) 44 | accrue := func(k, v string) { 45 | if v != "" { 46 | kvs = append(kvs, k+"="+escaper.Replace(v)) 47 | } 48 | } 49 | 50 | if u.User != nil { 51 | v := u.User.Username() 52 | accrue("user", v) 53 | 54 | v, _ = u.User.Password() 55 | accrue("password", v) 56 | } 57 | 58 | if host, port, err := net.SplitHostPort(u.Host); err != nil { 59 | accrue("host", u.Host) 60 | } else { 61 | accrue("host", host) 62 | accrue("port", port) 63 | } 64 | 65 | if u.Path != "" { 66 | accrue("dbname", u.Path[1:]) 67 | } 68 | 69 | q := u.Query() 70 | for k := range q { 71 | accrue(k, q.Get(k)) 72 | } 73 | 74 | sort.Strings(kvs) // Makes testing easier (not a performance concern) 75 | return strings.Join(kvs, " "), nil 76 | } 77 | -------------------------------------------------------------------------------- /vendor/github.com/lib/pq/user_posix.go: -------------------------------------------------------------------------------- 1 | // Package pq is a pure Go Postgres driver for the database/sql package. 2 | 3 | // +build darwin dragonfly freebsd linux nacl netbsd openbsd solaris rumprun 4 | 5 | package pq 6 | 7 | import ( 8 | "os" 9 | "os/user" 10 | ) 11 | 12 | func userCurrent() (string, error) { 13 | u, err := user.Current() 14 | if err == nil { 15 | return u.Username, nil 16 | } 17 | 18 | name := os.Getenv("USER") 19 | if name != "" { 20 | return name, nil 21 | } 22 | 23 | return "", ErrCouldNotDetectUsername 24 | } 25 | -------------------------------------------------------------------------------- /vendor/github.com/lib/pq/user_windows.go: -------------------------------------------------------------------------------- 1 | // Package pq is a pure Go Postgres driver for the database/sql package. 2 | package pq 3 | 4 | import ( 5 | "path/filepath" 6 | "syscall" 7 | ) 8 | 9 | // Perform Windows user name lookup identically to libpq. 10 | // 11 | // The PostgreSQL code makes use of the legacy Win32 function 12 | // GetUserName, and that function has not been imported into stock Go. 13 | // GetUserNameEx is available though, the difference being that a 14 | // wider range of names are available. To get the output to be the 15 | // same as GetUserName, only the base (or last) component of the 16 | // result is returned. 17 | func userCurrent() (string, error) { 18 | pw_name := make([]uint16, 128) 19 | pwname_size := uint32(len(pw_name)) - 1 20 | err := syscall.GetUserNameEx(syscall.NameSamCompatible, &pw_name[0], &pwname_size) 21 | if err != nil { 22 | return "", ErrCouldNotDetectUsername 23 | } 24 | s := syscall.UTF16ToString(pw_name) 25 | u := filepath.Base(s) 26 | return u, nil 27 | } 28 | -------------------------------------------------------------------------------- /vendor/golang.org/x/net/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2009 The Go Authors. All rights reserved. 2 | 3 | Redistribution and use in source and binary forms, with or without 4 | modification, are permitted provided that the following conditions are 5 | met: 6 | 7 | * Redistributions of source code must retain the above copyright 8 | notice, this list of conditions and the following disclaimer. 9 | * Redistributions in binary form must reproduce the above 10 | copyright notice, this list of conditions and the following disclaimer 11 | in the documentation and/or other materials provided with the 12 | distribution. 13 | * Neither the name of Google Inc. nor the names of its 14 | contributors may be used to endorse or promote products derived from 15 | this software without specific prior written permission. 16 | 17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 20 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 21 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 23 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | -------------------------------------------------------------------------------- /vendor/golang.org/x/net/PATENTS: -------------------------------------------------------------------------------- 1 | Additional IP Rights Grant (Patents) 2 | 3 | "This implementation" means the copyrightable works distributed by 4 | Google as part of the Go project. 5 | 6 | Google hereby grants to You a perpetual, worldwide, non-exclusive, 7 | no-charge, royalty-free, irrevocable (except as stated in this section) 8 | patent license to make, have made, use, offer to sell, sell, import, 9 | transfer and otherwise run, modify and propagate the contents of this 10 | implementation of Go, where such license applies only to those patent 11 | claims, both currently owned or controlled by Google and acquired in 12 | the future, licensable by Google that are necessarily infringed by this 13 | implementation of Go. This grant does not include claims that would be 14 | infringed only as a consequence of further modification of this 15 | implementation. If you or your agent or exclusive licensee institute or 16 | order or agree to the institution of patent litigation against any 17 | entity (including a cross-claim or counterclaim in a lawsuit) alleging 18 | that this implementation of Go or any code incorporated within this 19 | implementation of Go constitutes direct or contributory patent 20 | infringement, or inducement of patent infringement, then any patent 21 | rights granted to you under this License for this implementation of Go 22 | shall terminate as of the date such litigation is filed. 23 | -------------------------------------------------------------------------------- /vendor/golang.org/x/net/context/ctxhttp/cancelreq.go: -------------------------------------------------------------------------------- 1 | // Copyright 2015 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build go1.5 6 | 7 | package ctxhttp 8 | 9 | import "net/http" 10 | 11 | func canceler(client *http.Client, req *http.Request) func() { 12 | // TODO(djd): Respect any existing value of req.Cancel. 13 | ch := make(chan struct{}) 14 | req.Cancel = ch 15 | 16 | return func() { 17 | close(ch) 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /vendor/golang.org/x/net/context/ctxhttp/cancelreq_go14.go: -------------------------------------------------------------------------------- 1 | // Copyright 2015 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build !go1.5 6 | 7 | package ctxhttp 8 | 9 | import "net/http" 10 | 11 | type requestCanceler interface { 12 | CancelRequest(*http.Request) 13 | } 14 | 15 | func canceler(client *http.Client, req *http.Request) func() { 16 | rc, ok := client.Transport.(requestCanceler) 17 | if !ok { 18 | return func() {} 19 | } 20 | return func() { 21 | rc.CancelRequest(req) 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /vendor/golang.org/x/net/context/ctxhttp/ctxhttp.go: -------------------------------------------------------------------------------- 1 | // Copyright 2015 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // Package ctxhttp provides helper functions for performing context-aware HTTP requests. 6 | package ctxhttp // import "golang.org/x/net/context/ctxhttp" 7 | 8 | import ( 9 | "io" 10 | "net/http" 11 | "net/url" 12 | "strings" 13 | 14 | "golang.org/x/net/context" 15 | ) 16 | 17 | func nop() {} 18 | 19 | var ( 20 | testHookContextDoneBeforeHeaders = nop 21 | testHookDoReturned = nop 22 | testHookDidBodyClose = nop 23 | ) 24 | 25 | // Do sends an HTTP request with the provided http.Client and returns an HTTP response. 26 | // If the client is nil, http.DefaultClient is used. 27 | // If the context is canceled or times out, ctx.Err() will be returned. 28 | func Do(ctx context.Context, client *http.Client, req *http.Request) (*http.Response, error) { 29 | if client == nil { 30 | client = http.DefaultClient 31 | } 32 | 33 | // Request cancelation changed in Go 1.5, see cancelreq.go and cancelreq_go14.go. 34 | cancel := canceler(client, req) 35 | 36 | type responseAndError struct { 37 | resp *http.Response 38 | err error 39 | } 40 | result := make(chan responseAndError, 1) 41 | 42 | // Make local copies of test hooks closed over by goroutines below. 43 | // Prevents data races in tests. 44 | testHookDoReturned := testHookDoReturned 45 | testHookDidBodyClose := testHookDidBodyClose 46 | 47 | go func() { 48 | resp, err := client.Do(req) 49 | testHookDoReturned() 50 | result <- responseAndError{resp, err} 51 | }() 52 | 53 | var resp *http.Response 54 | 55 | select { 56 | case <-ctx.Done(): 57 | testHookContextDoneBeforeHeaders() 58 | cancel() 59 | // Clean up after the goroutine calling client.Do: 60 | go func() { 61 | if r := <-result; r.resp != nil { 62 | testHookDidBodyClose() 63 | r.resp.Body.Close() 64 | } 65 | }() 66 | return nil, ctx.Err() 67 | case r := <-result: 68 | var err error 69 | resp, err = r.resp, r.err 70 | if err != nil { 71 | return resp, err 72 | } 73 | } 74 | 75 | c := make(chan struct{}) 76 | go func() { 77 | select { 78 | case <-ctx.Done(): 79 | cancel() 80 | case <-c: 81 | // The response's Body is closed. 82 | } 83 | }() 84 | resp.Body = ¬ifyingReader{resp.Body, c} 85 | 86 | return resp, nil 87 | } 88 | 89 | // Get issues a GET request via the Do function. 90 | func Get(ctx context.Context, client *http.Client, url string) (*http.Response, error) { 91 | req, err := http.NewRequest("GET", url, nil) 92 | if err != nil { 93 | return nil, err 94 | } 95 | return Do(ctx, client, req) 96 | } 97 | 98 | // Head issues a HEAD request via the Do function. 99 | func Head(ctx context.Context, client *http.Client, url string) (*http.Response, error) { 100 | req, err := http.NewRequest("HEAD", url, nil) 101 | if err != nil { 102 | return nil, err 103 | } 104 | return Do(ctx, client, req) 105 | } 106 | 107 | // Post issues a POST request via the Do function. 108 | func Post(ctx context.Context, client *http.Client, url string, bodyType string, body io.Reader) (*http.Response, error) { 109 | req, err := http.NewRequest("POST", url, body) 110 | if err != nil { 111 | return nil, err 112 | } 113 | req.Header.Set("Content-Type", bodyType) 114 | return Do(ctx, client, req) 115 | } 116 | 117 | // PostForm issues a POST request via the Do function. 118 | func PostForm(ctx context.Context, client *http.Client, url string, data url.Values) (*http.Response, error) { 119 | return Post(ctx, client, url, "application/x-www-form-urlencoded", strings.NewReader(data.Encode())) 120 | } 121 | 122 | // notifyingReader is an io.ReadCloser that closes the notify channel after 123 | // Close is called or a Read fails on the underlying ReadCloser. 124 | type notifyingReader struct { 125 | io.ReadCloser 126 | notify chan<- struct{} 127 | } 128 | 129 | func (r *notifyingReader) Read(p []byte) (int, error) { 130 | n, err := r.ReadCloser.Read(p) 131 | if err != nil && r.notify != nil { 132 | close(r.notify) 133 | r.notify = nil 134 | } 135 | return n, err 136 | } 137 | 138 | func (r *notifyingReader) Close() error { 139 | err := r.ReadCloser.Close() 140 | if r.notify != nil { 141 | close(r.notify) 142 | r.notify = nil 143 | } 144 | return err 145 | } 146 | -------------------------------------------------------------------------------- /vendor/golang.org/x/net/context/go17.go: -------------------------------------------------------------------------------- 1 | // Copyright 2016 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build go1.7 6 | 7 | package context 8 | 9 | import ( 10 | "context" // standard library's context, as of Go 1.7 11 | "time" 12 | ) 13 | 14 | var ( 15 | todo = context.TODO() 16 | background = context.Background() 17 | ) 18 | 19 | // Canceled is the error returned by Context.Err when the context is canceled. 20 | var Canceled = context.Canceled 21 | 22 | // DeadlineExceeded is the error returned by Context.Err when the context's 23 | // deadline passes. 24 | var DeadlineExceeded = context.DeadlineExceeded 25 | 26 | // WithCancel returns a copy of parent with a new Done channel. The returned 27 | // context's Done channel is closed when the returned cancel function is called 28 | // or when the parent context's Done channel is closed, whichever happens first. 29 | // 30 | // Canceling this context releases resources associated with it, so code should 31 | // call cancel as soon as the operations running in this Context complete. 32 | func WithCancel(parent Context) (ctx Context, cancel CancelFunc) { 33 | ctx, f := context.WithCancel(parent) 34 | return ctx, CancelFunc(f) 35 | } 36 | 37 | // WithDeadline returns a copy of the parent context with the deadline adjusted 38 | // to be no later than d. If the parent's deadline is already earlier than d, 39 | // WithDeadline(parent, d) is semantically equivalent to parent. The returned 40 | // context's Done channel is closed when the deadline expires, when the returned 41 | // cancel function is called, or when the parent context's Done channel is 42 | // closed, whichever happens first. 43 | // 44 | // Canceling this context releases resources associated with it, so code should 45 | // call cancel as soon as the operations running in this Context complete. 46 | func WithDeadline(parent Context, deadline time.Time) (Context, CancelFunc) { 47 | ctx, f := context.WithDeadline(parent, deadline) 48 | return ctx, CancelFunc(f) 49 | } 50 | 51 | // WithTimeout returns WithDeadline(parent, time.Now().Add(timeout)). 52 | // 53 | // Canceling this context releases resources associated with it, so code should 54 | // call cancel as soon as the operations running in this Context complete: 55 | // 56 | // func slowOperationWithTimeout(ctx context.Context) (Result, error) { 57 | // ctx, cancel := context.WithTimeout(ctx, 100*time.Millisecond) 58 | // defer cancel() // releases resources if slowOperation completes before timeout elapses 59 | // return slowOperation(ctx) 60 | // } 61 | func WithTimeout(parent Context, timeout time.Duration) (Context, CancelFunc) { 62 | return WithDeadline(parent, time.Now().Add(timeout)) 63 | } 64 | 65 | // WithValue returns a copy of parent in which the value associated with key is 66 | // val. 67 | // 68 | // Use context Values only for request-scoped data that transits processes and 69 | // APIs, not for passing optional parameters to functions. 70 | func WithValue(parent Context, key interface{}, val interface{}) Context { 71 | return context.WithValue(parent, key, val) 72 | } 73 | -------------------------------------------------------------------------------- /vendor/golang.org/x/oauth2/AUTHORS: -------------------------------------------------------------------------------- 1 | # This source code refers to The Go Authors for copyright purposes. 2 | # The master list of authors is in the main Go distribution, 3 | # visible at http://tip.golang.org/AUTHORS. 4 | -------------------------------------------------------------------------------- /vendor/golang.org/x/oauth2/CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing to Go 2 | 3 | Go is an open source project. 4 | 5 | It is the work of hundreds of contributors. We appreciate your help! 6 | 7 | 8 | ## Filing issues 9 | 10 | When [filing an issue](https://github.com/golang/oauth2/issues), make sure to answer these five questions: 11 | 12 | 1. What version of Go are you using (`go version`)? 13 | 2. What operating system and processor architecture are you using? 14 | 3. What did you do? 15 | 4. What did you expect to see? 16 | 5. What did you see instead? 17 | 18 | General questions should go to the [golang-nuts mailing list](https://groups.google.com/group/golang-nuts) instead of the issue tracker. 19 | The gophers there will answer or ask you to file an issue if you've tripped over a bug. 20 | 21 | ## Contributing code 22 | 23 | Please read the [Contribution Guidelines](https://golang.org/doc/contribute.html) 24 | before sending patches. 25 | 26 | **We do not accept GitHub pull requests** 27 | (we use [Gerrit](https://code.google.com/p/gerrit/) instead for code review). 28 | 29 | Unless otherwise noted, the Go source files are distributed under 30 | the BSD-style license found in the LICENSE file. 31 | 32 | -------------------------------------------------------------------------------- /vendor/golang.org/x/oauth2/CONTRIBUTORS: -------------------------------------------------------------------------------- 1 | # This source code was written by the Go contributors. 2 | # The master list of contributors is in the main Go distribution, 3 | # visible at http://tip.golang.org/CONTRIBUTORS. 4 | -------------------------------------------------------------------------------- /vendor/golang.org/x/oauth2/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2009 The oauth2 Authors. All rights reserved. 2 | 3 | Redistribution and use in source and binary forms, with or without 4 | modification, are permitted provided that the following conditions are 5 | met: 6 | 7 | * Redistributions of source code must retain the above copyright 8 | notice, this list of conditions and the following disclaimer. 9 | * Redistributions in binary form must reproduce the above 10 | copyright notice, this list of conditions and the following disclaimer 11 | in the documentation and/or other materials provided with the 12 | distribution. 13 | * Neither the name of Google Inc. nor the names of its 14 | contributors may be used to endorse or promote products derived from 15 | this software without specific prior written permission. 16 | 17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 20 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 21 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 23 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | -------------------------------------------------------------------------------- /vendor/golang.org/x/oauth2/README.md: -------------------------------------------------------------------------------- 1 | # OAuth2 for Go 2 | 3 | [![Build Status](https://travis-ci.org/golang/oauth2.svg?branch=master)](https://travis-ci.org/golang/oauth2) 4 | 5 | oauth2 package contains a client implementation for OAuth 2.0 spec. 6 | 7 | ## Installation 8 | 9 | ~~~~ 10 | go get golang.org/x/oauth2 11 | ~~~~ 12 | 13 | See godoc for further documentation and examples. 14 | 15 | * [godoc.org/golang.org/x/oauth2](http://godoc.org/golang.org/x/oauth2) 16 | * [godoc.org/golang.org/x/oauth2/google](http://godoc.org/golang.org/x/oauth2/google) 17 | 18 | 19 | ## App Engine 20 | 21 | In change 96e89be (March 2015) we removed the `oauth2.Context2` type in favor 22 | of the [`context.Context`](https://golang.org/x/net/context#Context) type from 23 | the `golang.org/x/net/context` package 24 | 25 | This means its no longer possible to use the "Classic App Engine" 26 | `appengine.Context` type with the `oauth2` package. (You're using 27 | Classic App Engine if you import the package `"appengine"`.) 28 | 29 | To work around this, you may use the new `"google.golang.org/appengine"` 30 | package. This package has almost the same API as the `"appengine"` package, 31 | but it can be fetched with `go get` and used on "Managed VMs" and well as 32 | Classic App Engine. 33 | 34 | See the [new `appengine` package's readme](https://github.com/golang/appengine#updating-a-go-app-engine-app) 35 | for information on updating your app. 36 | 37 | If you don't want to update your entire app to use the new App Engine packages, 38 | you may use both sets of packages in parallel, using only the new packages 39 | with the `oauth2` package. 40 | 41 | import ( 42 | "golang.org/x/net/context" 43 | "golang.org/x/oauth2" 44 | "golang.org/x/oauth2/google" 45 | newappengine "google.golang.org/appengine" 46 | newurlfetch "google.golang.org/appengine/urlfetch" 47 | 48 | "appengine" 49 | ) 50 | 51 | func handler(w http.ResponseWriter, r *http.Request) { 52 | var c appengine.Context = appengine.NewContext(r) 53 | c.Infof("Logging a message with the old package") 54 | 55 | var ctx context.Context = newappengine.NewContext(r) 56 | client := &http.Client{ 57 | Transport: &oauth2.Transport{ 58 | Source: google.AppEngineTokenSource(ctx, "scope"), 59 | Base: &newurlfetch.Transport{Context: ctx}, 60 | }, 61 | } 62 | client.Get("...") 63 | } 64 | 65 | -------------------------------------------------------------------------------- /vendor/golang.org/x/oauth2/client_appengine.go: -------------------------------------------------------------------------------- 1 | // Copyright 2014 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build appengine 6 | 7 | // App Engine hooks. 8 | 9 | package oauth2 10 | 11 | import ( 12 | "net/http" 13 | 14 | "golang.org/x/net/context" 15 | "golang.org/x/oauth2/internal" 16 | "google.golang.org/appengine/urlfetch" 17 | ) 18 | 19 | func init() { 20 | internal.RegisterContextClientFunc(contextClientAppEngine) 21 | } 22 | 23 | func contextClientAppEngine(ctx context.Context) (*http.Client, error) { 24 | return urlfetch.Client(ctx), nil 25 | } 26 | -------------------------------------------------------------------------------- /vendor/golang.org/x/oauth2/google/appengine.go: -------------------------------------------------------------------------------- 1 | // Copyright 2014 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package google 6 | 7 | import ( 8 | "sort" 9 | "strings" 10 | "sync" 11 | "time" 12 | 13 | "golang.org/x/net/context" 14 | "golang.org/x/oauth2" 15 | ) 16 | 17 | // Set at init time by appenginevm_hook.go. If true, we are on App Engine Managed VMs. 18 | var appengineVM bool 19 | 20 | // Set at init time by appengine_hook.go. If nil, we're not on App Engine. 21 | var appengineTokenFunc func(c context.Context, scopes ...string) (token string, expiry time.Time, err error) 22 | 23 | // AppEngineTokenSource returns a token source that fetches tokens 24 | // issued to the current App Engine application's service account. 25 | // If you are implementing a 3-legged OAuth 2.0 flow on App Engine 26 | // that involves user accounts, see oauth2.Config instead. 27 | // 28 | // The provided context must have come from appengine.NewContext. 29 | func AppEngineTokenSource(ctx context.Context, scope ...string) oauth2.TokenSource { 30 | if appengineTokenFunc == nil { 31 | panic("google: AppEngineTokenSource can only be used on App Engine.") 32 | } 33 | scopes := append([]string{}, scope...) 34 | sort.Strings(scopes) 35 | return &appEngineTokenSource{ 36 | ctx: ctx, 37 | scopes: scopes, 38 | key: strings.Join(scopes, " "), 39 | } 40 | } 41 | 42 | // aeTokens helps the fetched tokens to be reused until their expiration. 43 | var ( 44 | aeTokensMu sync.Mutex 45 | aeTokens = make(map[string]*tokenLock) // key is space-separated scopes 46 | ) 47 | 48 | type tokenLock struct { 49 | mu sync.Mutex // guards t; held while fetching or updating t 50 | t *oauth2.Token 51 | } 52 | 53 | type appEngineTokenSource struct { 54 | ctx context.Context 55 | scopes []string 56 | key string // to aeTokens map; space-separated scopes 57 | } 58 | 59 | func (ts *appEngineTokenSource) Token() (*oauth2.Token, error) { 60 | if appengineTokenFunc == nil { 61 | panic("google: AppEngineTokenSource can only be used on App Engine.") 62 | } 63 | 64 | aeTokensMu.Lock() 65 | tok, ok := aeTokens[ts.key] 66 | if !ok { 67 | tok = &tokenLock{} 68 | aeTokens[ts.key] = tok 69 | } 70 | aeTokensMu.Unlock() 71 | 72 | tok.mu.Lock() 73 | defer tok.mu.Unlock() 74 | if tok.t.Valid() { 75 | return tok.t, nil 76 | } 77 | access, exp, err := appengineTokenFunc(ts.ctx, ts.scopes...) 78 | if err != nil { 79 | return nil, err 80 | } 81 | tok.t = &oauth2.Token{ 82 | AccessToken: access, 83 | Expiry: exp, 84 | } 85 | return tok.t, nil 86 | } 87 | -------------------------------------------------------------------------------- /vendor/golang.org/x/oauth2/google/appengine_hook.go: -------------------------------------------------------------------------------- 1 | // Copyright 2015 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build appengine 6 | 7 | package google 8 | 9 | import "google.golang.org/appengine" 10 | 11 | func init() { 12 | appengineTokenFunc = appengine.AccessToken 13 | } 14 | -------------------------------------------------------------------------------- /vendor/golang.org/x/oauth2/google/appenginevm_hook.go: -------------------------------------------------------------------------------- 1 | // Copyright 2015 The oauth2 Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build appenginevm 6 | 7 | package google 8 | 9 | import "google.golang.org/appengine" 10 | 11 | func init() { 12 | appengineVM = true 13 | appengineTokenFunc = appengine.AccessToken 14 | } 15 | -------------------------------------------------------------------------------- /vendor/golang.org/x/oauth2/google/default.go: -------------------------------------------------------------------------------- 1 | // Copyright 2015 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package google 6 | 7 | import ( 8 | "encoding/json" 9 | "errors" 10 | "fmt" 11 | "io/ioutil" 12 | "net/http" 13 | "os" 14 | "path/filepath" 15 | "runtime" 16 | 17 | "golang.org/x/net/context" 18 | "golang.org/x/oauth2" 19 | "golang.org/x/oauth2/jwt" 20 | "google.golang.org/cloud/compute/metadata" 21 | ) 22 | 23 | // DefaultClient returns an HTTP Client that uses the 24 | // DefaultTokenSource to obtain authentication credentials. 25 | // 26 | // This client should be used when developing services 27 | // that run on Google App Engine or Google Compute Engine 28 | // and use "Application Default Credentials." 29 | // 30 | // For more details, see: 31 | // https://developers.google.com/accounts/docs/application-default-credentials 32 | // 33 | func DefaultClient(ctx context.Context, scope ...string) (*http.Client, error) { 34 | ts, err := DefaultTokenSource(ctx, scope...) 35 | if err != nil { 36 | return nil, err 37 | } 38 | return oauth2.NewClient(ctx, ts), nil 39 | } 40 | 41 | // DefaultTokenSource is a token source that uses 42 | // "Application Default Credentials". 43 | // 44 | // It looks for credentials in the following places, 45 | // preferring the first location found: 46 | // 47 | // 1. A JSON file whose path is specified by the 48 | // GOOGLE_APPLICATION_CREDENTIALS environment variable. 49 | // 2. A JSON file in a location known to the gcloud command-line tool. 50 | // On Windows, this is %APPDATA%/gcloud/application_default_credentials.json. 51 | // On other systems, $HOME/.config/gcloud/application_default_credentials.json. 52 | // 3. On Google App Engine it uses the appengine.AccessToken function. 53 | // 4. On Google Compute Engine and Google App Engine Managed VMs, it fetches 54 | // credentials from the metadata server. 55 | // (In this final case any provided scopes are ignored.) 56 | // 57 | // For more details, see: 58 | // https://developers.google.com/accounts/docs/application-default-credentials 59 | // 60 | func DefaultTokenSource(ctx context.Context, scope ...string) (oauth2.TokenSource, error) { 61 | // First, try the environment variable. 62 | const envVar = "GOOGLE_APPLICATION_CREDENTIALS" 63 | if filename := os.Getenv(envVar); filename != "" { 64 | ts, err := tokenSourceFromFile(ctx, filename, scope) 65 | if err != nil { 66 | return nil, fmt.Errorf("google: error getting credentials using %v environment variable: %v", envVar, err) 67 | } 68 | return ts, nil 69 | } 70 | 71 | // Second, try a well-known file. 72 | filename := wellKnownFile() 73 | _, err := os.Stat(filename) 74 | if err == nil { 75 | ts, err2 := tokenSourceFromFile(ctx, filename, scope) 76 | if err2 == nil { 77 | return ts, nil 78 | } 79 | err = err2 80 | } else if os.IsNotExist(err) { 81 | err = nil // ignore this error 82 | } 83 | if err != nil { 84 | return nil, fmt.Errorf("google: error getting credentials using well-known file (%v): %v", filename, err) 85 | } 86 | 87 | // Third, if we're on Google App Engine use those credentials. 88 | if appengineTokenFunc != nil && !appengineVM { 89 | return AppEngineTokenSource(ctx, scope...), nil 90 | } 91 | 92 | // Fourth, if we're on Google Compute Engine use the metadata server. 93 | if metadata.OnGCE() { 94 | return ComputeTokenSource(""), nil 95 | } 96 | 97 | // None are found; return helpful error. 98 | const url = "https://developers.google.com/accounts/docs/application-default-credentials" 99 | return nil, fmt.Errorf("google: could not find default credentials. See %v for more information.", url) 100 | } 101 | 102 | func wellKnownFile() string { 103 | const f = "application_default_credentials.json" 104 | if runtime.GOOS == "windows" { 105 | return filepath.Join(os.Getenv("APPDATA"), "gcloud", f) 106 | } 107 | return filepath.Join(guessUnixHomeDir(), ".config", "gcloud", f) 108 | } 109 | 110 | func tokenSourceFromFile(ctx context.Context, filename string, scopes []string) (oauth2.TokenSource, error) { 111 | b, err := ioutil.ReadFile(filename) 112 | if err != nil { 113 | return nil, err 114 | } 115 | var d struct { 116 | // Common fields 117 | Type string 118 | ClientID string `json:"client_id"` 119 | 120 | // User Credential fields 121 | ClientSecret string `json:"client_secret"` 122 | RefreshToken string `json:"refresh_token"` 123 | 124 | // Service Account fields 125 | ClientEmail string `json:"client_email"` 126 | PrivateKeyID string `json:"private_key_id"` 127 | PrivateKey string `json:"private_key"` 128 | } 129 | if err := json.Unmarshal(b, &d); err != nil { 130 | return nil, err 131 | } 132 | switch d.Type { 133 | case "authorized_user": 134 | cfg := &oauth2.Config{ 135 | ClientID: d.ClientID, 136 | ClientSecret: d.ClientSecret, 137 | Scopes: append([]string{}, scopes...), // copy 138 | Endpoint: Endpoint, 139 | } 140 | tok := &oauth2.Token{RefreshToken: d.RefreshToken} 141 | return cfg.TokenSource(ctx, tok), nil 142 | case "service_account": 143 | cfg := &jwt.Config{ 144 | Email: d.ClientEmail, 145 | PrivateKey: []byte(d.PrivateKey), 146 | Scopes: append([]string{}, scopes...), // copy 147 | TokenURL: JWTTokenURL, 148 | } 149 | return cfg.TokenSource(ctx), nil 150 | case "": 151 | return nil, errors.New("missing 'type' field in credentials") 152 | default: 153 | return nil, fmt.Errorf("unknown credential type: %q", d.Type) 154 | } 155 | } 156 | -------------------------------------------------------------------------------- /vendor/golang.org/x/oauth2/google/google.go: -------------------------------------------------------------------------------- 1 | // Copyright 2014 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // Package google provides support for making OAuth2 authorized and 6 | // authenticated HTTP requests to Google APIs. 7 | // It supports the Web server flow, client-side credentials, service accounts, 8 | // Google Compute Engine service accounts, and Google App Engine service 9 | // accounts. 10 | // 11 | // For more information, please read 12 | // https://developers.google.com/accounts/docs/OAuth2 13 | // and 14 | // https://developers.google.com/accounts/docs/application-default-credentials. 15 | package google // import "golang.org/x/oauth2/google" 16 | 17 | import ( 18 | "encoding/json" 19 | "errors" 20 | "fmt" 21 | "strings" 22 | "time" 23 | 24 | "golang.org/x/oauth2" 25 | "golang.org/x/oauth2/jwt" 26 | "google.golang.org/cloud/compute/metadata" 27 | ) 28 | 29 | // Endpoint is Google's OAuth 2.0 endpoint. 30 | var Endpoint = oauth2.Endpoint{ 31 | AuthURL: "https://accounts.google.com/o/oauth2/auth", 32 | TokenURL: "https://accounts.google.com/o/oauth2/token", 33 | } 34 | 35 | // JWTTokenURL is Google's OAuth 2.0 token URL to use with the JWT flow. 36 | const JWTTokenURL = "https://accounts.google.com/o/oauth2/token" 37 | 38 | // ConfigFromJSON uses a Google Developers Console client_credentials.json 39 | // file to construct a config. 40 | // client_credentials.json can be downloadable from https://console.developers.google.com, 41 | // under "APIs & Auth" > "Credentials". Download the Web application credentials in the 42 | // JSON format and provide the contents of the file as jsonKey. 43 | func ConfigFromJSON(jsonKey []byte, scope ...string) (*oauth2.Config, error) { 44 | type cred struct { 45 | ClientID string `json:"client_id"` 46 | ClientSecret string `json:"client_secret"` 47 | RedirectURIs []string `json:"redirect_uris"` 48 | AuthURI string `json:"auth_uri"` 49 | TokenURI string `json:"token_uri"` 50 | } 51 | var j struct { 52 | Web *cred `json:"web"` 53 | Installed *cred `json:"installed"` 54 | } 55 | if err := json.Unmarshal(jsonKey, &j); err != nil { 56 | return nil, err 57 | } 58 | var c *cred 59 | switch { 60 | case j.Web != nil: 61 | c = j.Web 62 | case j.Installed != nil: 63 | c = j.Installed 64 | default: 65 | return nil, fmt.Errorf("oauth2/google: no credentials found") 66 | } 67 | if len(c.RedirectURIs) < 1 { 68 | return nil, errors.New("oauth2/google: missing redirect URL in the client_credentials.json") 69 | } 70 | return &oauth2.Config{ 71 | ClientID: c.ClientID, 72 | ClientSecret: c.ClientSecret, 73 | RedirectURL: c.RedirectURIs[0], 74 | Scopes: scope, 75 | Endpoint: oauth2.Endpoint{ 76 | AuthURL: c.AuthURI, 77 | TokenURL: c.TokenURI, 78 | }, 79 | }, nil 80 | } 81 | 82 | // JWTConfigFromJSON uses a Google Developers service account JSON key file to read 83 | // the credentials that authorize and authenticate the requests. 84 | // Create a service account on "Credentials" page under "APIs & Auth" for your 85 | // project at https://console.developers.google.com to download a JSON key file. 86 | func JWTConfigFromJSON(jsonKey []byte, scope ...string) (*jwt.Config, error) { 87 | var key struct { 88 | Email string `json:"client_email"` 89 | PrivateKey string `json:"private_key"` 90 | } 91 | if err := json.Unmarshal(jsonKey, &key); err != nil { 92 | return nil, err 93 | } 94 | return &jwt.Config{ 95 | Email: key.Email, 96 | PrivateKey: []byte(key.PrivateKey), 97 | Scopes: scope, 98 | TokenURL: JWTTokenURL, 99 | }, nil 100 | } 101 | 102 | // ComputeTokenSource returns a token source that fetches access tokens 103 | // from Google Compute Engine (GCE)'s metadata server. It's only valid to use 104 | // this token source if your program is running on a GCE instance. 105 | // If no account is specified, "default" is used. 106 | // Further information about retrieving access tokens from the GCE metadata 107 | // server can be found at https://cloud.google.com/compute/docs/authentication. 108 | func ComputeTokenSource(account string) oauth2.TokenSource { 109 | return oauth2.ReuseTokenSource(nil, computeSource{account: account}) 110 | } 111 | 112 | type computeSource struct { 113 | account string 114 | } 115 | 116 | func (cs computeSource) Token() (*oauth2.Token, error) { 117 | if !metadata.OnGCE() { 118 | return nil, errors.New("oauth2/google: can't get a token from the metadata service; not running on GCE") 119 | } 120 | acct := cs.account 121 | if acct == "" { 122 | acct = "default" 123 | } 124 | tokenJSON, err := metadata.Get("instance/service-accounts/" + acct + "/token") 125 | if err != nil { 126 | return nil, err 127 | } 128 | var res struct { 129 | AccessToken string `json:"access_token"` 130 | ExpiresInSec int `json:"expires_in"` 131 | TokenType string `json:"token_type"` 132 | } 133 | err = json.NewDecoder(strings.NewReader(tokenJSON)).Decode(&res) 134 | if err != nil { 135 | return nil, fmt.Errorf("oauth2/google: invalid token JSON from metadata: %v", err) 136 | } 137 | if res.ExpiresInSec == 0 || res.AccessToken == "" { 138 | return nil, fmt.Errorf("oauth2/google: incomplete token received from metadata") 139 | } 140 | return &oauth2.Token{ 141 | AccessToken: res.AccessToken, 142 | TokenType: res.TokenType, 143 | Expiry: time.Now().Add(time.Duration(res.ExpiresInSec) * time.Second), 144 | }, nil 145 | } 146 | -------------------------------------------------------------------------------- /vendor/golang.org/x/oauth2/google/jwt.go: -------------------------------------------------------------------------------- 1 | // Copyright 2015 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package google 6 | 7 | import ( 8 | "crypto/rsa" 9 | "fmt" 10 | "time" 11 | 12 | "golang.org/x/oauth2" 13 | "golang.org/x/oauth2/internal" 14 | "golang.org/x/oauth2/jws" 15 | ) 16 | 17 | // JWTAccessTokenSourceFromJSON uses a Google Developers service account JSON 18 | // key file to read the credentials that authorize and authenticate the 19 | // requests, and returns a TokenSource that does not use any OAuth2 flow but 20 | // instead creates a JWT and sends that as the access token. 21 | // The audience is typically a URL that specifies the scope of the credentials. 22 | // 23 | // Note that this is not a standard OAuth flow, but rather an 24 | // optimization supported by a few Google services. 25 | // Unless you know otherwise, you should use JWTConfigFromJSON instead. 26 | func JWTAccessTokenSourceFromJSON(jsonKey []byte, audience string) (oauth2.TokenSource, error) { 27 | cfg, err := JWTConfigFromJSON(jsonKey) 28 | if err != nil { 29 | return nil, fmt.Errorf("google: could not parse JSON key: %v", err) 30 | } 31 | pk, err := internal.ParseKey(cfg.PrivateKey) 32 | if err != nil { 33 | return nil, fmt.Errorf("google: could not parse key: %v", err) 34 | } 35 | ts := &jwtAccessTokenSource{ 36 | email: cfg.Email, 37 | audience: audience, 38 | pk: pk, 39 | } 40 | tok, err := ts.Token() 41 | if err != nil { 42 | return nil, err 43 | } 44 | return oauth2.ReuseTokenSource(tok, ts), nil 45 | } 46 | 47 | type jwtAccessTokenSource struct { 48 | email, audience string 49 | pk *rsa.PrivateKey 50 | } 51 | 52 | func (ts *jwtAccessTokenSource) Token() (*oauth2.Token, error) { 53 | iat := time.Now() 54 | exp := iat.Add(time.Hour) 55 | cs := &jws.ClaimSet{ 56 | Iss: ts.email, 57 | Sub: ts.email, 58 | Aud: ts.audience, 59 | Iat: iat.Unix(), 60 | Exp: exp.Unix(), 61 | } 62 | hdr := &jws.Header{ 63 | Algorithm: "RS256", 64 | Typ: "JWT", 65 | } 66 | msg, err := jws.Encode(hdr, cs, ts.pk) 67 | if err != nil { 68 | return nil, fmt.Errorf("google: could not encode JWT: %v", err) 69 | } 70 | return &oauth2.Token{AccessToken: msg, TokenType: "Bearer", Expiry: exp}, nil 71 | } 72 | -------------------------------------------------------------------------------- /vendor/golang.org/x/oauth2/google/sdk.go: -------------------------------------------------------------------------------- 1 | // Copyright 2015 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package google 6 | 7 | import ( 8 | "encoding/json" 9 | "errors" 10 | "fmt" 11 | "net/http" 12 | "os" 13 | "os/user" 14 | "path/filepath" 15 | "runtime" 16 | "strings" 17 | "time" 18 | 19 | "golang.org/x/net/context" 20 | "golang.org/x/oauth2" 21 | "golang.org/x/oauth2/internal" 22 | ) 23 | 24 | type sdkCredentials struct { 25 | Data []struct { 26 | Credential struct { 27 | ClientID string `json:"client_id"` 28 | ClientSecret string `json:"client_secret"` 29 | AccessToken string `json:"access_token"` 30 | RefreshToken string `json:"refresh_token"` 31 | TokenExpiry *time.Time `json:"token_expiry"` 32 | } `json:"credential"` 33 | Key struct { 34 | Account string `json:"account"` 35 | Scope string `json:"scope"` 36 | } `json:"key"` 37 | } 38 | } 39 | 40 | // An SDKConfig provides access to tokens from an account already 41 | // authorized via the Google Cloud SDK. 42 | type SDKConfig struct { 43 | conf oauth2.Config 44 | initialToken *oauth2.Token 45 | } 46 | 47 | // NewSDKConfig creates an SDKConfig for the given Google Cloud SDK 48 | // account. If account is empty, the account currently active in 49 | // Google Cloud SDK properties is used. 50 | // Google Cloud SDK credentials must be created by running `gcloud auth` 51 | // before using this function. 52 | // The Google Cloud SDK is available at https://cloud.google.com/sdk/. 53 | func NewSDKConfig(account string) (*SDKConfig, error) { 54 | configPath, err := sdkConfigPath() 55 | if err != nil { 56 | return nil, fmt.Errorf("oauth2/google: error getting SDK config path: %v", err) 57 | } 58 | credentialsPath := filepath.Join(configPath, "credentials") 59 | f, err := os.Open(credentialsPath) 60 | if err != nil { 61 | return nil, fmt.Errorf("oauth2/google: failed to load SDK credentials: %v", err) 62 | } 63 | defer f.Close() 64 | 65 | var c sdkCredentials 66 | if err := json.NewDecoder(f).Decode(&c); err != nil { 67 | return nil, fmt.Errorf("oauth2/google: failed to decode SDK credentials from %q: %v", credentialsPath, err) 68 | } 69 | if len(c.Data) == 0 { 70 | return nil, fmt.Errorf("oauth2/google: no credentials found in %q, run `gcloud auth login` to create one", credentialsPath) 71 | } 72 | if account == "" { 73 | propertiesPath := filepath.Join(configPath, "properties") 74 | f, err := os.Open(propertiesPath) 75 | if err != nil { 76 | return nil, fmt.Errorf("oauth2/google: failed to load SDK properties: %v", err) 77 | } 78 | defer f.Close() 79 | ini, err := internal.ParseINI(f) 80 | if err != nil { 81 | return nil, fmt.Errorf("oauth2/google: failed to parse SDK properties %q: %v", propertiesPath, err) 82 | } 83 | core, ok := ini["core"] 84 | if !ok { 85 | return nil, fmt.Errorf("oauth2/google: failed to find [core] section in %v", ini) 86 | } 87 | active, ok := core["account"] 88 | if !ok { 89 | return nil, fmt.Errorf("oauth2/google: failed to find %q attribute in %v", "account", core) 90 | } 91 | account = active 92 | } 93 | 94 | for _, d := range c.Data { 95 | if account == "" || d.Key.Account == account { 96 | if d.Credential.AccessToken == "" && d.Credential.RefreshToken == "" { 97 | return nil, fmt.Errorf("oauth2/google: no token available for account %q", account) 98 | } 99 | var expiry time.Time 100 | if d.Credential.TokenExpiry != nil { 101 | expiry = *d.Credential.TokenExpiry 102 | } 103 | return &SDKConfig{ 104 | conf: oauth2.Config{ 105 | ClientID: d.Credential.ClientID, 106 | ClientSecret: d.Credential.ClientSecret, 107 | Scopes: strings.Split(d.Key.Scope, " "), 108 | Endpoint: Endpoint, 109 | RedirectURL: "oob", 110 | }, 111 | initialToken: &oauth2.Token{ 112 | AccessToken: d.Credential.AccessToken, 113 | RefreshToken: d.Credential.RefreshToken, 114 | Expiry: expiry, 115 | }, 116 | }, nil 117 | } 118 | } 119 | return nil, fmt.Errorf("oauth2/google: no such credentials for account %q", account) 120 | } 121 | 122 | // Client returns an HTTP client using Google Cloud SDK credentials to 123 | // authorize requests. The token will auto-refresh as necessary. The 124 | // underlying http.RoundTripper will be obtained using the provided 125 | // context. The returned client and its Transport should not be 126 | // modified. 127 | func (c *SDKConfig) Client(ctx context.Context) *http.Client { 128 | return &http.Client{ 129 | Transport: &oauth2.Transport{ 130 | Source: c.TokenSource(ctx), 131 | }, 132 | } 133 | } 134 | 135 | // TokenSource returns an oauth2.TokenSource that retrieve tokens from 136 | // Google Cloud SDK credentials using the provided context. 137 | // It will returns the current access token stored in the credentials, 138 | // and refresh it when it expires, but it won't update the credentials 139 | // with the new access token. 140 | func (c *SDKConfig) TokenSource(ctx context.Context) oauth2.TokenSource { 141 | return c.conf.TokenSource(ctx, c.initialToken) 142 | } 143 | 144 | // Scopes are the OAuth 2.0 scopes the current account is authorized for. 145 | func (c *SDKConfig) Scopes() []string { 146 | return c.conf.Scopes 147 | } 148 | 149 | // sdkConfigPath tries to guess where the gcloud config is located. 150 | // It can be overridden during tests. 151 | var sdkConfigPath = func() (string, error) { 152 | if runtime.GOOS == "windows" { 153 | return filepath.Join(os.Getenv("APPDATA"), "gcloud"), nil 154 | } 155 | homeDir := guessUnixHomeDir() 156 | if homeDir == "" { 157 | return "", errors.New("unable to get current user home directory: os/user lookup failed; $HOME is empty") 158 | } 159 | return filepath.Join(homeDir, ".config", "gcloud"), nil 160 | } 161 | 162 | func guessUnixHomeDir() string { 163 | usr, err := user.Current() 164 | if err == nil { 165 | return usr.HomeDir 166 | } 167 | return os.Getenv("HOME") 168 | } 169 | -------------------------------------------------------------------------------- /vendor/golang.org/x/oauth2/internal/oauth2.go: -------------------------------------------------------------------------------- 1 | // Copyright 2014 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // Package internal contains support packages for oauth2 package. 6 | package internal 7 | 8 | import ( 9 | "bufio" 10 | "crypto/rsa" 11 | "crypto/x509" 12 | "encoding/pem" 13 | "errors" 14 | "fmt" 15 | "io" 16 | "strings" 17 | ) 18 | 19 | // ParseKey converts the binary contents of a private key file 20 | // to an *rsa.PrivateKey. It detects whether the private key is in a 21 | // PEM container or not. If so, it extracts the the private key 22 | // from PEM container before conversion. It only supports PEM 23 | // containers with no passphrase. 24 | func ParseKey(key []byte) (*rsa.PrivateKey, error) { 25 | block, _ := pem.Decode(key) 26 | if block != nil { 27 | key = block.Bytes 28 | } 29 | parsedKey, err := x509.ParsePKCS8PrivateKey(key) 30 | if err != nil { 31 | parsedKey, err = x509.ParsePKCS1PrivateKey(key) 32 | if err != nil { 33 | return nil, fmt.Errorf("private key should be a PEM or plain PKSC1 or PKCS8; parse error: %v", err) 34 | } 35 | } 36 | parsed, ok := parsedKey.(*rsa.PrivateKey) 37 | if !ok { 38 | return nil, errors.New("private key is invalid") 39 | } 40 | return parsed, nil 41 | } 42 | 43 | func ParseINI(ini io.Reader) (map[string]map[string]string, error) { 44 | result := map[string]map[string]string{ 45 | "": map[string]string{}, // root section 46 | } 47 | scanner := bufio.NewScanner(ini) 48 | currentSection := "" 49 | for scanner.Scan() { 50 | line := strings.TrimSpace(scanner.Text()) 51 | if strings.HasPrefix(line, ";") { 52 | // comment. 53 | continue 54 | } 55 | if strings.HasPrefix(line, "[") && strings.HasSuffix(line, "]") { 56 | currentSection = strings.TrimSpace(line[1 : len(line)-1]) 57 | result[currentSection] = map[string]string{} 58 | continue 59 | } 60 | parts := strings.SplitN(line, "=", 2) 61 | if len(parts) == 2 && parts[0] != "" { 62 | result[currentSection][strings.TrimSpace(parts[0])] = strings.TrimSpace(parts[1]) 63 | } 64 | } 65 | if err := scanner.Err(); err != nil { 66 | return nil, fmt.Errorf("error scanning ini: %v", err) 67 | } 68 | return result, nil 69 | } 70 | 71 | func CondVal(v string) []string { 72 | if v == "" { 73 | return nil 74 | } 75 | return []string{v} 76 | } 77 | -------------------------------------------------------------------------------- /vendor/golang.org/x/oauth2/internal/transport.go: -------------------------------------------------------------------------------- 1 | // Copyright 2014 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // Package internal contains support packages for oauth2 package. 6 | package internal 7 | 8 | import ( 9 | "net/http" 10 | 11 | "golang.org/x/net/context" 12 | ) 13 | 14 | // HTTPClient is the context key to use with golang.org/x/net/context's 15 | // WithValue function to associate an *http.Client value with a context. 16 | var HTTPClient ContextKey 17 | 18 | // ContextKey is just an empty struct. It exists so HTTPClient can be 19 | // an immutable public variable with a unique type. It's immutable 20 | // because nobody else can create a ContextKey, being unexported. 21 | type ContextKey struct{} 22 | 23 | // ContextClientFunc is a func which tries to return an *http.Client 24 | // given a Context value. If it returns an error, the search stops 25 | // with that error. If it returns (nil, nil), the search continues 26 | // down the list of registered funcs. 27 | type ContextClientFunc func(context.Context) (*http.Client, error) 28 | 29 | var contextClientFuncs []ContextClientFunc 30 | 31 | func RegisterContextClientFunc(fn ContextClientFunc) { 32 | contextClientFuncs = append(contextClientFuncs, fn) 33 | } 34 | 35 | func ContextClient(ctx context.Context) (*http.Client, error) { 36 | if ctx != nil { 37 | if hc, ok := ctx.Value(HTTPClient).(*http.Client); ok { 38 | return hc, nil 39 | } 40 | } 41 | for _, fn := range contextClientFuncs { 42 | c, err := fn(ctx) 43 | if err != nil { 44 | return nil, err 45 | } 46 | if c != nil { 47 | return c, nil 48 | } 49 | } 50 | return http.DefaultClient, nil 51 | } 52 | 53 | func ContextTransport(ctx context.Context) http.RoundTripper { 54 | hc, err := ContextClient(ctx) 55 | // This is a rare error case (somebody using nil on App Engine). 56 | if err != nil { 57 | return ErrorTransport{err} 58 | } 59 | return hc.Transport 60 | } 61 | 62 | // ErrorTransport returns the specified error on RoundTrip. 63 | // This RoundTripper should be used in rare error cases where 64 | // error handling can be postponed to response handling time. 65 | type ErrorTransport struct{ Err error } 66 | 67 | func (t ErrorTransport) RoundTrip(*http.Request) (*http.Response, error) { 68 | return nil, t.Err 69 | } 70 | -------------------------------------------------------------------------------- /vendor/golang.org/x/oauth2/jws/jws.go: -------------------------------------------------------------------------------- 1 | // Copyright 2014 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // Package jws provides encoding and decoding utilities for 6 | // signed JWS messages. 7 | package jws // import "golang.org/x/oauth2/jws" 8 | 9 | import ( 10 | "bytes" 11 | "crypto" 12 | "crypto/rand" 13 | "crypto/rsa" 14 | "crypto/sha256" 15 | "encoding/base64" 16 | "encoding/json" 17 | "errors" 18 | "fmt" 19 | "strings" 20 | "time" 21 | ) 22 | 23 | // ClaimSet contains information about the JWT signature including the 24 | // permissions being requested (scopes), the target of the token, the issuer, 25 | // the time the token was issued, and the lifetime of the token. 26 | type ClaimSet struct { 27 | Iss string `json:"iss"` // email address of the client_id of the application making the access token request 28 | Scope string `json:"scope,omitempty"` // space-delimited list of the permissions the application requests 29 | Aud string `json:"aud"` // descriptor of the intended target of the assertion (Optional). 30 | Exp int64 `json:"exp"` // the expiration time of the assertion (seconds since Unix epoch) 31 | Iat int64 `json:"iat"` // the time the assertion was issued (seconds since Unix epoch) 32 | Typ string `json:"typ,omitempty"` // token type (Optional). 33 | 34 | // Email for which the application is requesting delegated access (Optional). 35 | Sub string `json:"sub,omitempty"` 36 | 37 | // The old name of Sub. Client keeps setting Prn to be 38 | // complaint with legacy OAuth 2.0 providers. (Optional) 39 | Prn string `json:"prn,omitempty"` 40 | 41 | // See http://tools.ietf.org/html/draft-jones-json-web-token-10#section-4.3 42 | // This array is marshalled using custom code (see (c *ClaimSet) encode()). 43 | PrivateClaims map[string]interface{} `json:"-"` 44 | } 45 | 46 | func (c *ClaimSet) encode() (string, error) { 47 | // Reverting time back for machines whose time is not perfectly in sync. 48 | // If client machine's time is in the future according 49 | // to Google servers, an access token will not be issued. 50 | now := time.Now().Add(-10 * time.Second) 51 | if c.Iat == 0 { 52 | c.Iat = now.Unix() 53 | } 54 | if c.Exp == 0 { 55 | c.Exp = now.Add(time.Hour).Unix() 56 | } 57 | if c.Exp < c.Iat { 58 | return "", fmt.Errorf("jws: invalid Exp = %v; must be later than Iat = %v", c.Exp, c.Iat) 59 | } 60 | 61 | b, err := json.Marshal(c) 62 | if err != nil { 63 | return "", err 64 | } 65 | 66 | if len(c.PrivateClaims) == 0 { 67 | return base64Encode(b), nil 68 | } 69 | 70 | // Marshal private claim set and then append it to b. 71 | prv, err := json.Marshal(c.PrivateClaims) 72 | if err != nil { 73 | return "", fmt.Errorf("jws: invalid map of private claims %v", c.PrivateClaims) 74 | } 75 | 76 | // Concatenate public and private claim JSON objects. 77 | if !bytes.HasSuffix(b, []byte{'}'}) { 78 | return "", fmt.Errorf("jws: invalid JSON %s", b) 79 | } 80 | if !bytes.HasPrefix(prv, []byte{'{'}) { 81 | return "", fmt.Errorf("jws: invalid JSON %s", prv) 82 | } 83 | b[len(b)-1] = ',' // Replace closing curly brace with a comma. 84 | b = append(b, prv[1:]...) // Append private claims. 85 | return base64Encode(b), nil 86 | } 87 | 88 | // Header represents the header for the signed JWS payloads. 89 | type Header struct { 90 | // The algorithm used for signature. 91 | Algorithm string `json:"alg"` 92 | 93 | // Represents the token type. 94 | Typ string `json:"typ"` 95 | } 96 | 97 | func (h *Header) encode() (string, error) { 98 | b, err := json.Marshal(h) 99 | if err != nil { 100 | return "", err 101 | } 102 | return base64Encode(b), nil 103 | } 104 | 105 | // Decode decodes a claim set from a JWS payload. 106 | func Decode(payload string) (*ClaimSet, error) { 107 | // decode returned id token to get expiry 108 | s := strings.Split(payload, ".") 109 | if len(s) < 2 { 110 | // TODO(jbd): Provide more context about the error. 111 | return nil, errors.New("jws: invalid token received") 112 | } 113 | decoded, err := base64Decode(s[1]) 114 | if err != nil { 115 | return nil, err 116 | } 117 | c := &ClaimSet{} 118 | err = json.NewDecoder(bytes.NewBuffer(decoded)).Decode(c) 119 | return c, err 120 | } 121 | 122 | // Signer returns a signature for the given data. 123 | type Signer func(data []byte) (sig []byte, err error) 124 | 125 | // EncodeWithSigner encodes a header and claim set with the provided signer. 126 | func EncodeWithSigner(header *Header, c *ClaimSet, sg Signer) (string, error) { 127 | head, err := header.encode() 128 | if err != nil { 129 | return "", err 130 | } 131 | cs, err := c.encode() 132 | if err != nil { 133 | return "", err 134 | } 135 | ss := fmt.Sprintf("%s.%s", head, cs) 136 | sig, err := sg([]byte(ss)) 137 | if err != nil { 138 | return "", err 139 | } 140 | return fmt.Sprintf("%s.%s", ss, base64Encode(sig)), nil 141 | } 142 | 143 | // Encode encodes a signed JWS with provided header and claim set. 144 | // This invokes EncodeWithSigner using crypto/rsa.SignPKCS1v15 with the given RSA private key. 145 | func Encode(header *Header, c *ClaimSet, key *rsa.PrivateKey) (string, error) { 146 | sg := func(data []byte) (sig []byte, err error) { 147 | h := sha256.New() 148 | h.Write([]byte(data)) 149 | return rsa.SignPKCS1v15(rand.Reader, key, crypto.SHA256, h.Sum(nil)) 150 | } 151 | return EncodeWithSigner(header, c, sg) 152 | } 153 | 154 | // base64Encode returns and Base64url encoded version of the input string with any 155 | // trailing "=" stripped. 156 | func base64Encode(b []byte) string { 157 | return strings.TrimRight(base64.URLEncoding.EncodeToString(b), "=") 158 | } 159 | 160 | // base64Decode decodes the Base64url encoded string 161 | func base64Decode(s string) ([]byte, error) { 162 | // add back missing padding 163 | switch len(s) % 4 { 164 | case 1: 165 | s += "===" 166 | case 2: 167 | s += "==" 168 | case 3: 169 | s += "=" 170 | } 171 | return base64.URLEncoding.DecodeString(s) 172 | } 173 | -------------------------------------------------------------------------------- /vendor/golang.org/x/oauth2/jwt/jwt.go: -------------------------------------------------------------------------------- 1 | // Copyright 2014 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // Package jwt implements the OAuth 2.0 JSON Web Token flow, commonly 6 | // known as "two-legged OAuth 2.0". 7 | // 8 | // See: https://tools.ietf.org/html/draft-ietf-oauth-jwt-bearer-12 9 | package jwt 10 | 11 | import ( 12 | "encoding/json" 13 | "fmt" 14 | "io" 15 | "io/ioutil" 16 | "net/http" 17 | "net/url" 18 | "strings" 19 | "time" 20 | 21 | "golang.org/x/net/context" 22 | "golang.org/x/oauth2" 23 | "golang.org/x/oauth2/internal" 24 | "golang.org/x/oauth2/jws" 25 | ) 26 | 27 | var ( 28 | defaultGrantType = "urn:ietf:params:oauth:grant-type:jwt-bearer" 29 | defaultHeader = &jws.Header{Algorithm: "RS256", Typ: "JWT"} 30 | ) 31 | 32 | // Config is the configuration for using JWT to fetch tokens, 33 | // commonly known as "two-legged OAuth 2.0". 34 | type Config struct { 35 | // Email is the OAuth client identifier used when communicating with 36 | // the configured OAuth provider. 37 | Email string 38 | 39 | // PrivateKey contains the contents of an RSA private key or the 40 | // contents of a PEM file that contains a private key. The provided 41 | // private key is used to sign JWT payloads. 42 | // PEM containers with a passphrase are not supported. 43 | // Use the following command to convert a PKCS 12 file into a PEM. 44 | // 45 | // $ openssl pkcs12 -in key.p12 -out key.pem -nodes 46 | // 47 | PrivateKey []byte 48 | 49 | // Subject is the optional user to impersonate. 50 | Subject string 51 | 52 | // Scopes optionally specifies a list of requested permission scopes. 53 | Scopes []string 54 | 55 | // TokenURL is the endpoint required to complete the 2-legged JWT flow. 56 | TokenURL string 57 | 58 | // Expires optionally specifies how long the token is valid for. 59 | Expires time.Duration 60 | } 61 | 62 | // TokenSource returns a JWT TokenSource using the configuration 63 | // in c and the HTTP client from the provided context. 64 | func (c *Config) TokenSource(ctx context.Context) oauth2.TokenSource { 65 | return oauth2.ReuseTokenSource(nil, jwtSource{ctx, c}) 66 | } 67 | 68 | // Client returns an HTTP client wrapping the context's 69 | // HTTP transport and adding Authorization headers with tokens 70 | // obtained from c. 71 | // 72 | // The returned client and its Transport should not be modified. 73 | func (c *Config) Client(ctx context.Context) *http.Client { 74 | return oauth2.NewClient(ctx, c.TokenSource(ctx)) 75 | } 76 | 77 | // jwtSource is a source that always does a signed JWT request for a token. 78 | // It should typically be wrapped with a reuseTokenSource. 79 | type jwtSource struct { 80 | ctx context.Context 81 | conf *Config 82 | } 83 | 84 | func (js jwtSource) Token() (*oauth2.Token, error) { 85 | pk, err := internal.ParseKey(js.conf.PrivateKey) 86 | if err != nil { 87 | return nil, err 88 | } 89 | hc := oauth2.NewClient(js.ctx, nil) 90 | claimSet := &jws.ClaimSet{ 91 | Iss: js.conf.Email, 92 | Scope: strings.Join(js.conf.Scopes, " "), 93 | Aud: js.conf.TokenURL, 94 | } 95 | if subject := js.conf.Subject; subject != "" { 96 | claimSet.Sub = subject 97 | // prn is the old name of sub. Keep setting it 98 | // to be compatible with legacy OAuth 2.0 providers. 99 | claimSet.Prn = subject 100 | } 101 | if t := js.conf.Expires; t > 0 { 102 | claimSet.Exp = time.Now().Add(t).Unix() 103 | } 104 | payload, err := jws.Encode(defaultHeader, claimSet, pk) 105 | if err != nil { 106 | return nil, err 107 | } 108 | v := url.Values{} 109 | v.Set("grant_type", defaultGrantType) 110 | v.Set("assertion", payload) 111 | resp, err := hc.PostForm(js.conf.TokenURL, v) 112 | if err != nil { 113 | return nil, fmt.Errorf("oauth2: cannot fetch token: %v", err) 114 | } 115 | defer resp.Body.Close() 116 | body, err := ioutil.ReadAll(io.LimitReader(resp.Body, 1<<20)) 117 | if err != nil { 118 | return nil, fmt.Errorf("oauth2: cannot fetch token: %v", err) 119 | } 120 | if c := resp.StatusCode; c < 200 || c > 299 { 121 | return nil, fmt.Errorf("oauth2: cannot fetch token: %v\nResponse: %s", resp.Status, body) 122 | } 123 | // tokenRes is the JSON response body. 124 | var tokenRes struct { 125 | AccessToken string `json:"access_token"` 126 | TokenType string `json:"token_type"` 127 | IDToken string `json:"id_token"` 128 | ExpiresIn int64 `json:"expires_in"` // relative seconds from now 129 | } 130 | if err := json.Unmarshal(body, &tokenRes); err != nil { 131 | return nil, fmt.Errorf("oauth2: cannot fetch token: %v", err) 132 | } 133 | token := &oauth2.Token{ 134 | AccessToken: tokenRes.AccessToken, 135 | TokenType: tokenRes.TokenType, 136 | } 137 | raw := make(map[string]interface{}) 138 | json.Unmarshal(body, &raw) // no error checks for optional fields 139 | token = token.WithExtra(raw) 140 | 141 | if secs := tokenRes.ExpiresIn; secs > 0 { 142 | token.Expiry = time.Now().Add(time.Duration(secs) * time.Second) 143 | } 144 | if v := tokenRes.IDToken; v != "" { 145 | // decode returned id token to get expiry 146 | claimSet, err := jws.Decode(v) 147 | if err != nil { 148 | return nil, fmt.Errorf("oauth2: error decoding JWT token: %v", err) 149 | } 150 | token.Expiry = time.Unix(claimSet.Exp, 0) 151 | } 152 | return token, nil 153 | } 154 | -------------------------------------------------------------------------------- /vendor/golang.org/x/oauth2/token.go: -------------------------------------------------------------------------------- 1 | // Copyright 2014 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package oauth2 6 | 7 | import ( 8 | "net/http" 9 | "net/url" 10 | "strconv" 11 | "strings" 12 | "time" 13 | 14 | "golang.org/x/net/context" 15 | "golang.org/x/oauth2/internal" 16 | ) 17 | 18 | // expiryDelta determines how earlier a token should be considered 19 | // expired than its actual expiration time. It is used to avoid late 20 | // expirations due to client-server time mismatches. 21 | const expiryDelta = 10 * time.Second 22 | 23 | // Token represents the crendentials used to authorize 24 | // the requests to access protected resources on the OAuth 2.0 25 | // provider's backend. 26 | // 27 | // Most users of this package should not access fields of Token 28 | // directly. They're exported mostly for use by related packages 29 | // implementing derivative OAuth2 flows. 30 | type Token struct { 31 | // AccessToken is the token that authorizes and authenticates 32 | // the requests. 33 | AccessToken string `json:"access_token"` 34 | 35 | // TokenType is the type of token. 36 | // The Type method returns either this or "Bearer", the default. 37 | TokenType string `json:"token_type,omitempty"` 38 | 39 | // RefreshToken is a token that's used by the application 40 | // (as opposed to the user) to refresh the access token 41 | // if it expires. 42 | RefreshToken string `json:"refresh_token,omitempty"` 43 | 44 | // Expiry is the optional expiration time of the access token. 45 | // 46 | // If zero, TokenSource implementations will reuse the same 47 | // token forever and RefreshToken or equivalent 48 | // mechanisms for that TokenSource will not be used. 49 | Expiry time.Time `json:"expiry,omitempty"` 50 | 51 | // raw optionally contains extra metadata from the server 52 | // when updating a token. 53 | raw interface{} 54 | } 55 | 56 | // Type returns t.TokenType if non-empty, else "Bearer". 57 | func (t *Token) Type() string { 58 | if strings.EqualFold(t.TokenType, "bearer") { 59 | return "Bearer" 60 | } 61 | if strings.EqualFold(t.TokenType, "mac") { 62 | return "MAC" 63 | } 64 | if strings.EqualFold(t.TokenType, "basic") { 65 | return "Basic" 66 | } 67 | if t.TokenType != "" { 68 | return t.TokenType 69 | } 70 | return "Bearer" 71 | } 72 | 73 | // SetAuthHeader sets the Authorization header to r using the access 74 | // token in t. 75 | // 76 | // This method is unnecessary when using Transport or an HTTP Client 77 | // returned by this package. 78 | func (t *Token) SetAuthHeader(r *http.Request) { 79 | r.Header.Set("Authorization", t.Type()+" "+t.AccessToken) 80 | } 81 | 82 | // WithExtra returns a new Token that's a clone of t, but using the 83 | // provided raw extra map. This is only intended for use by packages 84 | // implementing derivative OAuth2 flows. 85 | func (t *Token) WithExtra(extra interface{}) *Token { 86 | t2 := new(Token) 87 | *t2 = *t 88 | t2.raw = extra 89 | return t2 90 | } 91 | 92 | // Extra returns an extra field. 93 | // Extra fields are key-value pairs returned by the server as a 94 | // part of the token retrieval response. 95 | func (t *Token) Extra(key string) interface{} { 96 | if raw, ok := t.raw.(map[string]interface{}); ok { 97 | return raw[key] 98 | } 99 | 100 | vals, ok := t.raw.(url.Values) 101 | if !ok { 102 | return nil 103 | } 104 | 105 | v := vals.Get(key) 106 | switch s := strings.TrimSpace(v); strings.Count(s, ".") { 107 | case 0: // Contains no "."; try to parse as int 108 | if i, err := strconv.ParseInt(s, 10, 64); err == nil { 109 | return i 110 | } 111 | case 1: // Contains a single "."; try to parse as float 112 | if f, err := strconv.ParseFloat(s, 64); err == nil { 113 | return f 114 | } 115 | } 116 | 117 | return v 118 | } 119 | 120 | // expired reports whether the token is expired. 121 | // t must be non-nil. 122 | func (t *Token) expired() bool { 123 | if t.Expiry.IsZero() { 124 | return false 125 | } 126 | return t.Expiry.Add(-expiryDelta).Before(time.Now()) 127 | } 128 | 129 | // Valid reports whether t is non-nil, has an AccessToken, and is not expired. 130 | func (t *Token) Valid() bool { 131 | return t != nil && t.AccessToken != "" && !t.expired() 132 | } 133 | 134 | // tokenFromInternal maps an *internal.Token struct into 135 | // a *Token struct. 136 | func tokenFromInternal(t *internal.Token) *Token { 137 | if t == nil { 138 | return nil 139 | } 140 | return &Token{ 141 | AccessToken: t.AccessToken, 142 | TokenType: t.TokenType, 143 | RefreshToken: t.RefreshToken, 144 | Expiry: t.Expiry, 145 | raw: t.Raw, 146 | } 147 | } 148 | 149 | // retrieveToken takes a *Config and uses that to retrieve an *internal.Token. 150 | // This token is then mapped from *internal.Token into an *oauth2.Token which is returned along 151 | // with an error.. 152 | func retrieveToken(ctx context.Context, c *Config, v url.Values) (*Token, error) { 153 | tk, err := internal.RetrieveToken(ctx, c.ClientID, c.ClientSecret, c.Endpoint.TokenURL, v) 154 | if err != nil { 155 | return nil, err 156 | } 157 | return tokenFromInternal(tk), nil 158 | } 159 | -------------------------------------------------------------------------------- /vendor/golang.org/x/oauth2/transport.go: -------------------------------------------------------------------------------- 1 | // Copyright 2014 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package oauth2 6 | 7 | import ( 8 | "errors" 9 | "io" 10 | "net/http" 11 | "sync" 12 | ) 13 | 14 | // Transport is an http.RoundTripper that makes OAuth 2.0 HTTP requests, 15 | // wrapping a base RoundTripper and adding an Authorization header 16 | // with a token from the supplied Sources. 17 | // 18 | // Transport is a low-level mechanism. Most code will use the 19 | // higher-level Config.Client method instead. 20 | type Transport struct { 21 | // Source supplies the token to add to outgoing requests' 22 | // Authorization headers. 23 | Source TokenSource 24 | 25 | // Base is the base RoundTripper used to make HTTP requests. 26 | // If nil, http.DefaultTransport is used. 27 | Base http.RoundTripper 28 | 29 | mu sync.Mutex // guards modReq 30 | modReq map[*http.Request]*http.Request // original -> modified 31 | } 32 | 33 | // RoundTrip authorizes and authenticates the request with an 34 | // access token. If no token exists or token is expired, 35 | // tries to refresh/fetch a new token. 36 | func (t *Transport) RoundTrip(req *http.Request) (*http.Response, error) { 37 | if t.Source == nil { 38 | return nil, errors.New("oauth2: Transport's Source is nil") 39 | } 40 | token, err := t.Source.Token() 41 | if err != nil { 42 | return nil, err 43 | } 44 | 45 | req2 := cloneRequest(req) // per RoundTripper contract 46 | token.SetAuthHeader(req2) 47 | t.setModReq(req, req2) 48 | res, err := t.base().RoundTrip(req2) 49 | if err != nil { 50 | t.setModReq(req, nil) 51 | return nil, err 52 | } 53 | res.Body = &onEOFReader{ 54 | rc: res.Body, 55 | fn: func() { t.setModReq(req, nil) }, 56 | } 57 | return res, nil 58 | } 59 | 60 | // CancelRequest cancels an in-flight request by closing its connection. 61 | func (t *Transport) CancelRequest(req *http.Request) { 62 | type canceler interface { 63 | CancelRequest(*http.Request) 64 | } 65 | if cr, ok := t.base().(canceler); ok { 66 | t.mu.Lock() 67 | modReq := t.modReq[req] 68 | delete(t.modReq, req) 69 | t.mu.Unlock() 70 | cr.CancelRequest(modReq) 71 | } 72 | } 73 | 74 | func (t *Transport) base() http.RoundTripper { 75 | if t.Base != nil { 76 | return t.Base 77 | } 78 | return http.DefaultTransport 79 | } 80 | 81 | func (t *Transport) setModReq(orig, mod *http.Request) { 82 | t.mu.Lock() 83 | defer t.mu.Unlock() 84 | if t.modReq == nil { 85 | t.modReq = make(map[*http.Request]*http.Request) 86 | } 87 | if mod == nil { 88 | delete(t.modReq, orig) 89 | } else { 90 | t.modReq[orig] = mod 91 | } 92 | } 93 | 94 | // cloneRequest returns a clone of the provided *http.Request. 95 | // The clone is a shallow copy of the struct and its Header map. 96 | func cloneRequest(r *http.Request) *http.Request { 97 | // shallow copy of the struct 98 | r2 := new(http.Request) 99 | *r2 = *r 100 | // deep copy of the Header 101 | r2.Header = make(http.Header, len(r.Header)) 102 | for k, s := range r.Header { 103 | r2.Header[k] = append([]string(nil), s...) 104 | } 105 | return r2 106 | } 107 | 108 | type onEOFReader struct { 109 | rc io.ReadCloser 110 | fn func() 111 | } 112 | 113 | func (r *onEOFReader) Read(p []byte) (n int, err error) { 114 | n, err = r.rc.Read(p) 115 | if err == io.EOF { 116 | r.runFunc() 117 | } 118 | return 119 | } 120 | 121 | func (r *onEOFReader) Close() error { 122 | err := r.rc.Close() 123 | r.runFunc() 124 | return err 125 | } 126 | 127 | func (r *onEOFReader) runFunc() { 128 | if fn := r.fn; fn != nil { 129 | fn() 130 | r.fn = nil 131 | } 132 | } 133 | -------------------------------------------------------------------------------- /vendor/google.golang.org/api/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2011 Google Inc. All rights reserved. 2 | 3 | Redistribution and use in source and binary forms, with or without 4 | modification, are permitted provided that the following conditions are 5 | met: 6 | 7 | * Redistributions of source code must retain the above copyright 8 | notice, this list of conditions and the following disclaimer. 9 | * Redistributions in binary form must reproduce the above 10 | copyright notice, this list of conditions and the following disclaimer 11 | in the documentation and/or other materials provided with the 12 | distribution. 13 | * Neither the name of Google Inc. nor the names of its 14 | contributors may be used to endorse or promote products derived from 15 | this software without specific prior written permission. 16 | 17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 20 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 21 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 23 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | -------------------------------------------------------------------------------- /vendor/google.golang.org/api/gensupport/backoff.go: -------------------------------------------------------------------------------- 1 | // Copyright 2016 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package gensupport 6 | 7 | import ( 8 | "math/rand" 9 | "time" 10 | ) 11 | 12 | type BackoffStrategy interface { 13 | // Pause returns the duration of the next pause and true if the operation should be 14 | // retried, or false if no further retries should be attempted. 15 | Pause() (time.Duration, bool) 16 | 17 | // Reset restores the strategy to its initial state. 18 | Reset() 19 | } 20 | 21 | // ExponentialBackoff performs exponential backoff as per https://en.wikipedia.org/wiki/Exponential_backoff. 22 | // The initial pause time is given by Base. 23 | // Once the total pause time exceeds Max, Pause will indicate no further retries. 24 | type ExponentialBackoff struct { 25 | Base time.Duration 26 | Max time.Duration 27 | total time.Duration 28 | n uint 29 | } 30 | 31 | func (eb *ExponentialBackoff) Pause() (time.Duration, bool) { 32 | if eb.total > eb.Max { 33 | return 0, false 34 | } 35 | 36 | // The next pause is selected from randomly from [0, 2^n * Base). 37 | d := time.Duration(rand.Int63n((1 << eb.n) * int64(eb.Base))) 38 | eb.total += d 39 | eb.n++ 40 | return d, true 41 | } 42 | 43 | func (eb *ExponentialBackoff) Reset() { 44 | eb.n = 0 45 | eb.total = 0 46 | } 47 | -------------------------------------------------------------------------------- /vendor/google.golang.org/api/gensupport/buffer.go: -------------------------------------------------------------------------------- 1 | // Copyright 2016 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package gensupport 6 | 7 | import ( 8 | "bytes" 9 | "io" 10 | 11 | "google.golang.org/api/googleapi" 12 | ) 13 | 14 | // MediaBuffer buffers data from an io.Reader to support uploading media in retryable chunks. 15 | type MediaBuffer struct { 16 | media io.Reader 17 | 18 | chunk []byte // The current chunk which is pending upload. The capacity is the chunk size. 19 | err error // Any error generated when populating chunk by reading media. 20 | 21 | // The absolute position of chunk in the underlying media. 22 | off int64 23 | } 24 | 25 | func NewMediaBuffer(media io.Reader, chunkSize int) *MediaBuffer { 26 | return &MediaBuffer{media: media, chunk: make([]byte, 0, chunkSize)} 27 | } 28 | 29 | // Chunk returns the current buffered chunk, the offset in the underlying media 30 | // from which the chunk is drawn, and the size of the chunk. 31 | // Successive calls to Chunk return the same chunk between calls to Next. 32 | func (mb *MediaBuffer) Chunk() (chunk io.Reader, off int64, size int, err error) { 33 | // There may already be data in chunk if Next has not been called since the previous call to Chunk. 34 | if mb.err == nil && len(mb.chunk) == 0 { 35 | mb.err = mb.loadChunk() 36 | } 37 | return bytes.NewReader(mb.chunk), mb.off, len(mb.chunk), mb.err 38 | } 39 | 40 | // loadChunk will read from media into chunk, up to the capacity of chunk. 41 | func (mb *MediaBuffer) loadChunk() error { 42 | bufSize := cap(mb.chunk) 43 | mb.chunk = mb.chunk[:bufSize] 44 | 45 | read := 0 46 | var err error 47 | for err == nil && read < bufSize { 48 | var n int 49 | n, err = mb.media.Read(mb.chunk[read:]) 50 | read += n 51 | } 52 | mb.chunk = mb.chunk[:read] 53 | return err 54 | } 55 | 56 | // Next advances to the next chunk, which will be returned by the next call to Chunk. 57 | // Calls to Next without a corresponding prior call to Chunk will have no effect. 58 | func (mb *MediaBuffer) Next() { 59 | mb.off += int64(len(mb.chunk)) 60 | mb.chunk = mb.chunk[0:0] 61 | } 62 | 63 | type readerTyper struct { 64 | io.Reader 65 | googleapi.ContentTyper 66 | } 67 | 68 | // ReaderAtToReader adapts a ReaderAt to be used as a Reader. 69 | // If ra implements googleapi.ContentTyper, then the returned reader 70 | // will also implement googleapi.ContentTyper, delegating to ra. 71 | func ReaderAtToReader(ra io.ReaderAt, size int64) io.Reader { 72 | r := io.NewSectionReader(ra, 0, size) 73 | if typer, ok := ra.(googleapi.ContentTyper); ok { 74 | return readerTyper{r, typer} 75 | } 76 | return r 77 | } 78 | -------------------------------------------------------------------------------- /vendor/google.golang.org/api/gensupport/doc.go: -------------------------------------------------------------------------------- 1 | // Copyright 2016 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // Package gensupport is an internal implementation detail used by code 6 | // generated by the google-api-go-generator tool. 7 | // 8 | // This package may be modified at any time without regard for backwards 9 | // compatibility. It should not be used directly by API users. 10 | package gensupport 11 | -------------------------------------------------------------------------------- /vendor/google.golang.org/api/gensupport/json.go: -------------------------------------------------------------------------------- 1 | // Copyright 2015 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package gensupport 6 | 7 | import ( 8 | "encoding/json" 9 | "fmt" 10 | "reflect" 11 | "strings" 12 | ) 13 | 14 | // MarshalJSON returns a JSON encoding of schema containing only selected fields. 15 | // A field is selected if: 16 | // * it has a non-empty value, or 17 | // * its field name is present in forceSendFields, and 18 | // * it is not a nil pointer or nil interface. 19 | // The JSON key for each selected field is taken from the field's json: struct tag. 20 | func MarshalJSON(schema interface{}, forceSendFields []string) ([]byte, error) { 21 | if len(forceSendFields) == 0 { 22 | return json.Marshal(schema) 23 | } 24 | 25 | mustInclude := make(map[string]struct{}) 26 | for _, f := range forceSendFields { 27 | mustInclude[f] = struct{}{} 28 | } 29 | 30 | dataMap, err := schemaToMap(schema, mustInclude) 31 | if err != nil { 32 | return nil, err 33 | } 34 | return json.Marshal(dataMap) 35 | } 36 | 37 | func schemaToMap(schema interface{}, mustInclude map[string]struct{}) (map[string]interface{}, error) { 38 | m := make(map[string]interface{}) 39 | s := reflect.ValueOf(schema) 40 | st := s.Type() 41 | 42 | for i := 0; i < s.NumField(); i++ { 43 | jsonTag := st.Field(i).Tag.Get("json") 44 | if jsonTag == "" { 45 | continue 46 | } 47 | tag, err := parseJSONTag(jsonTag) 48 | if err != nil { 49 | return nil, err 50 | } 51 | if tag.ignore { 52 | continue 53 | } 54 | 55 | v := s.Field(i) 56 | f := st.Field(i) 57 | if !includeField(v, f, mustInclude) { 58 | continue 59 | } 60 | 61 | // nil maps are treated as empty maps. 62 | if f.Type.Kind() == reflect.Map && v.IsNil() { 63 | m[tag.apiName] = map[string]string{} 64 | continue 65 | } 66 | 67 | // nil slices are treated as empty slices. 68 | if f.Type.Kind() == reflect.Slice && v.IsNil() { 69 | m[tag.apiName] = []bool{} 70 | continue 71 | } 72 | 73 | if tag.stringFormat { 74 | m[tag.apiName] = formatAsString(v, f.Type.Kind()) 75 | } else { 76 | m[tag.apiName] = v.Interface() 77 | } 78 | } 79 | return m, nil 80 | } 81 | 82 | // formatAsString returns a string representation of v, dereferencing it first if possible. 83 | func formatAsString(v reflect.Value, kind reflect.Kind) string { 84 | if kind == reflect.Ptr && !v.IsNil() { 85 | v = v.Elem() 86 | } 87 | 88 | return fmt.Sprintf("%v", v.Interface()) 89 | } 90 | 91 | // jsonTag represents a restricted version of the struct tag format used by encoding/json. 92 | // It is used to describe the JSON encoding of fields in a Schema struct. 93 | type jsonTag struct { 94 | apiName string 95 | stringFormat bool 96 | ignore bool 97 | } 98 | 99 | // parseJSONTag parses a restricted version of the struct tag format used by encoding/json. 100 | // The format of the tag must match that generated by the Schema.writeSchemaStruct method 101 | // in the api generator. 102 | func parseJSONTag(val string) (jsonTag, error) { 103 | if val == "-" { 104 | return jsonTag{ignore: true}, nil 105 | } 106 | 107 | var tag jsonTag 108 | 109 | i := strings.Index(val, ",") 110 | if i == -1 || val[:i] == "" { 111 | return tag, fmt.Errorf("malformed json tag: %s", val) 112 | } 113 | 114 | tag = jsonTag{ 115 | apiName: val[:i], 116 | } 117 | 118 | switch val[i+1:] { 119 | case "omitempty": 120 | case "omitempty,string": 121 | tag.stringFormat = true 122 | default: 123 | return tag, fmt.Errorf("malformed json tag: %s", val) 124 | } 125 | 126 | return tag, nil 127 | } 128 | 129 | // Reports whether the struct field "f" with value "v" should be included in JSON output. 130 | func includeField(v reflect.Value, f reflect.StructField, mustInclude map[string]struct{}) bool { 131 | // The regular JSON encoding of a nil pointer is "null", which means "delete this field". 132 | // Therefore, we could enable field deletion by honoring pointer fields' presence in the mustInclude set. 133 | // However, many fields are not pointers, so there would be no way to delete these fields. 134 | // Rather than partially supporting field deletion, we ignore mustInclude for nil pointer fields. 135 | // Deletion will be handled by a separate mechanism. 136 | if f.Type.Kind() == reflect.Ptr && v.IsNil() { 137 | return false 138 | } 139 | 140 | // The "any" type is represented as an interface{}. If this interface 141 | // is nil, there is no reasonable representation to send. We ignore 142 | // these fields, for the same reasons as given above for pointers. 143 | if f.Type.Kind() == reflect.Interface && v.IsNil() { 144 | return false 145 | } 146 | 147 | _, ok := mustInclude[f.Name] 148 | return ok || !isEmptyValue(v) 149 | } 150 | 151 | // isEmptyValue reports whether v is the empty value for its type. This 152 | // implementation is based on that of the encoding/json package, but its 153 | // correctness does not depend on it being identical. What's important is that 154 | // this function return false in situations where v should not be sent as part 155 | // of a PATCH operation. 156 | func isEmptyValue(v reflect.Value) bool { 157 | switch v.Kind() { 158 | case reflect.Array, reflect.Map, reflect.Slice, reflect.String: 159 | return v.Len() == 0 160 | case reflect.Bool: 161 | return !v.Bool() 162 | case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: 163 | return v.Int() == 0 164 | case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: 165 | return v.Uint() == 0 166 | case reflect.Float32, reflect.Float64: 167 | return v.Float() == 0 168 | case reflect.Interface, reflect.Ptr: 169 | return v.IsNil() 170 | } 171 | return false 172 | } 173 | -------------------------------------------------------------------------------- /vendor/google.golang.org/api/gensupport/params.go: -------------------------------------------------------------------------------- 1 | // Copyright 2015 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package gensupport 6 | 7 | import ( 8 | "net/url" 9 | 10 | "google.golang.org/api/googleapi" 11 | ) 12 | 13 | // URLParams is a simplified replacement for url.Values 14 | // that safely builds up URL parameters for encoding. 15 | type URLParams map[string][]string 16 | 17 | // Get returns the first value for the given key, or "". 18 | func (u URLParams) Get(key string) string { 19 | vs := u[key] 20 | if len(vs) == 0 { 21 | return "" 22 | } 23 | return vs[0] 24 | } 25 | 26 | // Set sets the key to value. 27 | // It replaces any existing values. 28 | func (u URLParams) Set(key, value string) { 29 | u[key] = []string{value} 30 | } 31 | 32 | // SetMulti sets the key to an array of values. 33 | // It replaces any existing values. 34 | // Note that values must not be modified after calling SetMulti 35 | // so the caller is responsible for making a copy if necessary. 36 | func (u URLParams) SetMulti(key string, values []string) { 37 | u[key] = values 38 | } 39 | 40 | // Encode encodes the values into ``URL encoded'' form 41 | // ("bar=baz&foo=quux") sorted by key. 42 | func (u URLParams) Encode() string { 43 | return url.Values(u).Encode() 44 | } 45 | 46 | func SetOptions(u URLParams, opts ...googleapi.CallOption) { 47 | for _, o := range opts { 48 | u.Set(o.Get()) 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /vendor/google.golang.org/api/gensupport/retry.go: -------------------------------------------------------------------------------- 1 | package gensupport 2 | 3 | import ( 4 | "io" 5 | "net" 6 | "net/http" 7 | "time" 8 | 9 | "golang.org/x/net/context" 10 | ) 11 | 12 | // Retry invokes the given function, retrying it multiple times if the connection failed or 13 | // the HTTP status response indicates the request should be attempted again. ctx may be nil. 14 | func Retry(ctx context.Context, f func() (*http.Response, error), backoff BackoffStrategy) (*http.Response, error) { 15 | for { 16 | resp, err := f() 17 | 18 | var status int 19 | if resp != nil { 20 | status = resp.StatusCode 21 | } 22 | 23 | // Return if we shouldn't retry. 24 | pause, retry := backoff.Pause() 25 | if !shouldRetry(status, err) || !retry { 26 | return resp, err 27 | } 28 | 29 | // Ensure the response body is closed, if any. 30 | if resp != nil && resp.Body != nil { 31 | resp.Body.Close() 32 | } 33 | 34 | // Pause, but still listen to ctx.Done if context is not nil. 35 | var done <-chan struct{} 36 | if ctx != nil { 37 | done = ctx.Done() 38 | } 39 | select { 40 | case <-done: 41 | return nil, ctx.Err() 42 | case <-time.After(pause): 43 | } 44 | } 45 | } 46 | 47 | // DefaultBackoffStrategy returns a default strategy to use for retrying failed upload requests. 48 | func DefaultBackoffStrategy() BackoffStrategy { 49 | return &ExponentialBackoff{ 50 | Base: 250 * time.Millisecond, 51 | Max: 16 * time.Second, 52 | } 53 | } 54 | 55 | // shouldRetry returns true if the HTTP response / error indicates that the 56 | // request should be attempted again. 57 | func shouldRetry(status int, err error) bool { 58 | // Retry for 5xx response codes. 59 | if 500 <= status && status < 600 { 60 | return true 61 | } 62 | 63 | // Retry on statusTooManyRequests{ 64 | if status == statusTooManyRequests { 65 | return true 66 | } 67 | 68 | // Retry on unexpected EOFs and temporary network errors. 69 | if err == io.ErrUnexpectedEOF { 70 | return true 71 | } 72 | if err, ok := err.(net.Error); ok { 73 | return err.Temporary() 74 | } 75 | 76 | return false 77 | } 78 | -------------------------------------------------------------------------------- /vendor/google.golang.org/api/gensupport/send.go: -------------------------------------------------------------------------------- 1 | // Copyright 2016 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package gensupport 6 | 7 | import ( 8 | "net/http" 9 | 10 | "golang.org/x/net/context" 11 | "golang.org/x/net/context/ctxhttp" 12 | ) 13 | 14 | // Hook is the type of a function that is called once before each HTTP request 15 | // that is sent by a generated API. It returns a function that is called after 16 | // the request returns. 17 | // Hooks are not called if the context is nil. 18 | type Hook func(ctx context.Context, req *http.Request) func(resp *http.Response) 19 | 20 | var hooks []Hook 21 | 22 | // RegisterHook registers a Hook to be called before each HTTP request by a 23 | // generated API. Hooks are called in the order they are registered. Each 24 | // hook can return a function; if it is non-nil, it is called after the HTTP 25 | // request returns. These functions are called in the reverse order. 26 | // RegisterHook should not be called concurrently with itself or SendRequest. 27 | func RegisterHook(h Hook) { 28 | hooks = append(hooks, h) 29 | } 30 | 31 | // SendRequest sends a single HTTP request using the given client. 32 | // If ctx is non-nil, it calls all hooks, then sends the request with 33 | // ctxhttp.Do, then calls any functions returned by the hooks in reverse order. 34 | func SendRequest(ctx context.Context, client *http.Client, req *http.Request) (*http.Response, error) { 35 | if ctx == nil { 36 | return client.Do(req) 37 | } 38 | // Call hooks in order of registration, store returned funcs. 39 | post := make([]func(resp *http.Response), len(hooks)) 40 | for i, h := range hooks { 41 | fn := h(ctx, req) 42 | post[i] = fn 43 | } 44 | 45 | // Send request. 46 | resp, err := ctxhttp.Do(ctx, client, req) 47 | 48 | // Call returned funcs in reverse order. 49 | for i := len(post) - 1; i >= 0; i-- { 50 | if fn := post[i]; fn != nil { 51 | fn(resp) 52 | } 53 | } 54 | return resp, err 55 | } 56 | -------------------------------------------------------------------------------- /vendor/google.golang.org/api/googleapi/internal/uritemplates/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2013 Joshua Tacoma 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of 4 | this software and associated documentation files (the "Software"), to deal in 5 | the Software without restriction, including without limitation the rights to 6 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 7 | the Software, and to permit persons to whom the Software is furnished to do so, 8 | subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 15 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 16 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 17 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 18 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 19 | -------------------------------------------------------------------------------- /vendor/google.golang.org/api/googleapi/internal/uritemplates/utils.go: -------------------------------------------------------------------------------- 1 | // Copyright 2016 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package uritemplates 6 | 7 | func Expand(path string, values map[string]string) (string, error) { 8 | template, err := parse(path) 9 | if err != nil { 10 | return "", err 11 | } 12 | return template.Expand(values), nil 13 | } 14 | -------------------------------------------------------------------------------- /vendor/google.golang.org/api/googleapi/types.go: -------------------------------------------------------------------------------- 1 | // Copyright 2013 Google Inc. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package googleapi 6 | 7 | import ( 8 | "encoding/json" 9 | "strconv" 10 | ) 11 | 12 | // Int64s is a slice of int64s that marshal as quoted strings in JSON. 13 | type Int64s []int64 14 | 15 | func (q *Int64s) UnmarshalJSON(raw []byte) error { 16 | *q = (*q)[:0] 17 | var ss []string 18 | if err := json.Unmarshal(raw, &ss); err != nil { 19 | return err 20 | } 21 | for _, s := range ss { 22 | v, err := strconv.ParseInt(s, 10, 64) 23 | if err != nil { 24 | return err 25 | } 26 | *q = append(*q, int64(v)) 27 | } 28 | return nil 29 | } 30 | 31 | // Int32s is a slice of int32s that marshal as quoted strings in JSON. 32 | type Int32s []int32 33 | 34 | func (q *Int32s) UnmarshalJSON(raw []byte) error { 35 | *q = (*q)[:0] 36 | var ss []string 37 | if err := json.Unmarshal(raw, &ss); err != nil { 38 | return err 39 | } 40 | for _, s := range ss { 41 | v, err := strconv.ParseInt(s, 10, 32) 42 | if err != nil { 43 | return err 44 | } 45 | *q = append(*q, int32(v)) 46 | } 47 | return nil 48 | } 49 | 50 | // Uint64s is a slice of uint64s that marshal as quoted strings in JSON. 51 | type Uint64s []uint64 52 | 53 | func (q *Uint64s) UnmarshalJSON(raw []byte) error { 54 | *q = (*q)[:0] 55 | var ss []string 56 | if err := json.Unmarshal(raw, &ss); err != nil { 57 | return err 58 | } 59 | for _, s := range ss { 60 | v, err := strconv.ParseUint(s, 10, 64) 61 | if err != nil { 62 | return err 63 | } 64 | *q = append(*q, uint64(v)) 65 | } 66 | return nil 67 | } 68 | 69 | // Uint32s is a slice of uint32s that marshal as quoted strings in JSON. 70 | type Uint32s []uint32 71 | 72 | func (q *Uint32s) UnmarshalJSON(raw []byte) error { 73 | *q = (*q)[:0] 74 | var ss []string 75 | if err := json.Unmarshal(raw, &ss); err != nil { 76 | return err 77 | } 78 | for _, s := range ss { 79 | v, err := strconv.ParseUint(s, 10, 32) 80 | if err != nil { 81 | return err 82 | } 83 | *q = append(*q, uint32(v)) 84 | } 85 | return nil 86 | } 87 | 88 | // Float64s is a slice of float64s that marshal as quoted strings in JSON. 89 | type Float64s []float64 90 | 91 | func (q *Float64s) UnmarshalJSON(raw []byte) error { 92 | *q = (*q)[:0] 93 | var ss []string 94 | if err := json.Unmarshal(raw, &ss); err != nil { 95 | return err 96 | } 97 | for _, s := range ss { 98 | v, err := strconv.ParseFloat(s, 64) 99 | if err != nil { 100 | return err 101 | } 102 | *q = append(*q, float64(v)) 103 | } 104 | return nil 105 | } 106 | 107 | func quotedList(n int, fn func(dst []byte, i int) []byte) ([]byte, error) { 108 | dst := make([]byte, 0, 2+n*10) // somewhat arbitrary 109 | dst = append(dst, '[') 110 | for i := 0; i < n; i++ { 111 | if i > 0 { 112 | dst = append(dst, ',') 113 | } 114 | dst = append(dst, '"') 115 | dst = fn(dst, i) 116 | dst = append(dst, '"') 117 | } 118 | dst = append(dst, ']') 119 | return dst, nil 120 | } 121 | 122 | func (s Int64s) MarshalJSON() ([]byte, error) { 123 | return quotedList(len(s), func(dst []byte, i int) []byte { 124 | return strconv.AppendInt(dst, s[i], 10) 125 | }) 126 | } 127 | 128 | func (s Int32s) MarshalJSON() ([]byte, error) { 129 | return quotedList(len(s), func(dst []byte, i int) []byte { 130 | return strconv.AppendInt(dst, int64(s[i]), 10) 131 | }) 132 | } 133 | 134 | func (s Uint64s) MarshalJSON() ([]byte, error) { 135 | return quotedList(len(s), func(dst []byte, i int) []byte { 136 | return strconv.AppendUint(dst, s[i], 10) 137 | }) 138 | } 139 | 140 | func (s Uint32s) MarshalJSON() ([]byte, error) { 141 | return quotedList(len(s), func(dst []byte, i int) []byte { 142 | return strconv.AppendUint(dst, uint64(s[i]), 10) 143 | }) 144 | } 145 | 146 | func (s Float64s) MarshalJSON() ([]byte, error) { 147 | return quotedList(len(s), func(dst []byte, i int) []byte { 148 | return strconv.AppendFloat(dst, s[i], 'g', -1, 64) 149 | }) 150 | } 151 | 152 | /* 153 | * Helper routines for simplifying the creation of optional fields of basic type. 154 | */ 155 | 156 | // Bool is a helper routine that allocates a new bool value 157 | // to store v and returns a pointer to it. 158 | func Bool(v bool) *bool { return &v } 159 | 160 | // Int32 is a helper routine that allocates a new int32 value 161 | // to store v and returns a pointer to it. 162 | func Int32(v int32) *int32 { return &v } 163 | 164 | // Int64 is a helper routine that allocates a new int64 value 165 | // to store v and returns a pointer to it. 166 | func Int64(v int64) *int64 { return &v } 167 | 168 | // Float64 is a helper routine that allocates a new float64 value 169 | // to store v and returns a pointer to it. 170 | func Float64(v float64) *float64 { return &v } 171 | 172 | // Uint32 is a helper routine that allocates a new uint32 value 173 | // to store v and returns a pointer to it. 174 | func Uint32(v uint32) *uint32 { return &v } 175 | 176 | // Uint64 is a helper routine that allocates a new uint64 value 177 | // to store v and returns a pointer to it. 178 | func Uint64(v uint64) *uint64 { return &v } 179 | 180 | // String is a helper routine that allocates a new string value 181 | // to store v and returns a pointer to it. 182 | func String(v string) *string { return &v } 183 | -------------------------------------------------------------------------------- /vendor/google.golang.org/cloud/internal/cloud.go: -------------------------------------------------------------------------------- 1 | // Copyright 2014 Google Inc. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | // Package internal provides support for the cloud packages. 16 | // 17 | // Users should not import this package directly. 18 | package internal 19 | 20 | import ( 21 | "fmt" 22 | "net/http" 23 | "sync" 24 | 25 | "golang.org/x/net/context" 26 | ) 27 | 28 | type contextKey struct{} 29 | 30 | func WithContext(parent context.Context, projID string, c *http.Client) context.Context { 31 | if c == nil { 32 | panic("nil *http.Client passed to WithContext") 33 | } 34 | if projID == "" { 35 | panic("empty project ID passed to WithContext") 36 | } 37 | return context.WithValue(parent, contextKey{}, &cloudContext{ 38 | ProjectID: projID, 39 | HTTPClient: c, 40 | }) 41 | } 42 | 43 | const userAgent = "gcloud-golang/0.1" 44 | 45 | type cloudContext struct { 46 | ProjectID string 47 | HTTPClient *http.Client 48 | 49 | mu sync.Mutex // guards svc 50 | svc map[string]interface{} // e.g. "storage" => *rawStorage.Service 51 | } 52 | 53 | // Service returns the result of the fill function if it's never been 54 | // called before for the given name (which is assumed to be an API 55 | // service name, like "datastore"). If it has already been cached, the fill 56 | // func is not run. 57 | // It's safe for concurrent use by multiple goroutines. 58 | func Service(ctx context.Context, name string, fill func(*http.Client) interface{}) interface{} { 59 | return cc(ctx).service(name, fill) 60 | } 61 | 62 | func (c *cloudContext) service(name string, fill func(*http.Client) interface{}) interface{} { 63 | c.mu.Lock() 64 | defer c.mu.Unlock() 65 | 66 | if c.svc == nil { 67 | c.svc = make(map[string]interface{}) 68 | } else if v, ok := c.svc[name]; ok { 69 | return v 70 | } 71 | v := fill(c.HTTPClient) 72 | c.svc[name] = v 73 | return v 74 | } 75 | 76 | // Transport is an http.RoundTripper that appends 77 | // Google Cloud client's user-agent to the original 78 | // request's user-agent header. 79 | type Transport struct { 80 | // Base is the actual http.RoundTripper 81 | // requests will use. It must not be nil. 82 | Base http.RoundTripper 83 | } 84 | 85 | // RoundTrip appends a user-agent to the existing user-agent 86 | // header and delegates the request to the base http.RoundTripper. 87 | func (t *Transport) RoundTrip(req *http.Request) (*http.Response, error) { 88 | req = cloneRequest(req) 89 | ua := req.Header.Get("User-Agent") 90 | if ua == "" { 91 | ua = userAgent 92 | } else { 93 | ua = fmt.Sprintf("%s %s", ua, userAgent) 94 | } 95 | req.Header.Set("User-Agent", ua) 96 | return t.Base.RoundTrip(req) 97 | } 98 | 99 | // cloneRequest returns a clone of the provided *http.Request. 100 | // The clone is a shallow copy of the struct and its Header map. 101 | func cloneRequest(r *http.Request) *http.Request { 102 | // shallow copy of the struct 103 | r2 := new(http.Request) 104 | *r2 = *r 105 | // deep copy of the Header 106 | r2.Header = make(http.Header) 107 | for k, s := range r.Header { 108 | r2.Header[k] = s 109 | } 110 | return r2 111 | } 112 | 113 | func ProjID(ctx context.Context) string { 114 | return cc(ctx).ProjectID 115 | } 116 | 117 | func HTTPClient(ctx context.Context) *http.Client { 118 | return cc(ctx).HTTPClient 119 | } 120 | 121 | // cc returns the internal *cloudContext (cc) state for a context.Context. 122 | // It panics if the user did it wrong. 123 | func cc(ctx context.Context) *cloudContext { 124 | if c, ok := ctx.Value(contextKey{}).(*cloudContext); ok { 125 | return c 126 | } 127 | panic("invalid context.Context type; it should be created with cloud.NewContext") 128 | } 129 | -------------------------------------------------------------------------------- /vendor/gopkg.in/alecthomas/kingpin.v2/COPYING: -------------------------------------------------------------------------------- 1 | Copyright (C) 2014 Alec Thomas 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of 4 | this software and associated documentation files (the "Software"), to deal in 5 | the Software without restriction, including without limitation the rights to 6 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 7 | of the Software, and to permit persons to whom the Software is furnished to do 8 | so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 19 | SOFTWARE. 20 | -------------------------------------------------------------------------------- /vendor/gopkg.in/alecthomas/kingpin.v2/actions.go: -------------------------------------------------------------------------------- 1 | package kingpin 2 | 3 | // Action callback executed at various stages after all values are populated. 4 | // The application, commands, arguments and flags all have corresponding 5 | // actions. 6 | type Action func(*ParseContext) error 7 | 8 | type actionMixin struct { 9 | actions []Action 10 | preActions []Action 11 | } 12 | 13 | type actionApplier interface { 14 | applyActions(*ParseContext) error 15 | applyPreActions(*ParseContext) error 16 | } 17 | 18 | func (a *actionMixin) addAction(action Action) { 19 | a.actions = append(a.actions, action) 20 | } 21 | 22 | func (a *actionMixin) addPreAction(action Action) { 23 | a.preActions = append(a.preActions, action) 24 | } 25 | 26 | func (a *actionMixin) applyActions(context *ParseContext) error { 27 | for _, action := range a.actions { 28 | if err := action(context); err != nil { 29 | return err 30 | } 31 | } 32 | return nil 33 | } 34 | 35 | func (a *actionMixin) applyPreActions(context *ParseContext) error { 36 | for _, preAction := range a.preActions { 37 | if err := preAction(context); err != nil { 38 | return err 39 | } 40 | } 41 | return nil 42 | } 43 | -------------------------------------------------------------------------------- /vendor/gopkg.in/alecthomas/kingpin.v2/args.go: -------------------------------------------------------------------------------- 1 | package kingpin 2 | 3 | import "fmt" 4 | 5 | type argGroup struct { 6 | args []*ArgClause 7 | } 8 | 9 | func newArgGroup() *argGroup { 10 | return &argGroup{} 11 | } 12 | 13 | func (a *argGroup) have() bool { 14 | return len(a.args) > 0 15 | } 16 | 17 | // GetArg gets an argument definition. 18 | // 19 | // This allows existing arguments to be modified after definition but before parsing. Useful for 20 | // modular applications. 21 | func (a *argGroup) GetArg(name string) *ArgClause { 22 | for _, arg := range a.args { 23 | if arg.name == name { 24 | return arg 25 | } 26 | } 27 | return nil 28 | } 29 | 30 | func (a *argGroup) Arg(name, help string) *ArgClause { 31 | arg := newArg(name, help) 32 | a.args = append(a.args, arg) 33 | return arg 34 | } 35 | 36 | func (a *argGroup) init() error { 37 | required := 0 38 | seen := map[string]struct{}{} 39 | previousArgMustBeLast := false 40 | for i, arg := range a.args { 41 | if previousArgMustBeLast { 42 | return fmt.Errorf("Args() can't be followed by another argument '%s'", arg.name) 43 | } 44 | if arg.consumesRemainder() { 45 | previousArgMustBeLast = true 46 | } 47 | if _, ok := seen[arg.name]; ok { 48 | return fmt.Errorf("duplicate argument '%s'", arg.name) 49 | } 50 | seen[arg.name] = struct{}{} 51 | if arg.required && required != i { 52 | return fmt.Errorf("required arguments found after non-required") 53 | } 54 | if arg.required { 55 | required++ 56 | } 57 | if err := arg.init(); err != nil { 58 | return err 59 | } 60 | } 61 | return nil 62 | } 63 | 64 | type ArgClause struct { 65 | actionMixin 66 | parserMixin 67 | name string 68 | help string 69 | defaultValues []string 70 | required bool 71 | } 72 | 73 | func newArg(name, help string) *ArgClause { 74 | a := &ArgClause{ 75 | name: name, 76 | help: help, 77 | } 78 | return a 79 | } 80 | 81 | func (a *ArgClause) consumesRemainder() bool { 82 | if r, ok := a.value.(remainderArg); ok { 83 | return r.IsCumulative() 84 | } 85 | return false 86 | } 87 | 88 | // Required arguments must be input by the user. They can not have a Default() value provided. 89 | func (a *ArgClause) Required() *ArgClause { 90 | a.required = true 91 | return a 92 | } 93 | 94 | // Default values for this argument. They *must* be parseable by the value of the argument. 95 | func (a *ArgClause) Default(values ...string) *ArgClause { 96 | a.defaultValues = values 97 | return a 98 | } 99 | 100 | func (a *ArgClause) Action(action Action) *ArgClause { 101 | a.addAction(action) 102 | return a 103 | } 104 | 105 | func (a *ArgClause) PreAction(action Action) *ArgClause { 106 | a.addPreAction(action) 107 | return a 108 | } 109 | 110 | func (a *ArgClause) init() error { 111 | if a.required && len(a.defaultValues) > 0 { 112 | return fmt.Errorf("required argument '%s' with unusable default value", a.name) 113 | } 114 | if a.value == nil { 115 | return fmt.Errorf("no parser defined for arg '%s'", a.name) 116 | } 117 | return nil 118 | } 119 | -------------------------------------------------------------------------------- /vendor/gopkg.in/alecthomas/kingpin.v2/completions.go: -------------------------------------------------------------------------------- 1 | package kingpin 2 | 3 | // HintAction is a function type who is expected to return a slice of possible 4 | // command line arguments. 5 | type HintAction func() []string 6 | type completionsMixin struct { 7 | hintActions []HintAction 8 | builtinHintActions []HintAction 9 | } 10 | 11 | func (a *completionsMixin) addHintAction(action HintAction) { 12 | a.hintActions = append(a.hintActions, action) 13 | } 14 | 15 | // Allow adding of HintActions which are added internally, ie, EnumVar 16 | func (a *completionsMixin) addHintActionBuiltin(action HintAction) { 17 | a.builtinHintActions = append(a.builtinHintActions, action) 18 | } 19 | 20 | func (a *completionsMixin) resolveCompletions() []string { 21 | var hints []string 22 | 23 | options := a.builtinHintActions 24 | if len(a.hintActions) > 0 { 25 | // User specified their own hintActions. Use those instead. 26 | options = a.hintActions 27 | } 28 | 29 | for _, hintAction := range options { 30 | hints = append(hints, hintAction()...) 31 | } 32 | return hints 33 | } 34 | -------------------------------------------------------------------------------- /vendor/gopkg.in/alecthomas/kingpin.v2/doc.go: -------------------------------------------------------------------------------- 1 | // Package kingpin provides command line interfaces like this: 2 | // 3 | // $ chat 4 | // usage: chat [] [] [ ...] 5 | // 6 | // Flags: 7 | // --debug enable debug mode 8 | // --help Show help. 9 | // --server=127.0.0.1 server address 10 | // 11 | // Commands: 12 | // help 13 | // Show help for a command. 14 | // 15 | // post [] 16 | // Post a message to a channel. 17 | // 18 | // register 19 | // Register a new user. 20 | // 21 | // $ chat help post 22 | // usage: chat [] post [] [] 23 | // 24 | // Post a message to a channel. 25 | // 26 | // Flags: 27 | // --image=IMAGE image to post 28 | // 29 | // Args: 30 | // channel to post to 31 | // [] text to post 32 | // $ chat post --image=~/Downloads/owls.jpg pics 33 | // 34 | // From code like this: 35 | // 36 | // package main 37 | // 38 | // import "gopkg.in/alecthomas/kingpin.v1" 39 | // 40 | // var ( 41 | // debug = kingpin.Flag("debug", "enable debug mode").Default("false").Bool() 42 | // serverIP = kingpin.Flag("server", "server address").Default("127.0.0.1").IP() 43 | // 44 | // register = kingpin.Command("register", "Register a new user.") 45 | // registerNick = register.Arg("nick", "nickname for user").Required().String() 46 | // registerName = register.Arg("name", "name of user").Required().String() 47 | // 48 | // post = kingpin.Command("post", "Post a message to a channel.") 49 | // postImage = post.Flag("image", "image to post").ExistingFile() 50 | // postChannel = post.Arg("channel", "channel to post to").Required().String() 51 | // postText = post.Arg("text", "text to post").String() 52 | // ) 53 | // 54 | // func main() { 55 | // switch kingpin.Parse() { 56 | // // Register user 57 | // case "register": 58 | // println(*registerNick) 59 | // 60 | // // Post message 61 | // case "post": 62 | // if *postImage != nil { 63 | // } 64 | // if *postText != "" { 65 | // } 66 | // } 67 | // } 68 | package kingpin 69 | -------------------------------------------------------------------------------- /vendor/gopkg.in/alecthomas/kingpin.v2/global.go: -------------------------------------------------------------------------------- 1 | package kingpin 2 | 3 | import ( 4 | "os" 5 | "path/filepath" 6 | ) 7 | 8 | var ( 9 | // CommandLine is the default Kingpin parser. 10 | CommandLine = New(filepath.Base(os.Args[0]), "") 11 | // Global help flag. Exposed for user customisation. 12 | HelpFlag = CommandLine.HelpFlag 13 | // Top-level help command. Exposed for user customisation. May be nil. 14 | HelpCommand = CommandLine.HelpCommand 15 | // Global version flag. Exposed for user customisation. May be nil. 16 | VersionFlag = CommandLine.VersionFlag 17 | ) 18 | 19 | // Command adds a new command to the default parser. 20 | func Command(name, help string) *CmdClause { 21 | return CommandLine.Command(name, help) 22 | } 23 | 24 | // Flag adds a new flag to the default parser. 25 | func Flag(name, help string) *FlagClause { 26 | return CommandLine.Flag(name, help) 27 | } 28 | 29 | // Arg adds a new argument to the top-level of the default parser. 30 | func Arg(name, help string) *ArgClause { 31 | return CommandLine.Arg(name, help) 32 | } 33 | 34 | // Parse and return the selected command. Will call the termination handler if 35 | // an error is encountered. 36 | func Parse() string { 37 | selected := MustParse(CommandLine.Parse(os.Args[1:])) 38 | if selected == "" && CommandLine.cmdGroup.have() { 39 | Usage() 40 | CommandLine.terminate(0) 41 | } 42 | return selected 43 | } 44 | 45 | // Errorf prints an error message to stderr. 46 | func Errorf(format string, args ...interface{}) { 47 | CommandLine.Errorf(format, args...) 48 | } 49 | 50 | // Fatalf prints an error message to stderr and exits. 51 | func Fatalf(format string, args ...interface{}) { 52 | CommandLine.Fatalf(format, args...) 53 | } 54 | 55 | // FatalIfError prints an error and exits if err is not nil. The error is printed 56 | // with the given prefix. 57 | func FatalIfError(err error, format string, args ...interface{}) { 58 | CommandLine.FatalIfError(err, format, args...) 59 | } 60 | 61 | // FatalUsage prints an error message followed by usage information, then 62 | // exits with a non-zero status. 63 | func FatalUsage(format string, args ...interface{}) { 64 | CommandLine.FatalUsage(format, args...) 65 | } 66 | 67 | // FatalUsageContext writes a printf formatted error message to stderr, then 68 | // usage information for the given ParseContext, before exiting. 69 | func FatalUsageContext(context *ParseContext, format string, args ...interface{}) { 70 | CommandLine.FatalUsageContext(context, format, args...) 71 | } 72 | 73 | // Usage prints usage to stderr. 74 | func Usage() { 75 | CommandLine.Usage(os.Args[1:]) 76 | } 77 | 78 | // Set global usage template to use (defaults to DefaultUsageTemplate). 79 | func UsageTemplate(template string) *Application { 80 | return CommandLine.UsageTemplate(template) 81 | } 82 | 83 | // MustParse can be used with app.Parse(args) to exit with an error if parsing fails. 84 | func MustParse(command string, err error) string { 85 | if err != nil { 86 | Fatalf("%s, try --help", err) 87 | } 88 | return command 89 | } 90 | 91 | // Version adds a flag for displaying the application version number. 92 | func Version(version string) *Application { 93 | return CommandLine.Version(version) 94 | } 95 | -------------------------------------------------------------------------------- /vendor/gopkg.in/alecthomas/kingpin.v2/guesswidth.go: -------------------------------------------------------------------------------- 1 | // +build appengine !linux,!freebsd,!darwin,!dragonfly,!netbsd,!openbsd 2 | 3 | package kingpin 4 | 5 | import "io" 6 | 7 | func guessWidth(w io.Writer) int { 8 | return 80 9 | } 10 | -------------------------------------------------------------------------------- /vendor/gopkg.in/alecthomas/kingpin.v2/guesswidth_unix.go: -------------------------------------------------------------------------------- 1 | // +build !appengine,linux freebsd darwin dragonfly netbsd openbsd 2 | 3 | package kingpin 4 | 5 | import ( 6 | "io" 7 | "os" 8 | "strconv" 9 | "syscall" 10 | "unsafe" 11 | ) 12 | 13 | func guessWidth(w io.Writer) int { 14 | // check if COLUMNS env is set to comply with 15 | // http://pubs.opengroup.org/onlinepubs/009604499/basedefs/xbd_chap08.html 16 | colsStr := os.Getenv("COLUMNS") 17 | if colsStr != "" { 18 | if cols, err := strconv.Atoi(colsStr); err == nil { 19 | return cols 20 | } 21 | } 22 | 23 | if t, ok := w.(*os.File); ok { 24 | fd := t.Fd() 25 | var dimensions [4]uint16 26 | 27 | if _, _, err := syscall.Syscall6( 28 | syscall.SYS_IOCTL, 29 | uintptr(fd), 30 | uintptr(syscall.TIOCGWINSZ), 31 | uintptr(unsafe.Pointer(&dimensions)), 32 | 0, 0, 0, 33 | ); err == 0 { 34 | return int(dimensions[1]) 35 | } 36 | } 37 | return 80 38 | } 39 | -------------------------------------------------------------------------------- /vendor/gopkg.in/alecthomas/kingpin.v2/model.go: -------------------------------------------------------------------------------- 1 | package kingpin 2 | 3 | import ( 4 | "fmt" 5 | "strconv" 6 | "strings" 7 | ) 8 | 9 | // Data model for Kingpin command-line structure. 10 | 11 | type FlagGroupModel struct { 12 | Flags []*FlagModel 13 | } 14 | 15 | func (f *FlagGroupModel) FlagSummary() string { 16 | out := []string{} 17 | count := 0 18 | for _, flag := range f.Flags { 19 | if flag.Name != "help" { 20 | count++ 21 | } 22 | if flag.Required { 23 | if flag.IsBoolFlag() { 24 | out = append(out, fmt.Sprintf("--[no-]%s", flag.Name)) 25 | } else { 26 | out = append(out, fmt.Sprintf("--%s=%s", flag.Name, flag.FormatPlaceHolder())) 27 | } 28 | } 29 | } 30 | if count != len(out) { 31 | out = append(out, "[]") 32 | } 33 | return strings.Join(out, " ") 34 | } 35 | 36 | type FlagModel struct { 37 | Name string 38 | Help string 39 | Short rune 40 | Default []string 41 | Envar string 42 | PlaceHolder string 43 | Required bool 44 | Hidden bool 45 | Value Value 46 | } 47 | 48 | func (f *FlagModel) String() string { 49 | return f.Value.String() 50 | } 51 | 52 | func (f *FlagModel) IsBoolFlag() bool { 53 | if fl, ok := f.Value.(boolFlag); ok { 54 | return fl.IsBoolFlag() 55 | } 56 | return false 57 | } 58 | 59 | func (f *FlagModel) FormatPlaceHolder() string { 60 | if f.PlaceHolder != "" { 61 | return f.PlaceHolder 62 | } 63 | if len(f.Default) > 0 { 64 | ellipsis := "" 65 | if len(f.Default) > 1 { 66 | ellipsis = "..." 67 | } 68 | if _, ok := f.Value.(*stringValue); ok { 69 | return strconv.Quote(f.Default[0]) + ellipsis 70 | } 71 | return f.Default[0] + ellipsis 72 | } 73 | return strings.ToUpper(f.Name) 74 | } 75 | 76 | type ArgGroupModel struct { 77 | Args []*ArgModel 78 | } 79 | 80 | func (a *ArgGroupModel) ArgSummary() string { 81 | depth := 0 82 | out := []string{} 83 | for _, arg := range a.Args { 84 | h := "<" + arg.Name + ">" 85 | if !arg.Required { 86 | h = "[" + h 87 | depth++ 88 | } 89 | out = append(out, h) 90 | } 91 | out[len(out)-1] = out[len(out)-1] + strings.Repeat("]", depth) 92 | return strings.Join(out, " ") 93 | } 94 | 95 | type ArgModel struct { 96 | Name string 97 | Help string 98 | Default []string 99 | Required bool 100 | Value Value 101 | } 102 | 103 | func (a *ArgModel) String() string { 104 | return a.Value.String() 105 | } 106 | 107 | type CmdGroupModel struct { 108 | Commands []*CmdModel 109 | } 110 | 111 | func (c *CmdGroupModel) FlattenedCommands() (out []*CmdModel) { 112 | for _, cmd := range c.Commands { 113 | if len(cmd.Commands) == 0 { 114 | out = append(out, cmd) 115 | } 116 | out = append(out, cmd.FlattenedCommands()...) 117 | } 118 | return 119 | } 120 | 121 | type CmdModel struct { 122 | Name string 123 | Aliases []string 124 | Help string 125 | FullCommand string 126 | Depth int 127 | Hidden bool 128 | Default bool 129 | *FlagGroupModel 130 | *ArgGroupModel 131 | *CmdGroupModel 132 | } 133 | 134 | func (c *CmdModel) String() string { 135 | return c.FullCommand 136 | } 137 | 138 | type ApplicationModel struct { 139 | Name string 140 | Help string 141 | Version string 142 | Author string 143 | *ArgGroupModel 144 | *CmdGroupModel 145 | *FlagGroupModel 146 | } 147 | 148 | func (a *Application) Model() *ApplicationModel { 149 | return &ApplicationModel{ 150 | Name: a.Name, 151 | Help: a.Help, 152 | Version: a.version, 153 | Author: a.author, 154 | FlagGroupModel: a.flagGroup.Model(), 155 | ArgGroupModel: a.argGroup.Model(), 156 | CmdGroupModel: a.cmdGroup.Model(), 157 | } 158 | } 159 | 160 | func (a *argGroup) Model() *ArgGroupModel { 161 | m := &ArgGroupModel{} 162 | for _, arg := range a.args { 163 | m.Args = append(m.Args, arg.Model()) 164 | } 165 | return m 166 | } 167 | 168 | func (a *ArgClause) Model() *ArgModel { 169 | return &ArgModel{ 170 | Name: a.name, 171 | Help: a.help, 172 | Default: a.defaultValues, 173 | Required: a.required, 174 | Value: a.value, 175 | } 176 | } 177 | 178 | func (f *flagGroup) Model() *FlagGroupModel { 179 | m := &FlagGroupModel{} 180 | for _, fl := range f.flagOrder { 181 | m.Flags = append(m.Flags, fl.Model()) 182 | } 183 | return m 184 | } 185 | 186 | func (f *FlagClause) Model() *FlagModel { 187 | return &FlagModel{ 188 | Name: f.name, 189 | Help: f.help, 190 | Short: rune(f.shorthand), 191 | Default: f.defaultValues, 192 | Envar: f.envar, 193 | PlaceHolder: f.placeholder, 194 | Required: f.required, 195 | Hidden: f.hidden, 196 | Value: f.value, 197 | } 198 | } 199 | 200 | func (c *cmdGroup) Model() *CmdGroupModel { 201 | m := &CmdGroupModel{} 202 | for _, cm := range c.commandOrder { 203 | m.Commands = append(m.Commands, cm.Model()) 204 | } 205 | return m 206 | } 207 | 208 | func (c *CmdClause) Model() *CmdModel { 209 | depth := 0 210 | for i := c; i != nil; i = i.parent { 211 | depth++ 212 | } 213 | return &CmdModel{ 214 | Name: c.name, 215 | Aliases: c.aliases, 216 | Help: c.help, 217 | Depth: depth, 218 | Hidden: c.hidden, 219 | Default: c.isDefault, 220 | FullCommand: c.FullCommand(), 221 | FlagGroupModel: c.flagGroup.Model(), 222 | ArgGroupModel: c.argGroup.Model(), 223 | CmdGroupModel: c.cmdGroup.Model(), 224 | } 225 | } 226 | -------------------------------------------------------------------------------- /vendor/gopkg.in/alecthomas/kingpin.v2/values.json: -------------------------------------------------------------------------------- 1 | [ 2 | {"type": "bool", "parser": "strconv.ParseBool(s)"}, 3 | {"type": "string", "parser": "s, error(nil)", "format": "string(*f.v)", "plural": "Strings"}, 4 | {"type": "uint", "parser": "strconv.ParseUint(s, 0, 64)", "plural": "Uints"}, 5 | {"type": "uint8", "parser": "strconv.ParseUint(s, 0, 8)"}, 6 | {"type": "uint16", "parser": "strconv.ParseUint(s, 0, 16)"}, 7 | {"type": "uint32", "parser": "strconv.ParseUint(s, 0, 32)"}, 8 | {"type": "uint64", "parser": "strconv.ParseUint(s, 0, 64)"}, 9 | {"type": "int", "parser": "strconv.ParseFloat(s, 64)", "plural": "Ints"}, 10 | {"type": "int8", "parser": "strconv.ParseInt(s, 0, 8)"}, 11 | {"type": "int16", "parser": "strconv.ParseInt(s, 0, 16)"}, 12 | {"type": "int32", "parser": "strconv.ParseInt(s, 0, 32)"}, 13 | {"type": "int64", "parser": "strconv.ParseInt(s, 0, 64)"}, 14 | {"type": "float64", "parser": "strconv.ParseFloat(s, 64)"}, 15 | {"type": "float32", "parser": "strconv.ParseFloat(s, 32)"}, 16 | {"name": "Duration", "type": "time.Duration", "no_value_parser": true}, 17 | {"name": "IP", "type": "net.IP", "no_value_parser": true}, 18 | {"name": "TCPAddr", "Type": "*net.TCPAddr", "plural": "TCPList", "no_value_parser": true}, 19 | {"name": "ExistingFile", "Type": "string", "plural": "ExistingFiles", "no_value_parser": true}, 20 | {"name": "ExistingDir", "Type": "string", "plural": "ExistingDirs", "no_value_parser": true}, 21 | {"name": "ExistingFileOrDir", "Type": "string", "plural": "ExistingFilesOrDirs", "no_value_parser": true}, 22 | {"name": "Regexp", "Type": "*regexp.Regexp", "parser": "regexp.Compile(s)"}, 23 | {"name": "ResolvedIP", "Type": "net.IP", "parser": "resolveHost(s)", "help": "Resolve a hostname or IP to an IP."}, 24 | {"name": "HexBytes", "Type": "[]byte", "parser": "hex.DecodeString(s)", "help": "Bytes as a hex string."} 25 | ] 26 | -------------------------------------------------------------------------------- /vendor/gopkg.in/yaml.v2/LICENSE.libyaml: -------------------------------------------------------------------------------- 1 | The following files were ported to Go from C files of libyaml, and thus 2 | are still covered by their original copyright and license: 3 | 4 | apic.go 5 | emitterc.go 6 | parserc.go 7 | readerc.go 8 | scannerc.go 9 | writerc.go 10 | yamlh.go 11 | yamlprivateh.go 12 | 13 | Copyright (c) 2006 Kirill Simonov 14 | 15 | Permission is hereby granted, free of charge, to any person obtaining a copy of 16 | this software and associated documentation files (the "Software"), to deal in 17 | the Software without restriction, including without limitation the rights to 18 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 19 | of the Software, and to permit persons to whom the Software is furnished to do 20 | so, subject to the following conditions: 21 | 22 | The above copyright notice and this permission notice shall be included in all 23 | copies or substantial portions of the Software. 24 | 25 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 26 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 27 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 28 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 29 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 30 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 31 | SOFTWARE. 32 | -------------------------------------------------------------------------------- /vendor/gopkg.in/yaml.v2/README.md: -------------------------------------------------------------------------------- 1 | # YAML support for the Go language 2 | 3 | Introduction 4 | ------------ 5 | 6 | The yaml package enables Go programs to comfortably encode and decode YAML 7 | values. It was developed within [Canonical](https://www.canonical.com) as 8 | part of the [juju](https://juju.ubuntu.com) project, and is based on a 9 | pure Go port of the well-known [libyaml](http://pyyaml.org/wiki/LibYAML) 10 | C library to parse and generate YAML data quickly and reliably. 11 | 12 | Compatibility 13 | ------------- 14 | 15 | The yaml package supports most of YAML 1.1 and 1.2, including support for 16 | anchors, tags, map merging, etc. Multi-document unmarshalling is not yet 17 | implemented, and base-60 floats from YAML 1.1 are purposefully not 18 | supported since they're a poor design and are gone in YAML 1.2. 19 | 20 | Installation and usage 21 | ---------------------- 22 | 23 | The import path for the package is *gopkg.in/yaml.v2*. 24 | 25 | To install it, run: 26 | 27 | go get gopkg.in/yaml.v2 28 | 29 | API documentation 30 | ----------------- 31 | 32 | If opened in a browser, the import path itself leads to the API documentation: 33 | 34 | * [https://gopkg.in/yaml.v2](https://gopkg.in/yaml.v2) 35 | 36 | API stability 37 | ------------- 38 | 39 | The package API for yaml v2 will remain stable as described in [gopkg.in](https://gopkg.in). 40 | 41 | 42 | License 43 | ------- 44 | 45 | The yaml package is licensed under the LGPL with an exception that allows it to be linked statically. Please see the LICENSE file for details. 46 | 47 | 48 | Example 49 | ------- 50 | 51 | ```Go 52 | package main 53 | 54 | import ( 55 | "fmt" 56 | "log" 57 | 58 | "gopkg.in/yaml.v2" 59 | ) 60 | 61 | var data = ` 62 | a: Easy! 63 | b: 64 | c: 2 65 | d: [3, 4] 66 | ` 67 | 68 | type T struct { 69 | A string 70 | B struct { 71 | RenamedC int `yaml:"c"` 72 | D []int `yaml:",flow"` 73 | } 74 | } 75 | 76 | func main() { 77 | t := T{} 78 | 79 | err := yaml.Unmarshal([]byte(data), &t) 80 | if err != nil { 81 | log.Fatalf("error: %v", err) 82 | } 83 | fmt.Printf("--- t:\n%v\n\n", t) 84 | 85 | d, err := yaml.Marshal(&t) 86 | if err != nil { 87 | log.Fatalf("error: %v", err) 88 | } 89 | fmt.Printf("--- t dump:\n%s\n\n", string(d)) 90 | 91 | m := make(map[interface{}]interface{}) 92 | 93 | err = yaml.Unmarshal([]byte(data), &m) 94 | if err != nil { 95 | log.Fatalf("error: %v", err) 96 | } 97 | fmt.Printf("--- m:\n%v\n\n", m) 98 | 99 | d, err = yaml.Marshal(&m) 100 | if err != nil { 101 | log.Fatalf("error: %v", err) 102 | } 103 | fmt.Printf("--- m dump:\n%s\n\n", string(d)) 104 | } 105 | ``` 106 | 107 | This example will generate the following output: 108 | 109 | ``` 110 | --- t: 111 | {Easy! {2 [3 4]}} 112 | 113 | --- t dump: 114 | a: Easy! 115 | b: 116 | c: 2 117 | d: [3, 4] 118 | 119 | 120 | --- m: 121 | map[a:Easy! b:map[c:2 d:[3 4]]] 122 | 123 | --- m dump: 124 | a: Easy! 125 | b: 126 | c: 2 127 | d: 128 | - 3 129 | - 4 130 | ``` 131 | 132 | -------------------------------------------------------------------------------- /vendor/gopkg.in/yaml.v2/resolve.go: -------------------------------------------------------------------------------- 1 | package yaml 2 | 3 | import ( 4 | "encoding/base64" 5 | "math" 6 | "strconv" 7 | "strings" 8 | "unicode/utf8" 9 | ) 10 | 11 | type resolveMapItem struct { 12 | value interface{} 13 | tag string 14 | } 15 | 16 | var resolveTable = make([]byte, 256) 17 | var resolveMap = make(map[string]resolveMapItem) 18 | 19 | func init() { 20 | t := resolveTable 21 | t[int('+')] = 'S' // Sign 22 | t[int('-')] = 'S' 23 | for _, c := range "0123456789" { 24 | t[int(c)] = 'D' // Digit 25 | } 26 | for _, c := range "yYnNtTfFoO~" { 27 | t[int(c)] = 'M' // In map 28 | } 29 | t[int('.')] = '.' // Float (potentially in map) 30 | 31 | var resolveMapList = []struct { 32 | v interface{} 33 | tag string 34 | l []string 35 | }{ 36 | {true, yaml_BOOL_TAG, []string{"y", "Y", "yes", "Yes", "YES"}}, 37 | {true, yaml_BOOL_TAG, []string{"true", "True", "TRUE"}}, 38 | {true, yaml_BOOL_TAG, []string{"on", "On", "ON"}}, 39 | {false, yaml_BOOL_TAG, []string{"n", "N", "no", "No", "NO"}}, 40 | {false, yaml_BOOL_TAG, []string{"false", "False", "FALSE"}}, 41 | {false, yaml_BOOL_TAG, []string{"off", "Off", "OFF"}}, 42 | {nil, yaml_NULL_TAG, []string{"", "~", "null", "Null", "NULL"}}, 43 | {math.NaN(), yaml_FLOAT_TAG, []string{".nan", ".NaN", ".NAN"}}, 44 | {math.Inf(+1), yaml_FLOAT_TAG, []string{".inf", ".Inf", ".INF"}}, 45 | {math.Inf(+1), yaml_FLOAT_TAG, []string{"+.inf", "+.Inf", "+.INF"}}, 46 | {math.Inf(-1), yaml_FLOAT_TAG, []string{"-.inf", "-.Inf", "-.INF"}}, 47 | {"<<", yaml_MERGE_TAG, []string{"<<"}}, 48 | } 49 | 50 | m := resolveMap 51 | for _, item := range resolveMapList { 52 | for _, s := range item.l { 53 | m[s] = resolveMapItem{item.v, item.tag} 54 | } 55 | } 56 | } 57 | 58 | const longTagPrefix = "tag:yaml.org,2002:" 59 | 60 | func shortTag(tag string) string { 61 | // TODO This can easily be made faster and produce less garbage. 62 | if strings.HasPrefix(tag, longTagPrefix) { 63 | return "!!" + tag[len(longTagPrefix):] 64 | } 65 | return tag 66 | } 67 | 68 | func longTag(tag string) string { 69 | if strings.HasPrefix(tag, "!!") { 70 | return longTagPrefix + tag[2:] 71 | } 72 | return tag 73 | } 74 | 75 | func resolvableTag(tag string) bool { 76 | switch tag { 77 | case "", yaml_STR_TAG, yaml_BOOL_TAG, yaml_INT_TAG, yaml_FLOAT_TAG, yaml_NULL_TAG: 78 | return true 79 | } 80 | return false 81 | } 82 | 83 | func resolve(tag string, in string) (rtag string, out interface{}) { 84 | if !resolvableTag(tag) { 85 | return tag, in 86 | } 87 | 88 | defer func() { 89 | switch tag { 90 | case "", rtag, yaml_STR_TAG, yaml_BINARY_TAG: 91 | return 92 | } 93 | failf("cannot decode %s `%s` as a %s", shortTag(rtag), in, shortTag(tag)) 94 | }() 95 | 96 | // Any data is accepted as a !!str or !!binary. 97 | // Otherwise, the prefix is enough of a hint about what it might be. 98 | hint := byte('N') 99 | if in != "" { 100 | hint = resolveTable[in[0]] 101 | } 102 | if hint != 0 && tag != yaml_STR_TAG && tag != yaml_BINARY_TAG { 103 | // Handle things we can lookup in a map. 104 | if item, ok := resolveMap[in]; ok { 105 | return item.tag, item.value 106 | } 107 | 108 | // Base 60 floats are a bad idea, were dropped in YAML 1.2, and 109 | // are purposefully unsupported here. They're still quoted on 110 | // the way out for compatibility with other parser, though. 111 | 112 | switch hint { 113 | case 'M': 114 | // We've already checked the map above. 115 | 116 | case '.': 117 | // Not in the map, so maybe a normal float. 118 | floatv, err := strconv.ParseFloat(in, 64) 119 | if err == nil { 120 | return yaml_FLOAT_TAG, floatv 121 | } 122 | 123 | case 'D', 'S': 124 | // Int, float, or timestamp. 125 | plain := strings.Replace(in, "_", "", -1) 126 | intv, err := strconv.ParseInt(plain, 0, 64) 127 | if err == nil { 128 | if intv == int64(int(intv)) { 129 | return yaml_INT_TAG, int(intv) 130 | } else { 131 | return yaml_INT_TAG, intv 132 | } 133 | } 134 | uintv, err := strconv.ParseUint(plain, 0, 64) 135 | if err == nil { 136 | return yaml_INT_TAG, uintv 137 | } 138 | floatv, err := strconv.ParseFloat(plain, 64) 139 | if err == nil { 140 | return yaml_FLOAT_TAG, floatv 141 | } 142 | if strings.HasPrefix(plain, "0b") { 143 | intv, err := strconv.ParseInt(plain[2:], 2, 64) 144 | if err == nil { 145 | if intv == int64(int(intv)) { 146 | return yaml_INT_TAG, int(intv) 147 | } else { 148 | return yaml_INT_TAG, intv 149 | } 150 | } 151 | uintv, err := strconv.ParseUint(plain[2:], 2, 64) 152 | if err == nil { 153 | return yaml_INT_TAG, uintv 154 | } 155 | } else if strings.HasPrefix(plain, "-0b") { 156 | intv, err := strconv.ParseInt(plain[3:], 2, 64) 157 | if err == nil { 158 | if intv == int64(int(intv)) { 159 | return yaml_INT_TAG, -int(intv) 160 | } else { 161 | return yaml_INT_TAG, -intv 162 | } 163 | } 164 | } 165 | // XXX Handle timestamps here. 166 | 167 | default: 168 | panic("resolveTable item not yet handled: " + string(rune(hint)) + " (with " + in + ")") 169 | } 170 | } 171 | if tag == yaml_BINARY_TAG { 172 | return yaml_BINARY_TAG, in 173 | } 174 | if utf8.ValidString(in) { 175 | return yaml_STR_TAG, in 176 | } 177 | return yaml_BINARY_TAG, encodeBase64(in) 178 | } 179 | 180 | // encodeBase64 encodes s as base64 that is broken up into multiple lines 181 | // as appropriate for the resulting length. 182 | func encodeBase64(s string) string { 183 | const lineLen = 70 184 | encLen := base64.StdEncoding.EncodedLen(len(s)) 185 | lines := encLen/lineLen + 1 186 | buf := make([]byte, encLen*2+lines) 187 | in := buf[0:encLen] 188 | out := buf[encLen:] 189 | base64.StdEncoding.Encode(in, []byte(s)) 190 | k := 0 191 | for i := 0; i < len(in); i += lineLen { 192 | j := i + lineLen 193 | if j > len(in) { 194 | j = len(in) 195 | } 196 | k += copy(out[k:], in[i:j]) 197 | if lines > 1 { 198 | out[k] = '\n' 199 | k++ 200 | } 201 | } 202 | return string(out[:k]) 203 | } 204 | -------------------------------------------------------------------------------- /vendor/gopkg.in/yaml.v2/sorter.go: -------------------------------------------------------------------------------- 1 | package yaml 2 | 3 | import ( 4 | "reflect" 5 | "unicode" 6 | ) 7 | 8 | type keyList []reflect.Value 9 | 10 | func (l keyList) Len() int { return len(l) } 11 | func (l keyList) Swap(i, j int) { l[i], l[j] = l[j], l[i] } 12 | func (l keyList) Less(i, j int) bool { 13 | a := l[i] 14 | b := l[j] 15 | ak := a.Kind() 16 | bk := b.Kind() 17 | for (ak == reflect.Interface || ak == reflect.Ptr) && !a.IsNil() { 18 | a = a.Elem() 19 | ak = a.Kind() 20 | } 21 | for (bk == reflect.Interface || bk == reflect.Ptr) && !b.IsNil() { 22 | b = b.Elem() 23 | bk = b.Kind() 24 | } 25 | af, aok := keyFloat(a) 26 | bf, bok := keyFloat(b) 27 | if aok && bok { 28 | if af != bf { 29 | return af < bf 30 | } 31 | if ak != bk { 32 | return ak < bk 33 | } 34 | return numLess(a, b) 35 | } 36 | if ak != reflect.String || bk != reflect.String { 37 | return ak < bk 38 | } 39 | ar, br := []rune(a.String()), []rune(b.String()) 40 | for i := 0; i < len(ar) && i < len(br); i++ { 41 | if ar[i] == br[i] { 42 | continue 43 | } 44 | al := unicode.IsLetter(ar[i]) 45 | bl := unicode.IsLetter(br[i]) 46 | if al && bl { 47 | return ar[i] < br[i] 48 | } 49 | if al || bl { 50 | return bl 51 | } 52 | var ai, bi int 53 | var an, bn int64 54 | for ai = i; ai < len(ar) && unicode.IsDigit(ar[ai]); ai++ { 55 | an = an*10 + int64(ar[ai]-'0') 56 | } 57 | for bi = i; bi < len(br) && unicode.IsDigit(br[bi]); bi++ { 58 | bn = bn*10 + int64(br[bi]-'0') 59 | } 60 | if an != bn { 61 | return an < bn 62 | } 63 | if ai != bi { 64 | return ai < bi 65 | } 66 | return ar[i] < br[i] 67 | } 68 | return len(ar) < len(br) 69 | } 70 | 71 | // keyFloat returns a float value for v if it is a number/bool 72 | // and whether it is a number/bool or not. 73 | func keyFloat(v reflect.Value) (f float64, ok bool) { 74 | switch v.Kind() { 75 | case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: 76 | return float64(v.Int()), true 77 | case reflect.Float32, reflect.Float64: 78 | return v.Float(), true 79 | case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: 80 | return float64(v.Uint()), true 81 | case reflect.Bool: 82 | if v.Bool() { 83 | return 1, true 84 | } 85 | return 0, true 86 | } 87 | return 0, false 88 | } 89 | 90 | // numLess returns whether a < b. 91 | // a and b must necessarily have the same kind. 92 | func numLess(a, b reflect.Value) bool { 93 | switch a.Kind() { 94 | case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: 95 | return a.Int() < b.Int() 96 | case reflect.Float32, reflect.Float64: 97 | return a.Float() < b.Float() 98 | case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: 99 | return a.Uint() < b.Uint() 100 | case reflect.Bool: 101 | return !a.Bool() && b.Bool() 102 | } 103 | panic("not a number") 104 | } 105 | -------------------------------------------------------------------------------- /vendor/gopkg.in/yaml.v2/writerc.go: -------------------------------------------------------------------------------- 1 | package yaml 2 | 3 | // Set the writer error and return false. 4 | func yaml_emitter_set_writer_error(emitter *yaml_emitter_t, problem string) bool { 5 | emitter.error = yaml_WRITER_ERROR 6 | emitter.problem = problem 7 | return false 8 | } 9 | 10 | // Flush the output buffer. 11 | func yaml_emitter_flush(emitter *yaml_emitter_t) bool { 12 | if emitter.write_handler == nil { 13 | panic("write handler not set") 14 | } 15 | 16 | // Check if the buffer is empty. 17 | if emitter.buffer_pos == 0 { 18 | return true 19 | } 20 | 21 | // If the output encoding is UTF-8, we don't need to recode the buffer. 22 | if emitter.encoding == yaml_UTF8_ENCODING { 23 | if err := emitter.write_handler(emitter, emitter.buffer[:emitter.buffer_pos]); err != nil { 24 | return yaml_emitter_set_writer_error(emitter, "write error: "+err.Error()) 25 | } 26 | emitter.buffer_pos = 0 27 | return true 28 | } 29 | 30 | // Recode the buffer into the raw buffer. 31 | var low, high int 32 | if emitter.encoding == yaml_UTF16LE_ENCODING { 33 | low, high = 0, 1 34 | } else { 35 | high, low = 1, 0 36 | } 37 | 38 | pos := 0 39 | for pos < emitter.buffer_pos { 40 | // See the "reader.c" code for more details on UTF-8 encoding. Note 41 | // that we assume that the buffer contains a valid UTF-8 sequence. 42 | 43 | // Read the next UTF-8 character. 44 | octet := emitter.buffer[pos] 45 | 46 | var w int 47 | var value rune 48 | switch { 49 | case octet&0x80 == 0x00: 50 | w, value = 1, rune(octet&0x7F) 51 | case octet&0xE0 == 0xC0: 52 | w, value = 2, rune(octet&0x1F) 53 | case octet&0xF0 == 0xE0: 54 | w, value = 3, rune(octet&0x0F) 55 | case octet&0xF8 == 0xF0: 56 | w, value = 4, rune(octet&0x07) 57 | } 58 | for k := 1; k < w; k++ { 59 | octet = emitter.buffer[pos+k] 60 | value = (value << 6) + (rune(octet) & 0x3F) 61 | } 62 | pos += w 63 | 64 | // Write the character. 65 | if value < 0x10000 { 66 | var b [2]byte 67 | b[high] = byte(value >> 8) 68 | b[low] = byte(value & 0xFF) 69 | emitter.raw_buffer = append(emitter.raw_buffer, b[0], b[1]) 70 | } else { 71 | // Write the character using a surrogate pair (check "reader.c"). 72 | var b [4]byte 73 | value -= 0x10000 74 | b[high] = byte(0xD8 + (value >> 18)) 75 | b[low] = byte((value >> 10) & 0xFF) 76 | b[high+2] = byte(0xDC + ((value >> 8) & 0xFF)) 77 | b[low+2] = byte(value & 0xFF) 78 | emitter.raw_buffer = append(emitter.raw_buffer, b[0], b[1], b[2], b[3]) 79 | } 80 | } 81 | 82 | // Write the raw buffer. 83 | if err := emitter.write_handler(emitter, emitter.raw_buffer); err != nil { 84 | return yaml_emitter_set_writer_error(emitter, "write error: "+err.Error()) 85 | } 86 | emitter.buffer_pos = 0 87 | emitter.raw_buffer = emitter.raw_buffer[:0] 88 | return true 89 | } 90 | -------------------------------------------------------------------------------- /vendor/gopkg.in/yaml.v2/yamlprivateh.go: -------------------------------------------------------------------------------- 1 | package yaml 2 | 3 | const ( 4 | // The size of the input raw buffer. 5 | input_raw_buffer_size = 512 6 | 7 | // The size of the input buffer. 8 | // It should be possible to decode the whole raw buffer. 9 | input_buffer_size = input_raw_buffer_size * 3 10 | 11 | // The size of the output buffer. 12 | output_buffer_size = 128 13 | 14 | // The size of the output raw buffer. 15 | // It should be possible to encode the whole output buffer. 16 | output_raw_buffer_size = (output_buffer_size*2 + 2) 17 | 18 | // The size of other stacks and queues. 19 | initial_stack_size = 16 20 | initial_queue_size = 16 21 | initial_string_size = 16 22 | ) 23 | 24 | // Check if the character at the specified position is an alphabetical 25 | // character, a digit, '_', or '-'. 26 | func is_alpha(b []byte, i int) bool { 27 | return b[i] >= '0' && b[i] <= '9' || b[i] >= 'A' && b[i] <= 'Z' || b[i] >= 'a' && b[i] <= 'z' || b[i] == '_' || b[i] == '-' 28 | } 29 | 30 | // Check if the character at the specified position is a digit. 31 | func is_digit(b []byte, i int) bool { 32 | return b[i] >= '0' && b[i] <= '9' 33 | } 34 | 35 | // Get the value of a digit. 36 | func as_digit(b []byte, i int) int { 37 | return int(b[i]) - '0' 38 | } 39 | 40 | // Check if the character at the specified position is a hex-digit. 41 | func is_hex(b []byte, i int) bool { 42 | return b[i] >= '0' && b[i] <= '9' || b[i] >= 'A' && b[i] <= 'F' || b[i] >= 'a' && b[i] <= 'f' 43 | } 44 | 45 | // Get the value of a hex-digit. 46 | func as_hex(b []byte, i int) int { 47 | bi := b[i] 48 | if bi >= 'A' && bi <= 'F' { 49 | return int(bi) - 'A' + 10 50 | } 51 | if bi >= 'a' && bi <= 'f' { 52 | return int(bi) - 'a' + 10 53 | } 54 | return int(bi) - '0' 55 | } 56 | 57 | // Check if the character is ASCII. 58 | func is_ascii(b []byte, i int) bool { 59 | return b[i] <= 0x7F 60 | } 61 | 62 | // Check if the character at the start of the buffer can be printed unescaped. 63 | func is_printable(b []byte, i int) bool { 64 | return ((b[i] == 0x0A) || // . == #x0A 65 | (b[i] >= 0x20 && b[i] <= 0x7E) || // #x20 <= . <= #x7E 66 | (b[i] == 0xC2 && b[i+1] >= 0xA0) || // #0xA0 <= . <= #xD7FF 67 | (b[i] > 0xC2 && b[i] < 0xED) || 68 | (b[i] == 0xED && b[i+1] < 0xA0) || 69 | (b[i] == 0xEE) || 70 | (b[i] == 0xEF && // #xE000 <= . <= #xFFFD 71 | !(b[i+1] == 0xBB && b[i+2] == 0xBF) && // && . != #xFEFF 72 | !(b[i+1] == 0xBF && (b[i+2] == 0xBE || b[i+2] == 0xBF)))) 73 | } 74 | 75 | // Check if the character at the specified position is NUL. 76 | func is_z(b []byte, i int) bool { 77 | return b[i] == 0x00 78 | } 79 | 80 | // Check if the beginning of the buffer is a BOM. 81 | func is_bom(b []byte, i int) bool { 82 | return b[0] == 0xEF && b[1] == 0xBB && b[2] == 0xBF 83 | } 84 | 85 | // Check if the character at the specified position is space. 86 | func is_space(b []byte, i int) bool { 87 | return b[i] == ' ' 88 | } 89 | 90 | // Check if the character at the specified position is tab. 91 | func is_tab(b []byte, i int) bool { 92 | return b[i] == '\t' 93 | } 94 | 95 | // Check if the character at the specified position is blank (space or tab). 96 | func is_blank(b []byte, i int) bool { 97 | //return is_space(b, i) || is_tab(b, i) 98 | return b[i] == ' ' || b[i] == '\t' 99 | } 100 | 101 | // Check if the character at the specified position is a line break. 102 | func is_break(b []byte, i int) bool { 103 | return (b[i] == '\r' || // CR (#xD) 104 | b[i] == '\n' || // LF (#xA) 105 | b[i] == 0xC2 && b[i+1] == 0x85 || // NEL (#x85) 106 | b[i] == 0xE2 && b[i+1] == 0x80 && b[i+2] == 0xA8 || // LS (#x2028) 107 | b[i] == 0xE2 && b[i+1] == 0x80 && b[i+2] == 0xA9) // PS (#x2029) 108 | } 109 | 110 | func is_crlf(b []byte, i int) bool { 111 | return b[i] == '\r' && b[i+1] == '\n' 112 | } 113 | 114 | // Check if the character is a line break or NUL. 115 | func is_breakz(b []byte, i int) bool { 116 | //return is_break(b, i) || is_z(b, i) 117 | return ( // is_break: 118 | b[i] == '\r' || // CR (#xD) 119 | b[i] == '\n' || // LF (#xA) 120 | b[i] == 0xC2 && b[i+1] == 0x85 || // NEL (#x85) 121 | b[i] == 0xE2 && b[i+1] == 0x80 && b[i+2] == 0xA8 || // LS (#x2028) 122 | b[i] == 0xE2 && b[i+1] == 0x80 && b[i+2] == 0xA9 || // PS (#x2029) 123 | // is_z: 124 | b[i] == 0) 125 | } 126 | 127 | // Check if the character is a line break, space, or NUL. 128 | func is_spacez(b []byte, i int) bool { 129 | //return is_space(b, i) || is_breakz(b, i) 130 | return ( // is_space: 131 | b[i] == ' ' || 132 | // is_breakz: 133 | b[i] == '\r' || // CR (#xD) 134 | b[i] == '\n' || // LF (#xA) 135 | b[i] == 0xC2 && b[i+1] == 0x85 || // NEL (#x85) 136 | b[i] == 0xE2 && b[i+1] == 0x80 && b[i+2] == 0xA8 || // LS (#x2028) 137 | b[i] == 0xE2 && b[i+1] == 0x80 && b[i+2] == 0xA9 || // PS (#x2029) 138 | b[i] == 0) 139 | } 140 | 141 | // Check if the character is a line break, space, tab, or NUL. 142 | func is_blankz(b []byte, i int) bool { 143 | //return is_blank(b, i) || is_breakz(b, i) 144 | return ( // is_blank: 145 | b[i] == ' ' || b[i] == '\t' || 146 | // is_breakz: 147 | b[i] == '\r' || // CR (#xD) 148 | b[i] == '\n' || // LF (#xA) 149 | b[i] == 0xC2 && b[i+1] == 0x85 || // NEL (#x85) 150 | b[i] == 0xE2 && b[i+1] == 0x80 && b[i+2] == 0xA8 || // LS (#x2028) 151 | b[i] == 0xE2 && b[i+1] == 0x80 && b[i+2] == 0xA9 || // PS (#x2029) 152 | b[i] == 0) 153 | } 154 | 155 | // Determine the width of the character. 156 | func width(b byte) int { 157 | // Don't replace these by a switch without first 158 | // confirming that it is being inlined. 159 | if b&0x80 == 0x00 { 160 | return 1 161 | } 162 | if b&0xE0 == 0xC0 { 163 | return 2 164 | } 165 | if b&0xF0 == 0xE0 { 166 | return 3 167 | } 168 | if b&0xF8 == 0xF0 { 169 | return 4 170 | } 171 | return 0 172 | 173 | } 174 | -------------------------------------------------------------------------------- /vendor/vendor.json: -------------------------------------------------------------------------------- 1 | { 2 | "comment": "", 3 | "ignore": "test", 4 | "package": [ 5 | { 6 | "checksumSHA1": "KmjnydoAbofMieIWm+it5OWERaM=", 7 | "path": "github.com/alecthomas/template", 8 | "revision": "a0175ee3bccc567396460bf5acd36800cb10c49c", 9 | "revisionTime": "2016-04-05T07:15:01Z" 10 | }, 11 | { 12 | "checksumSHA1": "3wt0pTXXeS+S93unwhGoLIyGX/Q=", 13 | "path": "github.com/alecthomas/template/parse", 14 | "revision": "a0175ee3bccc567396460bf5acd36800cb10c49c", 15 | "revisionTime": "2016-04-05T07:15:01Z" 16 | }, 17 | { 18 | "checksumSHA1": "fCc3grA7vIxfBru7R3SqjcW+oLI=", 19 | "path": "github.com/alecthomas/units", 20 | "revision": "2efee857e7cfd4f3d0138cc3cbb1b4966962b93a", 21 | "revisionTime": "2015-10-22T06:55:26Z" 22 | }, 23 | { 24 | "checksumSHA1": "uQzoJ70PJvWwIFPvMeshNTAu3t4=", 25 | "path": "github.com/cenk/backoff", 26 | "revision": "8edc80b07f38c27352fb186d971c628a6c32552b", 27 | "revisionTime": "2016-09-04T14:09:58Z" 28 | }, 29 | { 30 | "checksumSHA1": "dNYxHiBLalTqluak2/Z8c3RsSEM=", 31 | "path": "github.com/lib/pq", 32 | "revision": "50761b0867bd1d9d069276790bcd4a3bccf2324a", 33 | "revisionTime": "2016-08-31T22:25:20Z" 34 | }, 35 | { 36 | "checksumSHA1": "xppHi82MLqVx1eyQmbhTesAEjx8=", 37 | "path": "github.com/lib/pq/oid", 38 | "revision": "50761b0867bd1d9d069276790bcd4a3bccf2324a", 39 | "revisionTime": "2016-08-31T22:25:20Z" 40 | }, 41 | { 42 | "checksumSHA1": "pancewZW3HwGvpDwfH5Imrbadc4=", 43 | "path": "golang.org/x/net/context", 44 | "revision": "e45385e9b226f570b1f086bf287b25d3d4117776", 45 | "revisionTime": "2016-04-07T02:17:48Z" 46 | }, 47 | { 48 | "checksumSHA1": "EJMLw8rk55bsqmIpSMtVORJpSGo=", 49 | "path": "golang.org/x/net/context/ctxhttp", 50 | "revision": "e45385e9b226f570b1f086bf287b25d3d4117776", 51 | "revisionTime": "2016-04-07T02:17:48Z" 52 | }, 53 | { 54 | "checksumSHA1": "mktBVED98G2vv+OKcSgtnFVZC1Y=", 55 | "path": "golang.org/x/oauth2", 56 | "revision": "b0e2337fe6ec0c637fa4f123268b972f334504eb", 57 | "revisionTime": "2016-04-08T01:06:28Z" 58 | }, 59 | { 60 | "checksumSHA1": "HSRFs3mt2eHJBaK+6HEEv66xKyA=", 61 | "path": "golang.org/x/oauth2/google", 62 | "revision": "b0e2337fe6ec0c637fa4f123268b972f334504eb", 63 | "revisionTime": "2016-04-08T01:06:28Z" 64 | }, 65 | { 66 | "checksumSHA1": "W/GiDqzsagBnR7/yEvxatMhUDBs=", 67 | "path": "golang.org/x/oauth2/internal", 68 | "revision": "b0e2337fe6ec0c637fa4f123268b972f334504eb", 69 | "revisionTime": "2016-04-08T01:06:28Z" 70 | }, 71 | { 72 | "checksumSHA1": "4GaanJZHtrkglrx6a585C3I07+s=", 73 | "path": "golang.org/x/oauth2/jws", 74 | "revision": "b0e2337fe6ec0c637fa4f123268b972f334504eb", 75 | "revisionTime": "2016-04-08T01:06:28Z" 76 | }, 77 | { 78 | "checksumSHA1": "xifBSq0Pn6pIoPA/o3tyzq8X4Ds=", 79 | "path": "golang.org/x/oauth2/jwt", 80 | "revision": "b0e2337fe6ec0c637fa4f123268b972f334504eb", 81 | "revisionTime": "2016-04-08T01:06:28Z" 82 | }, 83 | { 84 | "checksumSHA1": "LuEX6w6pTkZhLz5Ow+gAqxrhbLU=", 85 | "path": "google.golang.org/api/bigquery/v2", 86 | "revision": "adba394bac5800ff2e620d040e9401528f5b7615", 87 | "revisionTime": "2016-09-27T03:03:17Z" 88 | }, 89 | { 90 | "checksumSHA1": "awFDzMy1r/KM9mrqgCI9WqkxXc8=", 91 | "path": "google.golang.org/api/gensupport", 92 | "revision": "adba394bac5800ff2e620d040e9401528f5b7615", 93 | "revisionTime": "2016-09-27T03:03:17Z" 94 | }, 95 | { 96 | "checksumSHA1": "yQREK/OWrz9PLljbr127+xFk6J0=", 97 | "path": "google.golang.org/api/googleapi", 98 | "revision": "9737cc9e103c00d06a8f3993361dec083df3d252", 99 | "revisionTime": "2016-04-08T06:59:26Z" 100 | }, 101 | { 102 | "checksumSHA1": "ii4ET3JHk3vkMUEcg+9t/1RZSUU=", 103 | "path": "google.golang.org/api/googleapi/internal/uritemplates", 104 | "revision": "9737cc9e103c00d06a8f3993361dec083df3d252", 105 | "revisionTime": "2016-04-08T06:59:26Z" 106 | }, 107 | { 108 | "checksumSHA1": "dQs4ijwWtYxz5KogjTOuPQDiTts=", 109 | "path": "google.golang.org/api/storagetransfer/v1", 110 | "revision": "9737cc9e103c00d06a8f3993361dec083df3d252", 111 | "revisionTime": "2016-04-08T06:59:26Z" 112 | }, 113 | { 114 | "checksumSHA1": "Wp8g9MHRmK8SwcyGVCoGtPx+5Lo=", 115 | "path": "google.golang.org/cloud/compute/metadata", 116 | "revision": "79ffda073da804f325135da5ff645a630a4d7625", 117 | "revisionTime": "2016-04-06T00:59:02Z" 118 | }, 119 | { 120 | "checksumSHA1": "U7dGDNwEHORvJFMoNSXErKE7ITg=", 121 | "path": "google.golang.org/cloud/internal", 122 | "revision": "79ffda073da804f325135da5ff645a630a4d7625", 123 | "revisionTime": "2016-04-06T00:59:02Z" 124 | }, 125 | { 126 | "checksumSHA1": "QPs8F/aqKAAQJr8dLc3CVQ5SxlM=", 127 | "path": "gopkg.in/alecthomas/kingpin.v2", 128 | "revision": "8cccfa8eb2e3183254457fb1749b2667fbc364c7", 129 | "revisionTime": "2016-02-17T09:03:01Z" 130 | }, 131 | { 132 | "checksumSHA1": "+OgOXBoiQ+X+C2dsAeiOHwBIEH0=", 133 | "path": "gopkg.in/yaml.v2", 134 | "revision": "a83829b6f1293c91addabc89d0571c246397bbf4", 135 | "revisionTime": "2016-03-01T20:40:22Z" 136 | } 137 | ], 138 | "rootPath": "github.com/uswitch/bqshift" 139 | } 140 | --------------------------------------------------------------------------------