diff options
Diffstat (limited to 'vendor/github.com/hashicorp/go-getter')
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 | ||
10 | language: go | 10 | language: go |
11 | 11 | ||
12 | os: | ||
13 | - linux | ||
14 | - osx | ||
15 | |||
12 | go: | 16 | go: |
13 | - 1.8.x | 17 | - "1.11.x" |
14 | - 1.9.x | 18 | |
15 | - master | 19 | before_script: |
20 | - go build ./cmd/go-getter | ||
16 | 21 | ||
17 | branches: | 22 | branches: |
18 | only: | 23 | only: |
19 | - master | 24 | - master |
20 | |||
21 | matrix: | ||
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 | ||
75 | In addition to the above protocols, go-getter has what are called "detectors." | 76 | In addition to the above protocols, go-getter has what are called "detectors." |
76 | These take a URL and attempt to automatically choose the best protocol for | 77 | These 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 | ||
98 | Forced protocols will also override any detectors. | 99 | Forced protocols will also override any detectors. |
99 | 100 | ||
100 | In the absense of a forced protocol, detectors may be run on the URL, transforming | 101 | In the absence of a forced protocol, detectors may be run on the URL, transforming |
101 | the protocol anyways. The above example would've used the Git protocol either | 102 | the protocol anyways. The above example would've used the Git protocol either |
102 | way since the Git detector would've detected it was a GitHub URL. | 103 | way 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 | |||
155 | a checksum for you. Note that checksumming only works for downloading files, | 156 | a checksum for you. Note that checksumming only works for downloading files, |
156 | not directories, but checksumming will work for any protocol. | 157 | not directories, but checksumming will work for any protocol. |
157 | 158 | ||
158 | To checksum a file, append a `checksum` query parameter to the URL. | 159 | To checksum a file, append a `checksum` query parameter to the URL. go-getter |
159 | The paramter value should be in the format of `type:value`, where | 160 | will parse out this query parameter automatically and use it to verify the |
160 | type is "md5", "sha1", "sha256", or "sha512". The "value" should be | 161 | checksum. The parameter value can be in the format of `type:value` or just |
161 | the actual checksum value. go-getter will parse out this query parameter | 162 | `value`, where type is "md5", "sha1", "sha256", "sha512" or "file" . The |
162 | automatically and use it to verify the checksum. An example URL | 163 | "value" should be the actual checksum value or download URL for "file". When |
163 | is shown below: | 164 | `type` part is omitted, type will be guessed based on the length of the |
165 | checksum 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 | |||
179 | When checksumming from a file - ex: with `checksum=file:url` - go-getter will | ||
180 | get the file linked in the URL after `file:` using the same configuration. For | ||
181 | example, in `file:http://releases.ubuntu.com/cosmic/MD5SUMS` go-getter will | ||
182 | download a checksum file under the aforementioned url using the http protocol. | ||
183 | All protocols supported by go-getter can be used. The checksum file will be | ||
184 | downloaded in a temporary file then parsed. The destination of the temporary | ||
185 | file can be changed by setting system specific environment variables: `TMPDIR` | ||
186 | for unix; `TMP`, `TEMP` or `USERPROFILE` on windows. Read godoc of | ||
187 | [os.TempDir](https://golang.org/pkg/os/#TempDir) for more information on the | ||
188 | temporary directory selection. Content of files are expected to be BSD or GNU | ||
189 | style. Once go-getter is done with the checksum file; it is deleted. | ||
190 | |||
169 | The checksum query parameter is never sent to the backend protocol | 191 | The checksum query parameter is never sent to the backend protocol |
170 | implementation. It is used at a higher level by go-getter itself. | 192 | implementation. It is used at a higher level by go-getter itself. |
171 | 193 | ||
194 | If the destination file exists and the checksums match: download | ||
195 | will be skipped. | ||
196 | |||
172 | ### Unarchiving | 197 | ### Unarchiving |
173 | 198 | ||
174 | go-getter will automatically unarchive files into a file or directory | 199 | go-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 | ||
218 | This section documents the protocol-specific options that can be specified | 243 | This section documents the protocol-specific options that can be specified for |
219 | for go-getter. These options should be appended to the input as normal query | 244 | go-getter. These options should be appended to the input as normal query |
220 | parameters. Depending on the usage of go-getter, applications may provide | 245 | parameters ([HTTP headers](#headers) are an exception to this, however). |
221 | alternate ways of inputting options. For example, [Nomad](https://www.nomadproject.io) | 246 | Depending on the usage of go-getter, applications may provide alternate ways of |
222 | provides a nice options block for specifying options rather than in the URL. | 247 | inputting options. For example, [Nomad](https://www.nomadproject.io) provides a |
248 | nice 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 | |||
284 | The `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::` | ||
287 | force prefix is allowed if the username prefix is exactly `git@`. | ||
288 | |||
289 | The "scp-style" addresses _cannot_ be used in conjunction with the `ssh://` | ||
290 | scheme prefix, because in that case the colon is used to mark an optional | ||
291 | port 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 | |||
263 | hostname in the URL such as `https://Aladdin:OpenSesame@www.example.com/index.html`. All special | 302 | hostname in the URL such as `https://Aladdin:OpenSesame@www.example.com/index.html`. All special |
264 | characters, including the username and password, must be URL encoded. | 303 | characters, including the username and password, must be URL encoded. |
265 | 304 | ||
305 | #### Headers | ||
306 | |||
307 | Optional 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 | ||
310 | out on every request the getter in question makes. | ||
311 | |||
266 | ### S3 (`s3`) | 312 | ### S3 (`s3`) |
267 | 313 | ||
268 | S3 takes various access configurations in the URL. Note that it will also | 314 | S3 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®ion=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®ion=us-east-2" |
301 | 347 | ||
348 | ### GCS (`gcs`) | ||
349 | |||
350 | #### GCS Authentication | ||
351 | |||
352 | In 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 ./... |
15 | build_script: | 15 | build_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 @@ | |||
1 | package getter | ||
2 | |||
3 | import ( | ||
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. | ||
23 | type 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 | ||
31 | type ChecksumError struct { | ||
32 | Hash hash.Hash | ||
33 | Actual []byte | ||
34 | Expected []byte | ||
35 | File string | ||
36 | } | ||
37 | |||
38 | func (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. | ||
53 | func (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 | ||
96 | func (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 | |||
124 | func 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 | |||
136 | func 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 | |||
160 | func 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 | ||
193 | func (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. | ||
289 | func 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 @@ | |||
1 | package getter | 1 | package getter |
2 | 2 | ||
3 | import ( | 3 | import ( |
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. |
28 | type Client struct { | 21 | type 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. |
68 | func (c *Client) Get() error { | 70 | func (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. | ||
331 | func 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 @@ | |||
1 | package getter | ||
2 | |||
3 | import "context" | ||
4 | |||
5 | // A ClientOption allows to configure a client | ||
6 | type ClientOption func(*Client) error | ||
7 | |||
8 | // Configure configures a client with options. | ||
9 | func (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. | ||
41 | func 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 @@ | |||
1 | package getter | ||
2 | |||
3 | import ( | ||
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. | ||
12 | func 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. | ||
20 | type 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 @@ | |||
1 | package getter | ||
2 | |||
3 | import ( | ||
4 | "io/ioutil" | ||
5 | ) | ||
6 | |||
7 | func 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 @@ | |||
1 | package getter | 1 | package getter |
2 | 2 | ||
3 | import ( | 3 | import ( |
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. |
14 | func copyDir(dst string, src string, ignoreDot bool) error { | 14 | func 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 |
20 | type TestDecompressCase struct { | 20 | type 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. |
30 | func TestDecompressor(t testing.T, d Decompressor, cases []TestDecompressCase) { | 30 | func 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. |
13 | type ZipDecompressor struct{} | 13 | type ZipDecompressor struct{} |
14 | 14 | ||
15 | func (d *ZipDecompressor) Decompress(dst, src string, dir bool) error { | 15 | func (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 | |||
23 | func init() { | 23 | func 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 @@ | |||
1 | package getter | ||
2 | |||
3 | import ( | ||
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. | ||
11 | type GCSDetector struct{} | ||
12 | |||
13 | func (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 | |||
25 | func (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 @@ | |||
1 | package 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. | ||
5 | type GitDetector struct{} | ||
6 | |||
7 | func (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 | |||
51 | func (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 @@ | |||
1 | package getter | ||
2 | |||
3 | import ( | ||
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) | ||
14 | var 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 | ||
21 | func 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. |
77 | func Get(dst, src string) error { | 83 | func 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. |
92 | func GetAny(dst, src string) error { | 98 | func 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. |
103 | func GetFile(dst, src string) error { | 109 | func 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 @@ | |||
1 | package getter | ||
2 | |||
3 | import "context" | ||
4 | |||
5 | // getter is our base getter; it regroups | ||
6 | // fields all getters have in common. | ||
7 | type getter struct { | ||
8 | client *Client | ||
9 | } | ||
10 | |||
11 | func (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. | ||
15 | func (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. |
10 | type FileGetter struct { | 10 | type 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 @@ | |||
1 | package getter | ||
2 | |||
3 | import ( | ||
4 | "context" | ||
5 | "io" | ||
6 | ) | ||
7 | |||
8 | // readerFunc is syntactic sugar for read interface. | ||
9 | type readerFunc func(p []byte) (n int, err error) | ||
10 | |||
11 | func (rf readerFunc) Read(p []byte) (n int, err error) { return rf(p) } | ||
12 | |||
13 | // Copy is a io.Copy cancellable by context | ||
14 | func 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 | ||
5 | import ( | 5 | import ( |
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 | ||
52 | func (g *FileGetter) GetFile(dst string, u *url.URL) error { | 51 | func (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 | ||
5 | import ( | 5 | import ( |
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 | ||
15 | func (g *FileGetter) Get(dst string, u *url.URL) error { | 15 | func (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 | ||
62 | func (g *FileGetter) GetFile(dst string, u *url.URL) error { | 63 | func (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 @@ | |||
1 | package getter | ||
2 | |||
3 | import ( | ||
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. | ||
17 | type GCSGetter struct { | ||
18 | getter | ||
19 | } | ||
20 | |||
21 | func (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 | |||
58 | func (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 | |||
117 | func (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 | |||
133 | func (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 | |||
155 | func (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 @@ | |||
1 | package getter | 1 | package getter |
2 | 2 | ||
3 | import ( | 3 | import ( |
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. |
20 | type GitGetter struct{} | 23 | type GitGetter struct { |
24 | getter | ||
25 | } | ||
21 | 26 | ||
22 | func (g *GitGetter) ClientMode(_ *url.URL) (ClientMode, error) { | 27 | func (g *GitGetter) ClientMode(_ *url.URL) (ClientMode, error) { |
23 | return ClientModeDir, nil | 28 | return ClientModeDir, nil |
24 | } | 29 | } |
25 | 30 | ||
26 | func (g *GitGetter) Get(dst string, u *url.URL) error { | 31 | func (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 | ||
141 | func (g *GitGetter) clone(dst, sshKeyFile string, u *url.URL) error { | 162 | func (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 | ||
147 | func (g *GitGetter) update(dst, sshKeyFile, ref string) error { | 175 | func (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. |
172 | func (g *GitGetter) fetchSubmodules(dst, sshKeyFile string) error { | 205 | func (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 @@ | |||
1 | package getter | 1 | package getter |
2 | 2 | ||
3 | import ( | 3 | import ( |
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. |
17 | type HgGetter struct{} | 18 | type HgGetter struct { |
19 | getter | ||
20 | } | ||
18 | 21 | ||
19 | func (g *HgGetter) ClientMode(_ *url.URL) (ClientMode, error) { | 22 | func (g *HgGetter) ClientMode(_ *url.URL) (ClientMode, error) { |
20 | return ClientModeDir, nil | 23 | return ClientModeDir, nil |
21 | } | 24 | } |
22 | 25 | ||
23 | func (g *HgGetter) Get(dst string, u *url.URL) error { | 26 | func (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 | ||
111 | func (g *HgGetter) update(dst string, u *url.URL, rev string) error { | 115 | func (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 @@ | |||
1 | package getter | 1 | package getter |
2 | 2 | ||
3 | import ( | 3 | import ( |
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. |
36 | type HttpGetter struct { | 38 | type 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 | ||
46 | func (g *HttpGetter) ClientMode(u *url.URL) (ClientMode, error) { | 56 | func (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 | ||
53 | func (g *HttpGetter) Get(dst string, u *url.URL) error { | 63 | func (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 | ||
109 | func (g *HttpGetter) GetFile(dst string, u *url.URL) error { | 131 | func (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. |
152 | func (g *HttpGetter) getSubdir(dst, source, subDir string) error { | 220 | func (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. |
8 | type MockGetter struct { | 8 | type 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 @@ | |||
1 | package getter | 1 | package getter |
2 | 2 | ||
3 | import ( | 3 | import ( |
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. |
21 | type S3Getter struct{} | 21 | type S3Getter struct { |
22 | getter | ||
23 | } | ||
22 | 24 | ||
23 | func (g *S3Getter) ClientMode(u *url.URL) (ClientMode, error) { | 25 | func (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 | ||
62 | func (g *S3Getter) Get(dst string, u *url.URL) error { | 64 | func (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 | ||
136 | func (g *S3Getter) GetFile(dst string, u *url.URL) error { | 140 | func (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 | ||
148 | func (g *S3Getter) getObject(client *s3.S3, dst, bucket, key, version string) error { | 153 | func (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 @@ | |||
1 | module github.com/hashicorp/go-getter | ||
2 | |||
3 | require ( | ||
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 @@ | |||
1 | cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= | ||
2 | cloud.google.com/go v0.31.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= | ||
3 | cloud.google.com/go v0.36.0 h1:+aCSj7tOo2LODWVEuZDZeGCckdt6MlSF+X/rB3wUiS8= | ||
4 | cloud.google.com/go v0.36.0/go.mod h1:RUoy9p/M4ge0HzT8L+SDZ8jg+Q6fth0CiBuhFJpSV40= | ||
5 | dmitri.shuralyov.com/app/changes v0.0.0-20180602232624-0a106ad413e3/go.mod h1:Yl+fi1br7+Rr3LqpNJf1/uxUdtRUV+Tnj0o93V2B9MU= | ||
6 | dmitri.shuralyov.com/html/belt v0.0.0-20180602232347-f7d459c86be0/go.mod h1:JLBrvjyP0v+ecvNYvCpyZgu5/xkfAUhi6wJj28eUfSU= | ||
7 | dmitri.shuralyov.com/service/change v0.0.0-20181023043359-a85b471d5412/go.mod h1:a1inKt/atXimZ4Mv927x+r7UpyzRUf4emIoiiSC2TN4= | ||
8 | dmitri.shuralyov.com/state v0.0.0-20180228185332-28bcc343414c/go.mod h1:0PRwlb0D6DFvNNtx+9ybjezNCa8XF0xaYcETyp6rHWU= | ||
9 | git.apache.org/thrift.git v0.0.0-20180902110319-2566ecd5d999/go.mod h1:fPE2ZNJGynbRyZ4dJvy6G277gSllfV2HJqblrnkyeyg= | ||
10 | github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= | ||
11 | github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c= | ||
12 | github.com/aws/aws-sdk-go v1.15.78 h1:LaXy6lWR0YK7LKyuU0QWy2ws/LWTPfYV/UgfiBu4tvY= | ||
13 | github.com/aws/aws-sdk-go v1.15.78/go.mod h1:E3/ieXAlvM0XWO57iftYVDLLvQ824smPP3ATZkfNZeM= | ||
14 | github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= | ||
15 | github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d h1:xDfNPAt8lFiC1UJrqV3uuy861HCTo708pDMbjHHdCas= | ||
16 | github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d/go.mod h1:6QX/PXZ00z/TKoufEY6K/a0k6AhaJrQKdFe6OfVXsa4= | ||
17 | github.com/bradfitz/go-smtpd v0.0.0-20170404230938-deb6d6237625/go.mod h1:HYsPBTaaSFSlLx/70C2HPIMNZpVV8+vt/A+FMnYP11g= | ||
18 | github.com/cheggaaa/pb v1.0.27 h1:wIkZHkNfC7R6GI5w7l/PdAdzXzlrbcI3p8OAlnkTsnc= | ||
19 | github.com/cheggaaa/pb v1.0.27/go.mod h1:pQciLPpbU0oxA0h+VJYYLxO+XeDQb5pZijXscXHm81s= | ||
20 | github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= | ||
21 | github.com/coreos/go-systemd v0.0.0-20181012123002-c6f51f82210d/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= | ||
22 | github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= | ||
23 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= | ||
24 | github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= | ||
25 | github.com/fatih/color v1.7.0 h1:DkWD4oS2D8LGGgTQ6IvwJJXSL5Vp2ffcQg58nFV38Ys= | ||
26 | github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= | ||
27 | github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc= | ||
28 | github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= | ||
29 | github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= | ||
30 | github.com/gliderlabs/ssh v0.1.1/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0= | ||
31 | github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= | ||
32 | github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58= | ||
33 | github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= | ||
34 | github.com/golang/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:tluoj9z5200jBnyusfRPU2LqT6J+DAorxEvtC7LHB+E= | ||
35 | github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= | ||
36 | github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= | ||
37 | github.com/golang/protobuf v1.2.0 h1:P3YflyNX/ehuJFLhxviNdFxQPkGK5cDcApsge1SqnvM= | ||
38 | github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= | ||
39 | github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= | ||
40 | github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= | ||
41 | github.com/google/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ= | ||
42 | github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= | ||
43 | github.com/google/martian v2.1.0+incompatible h1:/CP5g8u/VJHijgedC/Legn3BAbAaWPgecwXBIDzw5no= | ||
44 | github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= | ||
45 | github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= | ||
46 | github.com/googleapis/gax-go v2.0.0+incompatible h1:j0GKcs05QVmm7yesiZq2+9cxHkNK9YM6zKx4D2qucQU= | ||
47 | github.com/googleapis/gax-go v2.0.0+incompatible/go.mod h1:SFVmujtThgffbyetf+mdk2eWhX2bMyUtNHzFKcPA9HY= | ||
48 | github.com/googleapis/gax-go/v2 v2.0.3 h1:siORttZ36U2R/WjiJuDz8znElWBiAlO9rVt+mqJt0Cc= | ||
49 | github.com/googleapis/gax-go/v2 v2.0.3/go.mod h1:LLvjysVCY1JZeum8Z6l8qUty8fiNwE08qbEPm1M08qg= | ||
50 | github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= | ||
51 | github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= | ||
52 | github.com/grpc-ecosystem/grpc-gateway v1.5.0/go.mod h1:RSKVYQBd5MCa4OVpNdGskqpgL2+G+NZTnrVHpWWfpdw= | ||
53 | github.com/hashicorp/go-cleanhttp v0.5.0 h1:wvCrVc9TjDls6+YGAF2hAifE1E5U1+b4tH6KdvN3Gig= | ||
54 | github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= | ||
55 | github.com/hashicorp/go-safetemp v1.0.0 h1:2HR189eFNrjHQyENnQMMpCiBAsRxzbTMIgBhEyExpmo= | ||
56 | github.com/hashicorp/go-safetemp v1.0.0/go.mod h1:oaerMy3BhqiTbVye6QuFhFtIceqFoDHxNAB65b+Rj1I= | ||
57 | github.com/hashicorp/go-version v1.1.0 h1:bPIoEKD27tNdebFGGxxYwcL4nepeY4j1QP23PFRGzg0= | ||
58 | github.com/hashicorp/go-version v1.1.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= | ||
59 | github.com/jellevandenhooff/dkim v0.0.0-20150330215556-f50fe3d243e1/go.mod h1:E0B/fFc00Y+Rasa88328GlI/XbtyysCtTHZS8h7IrBU= | ||
60 | github.com/jmespath/go-jmespath v0.0.0-20160202185014-0b12d6b521d8 h1:12VvqtR6Aowv3l/EQUlocDHW2Cp4G9WJVH7uyH8QFJE= | ||
61 | github.com/jmespath/go-jmespath v0.0.0-20160202185014-0b12d6b521d8/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= | ||
62 | github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= | ||
63 | github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= | ||
64 | github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= | ||
65 | github.com/kr/pty v1.1.3/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= | ||
66 | github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= | ||
67 | github.com/mattn/go-colorable v0.0.9 h1:UVL0vNpWh04HeJXV0KLcaT7r06gOH2l4OW6ddYRUIY4= | ||
68 | github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= | ||
69 | github.com/mattn/go-isatty v0.0.4 h1:bnP0vzxcAdeI1zdubAl5PjU6zsERjGZb7raWodagDYs= | ||
70 | github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= | ||
71 | github.com/mattn/go-runewidth v0.0.4 h1:2BvfKmzob6Bmd4YsL0zygOqfdFnK7GR4QL06Do4/p7Y= | ||
72 | github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= | ||
73 | github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= | ||
74 | github.com/microcosm-cc/bluemonday v1.0.1/go.mod h1:hsXNsILzKxV+sX77C5b8FSuKF00vh2OMYv+xgHpAMF4= | ||
75 | github.com/mitchellh/go-homedir v1.0.0 h1:vKb8ShqSby24Yrqr/yDYkuFz8d0WUjys40rvnGC8aR0= | ||
76 | github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= | ||
77 | github.com/mitchellh/go-testing-interface v1.0.0 h1:fzU/JVNcaqHQEcVFAKeR41fkiLdIPrefOvVG1VZ96U0= | ||
78 | github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= | ||
79 | github.com/neelance/astrewrite v0.0.0-20160511093645-99348263ae86/go.mod h1:kHJEU3ofeGjhHklVoIGuVj85JJwZ6kWPaJwCIxgnFmo= | ||
80 | github.com/neelance/sourcemap v0.0.0-20151028013722-8c68805598ab/go.mod h1:Qr6/a/Q4r9LP1IltGz7tA7iOK1WonHEYhu1HRBA7ZiM= | ||
81 | github.com/openzipkin/zipkin-go v0.1.1/go.mod h1:NtoC/o8u3JlF1lSlyPNswIbeQH9bJTmOf0Erfk+hxe8= | ||
82 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= | ||
83 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= | ||
84 | github.com/prometheus/client_golang v0.8.0/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= | ||
85 | github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= | ||
86 | github.com/prometheus/common v0.0.0-20180801064454-c7de2306084e/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= | ||
87 | github.com/prometheus/procfs v0.0.0-20180725123919-05ee40e3a273/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= | ||
88 | github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= | ||
89 | github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= | ||
90 | github.com/shurcooL/component v0.0.0-20170202220835-f88ec8f54cc4/go.mod h1:XhFIlyj5a1fBNx5aJTbKoIq0mNaPvOagO+HjB3EtxrY= | ||
91 | github.com/shurcooL/events v0.0.0-20181021180414-410e4ca65f48/go.mod h1:5u70Mqkb5O5cxEA8nxTsgrgLehJeAw6Oc4Ab1c/P1HM= | ||
92 | github.com/shurcooL/github_flavored_markdown v0.0.0-20181002035957-2122de532470/go.mod h1:2dOwnU2uBioM+SGy2aZoq1f/Sd1l9OkAeAUvjSyvgU0= | ||
93 | github.com/shurcooL/go v0.0.0-20180423040247-9e1955d9fb6e/go.mod h1:TDJrrUr11Vxrven61rcy3hJMUqaf/CLWYhHNPmT14Lk= | ||
94 | github.com/shurcooL/go-goon v0.0.0-20170922171312-37c2f522c041/go.mod h1:N5mDOmsrJOB+vfqUK+7DmDyjhSLIIBnXo9lvZJj3MWQ= | ||
95 | github.com/shurcooL/gofontwoff v0.0.0-20180329035133-29b52fc0a18d/go.mod h1:05UtEgK5zq39gLST6uB0cf3NEHjETfB4Fgr3Gx5R9Vw= | ||
96 | github.com/shurcooL/gopherjslib v0.0.0-20160914041154-feb6d3990c2c/go.mod h1:8d3azKNyqcHP1GaQE/c6dDgjkgSx2BZ4IoEi4F1reUI= | ||
97 | github.com/shurcooL/highlight_diff v0.0.0-20170515013008-09bb4053de1b/go.mod h1:ZpfEhSmds4ytuByIcDnOLkTHGUI6KNqRNPDLHDk+mUU= | ||
98 | github.com/shurcooL/highlight_go v0.0.0-20181028180052-98c3abbbae20/go.mod h1:UDKB5a1T23gOMUJrI+uSuH0VRDStOiUVSjBTRDVBVag= | ||
99 | github.com/shurcooL/home v0.0.0-20181020052607-80b7ffcb30f9/go.mod h1:+rgNQw2P9ARFAs37qieuu7ohDNQ3gds9msbT2yn85sg= | ||
100 | github.com/shurcooL/htmlg v0.0.0-20170918183704-d01228ac9e50/go.mod h1:zPn1wHpTIePGnXSHpsVPWEktKXHr6+SS6x/IKRb7cpw= | ||
101 | github.com/shurcooL/httperror v0.0.0-20170206035902-86b7830d14cc/go.mod h1:aYMfkZ6DWSJPJ6c4Wwz3QtW22G7mf/PEgaB9k/ik5+Y= | ||
102 | github.com/shurcooL/httpfs v0.0.0-20171119174359-809beceb2371/go.mod h1:ZY1cvUeJuFPAdZ/B6v7RHavJWZn2YPVFQ1OSXhCGOkg= | ||
103 | github.com/shurcooL/httpgzip v0.0.0-20180522190206-b1c53ac65af9/go.mod h1:919LwcH0M7/W4fcZ0/jy0qGght1GIhqyS/EgWGH2j5Q= | ||
104 | github.com/shurcooL/issues v0.0.0-20181008053335-6292fdc1e191/go.mod h1:e2qWDig5bLteJ4fwvDAc2NHzqFEthkqn7aOZAOpj+PQ= | ||
105 | github.com/shurcooL/issuesapp v0.0.0-20180602232740-048589ce2241/go.mod h1:NPpHK2TI7iSaM0buivtFUc9offApnI0Alt/K8hcHy0I= | ||
106 | github.com/shurcooL/notifications v0.0.0-20181007000457-627ab5aea122/go.mod h1:b5uSkrEVM1jQUspwbixRBhaIjIzL2xazXp6kntxYle0= | ||
107 | github.com/shurcooL/octicon v0.0.0-20181028054416-fa4f57f9efb2/go.mod h1:eWdoE5JD4R5UVWDucdOPg1g2fqQRq78IQa9zlOV1vpQ= | ||
108 | github.com/shurcooL/reactions v0.0.0-20181006231557-f2e0b4ca5b82/go.mod h1:TCR1lToEk4d2s07G3XGfz2QrgHXg4RJBvjrOozvoWfk= | ||
109 | github.com/shurcooL/sanitized_anchor_name v0.0.0-20170918181015-86672fcb3f95/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= | ||
110 | github.com/shurcooL/users v0.0.0-20180125191416-49c67e49c537/go.mod h1:QJTqeLYEDaXHZDBsXlPCDqdhQuJkuw4NOtaxYe3xii4= | ||
111 | github.com/shurcooL/webdavfs v0.0.0-20170829043945-18c3829fa133/go.mod h1:hKmq5kWdCj2z2KEozexVbfEZIWiTjhE0+UjmZgPqehw= | ||
112 | github.com/sourcegraph/annotate v0.0.0-20160123013949-f4cad6c6324d/go.mod h1:UdhH50NIW0fCiwBSr0co2m7BnFLdv4fQTgdqdJTHFeE= | ||
113 | github.com/sourcegraph/syntaxhighlight v0.0.0-20170531221838-bd320f5d308e/go.mod h1:HuIsMU8RRBOtsCgI77wP899iHVBQpCmg4ErYMZB+2IA= | ||
114 | github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w= | ||
115 | github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= | ||
116 | github.com/tarm/serial v0.0.0-20180830185346-98f6abe2eb07/go.mod h1:kDXzergiv9cbyO7IOYJZWg1U88JhDg3PB6klq9Hg2pA= | ||
117 | github.com/ulikunitz/xz v0.5.5 h1:pFrO0lVpTBXLpYw+pnLj6TbvHuyjXMfjGeCwSqCVwok= | ||
118 | github.com/ulikunitz/xz v0.5.5/go.mod h1:2bypXElzHzzJZwzH67Y6wb67pO62Rzfn7BSiF4ABRW8= | ||
119 | go.opencensus.io v0.18.0 h1:Mk5rgZcggtbvtAun5aJzAtjKKN/t0R3jJPlWILlv938= | ||
120 | go.opencensus.io v0.18.0/go.mod h1:vKdFvxhtzZ9onBp9VKHK8z/sRpBMnKAsufL7wlDrCOA= | ||
121 | go4.org v0.0.0-20180809161055-417644f6feb5/go.mod h1:MkTOUMDaeVYJUOUsaDXIhWPZYa1yOyC1qaOBpL57BhE= | ||
122 | golang.org/x/build v0.0.0-20190111050920-041ab4dc3f9d/go.mod h1:OWs+y06UdEOHN4y+MfF/py+xQ/tYqIWW03b70/CG9Rw= | ||
123 | golang.org/x/crypto v0.0.0-20181030102418-4d3f4d9ffa16/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= | ||
124 | golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= | ||
125 | golang.org/x/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= | ||
126 | golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= | ||
127 | golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= | ||
128 | golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= | ||
129 | golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= | ||
130 | golang.org/x/net v0.0.0-20181029044818-c44066c5c816/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= | ||
131 | golang.org/x/net v0.0.0-20181106065722-10aee1819953/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= | ||
132 | golang.org/x/net v0.0.0-20181114220301-adae6a3d119a h1:gOpx8G595UYyvj8UK4+OFyY4rx037g3fmfhe5SasG3U= | ||
133 | golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= | ||
134 | golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= | ||
135 | golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= | ||
136 | golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890 h1:uESlIz09WIHT2I+pasSXcpLYqYK8wHcdCetU3VuMBJE= | ||
137 | golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= | ||
138 | golang.org/x/perf v0.0.0-20180704124530-6e6d33e29852/go.mod h1:JLpeXjPJfIyPr5TlbXLkXWLhP8nz10XfvxElABhCtcw= | ||
139 | golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= | ||
140 | golang.org/x/sync v0.0.0-20181108010431-42b317875d0f h1:Bl/8QSvNqXvPGPGXa2z5xUTmV7VDcZyvRZ+QQXkXTZQ= | ||
141 | golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= | ||
142 | golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= | ||
143 | golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= | ||
144 | golang.org/x/sys v0.0.0-20181029174526-d69651ed3497/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= | ||
145 | golang.org/x/sys v0.0.0-20181213200352-4d1cda033e06 h1:0oC8rFnE+74kEmuHZ46F6KHsMr5Gx2gUQPuNz28iQZM= | ||
146 | golang.org/x/sys v0.0.0-20181213200352-4d1cda033e06/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= | ||
147 | golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg= | ||
148 | golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= | ||
149 | golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2 h1:z99zHgr7hKfrUcX/KsoJk5FJfjTceCKIp96+biqP4To= | ||
150 | golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= | ||
151 | golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= | ||
152 | golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= | ||
153 | golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= | ||
154 | golang.org/x/tools v0.0.0-20181030000716-a0a13e073c7b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= | ||
155 | google.golang.org/api v0.0.0-20180910000450-7ca32eb868bf/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0= | ||
156 | google.golang.org/api v0.0.0-20181030000543-1d582fd0359e/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0= | ||
157 | google.golang.org/api v0.1.0 h1:K6z2u68e86TPdSdefXdzvXgR1zEMa+459vBSfWYAZkI= | ||
158 | google.golang.org/api v0.1.0/go.mod h1:UGEZY7KEX120AnNLIHFMKIo4obdJhkp2tPbaPlQx13Y= | ||
159 | google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= | ||
160 | google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= | ||
161 | google.golang.org/appengine v1.3.0 h1:FBSsiFRMz3LBeXIomRnVzrQwSDj4ibvcRexLG0LZGQk= | ||
162 | google.golang.org/appengine v1.3.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= | ||
163 | google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= | ||
164 | google.golang.org/genproto v0.0.0-20180831171423-11092d34479b/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= | ||
165 | google.golang.org/genproto v0.0.0-20181029155118-b69ba1387ce2/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= | ||
166 | google.golang.org/genproto v0.0.0-20181202183823-bd91e49a0898/go.mod h1:7Ep/1NZk928CDR8SjdVbjWNpdIf6nzjE3BTgJDr2Atg= | ||
167 | google.golang.org/genproto v0.0.0-20190201180003-4b09977fb922 h1:mBVYJnbrXLA/ZCBTCe7PtEgAUP+1bg92qTaFoPHdz+8= | ||
168 | google.golang.org/genproto v0.0.0-20190201180003-4b09977fb922/go.mod h1:L3J43x8/uS+qIUoksaLKe6OS3nUKxOKuIFz1sl2/jx4= | ||
169 | google.golang.org/grpc v1.14.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= | ||
170 | google.golang.org/grpc v1.16.0/go.mod h1:0JHn/cJsOMiMfNA9+DeHDlAU7KAAB5GDlYFpa9MZMio= | ||
171 | google.golang.org/grpc v1.17.0 h1:TRJYBgMclJvGYn2rIMjj+h9KtMt5r1Ij7ODVRIZkwhk= | ||
172 | google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= | ||
173 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= | ||
174 | gopkg.in/cheggaaa/pb.v1 v1.0.27 h1:kJdccidYzt3CaHD1crCFTS1hxyhSi059NhOFUf03YFo= | ||
175 | gopkg.in/cheggaaa/pb.v1 v1.0.27/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw= | ||
176 | gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= | ||
177 | gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= | ||
178 | grpc.go4.org v0.0.0-20170609214715-11d0a25b4919/go.mod h1:77eQGdRu53HpSqPFJFmuJdjuHRquDANNeA4x7B8WQ9o= | ||
179 | honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= | ||
180 | honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= | ||
181 | sourcegraph.com/sourcegraph/go-diff v0.5.0/go.mod h1:kuch7UrkMzY0X+p9CRK03kfuPQ2zzQcaEFbx8wA8rck= | ||
182 | sourcegraph.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 | // | ||
11 | func SourceDirSubdir(src string) (string, string) { | 17 | func 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 | } |