.gitignore added
[dotfiles/.git] / .config / coc / extensions / coc-go-data / tools / pkg / mod / golang.org / x / tools@v0.1.1-0.20210319172145-bda8f5cee399 / cmd / getgo / download.go
1 // Copyright 2017 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
4
5 //go:build !plan9
6 // +build !plan9
7
8 package main
9
10 import (
11         "archive/tar"
12         "archive/zip"
13         "compress/gzip"
14         "crypto/sha256"
15         "fmt"
16         "io"
17         "io/ioutil"
18         "net/http"
19         "os"
20         "path/filepath"
21         "strings"
22 )
23
24 const (
25         currentVersionURL = "https://golang.org/VERSION?m=text"
26         downloadURLPrefix = "https://dl.google.com/go"
27 )
28
29 // downloadGoVersion downloads and upacks the specific go version to dest/go.
30 func downloadGoVersion(version, ops, arch, dest string) error {
31         suffix := "tar.gz"
32         if ops == "windows" {
33                 suffix = "zip"
34         }
35         uri := fmt.Sprintf("%s/%s.%s-%s.%s", downloadURLPrefix, version, ops, arch, suffix)
36
37         verbosef("Downloading %s", uri)
38
39         req, err := http.NewRequest("GET", uri, nil)
40         if err != nil {
41                 return err
42         }
43         req.Header.Add("User-Agent", fmt.Sprintf("golang.org-getgo/%s", version))
44
45         resp, err := http.DefaultClient.Do(req)
46         if err != nil {
47                 return fmt.Errorf("Downloading Go from %s failed: %v", uri, err)
48         }
49         if resp.StatusCode > 299 {
50                 return fmt.Errorf("Downloading Go from %s failed with HTTP status %s", uri, resp.Status)
51         }
52         defer resp.Body.Close()
53
54         tmpf, err := ioutil.TempFile("", "go")
55         if err != nil {
56                 return err
57         }
58         defer os.Remove(tmpf.Name())
59
60         h := sha256.New()
61
62         w := io.MultiWriter(tmpf, h)
63         if _, err := io.Copy(w, resp.Body); err != nil {
64                 return err
65         }
66
67         verbosef("Downloading SHA %s.sha256", uri)
68
69         sresp, err := http.Get(uri + ".sha256")
70         if err != nil {
71                 return fmt.Errorf("Downloading Go sha256 from %s.sha256 failed: %v", uri, err)
72         }
73         defer sresp.Body.Close()
74         if sresp.StatusCode > 299 {
75                 return fmt.Errorf("Downloading Go sha256 from %s.sha256 failed with HTTP status %s", uri, sresp.Status)
76         }
77
78         shasum, err := ioutil.ReadAll(sresp.Body)
79         if err != nil {
80                 return err
81         }
82
83         // Check the shasum.
84         sum := fmt.Sprintf("%x", h.Sum(nil))
85         if sum != string(shasum) {
86                 return fmt.Errorf("Shasum mismatch %s vs. %s", sum, string(shasum))
87         }
88
89         unpackFunc := unpackTar
90         if ops == "windows" {
91                 unpackFunc = unpackZip
92         }
93         if err := unpackFunc(tmpf.Name(), dest); err != nil {
94                 return fmt.Errorf("Unpacking Go to %s failed: %v", dest, err)
95         }
96         return nil
97 }
98
99 func unpack(dest, name string, fi os.FileInfo, r io.Reader) error {
100         if strings.HasPrefix(name, "go/") {
101                 name = name[len("go/"):]
102         }
103
104         path := filepath.Join(dest, name)
105         if fi.IsDir() {
106                 return os.MkdirAll(path, fi.Mode())
107         }
108
109         f, err := os.OpenFile(path, os.O_CREATE|os.O_TRUNC|os.O_WRONLY, fi.Mode())
110         if err != nil {
111                 return err
112         }
113         defer f.Close()
114
115         _, err = io.Copy(f, r)
116         return err
117 }
118
119 func unpackTar(src, dest string) error {
120         r, err := os.Open(src)
121         if err != nil {
122                 return err
123         }
124         defer r.Close()
125
126         archive, err := gzip.NewReader(r)
127         if err != nil {
128                 return err
129         }
130         defer archive.Close()
131
132         tarReader := tar.NewReader(archive)
133
134         for {
135                 header, err := tarReader.Next()
136                 if err == io.EOF {
137                         break
138                 } else if err != nil {
139                         return err
140                 }
141
142                 if err := unpack(dest, header.Name, header.FileInfo(), tarReader); err != nil {
143                         return err
144                 }
145         }
146
147         return nil
148 }
149
150 func unpackZip(src, dest string) error {
151         zr, err := zip.OpenReader(src)
152         if err != nil {
153                 return err
154         }
155
156         for _, f := range zr.File {
157                 fr, err := f.Open()
158                 if err != nil {
159                         return err
160                 }
161                 if err := unpack(dest, f.Name, f.FileInfo(), fr); err != nil {
162                         return err
163                 }
164                 fr.Close()
165         }
166
167         return nil
168 }
169
170 func getLatestGoVersion() (string, error) {
171         resp, err := http.Get(currentVersionURL)
172         if err != nil {
173                 return "", fmt.Errorf("Getting current Go version failed: %v", err)
174         }
175         defer resp.Body.Close()
176         if resp.StatusCode > 299 {
177                 b, _ := ioutil.ReadAll(io.LimitReader(resp.Body, 1024))
178                 return "", fmt.Errorf("Could not get current Go version: HTTP %d: %q", resp.StatusCode, b)
179         }
180         version, err := ioutil.ReadAll(resp.Body)
181         if err != nil {
182                 return "", err
183         }
184         return strings.TrimSpace(string(version)), nil
185 }