downloadAsset downloads a single asset to the given file path. assetURL is an absolute URL supplied by the API, so it is requested as given rather than being resolved against the host's REST endpoint. hostname is still needed so the request is made through a client configured for the right host.
(httpClient *http.Client, hostname string, assetURL safeurl.SafeURL, destPath string)
| 80 | // being resolved against the host's REST endpoint. hostname is still needed so the request |
| 81 | // is made through a client configured for the right host. |
| 82 | func downloadAsset(httpClient *http.Client, hostname string, assetURL safeurl.SafeURL, destPath string) (downloadErr error) { |
| 83 | var resp *http.Response |
| 84 | // TODO(api-client-rollout) |
| 85 | // This line of code is part of a mechanical roll out of the api client. |
| 86 | // As a follow up, consider whether the api client can be injected to this call site, rather than constructed |
| 87 | resp, downloadErr = api.NewClientFromHTTP(httpClient).Request(hostname, http.MethodGet, assetURL.String(), nil, |
| 88 | api.WithHeader("Accept", "application/octet-stream")) |
| 89 | if downloadErr != nil { |
| 90 | return |
| 91 | } |
| 92 | defer resp.Body.Close() |
| 93 | |
| 94 | var f *os.File |
| 95 | if f, downloadErr = os.OpenFile(destPath, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0755); downloadErr != nil { |
| 96 | return |
| 97 | } |
| 98 | defer func() { |
| 99 | if err := f.Close(); downloadErr == nil && err != nil { |
| 100 | downloadErr = err |
| 101 | } |
| 102 | }() |
| 103 | |
| 104 | _, downloadErr = io.Copy(f, resp.Body) |
| 105 | return |
| 106 | } |
| 107 | |
| 108 | var commitNotFoundErr = errors.New("commit not found") |
| 109 | var releaseNotFoundErr = errors.New("release not found") |