| package deps |
| |
| import ( |
| "crypto/sha256" |
| "encoding/hex" |
| "fmt" |
| "io" |
| "net/http" |
| "os" |
| "path" |
| ) |
| |
| func fetchIntoFile(url string, file *os.File) error { |
| resp, err := http.Get(url) |
| if err != nil { |
| return err |
| } |
| defer resp.Body.Close() |
| _, err = io.Copy(file, resp.Body) |
| return err |
| } |
| |
| func fileSHA256(file *os.File) (string, error) { |
| file.Seek(0, 0) |
| hasher := sha256.New() |
| if _, err := io.Copy(hasher, file); err != nil { |
| return "", nil |
| } |
| return hex.EncodeToString(hasher.Sum(nil)), nil |
| } |
| |
| // FetchURL fetches the specified URL into the specified file path, and returns |
| // the SHA-256 hash of the file fetched. |
| func FetchURL(url string, path string) (string, error) { |
| file, err := os.Create(path) |
| if err != nil { |
| return "", err |
| } |
| defer file.Close() |
| |
| if err = fetchIntoFile(url, file); err != nil { |
| os.Remove(path) |
| return "", err |
| } |
| |
| checksum, err := fileSHA256(file) |
| if err != nil { |
| os.Remove(path) |
| return "", err |
| } |
| |
| return checksum, nil |
| } |
| |
| // FetchEntry retrieves an existing WORKSPACE file entry into a specified directory, |
| // verifies its checksum, and then returns the full path to the resulting file. |
| func FetchEntry(entry *Entry, dir string) (string, error) { |
| filename := path.Join(dir, entry.SHA256+".tar.gz") |
| checksum, err := FetchURL(entry.URL, filename) |
| if err != nil { |
| return "", err |
| } |
| |
| if checksum != entry.SHA256 { |
| os.Remove(filename) |
| return "", fmt.Errorf("SHA-256 mismatch: expected %s, got %s", entry.SHA256, checksum) |
| } |
| |
| return filename, nil |
| } |