aboutsummaryrefslogtreecommitdiffhomepage
path: root/vendor/github.com/hashicorp/go-getter
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/hashicorp/go-getter')
-rw-r--r--vendor/github.com/hashicorp/go-getter/.travis.yml15
-rw-r--r--vendor/github.com/hashicorp/go-getter/README.md81
-rw-r--r--vendor/github.com/hashicorp/go-getter/appveyor.yml2
-rw-r--r--vendor/github.com/hashicorp/go-getter/checksum.go314
-rw-r--r--vendor/github.com/hashicorp/go-getter/client.go140
-rw-r--r--vendor/github.com/hashicorp/go-getter/client_option.go46
-rw-r--r--vendor/github.com/hashicorp/go-getter/client_option_progress.go38
-rw-r--r--vendor/github.com/hashicorp/go-getter/common.go14
-rw-r--r--vendor/github.com/hashicorp/go-getter/copy_dir.go6
-rw-r--r--vendor/github.com/hashicorp/go-getter/decompress_tar.go32
-rw-r--r--vendor/github.com/hashicorp/go-getter/decompress_testing.go35
-rw-r--r--vendor/github.com/hashicorp/go-getter/decompress_zip.go2
-rw-r--r--vendor/github.com/hashicorp/go-getter/detect.go2
-rw-r--r--vendor/github.com/hashicorp/go-getter/detect_gcs.go43
-rw-r--r--vendor/github.com/hashicorp/go-getter/detect_git.go26
-rw-r--r--vendor/github.com/hashicorp/go-getter/detect_github.go26
-rw-r--r--vendor/github.com/hashicorp/go-getter/detect_ssh.go49
-rw-r--r--vendor/github.com/hashicorp/go-getter/get.go18
-rw-r--r--vendor/github.com/hashicorp/go-getter/get_base.go20
-rw-r--r--vendor/github.com/hashicorp/go-getter/get_file.go6
-rw-r--r--vendor/github.com/hashicorp/go-getter/get_file_copy.go29
-rw-r--r--vendor/github.com/hashicorp/go-getter/get_file_unix.go4
-rw-r--r--vendor/github.com/hashicorp/go-getter/get_file_windows.go24
-rw-r--r--vendor/github.com/hashicorp/go-getter/get_gcs.go172
-rw-r--r--vendor/github.com/hashicorp/go-getter/get_git.go81
-rw-r--r--vendor/github.com/hashicorp/go-getter/get_hg.go16
-rw-r--r--vendor/github.com/hashicorp/go-getter/get_http.go118
-rw-r--r--vendor/github.com/hashicorp/go-getter/get_mock.go2
-rw-r--r--vendor/github.com/hashicorp/go-getter/get_s3.go17
-rw-r--r--vendor/github.com/hashicorp/go-getter/go.mod22
-rw-r--r--vendor/github.com/hashicorp/go-getter/go.sum182
-rw-r--r--vendor/github.com/hashicorp/go-getter/helper/url/url_windows.go15
-rw-r--r--vendor/github.com/hashicorp/go-getter/source.go23
33 files changed, 1380 insertions, 240 deletions
diff --git a/vendor/github.com/hashicorp/go-getter/.travis.yml b/vendor/github.com/hashicorp/go-getter/.travis.yml
index da804c2..4fe9176 100644
--- a/vendor/github.com/hashicorp/go-getter/.travis.yml
+++ b/vendor/github.com/hashicorp/go-getter/.travis.yml
@@ -9,15 +9,16 @@ addons:
9 9
10language: go 10language: go
11 11
12os:
13 - linux
14 - osx
15
12go: 16go:
13 - 1.8.x 17 - "1.11.x"
14 - 1.9.x 18
15 - master 19before_script:
20 - go build ./cmd/go-getter
16 21
17branches: 22branches:
18 only: 23 only:
19 - master 24 - master
20
21matrix:
22 allow_failures:
23 - go: master
diff --git a/vendor/github.com/hashicorp/go-getter/README.md b/vendor/github.com/hashicorp/go-getter/README.md
index 40ace74..ba4df6f 100644
--- a/vendor/github.com/hashicorp/go-getter/README.md
+++ b/vendor/github.com/hashicorp/go-getter/README.md
@@ -71,6 +71,7 @@ can be augmented at runtime by implementing the `Getter` interface.
71 * Mercurial 71 * Mercurial
72 * HTTP 72 * HTTP
73 * Amazon S3 73 * Amazon S3
74 * Google GCP
74 75
75In addition to the above protocols, go-getter has what are called "detectors." 76In addition to the above protocols, go-getter has what are called "detectors."
76These take a URL and attempt to automatically choose the best protocol for 77These take a URL and attempt to automatically choose the best protocol for
@@ -97,7 +98,7 @@ would download the given HTTP URL using the Git protocol.
97 98
98Forced protocols will also override any detectors. 99Forced protocols will also override any detectors.
99 100
100In the absense of a forced protocol, detectors may be run on the URL, transforming 101In the absence of a forced protocol, detectors may be run on the URL, transforming
101the protocol anyways. The above example would've used the Git protocol either 102the protocol anyways. The above example would've used the Git protocol either
102way since the Git detector would've detected it was a GitHub URL. 103way since the Git detector would've detected it was a GitHub URL.
103 104
@@ -155,20 +156,44 @@ For file downloads of any protocol, go-getter can automatically verify
155a checksum for you. Note that checksumming only works for downloading files, 156a checksum for you. Note that checksumming only works for downloading files,
156not directories, but checksumming will work for any protocol. 157not directories, but checksumming will work for any protocol.
157 158
158To checksum a file, append a `checksum` query parameter to the URL. 159To checksum a file, append a `checksum` query parameter to the URL. go-getter
159The paramter value should be in the format of `type:value`, where 160will parse out this query parameter automatically and use it to verify the
160type is "md5", "sha1", "sha256", or "sha512". The "value" should be 161checksum. The parameter value can be in the format of `type:value` or just
161the actual checksum value. go-getter will parse out this query parameter 162`value`, where type is "md5", "sha1", "sha256", "sha512" or "file" . The
162automatically and use it to verify the checksum. An example URL 163"value" should be the actual checksum value or download URL for "file". When
163is shown below: 164`type` part is omitted, type will be guessed based on the length of the
165checksum string. Examples:
164 166
165``` 167```
166./foo.txt?checksum=md5:b7d96c89d09d9e204f5fedc4d5d55b21 168./foo.txt?checksum=md5:b7d96c89d09d9e204f5fedc4d5d55b21
167``` 169```
168 170
171```
172./foo.txt?checksum=b7d96c89d09d9e204f5fedc4d5d55b21
173```
174
175```
176./foo.txt?checksum=file:./foo.txt.sha256sum
177```
178
179When checksumming from a file - ex: with `checksum=file:url` - go-getter will
180get the file linked in the URL after `file:` using the same configuration. For
181example, in `file:http://releases.ubuntu.com/cosmic/MD5SUMS` go-getter will
182download a checksum file under the aforementioned url using the http protocol.
183All protocols supported by go-getter can be used. The checksum file will be
184downloaded in a temporary file then parsed. The destination of the temporary
185file can be changed by setting system specific environment variables: `TMPDIR`
186for unix; `TMP`, `TEMP` or `USERPROFILE` on windows. Read godoc of
187[os.TempDir](https://golang.org/pkg/os/#TempDir) for more information on the
188temporary directory selection. Content of files are expected to be BSD or GNU
189style. Once go-getter is done with the checksum file; it is deleted.
190
169The checksum query parameter is never sent to the backend protocol 191The checksum query parameter is never sent to the backend protocol
170implementation. It is used at a higher level by go-getter itself. 192implementation. It is used at a higher level by go-getter itself.
171 193
194If the destination file exists and the checksums match: download
195will be skipped.
196
172### Unarchiving 197### Unarchiving
173 198
174go-getter will automatically unarchive files into a file or directory 199go-getter will automatically unarchive files into a file or directory
@@ -215,11 +240,12 @@ from the URL before going to the final protocol downloader.
215 240
216## Protocol-Specific Options 241## Protocol-Specific Options
217 242
218This section documents the protocol-specific options that can be specified 243This section documents the protocol-specific options that can be specified for
219for go-getter. These options should be appended to the input as normal query 244go-getter. These options should be appended to the input as normal query
220parameters. Depending on the usage of go-getter, applications may provide 245parameters ([HTTP headers](#headers) are an exception to this, however).
221alternate ways of inputting options. For example, [Nomad](https://www.nomadproject.io) 246Depending on the usage of go-getter, applications may provide alternate ways of
222provides a nice options block for specifying options rather than in the URL. 247inputting options. For example, [Nomad](https://www.nomadproject.io) provides a
248nice options block for specifying options rather than in the URL.
223 249
224## General (All Protocols) 250## General (All Protocols)
225 251
@@ -250,6 +276,19 @@ None
250 from a private key file on disk, you would run `base64 -w0 <file>`. 276 from a private key file on disk, you would run `base64 -w0 <file>`.
251 277
252 **Note**: Git 2.3+ is required to use this feature. 278 **Note**: Git 2.3+ is required to use this feature.
279
280 * `depth` - The Git clone depth. The provided number specifies the last `n`
281 revisions to clone from the repository.
282
283
284The `git` getter accepts both URL-style SSH addresses like
285`git::ssh://git@example.com/foo/bar`, and "scp-style" addresses like
286`git::git@example.com/foo/bar`. In the latter case, omitting the `git::`
287force prefix is allowed if the username prefix is exactly `git@`.
288
289The "scp-style" addresses _cannot_ be used in conjunction with the `ssh://`
290scheme prefix, because in that case the colon is used to mark an optional
291port number to connect on, rather than to delimit the path from the host.
253 292
254### Mercurial (`hg`) 293### Mercurial (`hg`)
255 294
@@ -263,6 +302,13 @@ To use HTTP basic authentication with go-getter, simply prepend `username:passwo
263hostname in the URL such as `https://Aladdin:OpenSesame@www.example.com/index.html`. All special 302hostname in the URL such as `https://Aladdin:OpenSesame@www.example.com/index.html`. All special
264characters, including the username and password, must be URL encoded. 303characters, including the username and password, must be URL encoded.
265 304
305#### Headers
306
307Optional request headers can be added by supplying them in a custom
308[`HttpGetter`](https://godoc.org/github.com/hashicorp/go-getter#HttpGetter)
309(_not_ as query parameters like most other options). These headers will be sent
310out on every request the getter in question makes.
311
266### S3 (`s3`) 312### S3 (`s3`)
267 313
268S3 takes various access configurations in the URL. Note that it will also 314S3 takes various access configurations in the URL. Note that it will also
@@ -299,3 +345,14 @@ Some examples for these addressing schemes:
299- bucket.s3-eu-west-1.amazonaws.com/foo/bar 345- bucket.s3-eu-west-1.amazonaws.com/foo/bar
300- "s3::http://127.0.0.1:9000/test-bucket/hello.txt?aws_access_key_id=KEYID&aws_access_key_secret=SECRETKEY&region=us-east-2" 346- "s3::http://127.0.0.1:9000/test-bucket/hello.txt?aws_access_key_id=KEYID&aws_access_key_secret=SECRETKEY&region=us-east-2"
301 347
348### GCS (`gcs`)
349
350#### GCS Authentication
351
352In order to access to GCS, authentication credentials should be provided. More information can be found [here](https://cloud.google.com/docs/authentication/getting-started)
353
354#### GCS Bucket Examples
355
356- gcs::https://www.googleapis.com/storage/v1/bucket
357- gcs::https://www.googleapis.com/storage/v1/bucket/foo.zip
358- www.googleapis.com/storage/v1/bucket/foo
diff --git a/vendor/github.com/hashicorp/go-getter/appveyor.yml b/vendor/github.com/hashicorp/go-getter/appveyor.yml
index ec48d45..1e8718e 100644
--- a/vendor/github.com/hashicorp/go-getter/appveyor.yml
+++ b/vendor/github.com/hashicorp/go-getter/appveyor.yml
@@ -13,4 +13,4 @@ install:
13 13
14 go get -d -v -t ./... 14 go get -d -v -t ./...
15build_script: 15build_script:
16- cmd: go test -v ./... 16- cmd: go test ./...
diff --git a/vendor/github.com/hashicorp/go-getter/checksum.go b/vendor/github.com/hashicorp/go-getter/checksum.go
new file mode 100644
index 0000000..bea7ed1
--- /dev/null
+++ b/vendor/github.com/hashicorp/go-getter/checksum.go
@@ -0,0 +1,314 @@
1package getter
2
3import (
4 "bufio"
5 "bytes"
6 "crypto/md5"
7 "crypto/sha1"
8 "crypto/sha256"
9 "crypto/sha512"
10 "encoding/hex"
11 "fmt"
12 "hash"
13 "io"
14 "net/url"
15 "os"
16 "path/filepath"
17 "strings"
18
19 urlhelper "github.com/hashicorp/go-getter/helper/url"
20)
21
22// fileChecksum helps verifying the checksum for a file.
23type fileChecksum struct {
24 Type string
25 Hash hash.Hash
26 Value []byte
27 Filename string
28}
29
30// A ChecksumError is returned when a checksum differs
31type ChecksumError struct {
32 Hash hash.Hash
33 Actual []byte
34 Expected []byte
35 File string
36}
37
38func (cerr *ChecksumError) Error() string {
39 if cerr == nil {
40 return "<nil>"
41 }
42 return fmt.Sprintf(
43 "Checksums did not match for %s.\nExpected: %s\nGot: %s\n%T",
44 cerr.File,
45 hex.EncodeToString(cerr.Expected),
46 hex.EncodeToString(cerr.Actual),
47 cerr.Hash, // ex: *sha256.digest
48 )
49}
50
51// checksum is a simple method to compute the checksum of a source file
52// and compare it to the given expected value.
53func (c *fileChecksum) checksum(source string) error {
54 f, err := os.Open(source)
55 if err != nil {
56 return fmt.Errorf("Failed to open file for checksum: %s", err)
57 }
58 defer f.Close()
59
60 c.Hash.Reset()
61 if _, err := io.Copy(c.Hash, f); err != nil {
62 return fmt.Errorf("Failed to hash: %s", err)
63 }
64
65 if actual := c.Hash.Sum(nil); !bytes.Equal(actual, c.Value) {
66 return &ChecksumError{
67 Hash: c.Hash,
68 Actual: actual,
69 Expected: c.Value,
70 File: source,
71 }
72 }
73
74 return nil
75}
76
77// extractChecksum will return a fileChecksum based on the 'checksum'
78// parameter of u.
79// ex:
80// http://hashicorp.com/terraform?checksum=<checksumValue>
81// http://hashicorp.com/terraform?checksum=<checksumType>:<checksumValue>
82// http://hashicorp.com/terraform?checksum=file:<checksum_url>
83// when checksumming from a file, extractChecksum will go get checksum_url
84// in a temporary directory, parse the content of the file then delete it.
85// Content of files are expected to be BSD style or GNU style.
86//
87// BSD-style checksum:
88// MD5 (file1) = <checksum>
89// MD5 (file2) = <checksum>
90//
91// GNU-style:
92// <checksum> file1
93// <checksum> *file2
94//
95// see parseChecksumLine for more detail on checksum file parsing
96func (c *Client) extractChecksum(u *url.URL) (*fileChecksum, error) {
97 q := u.Query()
98 v := q.Get("checksum")
99
100 if v == "" {
101 return nil, nil
102 }
103
104 vs := strings.SplitN(v, ":", 2)
105 switch len(vs) {
106 case 2:
107 break // good
108 default:
109 // here, we try to guess the checksum from it's length
110 // if the type was not passed
111 return newChecksumFromValue(v, filepath.Base(u.EscapedPath()))
112 }
113
114 checksumType, checksumValue := vs[0], vs[1]
115
116 switch checksumType {
117 case "file":
118 return c.checksumFromFile(checksumValue, u)
119 default:
120 return newChecksumFromType(checksumType, checksumValue, filepath.Base(u.EscapedPath()))
121 }
122}
123
124func newChecksum(checksumValue, filename string) (*fileChecksum, error) {
125 c := &fileChecksum{
126 Filename: filename,
127 }
128 var err error
129 c.Value, err = hex.DecodeString(checksumValue)
130 if err != nil {
131 return nil, fmt.Errorf("invalid checksum: %s", err)
132 }
133 return c, nil
134}
135
136func newChecksumFromType(checksumType, checksumValue, filename string) (*fileChecksum, error) {
137 c, err := newChecksum(checksumValue, filename)
138 if err != nil {
139 return nil, err
140 }
141
142 c.Type = strings.ToLower(checksumType)
143 switch c.Type {
144 case "md5":
145 c.Hash = md5.New()
146 case "sha1":
147 c.Hash = sha1.New()
148 case "sha256":
149 c.Hash = sha256.New()
150 case "sha512":
151 c.Hash = sha512.New()
152 default:
153 return nil, fmt.Errorf(
154 "unsupported checksum type: %s", checksumType)
155 }
156
157 return c, nil
158}
159
160func newChecksumFromValue(checksumValue, filename string) (*fileChecksum, error) {
161 c, err := newChecksum(checksumValue, filename)
162 if err != nil {
163 return nil, err
164 }
165
166 switch len(c.Value) {
167 case md5.Size:
168 c.Hash = md5.New()
169 c.Type = "md5"
170 case sha1.Size:
171 c.Hash = sha1.New()
172 c.Type = "sha1"
173 case sha256.Size:
174 c.Hash = sha256.New()
175 c.Type = "sha256"
176 case sha512.Size:
177 c.Hash = sha512.New()
178 c.Type = "sha512"
179 default:
180 return nil, fmt.Errorf("Unknown type for checksum %s", checksumValue)
181 }
182
183 return c, nil
184}
185
186// checksumsFromFile will return all the fileChecksums found in file
187//
188// checksumsFromFile will try to guess the hashing algorithm based on content
189// of checksum file
190//
191// checksumsFromFile will only return checksums for files that match file
192// behind src
193func (c *Client) checksumFromFile(checksumFile string, src *url.URL) (*fileChecksum, error) {
194 checksumFileURL, err := urlhelper.Parse(checksumFile)
195 if err != nil {
196 return nil, err
197 }
198
199 tempfile, err := tmpFile("", filepath.Base(checksumFileURL.Path))
200 if err != nil {
201 return nil, err
202 }
203 defer os.Remove(tempfile)
204
205 c2 := &Client{
206 Ctx: c.Ctx,
207 Getters: c.Getters,
208 Decompressors: c.Decompressors,
209 Detectors: c.Detectors,
210 Pwd: c.Pwd,
211 Dir: false,
212 Src: checksumFile,
213 Dst: tempfile,
214 ProgressListener: c.ProgressListener,
215 }
216 if err = c2.Get(); err != nil {
217 return nil, fmt.Errorf(
218 "Error downloading checksum file: %s", err)
219 }
220
221 filename := filepath.Base(src.Path)
222 absPath, err := filepath.Abs(src.Path)
223 if err != nil {
224 return nil, err
225 }
226 checksumFileDir := filepath.Dir(checksumFileURL.Path)
227 relpath, err := filepath.Rel(checksumFileDir, absPath)
228 switch {
229 case err == nil ||
230 err.Error() == "Rel: can't make "+absPath+" relative to "+checksumFileDir:
231 // ex: on windows C:\gopath\...\content.txt cannot be relative to \
232 // which is okay, may be another expected path will work.
233 break
234 default:
235 return nil, err
236 }
237
238 // possible file identifiers:
239 options := []string{
240 filename, // ubuntu-14.04.1-server-amd64.iso
241 "*" + filename, // *ubuntu-14.04.1-server-amd64.iso Standard checksum
242 "?" + filename, // ?ubuntu-14.04.1-server-amd64.iso shasum -p
243 relpath, // dir/ubuntu-14.04.1-server-amd64.iso
244 "./" + relpath, // ./dir/ubuntu-14.04.1-server-amd64.iso
245 absPath, // fullpath; set if local
246 }
247
248 f, err := os.Open(tempfile)
249 if err != nil {
250 return nil, fmt.Errorf(
251 "Error opening downloaded file: %s", err)
252 }
253 defer f.Close()
254 rd := bufio.NewReader(f)
255 for {
256 line, err := rd.ReadString('\n')
257 if err != nil {
258 if err != io.EOF {
259 return nil, fmt.Errorf(
260 "Error reading checksum file: %s", err)
261 }
262 break
263 }
264 checksum, err := parseChecksumLine(line)
265 if err != nil || checksum == nil {
266 continue
267 }
268 if checksum.Filename == "" {
269 // filename not sure, let's try
270 return checksum, nil
271 }
272 // make sure the checksum is for the right file
273 for _, option := range options {
274 if option != "" && checksum.Filename == option {
275 // any checksum will work so we return the first one
276 return checksum, nil
277 }
278 }
279 }
280 return nil, fmt.Errorf("no checksum found in: %s", checksumFile)
281}
282
283// parseChecksumLine takes a line from a checksum file and returns
284// checksumType, checksumValue and filename parseChecksumLine guesses the style
285// of the checksum BSD vs GNU by splitting the line and by counting the parts.
286// of a line.
287// for BSD type sums parseChecksumLine guesses the hashing algorithm
288// by checking the length of the checksum.
289func parseChecksumLine(line string) (*fileChecksum, error) {
290 parts := strings.Fields(line)
291
292 switch len(parts) {
293 case 4:
294 // BSD-style checksum:
295 // MD5 (file1) = <checksum>
296 // MD5 (file2) = <checksum>
297 if len(parts[1]) <= 2 ||
298 parts[1][0] != '(' || parts[1][len(parts[1])-1] != ')' {
299 return nil, fmt.Errorf(
300 "Unexpected BSD-style-checksum filename format: %s", line)
301 }
302 filename := parts[1][1 : len(parts[1])-1]
303 return newChecksumFromType(parts[0], parts[3], filename)
304 case 2:
305 // GNU-style:
306 // <checksum> file1
307 // <checksum> *file2
308 return newChecksumFromValue(parts[0], parts[1])
309 case 0:
310 return nil, nil // empty line
311 default:
312 return newChecksumFromValue(parts[0], "")
313 }
314}
diff --git a/vendor/github.com/hashicorp/go-getter/client.go b/vendor/github.com/hashicorp/go-getter/client.go
index 300301c..007a78b 100644
--- a/vendor/github.com/hashicorp/go-getter/client.go
+++ b/vendor/github.com/hashicorp/go-getter/client.go
@@ -1,15 +1,8 @@
1package getter 1package getter
2 2
3import ( 3import (
4 "bytes" 4 "context"
5 "crypto/md5"
6 "crypto/sha1"
7 "crypto/sha256"
8 "crypto/sha512"
9 "encoding/hex"
10 "fmt" 5 "fmt"
11 "hash"
12 "io"
13 "io/ioutil" 6 "io/ioutil"
14 "os" 7 "os"
15 "path/filepath" 8 "path/filepath"
@@ -17,7 +10,7 @@ import (
17 "strings" 10 "strings"
18 11
19 urlhelper "github.com/hashicorp/go-getter/helper/url" 12 urlhelper "github.com/hashicorp/go-getter/helper/url"
20 "github.com/hashicorp/go-safetemp" 13 safetemp "github.com/hashicorp/go-safetemp"
21) 14)
22 15
23// Client is a client for downloading things. 16// Client is a client for downloading things.
@@ -26,6 +19,9 @@ import (
26// Using a client directly allows more fine-grained control over how downloading 19// Using a client directly allows more fine-grained control over how downloading
27// is done, as well as customizing the protocols supported. 20// is done, as well as customizing the protocols supported.
28type Client struct { 21type Client struct {
22 // Ctx for cancellation
23 Ctx context.Context
24
29 // Src is the source URL to get. 25 // Src is the source URL to get.
30 // 26 //
31 // Dst is the path to save the downloaded thing as. If Dir is set to 27 // Dst is the path to save the downloaded thing as. If Dir is set to
@@ -62,10 +58,20 @@ type Client struct {
62 // 58 //
63 // WARNING: deprecated. If Mode is set, that will take precedence. 59 // WARNING: deprecated. If Mode is set, that will take precedence.
64 Dir bool 60 Dir bool
61
62 // ProgressListener allows to track file downloads.
63 // By default a no op progress listener is used.
64 ProgressListener ProgressTracker
65
66 Options []ClientOption
65} 67}
66 68
67// Get downloads the configured source to the destination. 69// Get downloads the configured source to the destination.
68func (c *Client) Get() error { 70func (c *Client) Get() error {
71 if err := c.Configure(c.Options...); err != nil {
72 return err
73 }
74
69 // Store this locally since there are cases we swap this 75 // Store this locally since there are cases we swap this
70 mode := c.Mode 76 mode := c.Mode
71 if mode == ClientModeInvalid { 77 if mode == ClientModeInvalid {
@@ -76,18 +82,7 @@ func (c *Client) Get() error {
76 } 82 }
77 } 83 }
78 84
79 // Default decompressor value 85 src, err := Detect(c.Src, c.Pwd, c.Detectors)
80 decompressors := c.Decompressors
81 if decompressors == nil {
82 decompressors = Decompressors
83 }
84
85 // Detect the URL. This is safe if it is already detected.
86 detectors := c.Detectors
87 if detectors == nil {
88 detectors = Detectors
89 }
90 src, err := Detect(c.Src, c.Pwd, detectors)
91 if err != nil { 86 if err != nil {
92 return err 87 return err
93 } 88 }
@@ -119,12 +114,7 @@ func (c *Client) Get() error {
119 force = u.Scheme 114 force = u.Scheme
120 } 115 }
121 116
122 getters := c.Getters 117 g, ok := c.Getters[force]
123 if getters == nil {
124 getters = Getters
125 }
126
127 g, ok := getters[force]
128 if !ok { 118 if !ok {
129 return fmt.Errorf( 119 return fmt.Errorf(
130 "download not supported for scheme '%s'", force) 120 "download not supported for scheme '%s'", force)
@@ -150,7 +140,7 @@ func (c *Client) Get() error {
150 if archiveV == "" { 140 if archiveV == "" {
151 // We don't appear to... but is it part of the filename? 141 // We don't appear to... but is it part of the filename?
152 matchingLen := 0 142 matchingLen := 0
153 for k, _ := range decompressors { 143 for k := range c.Decompressors {
154 if strings.HasSuffix(u.Path, "."+k) && len(k) > matchingLen { 144 if strings.HasSuffix(u.Path, "."+k) && len(k) > matchingLen {
155 archiveV = k 145 archiveV = k
156 matchingLen = len(k) 146 matchingLen = len(k)
@@ -163,7 +153,7 @@ func (c *Client) Get() error {
163 // real path. 153 // real path.
164 var decompressDst string 154 var decompressDst string
165 var decompressDir bool 155 var decompressDir bool
166 decompressor := decompressors[archiveV] 156 decompressor := c.Decompressors[archiveV]
167 if decompressor != nil { 157 if decompressor != nil {
168 // Create a temporary directory to store our archive. We delete 158 // Create a temporary directory to store our archive. We delete
169 // this at the end of everything. 159 // this at the end of everything.
@@ -182,44 +172,16 @@ func (c *Client) Get() error {
182 mode = ClientModeFile 172 mode = ClientModeFile
183 } 173 }
184 174
185 // Determine if we have a checksum 175 // Determine checksum if we have one
186 var checksumHash hash.Hash 176 checksum, err := c.extractChecksum(u)
187 var checksumValue []byte 177 if err != nil {
188 if v := q.Get("checksum"); v != "" { 178 return fmt.Errorf("invalid checksum: %s", err)
189 // Delete the query parameter if we have it.
190 q.Del("checksum")
191 u.RawQuery = q.Encode()
192
193 // Determine the checksum hash type
194 checksumType := ""
195 idx := strings.Index(v, ":")
196 if idx > -1 {
197 checksumType = v[:idx]
198 }
199 switch checksumType {
200 case "md5":
201 checksumHash = md5.New()
202 case "sha1":
203 checksumHash = sha1.New()
204 case "sha256":
205 checksumHash = sha256.New()
206 case "sha512":
207 checksumHash = sha512.New()
208 default:
209 return fmt.Errorf(
210 "unsupported checksum type: %s", checksumType)
211 }
212
213 // Get the remainder of the value and parse it into bytes
214 b, err := hex.DecodeString(v[idx+1:])
215 if err != nil {
216 return fmt.Errorf("invalid checksum: %s", err)
217 }
218
219 // Set our value
220 checksumValue = b
221 } 179 }
222 180
181 // Delete the query parameter if we have it.
182 q.Del("checksum")
183 u.RawQuery = q.Encode()
184
223 if mode == ClientModeAny { 185 if mode == ClientModeAny {
224 // Ask the getter which client mode to use 186 // Ask the getter which client mode to use
225 mode, err = g.ClientMode(u) 187 mode, err = g.ClientMode(u)
@@ -248,15 +210,24 @@ func (c *Client) Get() error {
248 // If we're not downloading a directory, then just download the file 210 // If we're not downloading a directory, then just download the file
249 // and return. 211 // and return.
250 if mode == ClientModeFile { 212 if mode == ClientModeFile {
251 err := g.GetFile(dst, u) 213 getFile := true
252 if err != nil { 214 if checksum != nil {
253 return err 215 if err := checksum.checksum(dst); err == nil {
216 // don't get the file if the checksum of dst is correct
217 getFile = false
218 }
254 } 219 }
255 220 if getFile {
256 if checksumHash != nil { 221 err := g.GetFile(dst, u)
257 if err := checksum(dst, checksumHash, checksumValue); err != nil { 222 if err != nil {
258 return err 223 return err
259 } 224 }
225
226 if checksum != nil {
227 if err := checksum.checksum(dst); err != nil {
228 return err
229 }
230 }
260 } 231 }
261 232
262 if decompressor != nil { 233 if decompressor != nil {
@@ -291,7 +262,7 @@ func (c *Client) Get() error {
291 if decompressor == nil { 262 if decompressor == nil {
292 // If we're getting a directory, then this is an error. You cannot 263 // If we're getting a directory, then this is an error. You cannot
293 // checksum a directory. TODO: test 264 // checksum a directory. TODO: test
294 if checksumHash != nil { 265 if checksum != nil {
295 return fmt.Errorf( 266 return fmt.Errorf(
296 "checksum cannot be specified for directory download") 267 "checksum cannot be specified for directory download")
297 } 268 }
@@ -320,30 +291,7 @@ func (c *Client) Get() error {
320 return err 291 return err
321 } 292 }
322 293
323 return copyDir(realDst, subDir, false) 294 return copyDir(c.Ctx, realDst, subDir, false)
324 }
325
326 return nil
327}
328
329// checksum is a simple method to compute the checksum of a source file
330// and compare it to the given expected value.
331func checksum(source string, h hash.Hash, v []byte) error {
332 f, err := os.Open(source)
333 if err != nil {
334 return fmt.Errorf("Failed to open file for checksum: %s", err)
335 }
336 defer f.Close()
337
338 if _, err := io.Copy(h, f); err != nil {
339 return fmt.Errorf("Failed to hash: %s", err)
340 }
341
342 if actual := h.Sum(nil); !bytes.Equal(actual, v) {
343 return fmt.Errorf(
344 "Checksums did not match.\nExpected: %s\nGot: %s",
345 hex.EncodeToString(v),
346 hex.EncodeToString(actual))
347 } 295 }
348 296
349 return nil 297 return nil
diff --git a/vendor/github.com/hashicorp/go-getter/client_option.go b/vendor/github.com/hashicorp/go-getter/client_option.go
new file mode 100644
index 0000000..c1ee413
--- /dev/null
+++ b/vendor/github.com/hashicorp/go-getter/client_option.go
@@ -0,0 +1,46 @@
1package getter
2
3import "context"
4
5// A ClientOption allows to configure a client
6type ClientOption func(*Client) error
7
8// Configure configures a client with options.
9func (c *Client) Configure(opts ...ClientOption) error {
10 if c.Ctx == nil {
11 c.Ctx = context.Background()
12 }
13 c.Options = opts
14 for _, opt := range opts {
15 err := opt(c)
16 if err != nil {
17 return err
18 }
19 }
20 // Default decompressor values
21 if c.Decompressors == nil {
22 c.Decompressors = Decompressors
23 }
24 // Default detector values
25 if c.Detectors == nil {
26 c.Detectors = Detectors
27 }
28 // Default getter values
29 if c.Getters == nil {
30 c.Getters = Getters
31 }
32
33 for _, getter := range c.Getters {
34 getter.SetClient(c)
35 }
36 return nil
37}
38
39// WithContext allows to pass a context to operation
40// in order to be able to cancel a download in progress.
41func WithContext(ctx context.Context) func(*Client) error {
42 return func(c *Client) error {
43 c.Ctx = ctx
44 return nil
45 }
46}
diff --git a/vendor/github.com/hashicorp/go-getter/client_option_progress.go b/vendor/github.com/hashicorp/go-getter/client_option_progress.go
new file mode 100644
index 0000000..9b185f7
--- /dev/null
+++ b/vendor/github.com/hashicorp/go-getter/client_option_progress.go
@@ -0,0 +1,38 @@
1package getter
2
3import (
4 "io"
5)
6
7// WithProgress allows for a user to track
8// the progress of a download.
9// For example by displaying a progress bar with
10// current download.
11// Not all getters have progress support yet.
12func WithProgress(pl ProgressTracker) func(*Client) error {
13 return func(c *Client) error {
14 c.ProgressListener = pl
15 return nil
16 }
17}
18
19// ProgressTracker allows to track the progress of downloads.
20type ProgressTracker interface {
21 // TrackProgress should be called when
22 // a new object is being downloaded.
23 // src is the location the file is
24 // downloaded from.
25 // currentSize is the current size of
26 // the file in case it is a partial
27 // download.
28 // totalSize is the total size in bytes,
29 // size can be zero if the file size
30 // is not known.
31 // stream is the file being downloaded, every
32 // written byte will add up to processed size.
33 //
34 // TrackProgress returns a ReadCloser that wraps the
35 // download in progress ( stream ).
36 // When the download is finished, body shall be closed.
37 TrackProgress(src string, currentSize, totalSize int64, stream io.ReadCloser) (body io.ReadCloser)
38}
diff --git a/vendor/github.com/hashicorp/go-getter/common.go b/vendor/github.com/hashicorp/go-getter/common.go
new file mode 100644
index 0000000..d2afd8a
--- /dev/null
+++ b/vendor/github.com/hashicorp/go-getter/common.go
@@ -0,0 +1,14 @@
1package getter
2
3import (
4 "io/ioutil"
5)
6
7func tmpFile(dir, pattern string) (string, error) {
8 f, err := ioutil.TempFile(dir, pattern)
9 if err != nil {
10 return "", err
11 }
12 f.Close()
13 return f.Name(), nil
14}
diff --git a/vendor/github.com/hashicorp/go-getter/copy_dir.go b/vendor/github.com/hashicorp/go-getter/copy_dir.go
index 2f58e8a..641fe6d 100644
--- a/vendor/github.com/hashicorp/go-getter/copy_dir.go
+++ b/vendor/github.com/hashicorp/go-getter/copy_dir.go
@@ -1,7 +1,7 @@
1package getter 1package getter
2 2
3import ( 3import (
4 "io" 4 "context"
5 "os" 5 "os"
6 "path/filepath" 6 "path/filepath"
7 "strings" 7 "strings"
@@ -11,7 +11,7 @@ import (
11// should already exist. 11// should already exist.
12// 12//
13// If ignoreDot is set to true, then dot-prefixed files/folders are ignored. 13// If ignoreDot is set to true, then dot-prefixed files/folders are ignored.
14func copyDir(dst string, src string, ignoreDot bool) error { 14func copyDir(ctx context.Context, dst string, src string, ignoreDot bool) error {
15 src, err := filepath.EvalSymlinks(src) 15 src, err := filepath.EvalSymlinks(src)
16 if err != nil { 16 if err != nil {
17 return err 17 return err
@@ -66,7 +66,7 @@ func copyDir(dst string, src string, ignoreDot bool) error {
66 } 66 }
67 defer dstF.Close() 67 defer dstF.Close()
68 68
69 if _, err := io.Copy(dstF, srcF); err != nil { 69 if _, err := Copy(ctx, dstF, srcF); err != nil {
70 return err 70 return err
71 } 71 }
72 72
diff --git a/vendor/github.com/hashicorp/go-getter/decompress_tar.go b/vendor/github.com/hashicorp/go-getter/decompress_tar.go
index 39cb392..b6986a2 100644
--- a/vendor/github.com/hashicorp/go-getter/decompress_tar.go
+++ b/vendor/github.com/hashicorp/go-getter/decompress_tar.go
@@ -6,6 +6,7 @@ import (
6 "io" 6 "io"
7 "os" 7 "os"
8 "path/filepath" 8 "path/filepath"
9 "time"
9) 10)
10 11
11// untar is a shared helper for untarring an archive. The reader should provide 12// untar is a shared helper for untarring an archive. The reader should provide
@@ -14,6 +15,7 @@ func untar(input io.Reader, dst, src string, dir bool) error {
14 tarR := tar.NewReader(input) 15 tarR := tar.NewReader(input)
15 done := false 16 done := false
16 dirHdrs := []*tar.Header{} 17 dirHdrs := []*tar.Header{}
18 now := time.Now()
17 for { 19 for {
18 hdr, err := tarR.Next() 20 hdr, err := tarR.Next()
19 if err == io.EOF { 21 if err == io.EOF {
@@ -95,17 +97,37 @@ func untar(input io.Reader, dst, src string, dir bool) error {
95 return err 97 return err
96 } 98 }
97 99
98 // Set the access and modification time 100 // Set the access and modification time if valid, otherwise default to current time
99 if err := os.Chtimes(path, hdr.AccessTime, hdr.ModTime); err != nil { 101 aTime := now
102 mTime := now
103 if hdr.AccessTime.Unix() > 0 {
104 aTime = hdr.AccessTime
105 }
106 if hdr.ModTime.Unix() > 0 {
107 mTime = hdr.ModTime
108 }
109 if err := os.Chtimes(path, aTime, mTime); err != nil {
100 return err 110 return err
101 } 111 }
102 } 112 }
103 113
104 // Adding a file or subdirectory changes the mtime of a directory 114 // Perform a final pass over extracted directories to update metadata
105 // We therefore wait until we've extracted everything and then set the mtime and atime attributes
106 for _, dirHdr := range dirHdrs { 115 for _, dirHdr := range dirHdrs {
107 path := filepath.Join(dst, dirHdr.Name) 116 path := filepath.Join(dst, dirHdr.Name)
108 if err := os.Chtimes(path, dirHdr.AccessTime, dirHdr.ModTime); err != nil { 117 // Chmod the directory since they might be created before we know the mode flags
118 if err := os.Chmod(path, dirHdr.FileInfo().Mode()); err != nil {
119 return err
120 }
121 // Set the mtime/atime attributes since they would have been changed during extraction
122 aTime := now
123 mTime := now
124 if dirHdr.AccessTime.Unix() > 0 {
125 aTime = dirHdr.AccessTime
126 }
127 if dirHdr.ModTime.Unix() > 0 {
128 mTime = dirHdr.ModTime
129 }
130 if err := os.Chtimes(path, aTime, mTime); err != nil {
109 return err 131 return err
110 } 132 }
111 } 133 }
diff --git a/vendor/github.com/hashicorp/go-getter/decompress_testing.go b/vendor/github.com/hashicorp/go-getter/decompress_testing.go
index 91cf33d..b2f662a 100644
--- a/vendor/github.com/hashicorp/go-getter/decompress_testing.go
+++ b/vendor/github.com/hashicorp/go-getter/decompress_testing.go
@@ -18,16 +18,18 @@ import (
18 18
19// TestDecompressCase is a single test case for testing decompressors 19// TestDecompressCase is a single test case for testing decompressors
20type TestDecompressCase struct { 20type TestDecompressCase struct {
21 Input string // Input is the complete path to the input file 21 Input string // Input is the complete path to the input file
22 Dir bool // Dir is whether or not we're testing directory mode 22 Dir bool // Dir is whether or not we're testing directory mode
23 Err bool // Err is whether we expect an error or not 23 Err bool // Err is whether we expect an error or not
24 DirList []string // DirList is the list of files for Dir mode 24 DirList []string // DirList is the list of files for Dir mode
25 FileMD5 string // FileMD5 is the expected MD5 for a single file 25 FileMD5 string // FileMD5 is the expected MD5 for a single file
26 Mtime *time.Time // Mtime is the optionally expected mtime for a single file (or all files if in Dir mode) 26 Mtime *time.Time // Mtime is the optionally expected mtime for a single file (or all files if in Dir mode)
27} 27}
28 28
29// TestDecompressor is a helper function for testing generic decompressors. 29// TestDecompressor is a helper function for testing generic decompressors.
30func TestDecompressor(t testing.T, d Decompressor, cases []TestDecompressCase) { 30func TestDecompressor(t testing.T, d Decompressor, cases []TestDecompressCase) {
31 t.Helper()
32
31 for _, tc := range cases { 33 for _, tc := range cases {
32 t.Logf("Testing: %s", tc.Input) 34 t.Logf("Testing: %s", tc.Input)
33 35
@@ -72,9 +74,13 @@ func TestDecompressor(t testing.T, d Decompressor, cases []TestDecompressCase) {
72 74
73 if tc.Mtime != nil { 75 if tc.Mtime != nil {
74 actual := fi.ModTime() 76 actual := fi.ModTime()
75 expected := *tc.Mtime 77 if tc.Mtime.Unix() > 0 {
76 if actual != expected { 78 expected := *tc.Mtime
77 t.Fatalf("err %s: expected mtime '%s' for %s, got '%s'", tc.Input, expected.String(), dst, actual.String()) 79 if actual != expected {
80 t.Fatalf("err %s: expected mtime '%s' for %s, got '%s'", tc.Input, expected.String(), dst, actual.String())
81 }
82 } else if actual.Unix() <= 0 {
83 t.Fatalf("err %s: expected mtime to be > 0, got '%s'", actual.String())
78 } 84 }
79 } 85 }
80 86
@@ -103,10 +109,15 @@ func TestDecompressor(t testing.T, d Decompressor, cases []TestDecompressCase) {
103 t.Fatalf("err: %s", err) 109 t.Fatalf("err: %s", err)
104 } 110 }
105 actual := fi.ModTime() 111 actual := fi.ModTime()
106 expected := *tc.Mtime 112 if tc.Mtime.Unix() > 0 {
107 if actual != expected { 113 expected := *tc.Mtime
108 t.Fatalf("err %s: expected mtime '%s' for %s, got '%s'", tc.Input, expected.String(), path, actual.String()) 114 if actual != expected {
115 t.Fatalf("err %s: expected mtime '%s' for %s, got '%s'", tc.Input, expected.String(), path, actual.String())
116 }
117 } else if actual.Unix() < 0 {
118 t.Fatalf("err %s: expected mtime to be > 0, got '%s'", actual.String())
109 } 119 }
120
110 } 121 }
111 } 122 }
112 }() 123 }()
diff --git a/vendor/github.com/hashicorp/go-getter/decompress_zip.go b/vendor/github.com/hashicorp/go-getter/decompress_zip.go
index b0e70ca..0830f79 100644
--- a/vendor/github.com/hashicorp/go-getter/decompress_zip.go
+++ b/vendor/github.com/hashicorp/go-getter/decompress_zip.go
@@ -9,7 +9,7 @@ import (
9) 9)
10 10
11// ZipDecompressor is an implementation of Decompressor that can 11// ZipDecompressor is an implementation of Decompressor that can
12// decompress tar.gzip files. 12// decompress zip files.
13type ZipDecompressor struct{} 13type ZipDecompressor struct{}
14 14
15func (d *ZipDecompressor) Decompress(dst, src string, dir bool) error { 15func (d *ZipDecompressor) Decompress(dst, src string, dir bool) error {
diff --git a/vendor/github.com/hashicorp/go-getter/detect.go b/vendor/github.com/hashicorp/go-getter/detect.go
index c369551..5bb750c 100644
--- a/vendor/github.com/hashicorp/go-getter/detect.go
+++ b/vendor/github.com/hashicorp/go-getter/detect.go
@@ -23,8 +23,10 @@ var Detectors []Detector
23func init() { 23func init() {
24 Detectors = []Detector{ 24 Detectors = []Detector{
25 new(GitHubDetector), 25 new(GitHubDetector),
26 new(GitDetector),
26 new(BitBucketDetector), 27 new(BitBucketDetector),
27 new(S3Detector), 28 new(S3Detector),
29 new(GCSDetector),
28 new(FileDetector), 30 new(FileDetector),
29 } 31 }
30} 32}
diff --git a/vendor/github.com/hashicorp/go-getter/detect_gcs.go b/vendor/github.com/hashicorp/go-getter/detect_gcs.go
new file mode 100644
index 0000000..1136373
--- /dev/null
+++ b/vendor/github.com/hashicorp/go-getter/detect_gcs.go
@@ -0,0 +1,43 @@
1package getter
2
3import (
4 "fmt"
5 "net/url"
6 "strings"
7)
8
9// GCSDetector implements Detector to detect GCS URLs and turn
10// them into URLs that the GCSGetter can understand.
11type GCSDetector struct{}
12
13func (d *GCSDetector) Detect(src, _ string) (string, bool, error) {
14 if len(src) == 0 {
15 return "", false, nil
16 }
17
18 if strings.Contains(src, "googleapis.com/") {
19 return d.detectHTTP(src)
20 }
21
22 return "", false, nil
23}
24
25func (d *GCSDetector) detectHTTP(src string) (string, bool, error) {
26
27 parts := strings.Split(src, "/")
28 if len(parts) < 5 {
29 return "", false, fmt.Errorf(
30 "URL is not a valid GCS URL")
31 }
32 version := parts[2]
33 bucket := parts[3]
34 object := strings.Join(parts[4:], "/")
35
36 url, err := url.Parse(fmt.Sprintf("https://www.googleapis.com/storage/%s/%s/%s",
37 version, bucket, object))
38 if err != nil {
39 return "", false, fmt.Errorf("error parsing GCS URL: %s", err)
40 }
41
42 return "gcs::" + url.String(), true, nil
43}
diff --git a/vendor/github.com/hashicorp/go-getter/detect_git.go b/vendor/github.com/hashicorp/go-getter/detect_git.go
new file mode 100644
index 0000000..eeb8a04
--- /dev/null
+++ b/vendor/github.com/hashicorp/go-getter/detect_git.go
@@ -0,0 +1,26 @@
1package getter
2
3// GitDetector implements Detector to detect Git SSH URLs such as
4// git@host.com:dir1/dir2 and converts them to proper URLs.
5type GitDetector struct{}
6
7func (d *GitDetector) Detect(src, _ string) (string, bool, error) {
8 if len(src) == 0 {
9 return "", false, nil
10 }
11
12 u, err := detectSSH(src)
13 if err != nil {
14 return "", true, err
15 }
16 if u == nil {
17 return "", false, nil
18 }
19
20 // We require the username to be "git" to assume that this is a Git URL
21 if u.User.Username() != "git" {
22 return "", false, nil
23 }
24
25 return "git::" + u.String(), true, nil
26}
diff --git a/vendor/github.com/hashicorp/go-getter/detect_github.go b/vendor/github.com/hashicorp/go-getter/detect_github.go
index c084ad9..4bf4daf 100644
--- a/vendor/github.com/hashicorp/go-getter/detect_github.go
+++ b/vendor/github.com/hashicorp/go-getter/detect_github.go
@@ -17,8 +17,6 @@ func (d *GitHubDetector) Detect(src, _ string) (string, bool, error) {
17 17
18 if strings.HasPrefix(src, "github.com/") { 18 if strings.HasPrefix(src, "github.com/") {
19 return d.detectHTTP(src) 19 return d.detectHTTP(src)
20 } else if strings.HasPrefix(src, "git@github.com:") {
21 return d.detectSSH(src)
22 } 20 }
23 21
24 return "", false, nil 22 return "", false, nil
@@ -47,27 +45,3 @@ func (d *GitHubDetector) detectHTTP(src string) (string, bool, error) {
47 45
48 return "git::" + url.String(), true, nil 46 return "git::" + url.String(), true, nil
49} 47}
50
51func (d *GitHubDetector) detectSSH(src string) (string, bool, error) {
52 idx := strings.Index(src, ":")
53 qidx := strings.Index(src, "?")
54 if qidx == -1 {
55 qidx = len(src)
56 }
57
58 var u url.URL
59 u.Scheme = "ssh"
60 u.User = url.User("git")
61 u.Host = "github.com"
62 u.Path = src[idx+1 : qidx]
63 if qidx < len(src) {
64 q, err := url.ParseQuery(src[qidx+1:])
65 if err != nil {
66 return "", true, fmt.Errorf("error parsing GitHub SSH URL: %s", err)
67 }
68
69 u.RawQuery = q.Encode()
70 }
71
72 return "git::" + u.String(), true, nil
73}
diff --git a/vendor/github.com/hashicorp/go-getter/detect_ssh.go b/vendor/github.com/hashicorp/go-getter/detect_ssh.go
new file mode 100644
index 0000000..c0dbe9d
--- /dev/null
+++ b/vendor/github.com/hashicorp/go-getter/detect_ssh.go
@@ -0,0 +1,49 @@
1package getter
2
3import (
4 "fmt"
5 "net/url"
6 "regexp"
7 "strings"
8)
9
10// Note that we do not have an SSH-getter currently so this file serves
11// only to hold the detectSSH helper that is used by other detectors.
12
13// sshPattern matches SCP-like SSH patterns (user@host:path)
14var sshPattern = regexp.MustCompile("^(?:([^@]+)@)?([^:]+):/?(.+)$")
15
16// detectSSH determines if the src string matches an SSH-like URL and
17// converts it into a net.URL compatible string. This returns nil if the
18// string doesn't match the SSH pattern.
19//
20// This function is tested indirectly via detect_git_test.go
21func detectSSH(src string) (*url.URL, error) {
22 matched := sshPattern.FindStringSubmatch(src)
23 if matched == nil {
24 return nil, nil
25 }
26
27 user := matched[1]
28 host := matched[2]
29 path := matched[3]
30 qidx := strings.Index(path, "?")
31 if qidx == -1 {
32 qidx = len(path)
33 }
34
35 var u url.URL
36 u.Scheme = "ssh"
37 u.User = url.User(user)
38 u.Host = host
39 u.Path = path[0:qidx]
40 if qidx < len(path) {
41 q, err := url.ParseQuery(path[qidx+1:])
42 if err != nil {
43 return nil, fmt.Errorf("error parsing GitHub SSH URL: %s", err)
44 }
45 u.RawQuery = q.Encode()
46 }
47
48 return &u, nil
49}
diff --git a/vendor/github.com/hashicorp/go-getter/get.go b/vendor/github.com/hashicorp/go-getter/get.go
index e6053d9..c233763 100644
--- a/vendor/github.com/hashicorp/go-getter/get.go
+++ b/vendor/github.com/hashicorp/go-getter/get.go
@@ -41,6 +41,11 @@ type Getter interface {
41 // ClientMode returns the mode based on the given URL. This is used to 41 // ClientMode returns the mode based on the given URL. This is used to
42 // allow clients to let the getters decide which mode to use. 42 // allow clients to let the getters decide which mode to use.
43 ClientMode(*url.URL) (ClientMode, error) 43 ClientMode(*url.URL) (ClientMode, error)
44
45 // SetClient allows a getter to know it's client
46 // in order to access client's Get functions or
47 // progress tracking.
48 SetClient(*Client)
44} 49}
45 50
46// Getters is the mapping of scheme to the Getter implementation that will 51// Getters is the mapping of scheme to the Getter implementation that will
@@ -62,6 +67,7 @@ func init() {
62 Getters = map[string]Getter{ 67 Getters = map[string]Getter{
63 "file": new(FileGetter), 68 "file": new(FileGetter),
64 "git": new(GitGetter), 69 "git": new(GitGetter),
70 "gcs": new(GCSGetter),
65 "hg": new(HgGetter), 71 "hg": new(HgGetter),
66 "s3": new(S3Getter), 72 "s3": new(S3Getter),
67 "http": httpGetter, 73 "http": httpGetter,
@@ -74,12 +80,12 @@ func init() {
74// 80//
75// src is a URL, whereas dst is always just a file path to a folder. This 81// src is a URL, whereas dst is always just a file path to a folder. This
76// folder doesn't need to exist. It will be created if it doesn't exist. 82// folder doesn't need to exist. It will be created if it doesn't exist.
77func Get(dst, src string) error { 83func Get(dst, src string, opts ...ClientOption) error {
78 return (&Client{ 84 return (&Client{
79 Src: src, 85 Src: src,
80 Dst: dst, 86 Dst: dst,
81 Dir: true, 87 Dir: true,
82 Getters: Getters, 88 Options: opts,
83 }).Get() 89 }).Get()
84} 90}
85 91
@@ -89,23 +95,23 @@ func Get(dst, src string) error {
89// dst must be a directory. If src is a file, it will be downloaded 95// dst must be a directory. If src is a file, it will be downloaded
90// into dst with the basename of the URL. If src is a directory or 96// into dst with the basename of the URL. If src is a directory or
91// archive, it will be unpacked directly into dst. 97// archive, it will be unpacked directly into dst.
92func GetAny(dst, src string) error { 98func GetAny(dst, src string, opts ...ClientOption) error {
93 return (&Client{ 99 return (&Client{
94 Src: src, 100 Src: src,
95 Dst: dst, 101 Dst: dst,
96 Mode: ClientModeAny, 102 Mode: ClientModeAny,
97 Getters: Getters, 103 Options: opts,
98 }).Get() 104 }).Get()
99} 105}
100 106
101// GetFile downloads the file specified by src into the path specified by 107// GetFile downloads the file specified by src into the path specified by
102// dst. 108// dst.
103func GetFile(dst, src string) error { 109func GetFile(dst, src string, opts ...ClientOption) error {
104 return (&Client{ 110 return (&Client{
105 Src: src, 111 Src: src,
106 Dst: dst, 112 Dst: dst,
107 Dir: false, 113 Dir: false,
108 Getters: Getters, 114 Options: opts,
109 }).Get() 115 }).Get()
110} 116}
111 117
diff --git a/vendor/github.com/hashicorp/go-getter/get_base.go b/vendor/github.com/hashicorp/go-getter/get_base.go
new file mode 100644
index 0000000..09e9b63
--- /dev/null
+++ b/vendor/github.com/hashicorp/go-getter/get_base.go
@@ -0,0 +1,20 @@
1package getter
2
3import "context"
4
5// getter is our base getter; it regroups
6// fields all getters have in common.
7type getter struct {
8 client *Client
9}
10
11func (g *getter) SetClient(c *Client) { g.client = c }
12
13// Context tries to returns the Contex from the getter's
14// client. otherwise context.Background() is returned.
15func (g *getter) Context() context.Context {
16 if g == nil || g.client == nil {
17 return context.Background()
18 }
19 return g.client.Ctx
20}
diff --git a/vendor/github.com/hashicorp/go-getter/get_file.go b/vendor/github.com/hashicorp/go-getter/get_file.go
index e5d2d61..7866083 100644
--- a/vendor/github.com/hashicorp/go-getter/get_file.go
+++ b/vendor/github.com/hashicorp/go-getter/get_file.go
@@ -8,7 +8,11 @@ import (
8// FileGetter is a Getter implementation that will download a module from 8// FileGetter is a Getter implementation that will download a module from
9// a file scheme. 9// a file scheme.
10type FileGetter struct { 10type FileGetter struct {
11 // Copy, if set to true, will copy data instead of using a symlink 11 getter
12
13 // Copy, if set to true, will copy data instead of using a symlink. If
14 // false, attempts to symlink to speed up the operation and to lower the
15 // disk space usage. If the symlink fails, may attempt to copy on windows.
12 Copy bool 16 Copy bool
13} 17}
14 18
diff --git a/vendor/github.com/hashicorp/go-getter/get_file_copy.go b/vendor/github.com/hashicorp/go-getter/get_file_copy.go
new file mode 100644
index 0000000..d70fb49
--- /dev/null
+++ b/vendor/github.com/hashicorp/go-getter/get_file_copy.go
@@ -0,0 +1,29 @@
1package getter
2
3import (
4 "context"
5 "io"
6)
7
8// readerFunc is syntactic sugar for read interface.
9type readerFunc func(p []byte) (n int, err error)
10
11func (rf readerFunc) Read(p []byte) (n int, err error) { return rf(p) }
12
13// Copy is a io.Copy cancellable by context
14func Copy(ctx context.Context, dst io.Writer, src io.Reader) (int64, error) {
15 // Copy will call the Reader and Writer interface multiple time, in order
16 // to copy by chunk (avoiding loading the whole file in memory).
17 return io.Copy(dst, readerFunc(func(p []byte) (int, error) {
18
19 select {
20 case <-ctx.Done():
21 // context has been canceled
22 // stop process and propagate "context canceled" error
23 return 0, ctx.Err()
24 default:
25 // otherwise just run default io.Reader implementation
26 return src.Read(p)
27 }
28 }))
29}
diff --git a/vendor/github.com/hashicorp/go-getter/get_file_unix.go b/vendor/github.com/hashicorp/go-getter/get_file_unix.go
index c89a2d5..c3b28ae 100644
--- a/vendor/github.com/hashicorp/go-getter/get_file_unix.go
+++ b/vendor/github.com/hashicorp/go-getter/get_file_unix.go
@@ -4,7 +4,6 @@ package getter
4 4
5import ( 5import (
6 "fmt" 6 "fmt"
7 "io"
8 "net/url" 7 "net/url"
9 "os" 8 "os"
10 "path/filepath" 9 "path/filepath"
@@ -50,6 +49,7 @@ func (g *FileGetter) Get(dst string, u *url.URL) error {
50} 49}
51 50
52func (g *FileGetter) GetFile(dst string, u *url.URL) error { 51func (g *FileGetter) GetFile(dst string, u *url.URL) error {
52 ctx := g.Context()
53 path := u.Path 53 path := u.Path
54 if u.RawPath != "" { 54 if u.RawPath != "" {
55 path = u.RawPath 55 path = u.RawPath
@@ -98,6 +98,6 @@ func (g *FileGetter) GetFile(dst string, u *url.URL) error {
98 } 98 }
99 defer dstF.Close() 99 defer dstF.Close()
100 100
101 _, err = io.Copy(dstF, srcF) 101 _, err = Copy(ctx, dstF, srcF)
102 return err 102 return err
103} 103}
diff --git a/vendor/github.com/hashicorp/go-getter/get_file_windows.go b/vendor/github.com/hashicorp/go-getter/get_file_windows.go
index f87ed0a..24f1acb 100644
--- a/vendor/github.com/hashicorp/go-getter/get_file_windows.go
+++ b/vendor/github.com/hashicorp/go-getter/get_file_windows.go
@@ -4,15 +4,16 @@ package getter
4 4
5import ( 5import (
6 "fmt" 6 "fmt"
7 "io"
8 "net/url" 7 "net/url"
9 "os" 8 "os"
10 "os/exec" 9 "os/exec"
11 "path/filepath" 10 "path/filepath"
12 "strings" 11 "strings"
12 "syscall"
13) 13)
14 14
15func (g *FileGetter) Get(dst string, u *url.URL) error { 15func (g *FileGetter) Get(dst string, u *url.URL) error {
16 ctx := g.Context()
16 path := u.Path 17 path := u.Path
17 if u.RawPath != "" { 18 if u.RawPath != "" {
18 path = u.RawPath 19 path = u.RawPath
@@ -51,7 +52,7 @@ func (g *FileGetter) Get(dst string, u *url.URL) error {
51 sourcePath := toBackslash(path) 52 sourcePath := toBackslash(path)
52 53
53 // Use mklink to create a junction point 54 // Use mklink to create a junction point
54 output, err := exec.Command("cmd", "/c", "mklink", "/J", dst, sourcePath).CombinedOutput() 55 output, err := exec.CommandContext(ctx, "cmd", "/c", "mklink", "/J", dst, sourcePath).CombinedOutput()
55 if err != nil { 56 if err != nil {
56 return fmt.Errorf("failed to run mklink %v %v: %v %q", dst, sourcePath, err, output) 57 return fmt.Errorf("failed to run mklink %v %v: %v %q", dst, sourcePath, err, output)
57 } 58 }
@@ -60,6 +61,7 @@ func (g *FileGetter) Get(dst string, u *url.URL) error {
60} 61}
61 62
62func (g *FileGetter) GetFile(dst string, u *url.URL) error { 63func (g *FileGetter) GetFile(dst string, u *url.URL) error {
64 ctx := g.Context()
63 path := u.Path 65 path := u.Path
64 if u.RawPath != "" { 66 if u.RawPath != "" {
65 path = u.RawPath 67 path = u.RawPath
@@ -92,7 +94,21 @@ func (g *FileGetter) GetFile(dst string, u *url.URL) error {
92 94
93 // If we're not copying, just symlink and we're done 95 // If we're not copying, just symlink and we're done
94 if !g.Copy { 96 if !g.Copy {
95 return os.Symlink(path, dst) 97 if err = os.Symlink(path, dst); err == nil {
98 return err
99 }
100 lerr, ok := err.(*os.LinkError)
101 if !ok {
102 return err
103 }
104 switch lerr.Err {
105 case syscall.ERROR_PRIVILEGE_NOT_HELD:
106 // no symlink privilege, let's
107 // fallback to a copy to avoid an error.
108 break
109 default:
110 return err
111 }
96 } 112 }
97 113
98 // Copy 114 // Copy
@@ -108,7 +124,7 @@ func (g *FileGetter) GetFile(dst string, u *url.URL) error {
108 } 124 }
109 defer dstF.Close() 125 defer dstF.Close()
110 126
111 _, err = io.Copy(dstF, srcF) 127 _, err = Copy(ctx, dstF, srcF)
112 return err 128 return err
113} 129}
114 130
diff --git a/vendor/github.com/hashicorp/go-getter/get_gcs.go b/vendor/github.com/hashicorp/go-getter/get_gcs.go
new file mode 100644
index 0000000..6faa70f
--- /dev/null
+++ b/vendor/github.com/hashicorp/go-getter/get_gcs.go
@@ -0,0 +1,172 @@
1package getter
2
3import (
4 "context"
5 "fmt"
6 "net/url"
7 "os"
8 "path/filepath"
9 "strings"
10
11 "cloud.google.com/go/storage"
12 "google.golang.org/api/iterator"
13)
14
15// GCSGetter is a Getter implementation that will download a module from
16// a GCS bucket.
17type GCSGetter struct {
18 getter
19}
20
21func (g *GCSGetter) ClientMode(u *url.URL) (ClientMode, error) {
22 ctx := g.Context()
23
24 // Parse URL
25 bucket, object, err := g.parseURL(u)
26 if err != nil {
27 return 0, err
28 }
29
30 client, err := storage.NewClient(ctx)
31 if err != nil {
32 return 0, err
33 }
34 iter := client.Bucket(bucket).Objects(ctx, &storage.Query{Prefix: object})
35 for {
36 obj, err := iter.Next()
37 if err != nil && err != iterator.Done {
38 return 0, err
39 }
40
41 if err == iterator.Done {
42 break
43 }
44 if strings.HasSuffix(obj.Name, "/") {
45 // A directory matched the prefix search, so this must be a directory
46 return ClientModeDir, nil
47 } else if obj.Name != object {
48 // A file matched the prefix search and doesn't have the same name
49 // as the query, so this must be a directory
50 return ClientModeDir, nil
51 }
52 }
53 // There are no directories or subdirectories, and if a match was returned,
54 // it was exactly equal to the prefix search. So return File mode
55 return ClientModeFile, nil
56}
57
58func (g *GCSGetter) Get(dst string, u *url.URL) error {
59 ctx := g.Context()
60
61 // Parse URL
62 bucket, object, err := g.parseURL(u)
63 if err != nil {
64 return err
65 }
66
67 // Remove destination if it already exists
68 _, err = os.Stat(dst)
69 if err != nil && !os.IsNotExist(err) {
70 return err
71 }
72 if err == nil {
73 // Remove the destination
74 if err := os.RemoveAll(dst); err != nil {
75 return err
76 }
77 }
78
79 // Create all the parent directories
80 if err := os.MkdirAll(filepath.Dir(dst), 0755); err != nil {
81 return err
82 }
83
84 client, err := storage.NewClient(ctx)
85 if err != nil {
86 return err
87 }
88
89 // Iterate through all matching objects.
90 iter := client.Bucket(bucket).Objects(ctx, &storage.Query{Prefix: object})
91 for {
92 obj, err := iter.Next()
93 if err != nil && err != iterator.Done {
94 return err
95 }
96 if err == iterator.Done {
97 break
98 }
99
100 if !strings.HasSuffix(obj.Name, "/") {
101 // Get the object destination path
102 objDst, err := filepath.Rel(object, obj.Name)
103 if err != nil {
104 return err
105 }
106 objDst = filepath.Join(dst, objDst)
107 // Download the matching object.
108 err = g.getObject(ctx, client, objDst, bucket, obj.Name)
109 if err != nil {
110 return err
111 }
112 }
113 }
114 return nil
115}
116
117func (g *GCSGetter) GetFile(dst string, u *url.URL) error {
118 ctx := g.Context()
119
120 // Parse URL
121 bucket, object, err := g.parseURL(u)
122 if err != nil {
123 return err
124 }
125
126 client, err := storage.NewClient(ctx)
127 if err != nil {
128 return err
129 }
130 return g.getObject(ctx, client, dst, bucket, object)
131}
132
133func (g *GCSGetter) getObject(ctx context.Context, client *storage.Client, dst, bucket, object string) error {
134 rc, err := client.Bucket(bucket).Object(object).NewReader(ctx)
135 if err != nil {
136 return err
137 }
138 defer rc.Close()
139
140 // Create all the parent directories
141 if err := os.MkdirAll(filepath.Dir(dst), 0755); err != nil {
142 return err
143 }
144
145 f, err := os.Create(dst)
146 if err != nil {
147 return err
148 }
149 defer f.Close()
150
151 _, err = Copy(ctx, f, rc)
152 return err
153}
154
155func (g *GCSGetter) parseURL(u *url.URL) (bucket, path string, err error) {
156 if strings.Contains(u.Host, "googleapis.com") {
157 hostParts := strings.Split(u.Host, ".")
158 if len(hostParts) != 3 {
159 err = fmt.Errorf("URL is not a valid GCS URL")
160 return
161 }
162
163 pathParts := strings.SplitN(u.Path, "/", 5)
164 if len(pathParts) != 5 {
165 err = fmt.Errorf("URL is not a valid GCS URL")
166 return
167 }
168 bucket = pathParts[3]
169 path = pathParts[4]
170 }
171 return
172}
diff --git a/vendor/github.com/hashicorp/go-getter/get_git.go b/vendor/github.com/hashicorp/go-getter/get_git.go
index cb1d029..67e8b2f 100644
--- a/vendor/github.com/hashicorp/go-getter/get_git.go
+++ b/vendor/github.com/hashicorp/go-getter/get_git.go
@@ -1,6 +1,7 @@
1package getter 1package getter
2 2
3import ( 3import (
4 "context"
4 "encoding/base64" 5 "encoding/base64"
5 "fmt" 6 "fmt"
6 "io/ioutil" 7 "io/ioutil"
@@ -8,28 +9,43 @@ import (
8 "os" 9 "os"
9 "os/exec" 10 "os/exec"
10 "path/filepath" 11 "path/filepath"
12 "runtime"
13 "strconv"
11 "strings" 14 "strings"
12 15
13 urlhelper "github.com/hashicorp/go-getter/helper/url" 16 urlhelper "github.com/hashicorp/go-getter/helper/url"
14 "github.com/hashicorp/go-safetemp" 17 safetemp "github.com/hashicorp/go-safetemp"
15 "github.com/hashicorp/go-version" 18 version "github.com/hashicorp/go-version"
16) 19)
17 20
18// GitGetter is a Getter implementation that will download a module from 21// GitGetter is a Getter implementation that will download a module from
19// a git repository. 22// a git repository.
20type GitGetter struct{} 23type GitGetter struct {
24 getter
25}
21 26
22func (g *GitGetter) ClientMode(_ *url.URL) (ClientMode, error) { 27func (g *GitGetter) ClientMode(_ *url.URL) (ClientMode, error) {
23 return ClientModeDir, nil 28 return ClientModeDir, nil
24} 29}
25 30
26func (g *GitGetter) Get(dst string, u *url.URL) error { 31func (g *GitGetter) Get(dst string, u *url.URL) error {
32 ctx := g.Context()
27 if _, err := exec.LookPath("git"); err != nil { 33 if _, err := exec.LookPath("git"); err != nil {
28 return fmt.Errorf("git must be available and on the PATH") 34 return fmt.Errorf("git must be available and on the PATH")
29 } 35 }
30 36
37 // The port number must be parseable as an integer. If not, the user
38 // was probably trying to use a scp-style address, in which case the
39 // ssh:// prefix must be removed to indicate that.
40 if portStr := u.Port(); portStr != "" {
41 if _, err := strconv.ParseUint(portStr, 10, 16); err != nil {
42 return fmt.Errorf("invalid port number %q; if using the \"scp-like\" git address scheme where a colon introduces the path instead, remove the ssh:// portion and use just the git:: prefix", portStr)
43 }
44 }
45
31 // Extract some query parameters we use 46 // Extract some query parameters we use
32 var ref, sshKey string 47 var ref, sshKey string
48 var depth int
33 q := u.Query() 49 q := u.Query()
34 if len(q) > 0 { 50 if len(q) > 0 {
35 ref = q.Get("ref") 51 ref = q.Get("ref")
@@ -38,6 +54,11 @@ func (g *GitGetter) Get(dst string, u *url.URL) error {
38 sshKey = q.Get("sshkey") 54 sshKey = q.Get("sshkey")
39 q.Del("sshkey") 55 q.Del("sshkey")
40 56
57 if n, err := strconv.Atoi(q.Get("depth")); err == nil {
58 depth = n
59 }
60 q.Del("depth")
61
41 // Copy the URL 62 // Copy the URL
42 var newU url.URL = *u 63 var newU url.URL = *u
43 u = &newU 64 u = &newU
@@ -84,9 +105,9 @@ func (g *GitGetter) Get(dst string, u *url.URL) error {
84 return err 105 return err
85 } 106 }
86 if err == nil { 107 if err == nil {
87 err = g.update(dst, sshKeyFile, ref) 108 err = g.update(ctx, dst, sshKeyFile, ref, depth)
88 } else { 109 } else {
89 err = g.clone(dst, sshKeyFile, u) 110 err = g.clone(ctx, dst, sshKeyFile, u, depth)
90 } 111 }
91 if err != nil { 112 if err != nil {
92 return err 113 return err
@@ -100,7 +121,7 @@ func (g *GitGetter) Get(dst string, u *url.URL) error {
100 } 121 }
101 122
102 // Lastly, download any/all submodules. 123 // Lastly, download any/all submodules.
103 return g.fetchSubmodules(dst, sshKeyFile) 124 return g.fetchSubmodules(ctx, dst, sshKeyFile, depth)
104} 125}
105 126
106// GetFile for Git doesn't support updating at this time. It will download 127// GetFile for Git doesn't support updating at this time. It will download
@@ -138,16 +159,23 @@ func (g *GitGetter) checkout(dst string, ref string) error {
138 return getRunCommand(cmd) 159 return getRunCommand(cmd)
139} 160}
140 161
141func (g *GitGetter) clone(dst, sshKeyFile string, u *url.URL) error { 162func (g *GitGetter) clone(ctx context.Context, dst, sshKeyFile string, u *url.URL, depth int) error {
142 cmd := exec.Command("git", "clone", u.String(), dst) 163 args := []string{"clone"}
164
165 if depth > 0 {
166 args = append(args, "--depth", strconv.Itoa(depth))
167 }
168
169 args = append(args, u.String(), dst)
170 cmd := exec.CommandContext(ctx, "git", args...)
143 setupGitEnv(cmd, sshKeyFile) 171 setupGitEnv(cmd, sshKeyFile)
144 return getRunCommand(cmd) 172 return getRunCommand(cmd)
145} 173}
146 174
147func (g *GitGetter) update(dst, sshKeyFile, ref string) error { 175func (g *GitGetter) update(ctx context.Context, dst, sshKeyFile, ref string, depth int) error {
148 // Determine if we're a branch. If we're NOT a branch, then we just 176 // Determine if we're a branch. If we're NOT a branch, then we just
149 // switch to master prior to checking out 177 // switch to master prior to checking out
150 cmd := exec.Command("git", "show-ref", "-q", "--verify", "refs/heads/"+ref) 178 cmd := exec.CommandContext(ctx, "git", "show-ref", "-q", "--verify", "refs/heads/"+ref)
151 cmd.Dir = dst 179 cmd.Dir = dst
152 180
153 if getRunCommand(cmd) != nil { 181 if getRunCommand(cmd) != nil {
@@ -162,15 +190,24 @@ func (g *GitGetter) update(dst, sshKeyFile, ref string) error {
162 return err 190 return err
163 } 191 }
164 192
165 cmd = exec.Command("git", "pull", "--ff-only") 193 if depth > 0 {
194 cmd = exec.Command("git", "pull", "--depth", strconv.Itoa(depth), "--ff-only")
195 } else {
196 cmd = exec.Command("git", "pull", "--ff-only")
197 }
198
166 cmd.Dir = dst 199 cmd.Dir = dst
167 setupGitEnv(cmd, sshKeyFile) 200 setupGitEnv(cmd, sshKeyFile)
168 return getRunCommand(cmd) 201 return getRunCommand(cmd)
169} 202}
170 203
171// fetchSubmodules downloads any configured submodules recursively. 204// fetchSubmodules downloads any configured submodules recursively.
172func (g *GitGetter) fetchSubmodules(dst, sshKeyFile string) error { 205func (g *GitGetter) fetchSubmodules(ctx context.Context, dst, sshKeyFile string, depth int) error {
173 cmd := exec.Command("git", "submodule", "update", "--init", "--recursive") 206 args := []string{"submodule", "update", "--init", "--recursive"}
207 if depth > 0 {
208 args = append(args, "--depth", strconv.Itoa(depth))
209 }
210 cmd := exec.CommandContext(ctx, "git", args...)
174 cmd.Dir = dst 211 cmd.Dir = dst
175 setupGitEnv(cmd, sshKeyFile) 212 setupGitEnv(cmd, sshKeyFile)
176 return getRunCommand(cmd) 213 return getRunCommand(cmd)
@@ -187,7 +224,7 @@ func setupGitEnv(cmd *exec.Cmd, sshKeyFile string) {
187 // with versions of Go < 1.9. 224 // with versions of Go < 1.9.
188 env := os.Environ() 225 env := os.Environ()
189 for i, v := range env { 226 for i, v := range env {
190 if strings.HasPrefix(v, gitSSHCommand) { 227 if strings.HasPrefix(v, gitSSHCommand) && len(v) > len(gitSSHCommand) {
191 sshCmd = []string{v} 228 sshCmd = []string{v}
192 229
193 env[i], env[len(env)-1] = env[len(env)-1], env[i] 230 env[i], env[len(env)-1] = env[len(env)-1], env[i]
@@ -202,6 +239,9 @@ func setupGitEnv(cmd *exec.Cmd, sshKeyFile string) {
202 239
203 if sshKeyFile != "" { 240 if sshKeyFile != "" {
204 // We have an SSH key temp file configured, tell ssh about this. 241 // We have an SSH key temp file configured, tell ssh about this.
242 if runtime.GOOS == "windows" {
243 sshKeyFile = strings.Replace(sshKeyFile, `\`, `/`, -1)
244 }
205 sshCmd = append(sshCmd, "-i", sshKeyFile) 245 sshCmd = append(sshCmd, "-i", sshKeyFile)
206 } 246 }
207 247
@@ -224,11 +264,20 @@ func checkGitVersion(min string) error {
224 } 264 }
225 265
226 fields := strings.Fields(string(out)) 266 fields := strings.Fields(string(out))
227 if len(fields) != 3 { 267 if len(fields) < 3 {
228 return fmt.Errorf("Unexpected 'git version' output: %q", string(out)) 268 return fmt.Errorf("Unexpected 'git version' output: %q", string(out))
229 } 269 }
270 v := fields[2]
271 if runtime.GOOS == "windows" && strings.Contains(v, ".windows.") {
272 // on windows, git version will return for example:
273 // git version 2.20.1.windows.1
274 // Which does not follow the semantic versionning specs
275 // https://semver.org. We remove that part in order for
276 // go-version to not error.
277 v = v[:strings.Index(v, ".windows.")]
278 }
230 279
231 have, err := version.NewVersion(fields[2]) 280 have, err := version.NewVersion(v)
232 if err != nil { 281 if err != nil {
233 return err 282 return err
234 } 283 }
diff --git a/vendor/github.com/hashicorp/go-getter/get_hg.go b/vendor/github.com/hashicorp/go-getter/get_hg.go
index f386922..290649c 100644
--- a/vendor/github.com/hashicorp/go-getter/get_hg.go
+++ b/vendor/github.com/hashicorp/go-getter/get_hg.go
@@ -1,6 +1,7 @@
1package getter 1package getter
2 2
3import ( 3import (
4 "context"
4 "fmt" 5 "fmt"
5 "net/url" 6 "net/url"
6 "os" 7 "os"
@@ -9,18 +10,21 @@ import (
9 "runtime" 10 "runtime"
10 11
11 urlhelper "github.com/hashicorp/go-getter/helper/url" 12 urlhelper "github.com/hashicorp/go-getter/helper/url"
12 "github.com/hashicorp/go-safetemp" 13 safetemp "github.com/hashicorp/go-safetemp"
13) 14)
14 15
15// HgGetter is a Getter implementation that will download a module from 16// HgGetter is a Getter implementation that will download a module from
16// a Mercurial repository. 17// a Mercurial repository.
17type HgGetter struct{} 18type HgGetter struct {
19 getter
20}
18 21
19func (g *HgGetter) ClientMode(_ *url.URL) (ClientMode, error) { 22func (g *HgGetter) ClientMode(_ *url.URL) (ClientMode, error) {
20 return ClientModeDir, nil 23 return ClientModeDir, nil
21} 24}
22 25
23func (g *HgGetter) Get(dst string, u *url.URL) error { 26func (g *HgGetter) Get(dst string, u *url.URL) error {
27 ctx := g.Context()
24 if _, err := exec.LookPath("hg"); err != nil { 28 if _, err := exec.LookPath("hg"); err != nil {
25 return fmt.Errorf("hg must be available and on the PATH") 29 return fmt.Errorf("hg must be available and on the PATH")
26 } 30 }
@@ -58,7 +62,7 @@ func (g *HgGetter) Get(dst string, u *url.URL) error {
58 return err 62 return err
59 } 63 }
60 64
61 return g.update(dst, newURL, rev) 65 return g.update(ctx, dst, newURL, rev)
62} 66}
63 67
64// GetFile for Hg doesn't support updating at this time. It will download 68// GetFile for Hg doesn't support updating at this time. It will download
@@ -93,7 +97,7 @@ func (g *HgGetter) GetFile(dst string, u *url.URL) error {
93 return err 97 return err
94 } 98 }
95 99
96 fg := &FileGetter{Copy: true} 100 fg := &FileGetter{Copy: true, getter: g.getter}
97 return fg.GetFile(dst, u) 101 return fg.GetFile(dst, u)
98} 102}
99 103
@@ -108,13 +112,13 @@ func (g *HgGetter) pull(dst string, u *url.URL) error {
108 return getRunCommand(cmd) 112 return getRunCommand(cmd)
109} 113}
110 114
111func (g *HgGetter) update(dst string, u *url.URL, rev string) error { 115func (g *HgGetter) update(ctx context.Context, dst string, u *url.URL, rev string) error {
112 args := []string{"update"} 116 args := []string{"update"}
113 if rev != "" { 117 if rev != "" {
114 args = append(args, rev) 118 args = append(args, rev)
115 } 119 }
116 120
117 cmd := exec.Command("hg", args...) 121 cmd := exec.CommandContext(ctx, "hg", args...)
118 cmd.Dir = dst 122 cmd.Dir = dst
119 return getRunCommand(cmd) 123 return getRunCommand(cmd)
120} 124}
diff --git a/vendor/github.com/hashicorp/go-getter/get_http.go b/vendor/github.com/hashicorp/go-getter/get_http.go
index d2e2879..7c4541c 100644
--- a/vendor/github.com/hashicorp/go-getter/get_http.go
+++ b/vendor/github.com/hashicorp/go-getter/get_http.go
@@ -1,6 +1,7 @@
1package getter 1package getter
2 2
3import ( 3import (
4 "context"
4 "encoding/xml" 5 "encoding/xml"
5 "fmt" 6 "fmt"
6 "io" 7 "io"
@@ -8,9 +9,10 @@ import (
8 "net/url" 9 "net/url"
9 "os" 10 "os"
10 "path/filepath" 11 "path/filepath"
12 "strconv"
11 "strings" 13 "strings"
12 14
13 "github.com/hashicorp/go-safetemp" 15 safetemp "github.com/hashicorp/go-safetemp"
14) 16)
15 17
16// HttpGetter is a Getter implementation that will download from an HTTP 18// HttpGetter is a Getter implementation that will download from an HTTP
@@ -18,7 +20,7 @@ import (
18// 20//
19// For file downloads, HTTP is used directly. 21// For file downloads, HTTP is used directly.
20// 22//
21// The protocol for downloading a directory from an HTTP endpoing is as follows: 23// The protocol for downloading a directory from an HTTP endpoint is as follows:
22// 24//
23// An HTTP GET request is made to the URL with the additional GET parameter 25// An HTTP GET request is made to the URL with the additional GET parameter
24// "terraform-get=1". This lets you handle that scenario specially if you 26// "terraform-get=1". This lets you handle that scenario specially if you
@@ -34,6 +36,8 @@ import (
34// formed URL. The shorthand syntax of "github.com/foo/bar" or relative 36// formed URL. The shorthand syntax of "github.com/foo/bar" or relative
35// paths are not allowed. 37// paths are not allowed.
36type HttpGetter struct { 38type HttpGetter struct {
39 getter
40
37 // Netrc, if true, will lookup and use auth information found 41 // Netrc, if true, will lookup and use auth information found
38 // in the user's netrc file if available. 42 // in the user's netrc file if available.
39 Netrc bool 43 Netrc bool
@@ -41,6 +45,12 @@ type HttpGetter struct {
41 // Client is the http.Client to use for Get requests. 45 // Client is the http.Client to use for Get requests.
42 // This defaults to a cleanhttp.DefaultClient if left unset. 46 // This defaults to a cleanhttp.DefaultClient if left unset.
43 Client *http.Client 47 Client *http.Client
48
49 // Header contains optional request header fields that should be included
50 // with every HTTP request. Note that the zero value of this field is nil,
51 // and as such it needs to be initialized before use, via something like
52 // make(http.Header).
53 Header http.Header
44} 54}
45 55
46func (g *HttpGetter) ClientMode(u *url.URL) (ClientMode, error) { 56func (g *HttpGetter) ClientMode(u *url.URL) (ClientMode, error) {
@@ -51,6 +61,7 @@ func (g *HttpGetter) ClientMode(u *url.URL) (ClientMode, error) {
51} 61}
52 62
53func (g *HttpGetter) Get(dst string, u *url.URL) error { 63func (g *HttpGetter) Get(dst string, u *url.URL) error {
64 ctx := g.Context()
54 // Copy the URL so we can modify it 65 // Copy the URL so we can modify it
55 var newU url.URL = *u 66 var newU url.URL = *u
56 u = &newU 67 u = &newU
@@ -72,10 +83,17 @@ func (g *HttpGetter) Get(dst string, u *url.URL) error {
72 u.RawQuery = q.Encode() 83 u.RawQuery = q.Encode()
73 84
74 // Get the URL 85 // Get the URL
75 resp, err := g.Client.Get(u.String()) 86 req, err := http.NewRequest("GET", u.String(), nil)
76 if err != nil { 87 if err != nil {
77 return err 88 return err
78 } 89 }
90
91 req.Header = g.Header
92 resp, err := g.Client.Do(req)
93 if err != nil {
94 return err
95 }
96
79 defer resp.Body.Close() 97 defer resp.Body.Close()
80 if resp.StatusCode < 200 || resp.StatusCode >= 300 { 98 if resp.StatusCode < 200 || resp.StatusCode >= 300 {
81 return fmt.Errorf("bad response code: %d", resp.StatusCode) 99 return fmt.Errorf("bad response code: %d", resp.StatusCode)
@@ -99,57 +117,107 @@ func (g *HttpGetter) Get(dst string, u *url.URL) error {
99 // into a temporary directory, then copy over the proper subdir. 117 // into a temporary directory, then copy over the proper subdir.
100 source, subDir := SourceDirSubdir(source) 118 source, subDir := SourceDirSubdir(source)
101 if subDir == "" { 119 if subDir == "" {
102 return Get(dst, source) 120 var opts []ClientOption
121 if g.client != nil {
122 opts = g.client.Options
123 }
124 return Get(dst, source, opts...)
103 } 125 }
104 126
105 // We have a subdir, time to jump some hoops 127 // We have a subdir, time to jump some hoops
106 return g.getSubdir(dst, source, subDir) 128 return g.getSubdir(ctx, dst, source, subDir)
107} 129}
108 130
109func (g *HttpGetter) GetFile(dst string, u *url.URL) error { 131func (g *HttpGetter) GetFile(dst string, src *url.URL) error {
132 ctx := g.Context()
110 if g.Netrc { 133 if g.Netrc {
111 // Add auth from netrc if we can 134 // Add auth from netrc if we can
112 if err := addAuthFromNetrc(u); err != nil { 135 if err := addAuthFromNetrc(src); err != nil {
113 return err 136 return err
114 } 137 }
115 } 138 }
116 139
117 if g.Client == nil { 140 // Create all the parent directories if needed
118 g.Client = httpClient 141 if err := os.MkdirAll(filepath.Dir(dst), 0755); err != nil {
142 return err
119 } 143 }
120 144
121 resp, err := g.Client.Get(u.String()) 145 f, err := os.OpenFile(dst, os.O_RDWR|os.O_CREATE, os.FileMode(0666))
122 if err != nil { 146 if err != nil {
123 return err 147 return err
124 } 148 }
125 defer resp.Body.Close() 149 defer f.Close()
126 if resp.StatusCode != 200 { 150
127 return fmt.Errorf("bad response code: %d", resp.StatusCode) 151 if g.Client == nil {
152 g.Client = httpClient
128 } 153 }
129 154
130 // Create all the parent directories 155 var currentFileSize int64
131 if err := os.MkdirAll(filepath.Dir(dst), 0755); err != nil { 156
157 // We first make a HEAD request so we can check
158 // if the server supports range queries. If the server/URL doesn't
159 // support HEAD requests, we just fall back to GET.
160 req, err := http.NewRequest("HEAD", src.String(), nil)
161 if err != nil {
132 return err 162 return err
133 } 163 }
164 if g.Header != nil {
165 req.Header = g.Header
166 }
167 headResp, err := g.Client.Do(req)
168 if err == nil && headResp != nil {
169 headResp.Body.Close()
170 if headResp.StatusCode == 200 {
171 // If the HEAD request succeeded, then attempt to set the range
172 // query if we can.
173 if headResp.Header.Get("Accept-Ranges") == "bytes" {
174 if fi, err := f.Stat(); err == nil {
175 if _, err = f.Seek(0, os.SEEK_END); err == nil {
176 req.Header.Set("Range", fmt.Sprintf("bytes=%d-", fi.Size()))
177 currentFileSize = fi.Size()
178 totalFileSize, _ := strconv.ParseInt(headResp.Header.Get("Content-Length"), 10, 64)
179 if currentFileSize >= totalFileSize {
180 // file already present
181 return nil
182 }
183 }
184 }
185 }
186 }
187 }
188 req.Method = "GET"
134 189
135 f, err := os.Create(dst) 190 resp, err := g.Client.Do(req)
136 if err != nil { 191 if err != nil {
137 return err 192 return err
138 } 193 }
194 switch resp.StatusCode {
195 case http.StatusOK, http.StatusPartialContent:
196 // all good
197 default:
198 resp.Body.Close()
199 return fmt.Errorf("bad response code: %d", resp.StatusCode)
200 }
201
202 body := resp.Body
139 203
140 n, err := io.Copy(f, resp.Body) 204 if g.client != nil && g.client.ProgressListener != nil {
205 // track download
206 fn := filepath.Base(src.EscapedPath())
207 body = g.client.ProgressListener.TrackProgress(fn, currentFileSize, currentFileSize+resp.ContentLength, resp.Body)
208 }
209 defer body.Close()
210
211 n, err := Copy(ctx, f, body)
141 if err == nil && n < resp.ContentLength { 212 if err == nil && n < resp.ContentLength {
142 err = io.ErrShortWrite 213 err = io.ErrShortWrite
143 } 214 }
144 if err1 := f.Close(); err == nil {
145 err = err1
146 }
147 return err 215 return err
148} 216}
149 217
150// getSubdir downloads the source into the destination, but with 218// getSubdir downloads the source into the destination, but with
151// the proper subdir. 219// the proper subdir.
152func (g *HttpGetter) getSubdir(dst, source, subDir string) error { 220func (g *HttpGetter) getSubdir(ctx context.Context, dst, source, subDir string) error {
153 // Create a temporary directory to store the full source. This has to be 221 // Create a temporary directory to store the full source. This has to be
154 // a non-existent directory. 222 // a non-existent directory.
155 td, tdcloser, err := safetemp.Dir("", "getter") 223 td, tdcloser, err := safetemp.Dir("", "getter")
@@ -158,8 +226,12 @@ func (g *HttpGetter) getSubdir(dst, source, subDir string) error {
158 } 226 }
159 defer tdcloser.Close() 227 defer tdcloser.Close()
160 228
229 var opts []ClientOption
230 if g.client != nil {
231 opts = g.client.Options
232 }
161 // Download that into the given directory 233 // Download that into the given directory
162 if err := Get(td, source); err != nil { 234 if err := Get(td, source, opts...); err != nil {
163 return err 235 return err
164 } 236 }
165 237
@@ -185,7 +257,7 @@ func (g *HttpGetter) getSubdir(dst, source, subDir string) error {
185 return err 257 return err
186 } 258 }
187 259
188 return copyDir(dst, sourcePath, false) 260 return copyDir(ctx, dst, sourcePath, false)
189} 261}
190 262
191// parseMeta looks for the first meta tag in the given reader that 263// parseMeta looks for the first meta tag in the given reader that
diff --git a/vendor/github.com/hashicorp/go-getter/get_mock.go b/vendor/github.com/hashicorp/go-getter/get_mock.go
index 882e694..e2a98ea 100644
--- a/vendor/github.com/hashicorp/go-getter/get_mock.go
+++ b/vendor/github.com/hashicorp/go-getter/get_mock.go
@@ -6,6 +6,8 @@ import (
6 6
7// MockGetter is an implementation of Getter that can be used for tests. 7// MockGetter is an implementation of Getter that can be used for tests.
8type MockGetter struct { 8type MockGetter struct {
9 getter
10
9 // Proxy, if set, will be called after recording the calls below. 11 // Proxy, if set, will be called after recording the calls below.
10 // If it isn't set, then the *Err values will be returned. 12 // If it isn't set, then the *Err values will be returned.
11 Proxy Getter 13 Proxy Getter
diff --git a/vendor/github.com/hashicorp/go-getter/get_s3.go b/vendor/github.com/hashicorp/go-getter/get_s3.go
index ebb3217..93eeb0b 100644
--- a/vendor/github.com/hashicorp/go-getter/get_s3.go
+++ b/vendor/github.com/hashicorp/go-getter/get_s3.go
@@ -1,8 +1,8 @@
1package getter 1package getter
2 2
3import ( 3import (
4 "context"
4 "fmt" 5 "fmt"
5 "io"
6 "net/url" 6 "net/url"
7 "os" 7 "os"
8 "path/filepath" 8 "path/filepath"
@@ -18,7 +18,9 @@ import (
18 18
19// S3Getter is a Getter implementation that will download a module from 19// S3Getter is a Getter implementation that will download a module from
20// a S3 bucket. 20// a S3 bucket.
21type S3Getter struct{} 21type S3Getter struct {
22 getter
23}
22 24
23func (g *S3Getter) ClientMode(u *url.URL) (ClientMode, error) { 25func (g *S3Getter) ClientMode(u *url.URL) (ClientMode, error) {
24 // Parse URL 26 // Parse URL
@@ -60,6 +62,8 @@ func (g *S3Getter) ClientMode(u *url.URL) (ClientMode, error) {
60} 62}
61 63
62func (g *S3Getter) Get(dst string, u *url.URL) error { 64func (g *S3Getter) Get(dst string, u *url.URL) error {
65 ctx := g.Context()
66
63 // Parse URL 67 // Parse URL
64 region, bucket, path, _, creds, err := g.parseUrl(u) 68 region, bucket, path, _, creds, err := g.parseUrl(u)
65 if err != nil { 69 if err != nil {
@@ -124,7 +128,7 @@ func (g *S3Getter) Get(dst string, u *url.URL) error {
124 } 128 }
125 objDst = filepath.Join(dst, objDst) 129 objDst = filepath.Join(dst, objDst)
126 130
127 if err := g.getObject(client, objDst, bucket, objPath, ""); err != nil { 131 if err := g.getObject(ctx, client, objDst, bucket, objPath, ""); err != nil {
128 return err 132 return err
129 } 133 }
130 } 134 }
@@ -134,6 +138,7 @@ func (g *S3Getter) Get(dst string, u *url.URL) error {
134} 138}
135 139
136func (g *S3Getter) GetFile(dst string, u *url.URL) error { 140func (g *S3Getter) GetFile(dst string, u *url.URL) error {
141 ctx := g.Context()
137 region, bucket, path, version, creds, err := g.parseUrl(u) 142 region, bucket, path, version, creds, err := g.parseUrl(u)
138 if err != nil { 143 if err != nil {
139 return err 144 return err
@@ -142,10 +147,10 @@ func (g *S3Getter) GetFile(dst string, u *url.URL) error {
142 config := g.getAWSConfig(region, u, creds) 147 config := g.getAWSConfig(region, u, creds)
143 sess := session.New(config) 148 sess := session.New(config)
144 client := s3.New(sess) 149 client := s3.New(sess)
145 return g.getObject(client, dst, bucket, path, version) 150 return g.getObject(ctx, client, dst, bucket, path, version)
146} 151}
147 152
148func (g *S3Getter) getObject(client *s3.S3, dst, bucket, key, version string) error { 153func (g *S3Getter) getObject(ctx context.Context, client *s3.S3, dst, bucket, key, version string) error {
149 req := &s3.GetObjectInput{ 154 req := &s3.GetObjectInput{
150 Bucket: aws.String(bucket), 155 Bucket: aws.String(bucket),
151 Key: aws.String(key), 156 Key: aws.String(key),
@@ -170,7 +175,7 @@ func (g *S3Getter) getObject(client *s3.S3, dst, bucket, key, version string) er
170 } 175 }
171 defer f.Close() 176 defer f.Close()
172 177
173 _, err = io.Copy(f, resp.Body) 178 _, err = Copy(ctx, f, resp.Body)
174 return err 179 return err
175} 180}
176 181
diff --git a/vendor/github.com/hashicorp/go-getter/go.mod b/vendor/github.com/hashicorp/go-getter/go.mod
new file mode 100644
index 0000000..807c0a2
--- /dev/null
+++ b/vendor/github.com/hashicorp/go-getter/go.mod
@@ -0,0 +1,22 @@
1module github.com/hashicorp/go-getter
2
3require (
4 cloud.google.com/go v0.36.0
5 github.com/aws/aws-sdk-go v1.15.78
6 github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d
7 github.com/cheggaaa/pb v1.0.27
8 github.com/fatih/color v1.7.0 // indirect
9 github.com/hashicorp/go-cleanhttp v0.5.0
10 github.com/hashicorp/go-safetemp v1.0.0
11 github.com/hashicorp/go-version v1.1.0
12 github.com/mattn/go-colorable v0.0.9 // indirect
13 github.com/mattn/go-isatty v0.0.4 // indirect
14 github.com/mattn/go-runewidth v0.0.4 // indirect
15 github.com/mitchellh/go-homedir v1.0.0
16 github.com/mitchellh/go-testing-interface v1.0.0
17 github.com/ulikunitz/xz v0.5.5
18 golang.org/x/net v0.0.0-20181114220301-adae6a3d119a // indirect
19 golang.org/x/sys v0.0.0-20181213200352-4d1cda033e06 // indirect
20 google.golang.org/api v0.1.0
21 gopkg.in/cheggaaa/pb.v1 v1.0.27 // indirect
22)
diff --git a/vendor/github.com/hashicorp/go-getter/go.sum b/vendor/github.com/hashicorp/go-getter/go.sum
new file mode 100644
index 0000000..0fc5088
--- /dev/null
+++ b/vendor/github.com/hashicorp/go-getter/go.sum
@@ -0,0 +1,182 @@
1cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
2cloud.google.com/go v0.31.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
3cloud.google.com/go v0.36.0 h1:+aCSj7tOo2LODWVEuZDZeGCckdt6MlSF+X/rB3wUiS8=
4cloud.google.com/go v0.36.0/go.mod h1:RUoy9p/M4ge0HzT8L+SDZ8jg+Q6fth0CiBuhFJpSV40=
5dmitri.shuralyov.com/app/changes v0.0.0-20180602232624-0a106ad413e3/go.mod h1:Yl+fi1br7+Rr3LqpNJf1/uxUdtRUV+Tnj0o93V2B9MU=
6dmitri.shuralyov.com/html/belt v0.0.0-20180602232347-f7d459c86be0/go.mod h1:JLBrvjyP0v+ecvNYvCpyZgu5/xkfAUhi6wJj28eUfSU=
7dmitri.shuralyov.com/service/change v0.0.0-20181023043359-a85b471d5412/go.mod h1:a1inKt/atXimZ4Mv927x+r7UpyzRUf4emIoiiSC2TN4=
8dmitri.shuralyov.com/state v0.0.0-20180228185332-28bcc343414c/go.mod h1:0PRwlb0D6DFvNNtx+9ybjezNCa8XF0xaYcETyp6rHWU=
9git.apache.org/thrift.git v0.0.0-20180902110319-2566ecd5d999/go.mod h1:fPE2ZNJGynbRyZ4dJvy6G277gSllfV2HJqblrnkyeyg=
10github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
11github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c=
12github.com/aws/aws-sdk-go v1.15.78 h1:LaXy6lWR0YK7LKyuU0QWy2ws/LWTPfYV/UgfiBu4tvY=
13github.com/aws/aws-sdk-go v1.15.78/go.mod h1:E3/ieXAlvM0XWO57iftYVDLLvQ824smPP3ATZkfNZeM=
14github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
15github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d h1:xDfNPAt8lFiC1UJrqV3uuy861HCTo708pDMbjHHdCas=
16github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d/go.mod h1:6QX/PXZ00z/TKoufEY6K/a0k6AhaJrQKdFe6OfVXsa4=
17github.com/bradfitz/go-smtpd v0.0.0-20170404230938-deb6d6237625/go.mod h1:HYsPBTaaSFSlLx/70C2HPIMNZpVV8+vt/A+FMnYP11g=
18github.com/cheggaaa/pb v1.0.27 h1:wIkZHkNfC7R6GI5w7l/PdAdzXzlrbcI3p8OAlnkTsnc=
19github.com/cheggaaa/pb v1.0.27/go.mod h1:pQciLPpbU0oxA0h+VJYYLxO+XeDQb5pZijXscXHm81s=
20github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
21github.com/coreos/go-systemd v0.0.0-20181012123002-c6f51f82210d/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
22github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
23github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
24github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
25github.com/fatih/color v1.7.0 h1:DkWD4oS2D8LGGgTQ6IvwJJXSL5Vp2ffcQg58nFV38Ys=
26github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
27github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc=
28github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
29github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
30github.com/gliderlabs/ssh v0.1.1/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0=
31github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
32github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58=
33github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
34github.com/golang/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:tluoj9z5200jBnyusfRPU2LqT6J+DAorxEvtC7LHB+E=
35github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
36github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
37github.com/golang/protobuf v1.2.0 h1:P3YflyNX/ehuJFLhxviNdFxQPkGK5cDcApsge1SqnvM=
38github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
39github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
40github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
41github.com/google/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ=
42github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
43github.com/google/martian v2.1.0+incompatible h1:/CP5g8u/VJHijgedC/Legn3BAbAaWPgecwXBIDzw5no=
44github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
45github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
46github.com/googleapis/gax-go v2.0.0+incompatible h1:j0GKcs05QVmm7yesiZq2+9cxHkNK9YM6zKx4D2qucQU=
47github.com/googleapis/gax-go v2.0.0+incompatible/go.mod h1:SFVmujtThgffbyetf+mdk2eWhX2bMyUtNHzFKcPA9HY=
48github.com/googleapis/gax-go/v2 v2.0.3 h1:siORttZ36U2R/WjiJuDz8znElWBiAlO9rVt+mqJt0Cc=
49github.com/googleapis/gax-go/v2 v2.0.3/go.mod h1:LLvjysVCY1JZeum8Z6l8qUty8fiNwE08qbEPm1M08qg=
50github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
51github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA=
52github.com/grpc-ecosystem/grpc-gateway v1.5.0/go.mod h1:RSKVYQBd5MCa4OVpNdGskqpgL2+G+NZTnrVHpWWfpdw=
53github.com/hashicorp/go-cleanhttp v0.5.0 h1:wvCrVc9TjDls6+YGAF2hAifE1E5U1+b4tH6KdvN3Gig=
54github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=
55github.com/hashicorp/go-safetemp v1.0.0 h1:2HR189eFNrjHQyENnQMMpCiBAsRxzbTMIgBhEyExpmo=
56github.com/hashicorp/go-safetemp v1.0.0/go.mod h1:oaerMy3BhqiTbVye6QuFhFtIceqFoDHxNAB65b+Rj1I=
57github.com/hashicorp/go-version v1.1.0 h1:bPIoEKD27tNdebFGGxxYwcL4nepeY4j1QP23PFRGzg0=
58github.com/hashicorp/go-version v1.1.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
59github.com/jellevandenhooff/dkim v0.0.0-20150330215556-f50fe3d243e1/go.mod h1:E0B/fFc00Y+Rasa88328GlI/XbtyysCtTHZS8h7IrBU=
60github.com/jmespath/go-jmespath v0.0.0-20160202185014-0b12d6b521d8 h1:12VvqtR6Aowv3l/EQUlocDHW2Cp4G9WJVH7uyH8QFJE=
61github.com/jmespath/go-jmespath v0.0.0-20160202185014-0b12d6b521d8/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
62github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
63github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
64github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
65github.com/kr/pty v1.1.3/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
66github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
67github.com/mattn/go-colorable v0.0.9 h1:UVL0vNpWh04HeJXV0KLcaT7r06gOH2l4OW6ddYRUIY4=
68github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
69github.com/mattn/go-isatty v0.0.4 h1:bnP0vzxcAdeI1zdubAl5PjU6zsERjGZb7raWodagDYs=
70github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
71github.com/mattn/go-runewidth v0.0.4 h1:2BvfKmzob6Bmd4YsL0zygOqfdFnK7GR4QL06Do4/p7Y=
72github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
73github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
74github.com/microcosm-cc/bluemonday v1.0.1/go.mod h1:hsXNsILzKxV+sX77C5b8FSuKF00vh2OMYv+xgHpAMF4=
75github.com/mitchellh/go-homedir v1.0.0 h1:vKb8ShqSby24Yrqr/yDYkuFz8d0WUjys40rvnGC8aR0=
76github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
77github.com/mitchellh/go-testing-interface v1.0.0 h1:fzU/JVNcaqHQEcVFAKeR41fkiLdIPrefOvVG1VZ96U0=
78github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI=
79github.com/neelance/astrewrite v0.0.0-20160511093645-99348263ae86/go.mod h1:kHJEU3ofeGjhHklVoIGuVj85JJwZ6kWPaJwCIxgnFmo=
80github.com/neelance/sourcemap v0.0.0-20151028013722-8c68805598ab/go.mod h1:Qr6/a/Q4r9LP1IltGz7tA7iOK1WonHEYhu1HRBA7ZiM=
81github.com/openzipkin/zipkin-go v0.1.1/go.mod h1:NtoC/o8u3JlF1lSlyPNswIbeQH9bJTmOf0Erfk+hxe8=
82github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
83github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
84github.com/prometheus/client_golang v0.8.0/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
85github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
86github.com/prometheus/common v0.0.0-20180801064454-c7de2306084e/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
87github.com/prometheus/procfs v0.0.0-20180725123919-05ee40e3a273/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
88github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
89github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
90github.com/shurcooL/component v0.0.0-20170202220835-f88ec8f54cc4/go.mod h1:XhFIlyj5a1fBNx5aJTbKoIq0mNaPvOagO+HjB3EtxrY=
91github.com/shurcooL/events v0.0.0-20181021180414-410e4ca65f48/go.mod h1:5u70Mqkb5O5cxEA8nxTsgrgLehJeAw6Oc4Ab1c/P1HM=
92github.com/shurcooL/github_flavored_markdown v0.0.0-20181002035957-2122de532470/go.mod h1:2dOwnU2uBioM+SGy2aZoq1f/Sd1l9OkAeAUvjSyvgU0=
93github.com/shurcooL/go v0.0.0-20180423040247-9e1955d9fb6e/go.mod h1:TDJrrUr11Vxrven61rcy3hJMUqaf/CLWYhHNPmT14Lk=
94github.com/shurcooL/go-goon v0.0.0-20170922171312-37c2f522c041/go.mod h1:N5mDOmsrJOB+vfqUK+7DmDyjhSLIIBnXo9lvZJj3MWQ=
95github.com/shurcooL/gofontwoff v0.0.0-20180329035133-29b52fc0a18d/go.mod h1:05UtEgK5zq39gLST6uB0cf3NEHjETfB4Fgr3Gx5R9Vw=
96github.com/shurcooL/gopherjslib v0.0.0-20160914041154-feb6d3990c2c/go.mod h1:8d3azKNyqcHP1GaQE/c6dDgjkgSx2BZ4IoEi4F1reUI=
97github.com/shurcooL/highlight_diff v0.0.0-20170515013008-09bb4053de1b/go.mod h1:ZpfEhSmds4ytuByIcDnOLkTHGUI6KNqRNPDLHDk+mUU=
98github.com/shurcooL/highlight_go v0.0.0-20181028180052-98c3abbbae20/go.mod h1:UDKB5a1T23gOMUJrI+uSuH0VRDStOiUVSjBTRDVBVag=
99github.com/shurcooL/home v0.0.0-20181020052607-80b7ffcb30f9/go.mod h1:+rgNQw2P9ARFAs37qieuu7ohDNQ3gds9msbT2yn85sg=
100github.com/shurcooL/htmlg v0.0.0-20170918183704-d01228ac9e50/go.mod h1:zPn1wHpTIePGnXSHpsVPWEktKXHr6+SS6x/IKRb7cpw=
101github.com/shurcooL/httperror v0.0.0-20170206035902-86b7830d14cc/go.mod h1:aYMfkZ6DWSJPJ6c4Wwz3QtW22G7mf/PEgaB9k/ik5+Y=
102github.com/shurcooL/httpfs v0.0.0-20171119174359-809beceb2371/go.mod h1:ZY1cvUeJuFPAdZ/B6v7RHavJWZn2YPVFQ1OSXhCGOkg=
103github.com/shurcooL/httpgzip v0.0.0-20180522190206-b1c53ac65af9/go.mod h1:919LwcH0M7/W4fcZ0/jy0qGght1GIhqyS/EgWGH2j5Q=
104github.com/shurcooL/issues v0.0.0-20181008053335-6292fdc1e191/go.mod h1:e2qWDig5bLteJ4fwvDAc2NHzqFEthkqn7aOZAOpj+PQ=
105github.com/shurcooL/issuesapp v0.0.0-20180602232740-048589ce2241/go.mod h1:NPpHK2TI7iSaM0buivtFUc9offApnI0Alt/K8hcHy0I=
106github.com/shurcooL/notifications v0.0.0-20181007000457-627ab5aea122/go.mod h1:b5uSkrEVM1jQUspwbixRBhaIjIzL2xazXp6kntxYle0=
107github.com/shurcooL/octicon v0.0.0-20181028054416-fa4f57f9efb2/go.mod h1:eWdoE5JD4R5UVWDucdOPg1g2fqQRq78IQa9zlOV1vpQ=
108github.com/shurcooL/reactions v0.0.0-20181006231557-f2e0b4ca5b82/go.mod h1:TCR1lToEk4d2s07G3XGfz2QrgHXg4RJBvjrOozvoWfk=
109github.com/shurcooL/sanitized_anchor_name v0.0.0-20170918181015-86672fcb3f95/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
110github.com/shurcooL/users v0.0.0-20180125191416-49c67e49c537/go.mod h1:QJTqeLYEDaXHZDBsXlPCDqdhQuJkuw4NOtaxYe3xii4=
111github.com/shurcooL/webdavfs v0.0.0-20170829043945-18c3829fa133/go.mod h1:hKmq5kWdCj2z2KEozexVbfEZIWiTjhE0+UjmZgPqehw=
112github.com/sourcegraph/annotate v0.0.0-20160123013949-f4cad6c6324d/go.mod h1:UdhH50NIW0fCiwBSr0co2m7BnFLdv4fQTgdqdJTHFeE=
113github.com/sourcegraph/syntaxhighlight v0.0.0-20170531221838-bd320f5d308e/go.mod h1:HuIsMU8RRBOtsCgI77wP899iHVBQpCmg4ErYMZB+2IA=
114github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w=
115github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
116github.com/tarm/serial v0.0.0-20180830185346-98f6abe2eb07/go.mod h1:kDXzergiv9cbyO7IOYJZWg1U88JhDg3PB6klq9Hg2pA=
117github.com/ulikunitz/xz v0.5.5 h1:pFrO0lVpTBXLpYw+pnLj6TbvHuyjXMfjGeCwSqCVwok=
118github.com/ulikunitz/xz v0.5.5/go.mod h1:2bypXElzHzzJZwzH67Y6wb67pO62Rzfn7BSiF4ABRW8=
119go.opencensus.io v0.18.0 h1:Mk5rgZcggtbvtAun5aJzAtjKKN/t0R3jJPlWILlv938=
120go.opencensus.io v0.18.0/go.mod h1:vKdFvxhtzZ9onBp9VKHK8z/sRpBMnKAsufL7wlDrCOA=
121go4.org v0.0.0-20180809161055-417644f6feb5/go.mod h1:MkTOUMDaeVYJUOUsaDXIhWPZYa1yOyC1qaOBpL57BhE=
122golang.org/x/build v0.0.0-20190111050920-041ab4dc3f9d/go.mod h1:OWs+y06UdEOHN4y+MfF/py+xQ/tYqIWW03b70/CG9Rw=
123golang.org/x/crypto v0.0.0-20181030102418-4d3f4d9ffa16/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
124golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
125golang.org/x/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
126golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
127golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
128golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
129golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
130golang.org/x/net v0.0.0-20181029044818-c44066c5c816/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
131golang.org/x/net v0.0.0-20181106065722-10aee1819953/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
132golang.org/x/net v0.0.0-20181114220301-adae6a3d119a h1:gOpx8G595UYyvj8UK4+OFyY4rx037g3fmfhe5SasG3U=
133golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
134golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
135golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
136golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890 h1:uESlIz09WIHT2I+pasSXcpLYqYK8wHcdCetU3VuMBJE=
137golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
138golang.org/x/perf v0.0.0-20180704124530-6e6d33e29852/go.mod h1:JLpeXjPJfIyPr5TlbXLkXWLhP8nz10XfvxElABhCtcw=
139golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
140golang.org/x/sync v0.0.0-20181108010431-42b317875d0f h1:Bl/8QSvNqXvPGPGXa2z5xUTmV7VDcZyvRZ+QQXkXTZQ=
141golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
142golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
143golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
144golang.org/x/sys v0.0.0-20181029174526-d69651ed3497/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
145golang.org/x/sys v0.0.0-20181213200352-4d1cda033e06 h1:0oC8rFnE+74kEmuHZ46F6KHsMr5Gx2gUQPuNz28iQZM=
146golang.org/x/sys v0.0.0-20181213200352-4d1cda033e06/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
147golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
148golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
149golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2 h1:z99zHgr7hKfrUcX/KsoJk5FJfjTceCKIp96+biqP4To=
150golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
151golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
152golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
153golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
154golang.org/x/tools v0.0.0-20181030000716-a0a13e073c7b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
155google.golang.org/api v0.0.0-20180910000450-7ca32eb868bf/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0=
156google.golang.org/api v0.0.0-20181030000543-1d582fd0359e/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0=
157google.golang.org/api v0.1.0 h1:K6z2u68e86TPdSdefXdzvXgR1zEMa+459vBSfWYAZkI=
158google.golang.org/api v0.1.0/go.mod h1:UGEZY7KEX120AnNLIHFMKIo4obdJhkp2tPbaPlQx13Y=
159google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
160google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
161google.golang.org/appengine v1.3.0 h1:FBSsiFRMz3LBeXIomRnVzrQwSDj4ibvcRexLG0LZGQk=
162google.golang.org/appengine v1.3.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
163google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
164google.golang.org/genproto v0.0.0-20180831171423-11092d34479b/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
165google.golang.org/genproto v0.0.0-20181029155118-b69ba1387ce2/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
166google.golang.org/genproto v0.0.0-20181202183823-bd91e49a0898/go.mod h1:7Ep/1NZk928CDR8SjdVbjWNpdIf6nzjE3BTgJDr2Atg=
167google.golang.org/genproto v0.0.0-20190201180003-4b09977fb922 h1:mBVYJnbrXLA/ZCBTCe7PtEgAUP+1bg92qTaFoPHdz+8=
168google.golang.org/genproto v0.0.0-20190201180003-4b09977fb922/go.mod h1:L3J43x8/uS+qIUoksaLKe6OS3nUKxOKuIFz1sl2/jx4=
169google.golang.org/grpc v1.14.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw=
170google.golang.org/grpc v1.16.0/go.mod h1:0JHn/cJsOMiMfNA9+DeHDlAU7KAAB5GDlYFpa9MZMio=
171google.golang.org/grpc v1.17.0 h1:TRJYBgMclJvGYn2rIMjj+h9KtMt5r1Ij7ODVRIZkwhk=
172google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs=
173gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
174gopkg.in/cheggaaa/pb.v1 v1.0.27 h1:kJdccidYzt3CaHD1crCFTS1hxyhSi059NhOFUf03YFo=
175gopkg.in/cheggaaa/pb.v1 v1.0.27/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw=
176gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
177gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
178grpc.go4.org v0.0.0-20170609214715-11d0a25b4919/go.mod h1:77eQGdRu53HpSqPFJFmuJdjuHRquDANNeA4x7B8WQ9o=
179honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
180honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
181sourcegraph.com/sourcegraph/go-diff v0.5.0/go.mod h1:kuch7UrkMzY0X+p9CRK03kfuPQ2zzQcaEFbx8wA8rck=
182sourcegraph.com/sqs/pbtypes v0.0.0-20180604144634-d3ebe8f20ae4/go.mod h1:ketZ/q3QxT9HOBeFhu6RdvsftgpsbFHBF5Cas6cDKZ0=
diff --git a/vendor/github.com/hashicorp/go-getter/helper/url/url_windows.go b/vendor/github.com/hashicorp/go-getter/helper/url/url_windows.go
index 4655226..4280ec5 100644
--- a/vendor/github.com/hashicorp/go-getter/helper/url/url_windows.go
+++ b/vendor/github.com/hashicorp/go-getter/helper/url/url_windows.go
@@ -11,19 +11,18 @@ func parse(rawURL string) (*url.URL, error) {
11 // Make sure we're using "/" since URLs are "/"-based. 11 // Make sure we're using "/" since URLs are "/"-based.
12 rawURL = filepath.ToSlash(rawURL) 12 rawURL = filepath.ToSlash(rawURL)
13 13
14 if len(rawURL) > 1 && rawURL[1] == ':' {
15 // Assume we're dealing with a drive letter. In which case we
16 // force the 'file' scheme to avoid "net/url" URL.String() prepending
17 // our url with "./".
18 rawURL = "file://" + rawURL
19 }
20
14 u, err := url.Parse(rawURL) 21 u, err := url.Parse(rawURL)
15 if err != nil { 22 if err != nil {
16 return nil, err 23 return nil, err
17 } 24 }
18 25
19 if len(rawURL) > 1 && rawURL[1] == ':' {
20 // Assume we're dealing with a drive letter file path where the drive
21 // letter has been parsed into the URL Scheme, and the rest of the path
22 // has been parsed into the URL Path without the leading ':' character.
23 u.Path = fmt.Sprintf("%s:%s", string(rawURL[0]), u.Path)
24 u.Scheme = ""
25 }
26
27 if len(u.Host) > 1 && u.Host[1] == ':' && strings.HasPrefix(rawURL, "file://") { 26 if len(u.Host) > 1 && u.Host[1] == ':' && strings.HasPrefix(rawURL, "file://") {
28 // Assume we're dealing with a drive letter file path where the drive 27 // Assume we're dealing with a drive letter file path where the drive
29 // letter has been parsed into the URL Host. 28 // letter has been parsed into the URL Host.
diff --git a/vendor/github.com/hashicorp/go-getter/source.go b/vendor/github.com/hashicorp/go-getter/source.go
index c63f2bb..dab6d40 100644
--- a/vendor/github.com/hashicorp/go-getter/source.go
+++ b/vendor/github.com/hashicorp/go-getter/source.go
@@ -6,18 +6,31 @@ import (
6 "strings" 6 "strings"
7) 7)
8 8
9// SourceDirSubdir takes a source and returns a tuple of the URL without 9// SourceDirSubdir takes a source URL and returns a tuple of the URL without
10// the subdir and the URL with the subdir. 10// the subdir and the subdir.
11//
12// ex:
13// dom.com/path/?q=p => dom.com/path/?q=p, ""
14// proto://dom.com/path//*?q=p => proto://dom.com/path?q=p, "*"
15// proto://dom.com/path//path2?q=p => proto://dom.com/path?q=p, "path2"
16//
11func SourceDirSubdir(src string) (string, string) { 17func SourceDirSubdir(src string) (string, string) {
12 // Calcaulate an offset to avoid accidentally marking the scheme 18
19 // URL might contains another url in query parameters
20 stop := len(src)
21 if idx := strings.Index(src, "?"); idx > -1 {
22 stop = idx
23 }
24
25 // Calculate an offset to avoid accidentally marking the scheme
13 // as the dir. 26 // as the dir.
14 var offset int 27 var offset int
15 if idx := strings.Index(src, "://"); idx > -1 { 28 if idx := strings.Index(src[:stop], "://"); idx > -1 {
16 offset = idx + 3 29 offset = idx + 3
17 } 30 }
18 31
19 // First see if we even have an explicit subdir 32 // First see if we even have an explicit subdir
20 idx := strings.Index(src[offset:], "//") 33 idx := strings.Index(src[offset:stop], "//")
21 if idx == -1 { 34 if idx == -1 {
22 return src, "" 35 return src, ""
23 } 36 }