Giant blob of minor changes
[dotfiles/.git] / .config / coc / extensions / coc-go-data / tools / pkg / mod / golang.org / x / tools@v0.0.0-20201105173854-bc9fc8d8c4bc / internal / proxydir / proxydir.go
1 // Copyright 2020 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 // Package proxydir provides functions for writing module data to a directory
6 // in proxy format, so that it can be used as a module proxy by setting
7 // GOPROXY="file://<dir>".
8 package proxydir
9
10 import (
11         "archive/zip"
12         "fmt"
13         "io"
14         "io/ioutil"
15         "os"
16         "path/filepath"
17         "strings"
18
19         "golang.org/x/tools/internal/testenv"
20 )
21
22 // WriteModuleVersion creates a directory in the proxy dir for a module.
23 func WriteModuleVersion(rootDir, module, ver string, files map[string][]byte) (rerr error) {
24         dir := filepath.Join(rootDir, module, "@v")
25         if err := os.MkdirAll(dir, 0755); err != nil {
26                 return err
27         }
28
29         // The go command checks for versions by looking at the "list" file.  Since
30         // we are supporting multiple versions, create this file if it does not exist
31         // or append the version number to the preexisting file.
32         f, err := os.OpenFile(filepath.Join(dir, "list"), os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
33         if err != nil {
34                 return err
35         }
36         defer checkClose("list file", f, &rerr)
37         if _, err := f.WriteString(ver + "\n"); err != nil {
38                 return err
39         }
40
41         // Serve the go.mod file on the <version>.mod url, if it exists. Otherwise,
42         // serve a stub.
43         modContents, ok := files["go.mod"]
44         if !ok {
45                 modContents = []byte("module " + module)
46         }
47         if err := ioutil.WriteFile(filepath.Join(dir, ver+".mod"), modContents, 0644); err != nil {
48                 return err
49         }
50
51         // info file, just the bare bones.
52         infoContents := []byte(fmt.Sprintf(`{"Version": "%v", "Time":"2017-12-14T13:08:43Z"}`, ver))
53         if err := ioutil.WriteFile(filepath.Join(dir, ver+".info"), infoContents, 0644); err != nil {
54                 return err
55         }
56
57         // zip of all the source files.
58         f, err = os.OpenFile(filepath.Join(dir, ver+".zip"), os.O_CREATE|os.O_WRONLY, 0644)
59         if err != nil {
60                 return err
61         }
62         defer checkClose("zip file", f, &rerr)
63         z := zip.NewWriter(f)
64         defer checkClose("zip writer", z, &rerr)
65         for name, contents := range files {
66                 zf, err := z.Create(module + "@" + ver + "/" + name)
67                 if err != nil {
68                         return err
69                 }
70                 if _, err := zf.Write(contents); err != nil {
71                         return err
72                 }
73         }
74
75         return nil
76 }
77
78 func checkClose(name string, closer io.Closer, err *error) {
79         if cerr := closer.Close(); cerr != nil && *err == nil {
80                 *err = fmt.Errorf("closing %s: %v", name, cerr)
81         }
82 }
83
84 // ToURL returns the file uri for a proxy directory.
85 func ToURL(dir string) string {
86         if testenv.Go1Point() >= 13 {
87                 // file URLs on Windows must start with file:///. See golang.org/issue/6027.
88                 path := filepath.ToSlash(dir)
89                 if !strings.HasPrefix(path, "/") {
90                         path = "/" + path
91                 }
92                 return "file://" + path
93         } else {
94                 // Prior to go1.13, the Go command on Windows only accepted GOPROXY file URLs
95                 // of the form file://C:/path/to/proxy. This was incorrect: when parsed, "C:"
96                 // is interpreted as the host. See golang.org/issue/6027. This has been
97                 // fixed in go1.13, but we emit the old format for old releases.
98                 return "file://" + filepath.ToSlash(dir)
99         }
100 }