diff options
author | Nathan Dench <ndenc2@gmail.com> | 2019-05-24 15:16:44 +1000 |
---|---|---|
committer | Nathan Dench <ndenc2@gmail.com> | 2019-05-24 15:16:44 +1000 |
commit | 107c1cdb09c575aa2f61d97f48d8587eb6bada4c (patch) | |
tree | ca7d008643efc555c388baeaf1d986e0b6b3e28c /vendor/github.com/hashicorp/terraform/internal/initwd/getter.go | |
parent | 844b5a68d8af4791755b8f0ad293cc99f5959183 (diff) | |
download | terraform-provider-statuscake-107c1cdb09c575aa2f61d97f48d8587eb6bada4c.tar.gz terraform-provider-statuscake-107c1cdb09c575aa2f61d97f48d8587eb6bada4c.tar.zst terraform-provider-statuscake-107c1cdb09c575aa2f61d97f48d8587eb6bada4c.zip |
Upgrade to 0.12
Diffstat (limited to 'vendor/github.com/hashicorp/terraform/internal/initwd/getter.go')
-rw-r--r-- | vendor/github.com/hashicorp/terraform/internal/initwd/getter.go | 210 |
1 files changed, 210 insertions, 0 deletions
diff --git a/vendor/github.com/hashicorp/terraform/internal/initwd/getter.go b/vendor/github.com/hashicorp/terraform/internal/initwd/getter.go new file mode 100644 index 0000000..50e2572 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform/internal/initwd/getter.go | |||
@@ -0,0 +1,210 @@ | |||
1 | package initwd | ||
2 | |||
3 | import ( | ||
4 | "fmt" | ||
5 | "log" | ||
6 | "os" | ||
7 | "path/filepath" | ||
8 | "strings" | ||
9 | |||
10 | cleanhttp "github.com/hashicorp/go-cleanhttp" | ||
11 | getter "github.com/hashicorp/go-getter" | ||
12 | "github.com/hashicorp/terraform/registry/regsrc" | ||
13 | ) | ||
14 | |||
15 | // We configure our own go-getter detector and getter sets here, because | ||
16 | // the set of sources we support is part of Terraform's documentation and | ||
17 | // so we don't want any new sources introduced in go-getter to sneak in here | ||
18 | // and work even though they aren't documented. This also insulates us from | ||
19 | // any meddling that might be done by other go-getter callers linked into our | ||
20 | // executable. | ||
21 | |||
22 | var goGetterDetectors = []getter.Detector{ | ||
23 | new(getter.GitHubDetector), | ||
24 | new(getter.BitBucketDetector), | ||
25 | new(getter.S3Detector), | ||
26 | new(getter.FileDetector), | ||
27 | } | ||
28 | |||
29 | var goGetterNoDetectors = []getter.Detector{} | ||
30 | |||
31 | var goGetterDecompressors = map[string]getter.Decompressor{ | ||
32 | "bz2": new(getter.Bzip2Decompressor), | ||
33 | "gz": new(getter.GzipDecompressor), | ||
34 | "xz": new(getter.XzDecompressor), | ||
35 | "zip": new(getter.ZipDecompressor), | ||
36 | |||
37 | "tar.bz2": new(getter.TarBzip2Decompressor), | ||
38 | "tar.tbz2": new(getter.TarBzip2Decompressor), | ||
39 | |||
40 | "tar.gz": new(getter.TarGzipDecompressor), | ||
41 | "tgz": new(getter.TarGzipDecompressor), | ||
42 | |||
43 | "tar.xz": new(getter.TarXzDecompressor), | ||
44 | "txz": new(getter.TarXzDecompressor), | ||
45 | } | ||
46 | |||
47 | var goGetterGetters = map[string]getter.Getter{ | ||
48 | "file": new(getter.FileGetter), | ||
49 | "git": new(getter.GitGetter), | ||
50 | "hg": new(getter.HgGetter), | ||
51 | "s3": new(getter.S3Getter), | ||
52 | "http": getterHTTPGetter, | ||
53 | "https": getterHTTPGetter, | ||
54 | } | ||
55 | |||
56 | var getterHTTPClient = cleanhttp.DefaultClient() | ||
57 | |||
58 | var getterHTTPGetter = &getter.HttpGetter{ | ||
59 | Client: getterHTTPClient, | ||
60 | Netrc: true, | ||
61 | } | ||
62 | |||
63 | // A reusingGetter is a helper for the module installer that remembers | ||
64 | // the final resolved addresses of all of the sources it has already been | ||
65 | // asked to install, and will copy from a prior installation directory if | ||
66 | // it has the same resolved source address. | ||
67 | // | ||
68 | // The keys in a reusingGetter are resolved and trimmed source addresses | ||
69 | // (with a scheme always present, and without any "subdir" component), | ||
70 | // and the values are the paths where each source was previously installed. | ||
71 | type reusingGetter map[string]string | ||
72 | |||
73 | // getWithGoGetter retrieves the package referenced in the given address | ||
74 | // into the installation path and then returns the full path to any subdir | ||
75 | // indicated in the address. | ||
76 | // | ||
77 | // The errors returned by this function are those surfaced by the underlying | ||
78 | // go-getter library, which have very inconsistent quality as | ||
79 | // end-user-actionable error messages. At this time we do not have any | ||
80 | // reasonable way to improve these error messages at this layer because | ||
81 | // the underlying errors are not separately recognizable. | ||
82 | func (g reusingGetter) getWithGoGetter(instPath, addr string) (string, error) { | ||
83 | packageAddr, subDir := splitAddrSubdir(addr) | ||
84 | |||
85 | log.Printf("[DEBUG] will download %q to %s", packageAddr, instPath) | ||
86 | |||
87 | realAddr, err := getter.Detect(packageAddr, instPath, getter.Detectors) | ||
88 | if err != nil { | ||
89 | return "", err | ||
90 | } | ||
91 | |||
92 | if isMaybeRelativeLocalPath(realAddr) { | ||
93 | return "", &MaybeRelativePathErr{addr} | ||
94 | } | ||
95 | |||
96 | var realSubDir string | ||
97 | realAddr, realSubDir = splitAddrSubdir(realAddr) | ||
98 | if realSubDir != "" { | ||
99 | subDir = filepath.Join(realSubDir, subDir) | ||
100 | } | ||
101 | |||
102 | if realAddr != packageAddr { | ||
103 | log.Printf("[TRACE] go-getter detectors rewrote %q to %q", packageAddr, realAddr) | ||
104 | } | ||
105 | |||
106 | if prevDir, exists := g[realAddr]; exists { | ||
107 | log.Printf("[TRACE] copying previous install %s to %s", prevDir, instPath) | ||
108 | err := os.Mkdir(instPath, os.ModePerm) | ||
109 | if err != nil { | ||
110 | return "", fmt.Errorf("failed to create directory %s: %s", instPath, err) | ||
111 | } | ||
112 | err = copyDir(instPath, prevDir) | ||
113 | if err != nil { | ||
114 | return "", fmt.Errorf("failed to copy from %s to %s: %s", prevDir, instPath, err) | ||
115 | } | ||
116 | } else { | ||
117 | log.Printf("[TRACE] fetching %q to %q", realAddr, instPath) | ||
118 | client := getter.Client{ | ||
119 | Src: realAddr, | ||
120 | Dst: instPath, | ||
121 | Pwd: instPath, | ||
122 | |||
123 | Mode: getter.ClientModeDir, | ||
124 | |||
125 | Detectors: goGetterNoDetectors, // we already did detection above | ||
126 | Decompressors: goGetterDecompressors, | ||
127 | Getters: goGetterGetters, | ||
128 | } | ||
129 | err = client.Get() | ||
130 | if err != nil { | ||
131 | return "", err | ||
132 | } | ||
133 | // Remember where we installed this so we might reuse this directory | ||
134 | // on subsequent calls to avoid re-downloading. | ||
135 | g[realAddr] = instPath | ||
136 | } | ||
137 | |||
138 | // Our subDir string can contain wildcards until this point, so that | ||
139 | // e.g. a subDir of * can expand to one top-level directory in a .tar.gz | ||
140 | // archive. Now that we've expanded the archive successfully we must | ||
141 | // resolve that into a concrete path. | ||
142 | var finalDir string | ||
143 | if subDir != "" { | ||
144 | finalDir, err = getter.SubdirGlob(instPath, subDir) | ||
145 | log.Printf("[TRACE] expanded %q to %q", subDir, finalDir) | ||
146 | if err != nil { | ||
147 | return "", err | ||
148 | } | ||
149 | } else { | ||
150 | finalDir = instPath | ||
151 | } | ||
152 | |||
153 | // If we got this far then we have apparently succeeded in downloading | ||
154 | // the requested object! | ||
155 | return filepath.Clean(finalDir), nil | ||
156 | } | ||
157 | |||
158 | // splitAddrSubdir splits the given address (which is assumed to be a | ||
159 | // registry address or go-getter-style address) into a package portion | ||
160 | // and a sub-directory portion. | ||
161 | // | ||
162 | // The package portion defines what should be downloaded and then the | ||
163 | // sub-directory portion, if present, specifies a sub-directory within | ||
164 | // the downloaded object (an archive, VCS repository, etc) that contains | ||
165 | // the module's configuration files. | ||
166 | // | ||
167 | // The subDir portion will be returned as empty if no subdir separator | ||
168 | // ("//") is present in the address. | ||
169 | func splitAddrSubdir(addr string) (packageAddr, subDir string) { | ||
170 | return getter.SourceDirSubdir(addr) | ||
171 | } | ||
172 | |||
173 | var localSourcePrefixes = []string{ | ||
174 | "./", | ||
175 | "../", | ||
176 | ".\\", | ||
177 | "..\\", | ||
178 | } | ||
179 | |||
180 | func isLocalSourceAddr(addr string) bool { | ||
181 | for _, prefix := range localSourcePrefixes { | ||
182 | if strings.HasPrefix(addr, prefix) { | ||
183 | return true | ||
184 | } | ||
185 | } | ||
186 | return false | ||
187 | } | ||
188 | |||
189 | func isRegistrySourceAddr(addr string) bool { | ||
190 | _, err := regsrc.ParseModuleSource(addr) | ||
191 | return err == nil | ||
192 | } | ||
193 | |||
194 | type MaybeRelativePathErr struct { | ||
195 | Addr string | ||
196 | } | ||
197 | |||
198 | func (e *MaybeRelativePathErr) Error() string { | ||
199 | return fmt.Sprintf("Terraform cannot determine the module source for %s", e.Addr) | ||
200 | } | ||
201 | |||
202 | func isMaybeRelativeLocalPath(addr string) bool { | ||
203 | if strings.HasPrefix(addr, "file://") { | ||
204 | _, err := os.Stat(addr[7:]) | ||
205 | if err != nil { | ||
206 | return true | ||
207 | } | ||
208 | } | ||
209 | return false | ||
210 | } | ||