diff options
Diffstat (limited to 'vendor/github.com/hashicorp/go-getter/get.go')
-rw-r--r-- | vendor/github.com/hashicorp/go-getter/get.go | 139 |
1 files changed, 139 insertions, 0 deletions
diff --git a/vendor/github.com/hashicorp/go-getter/get.go b/vendor/github.com/hashicorp/go-getter/get.go new file mode 100644 index 0000000..c3236f5 --- /dev/null +++ b/vendor/github.com/hashicorp/go-getter/get.go | |||
@@ -0,0 +1,139 @@ | |||
1 | // getter is a package for downloading files or directories from a variety of | ||
2 | // protocols. | ||
3 | // | ||
4 | // getter is unique in its ability to download both directories and files. | ||
5 | // It also detects certain source strings to be protocol-specific URLs. For | ||
6 | // example, "github.com/hashicorp/go-getter" would turn into a Git URL and | ||
7 | // use the Git protocol. | ||
8 | // | ||
9 | // Protocols and detectors are extensible. | ||
10 | // | ||
11 | // To get started, see Client. | ||
12 | package getter | ||
13 | |||
14 | import ( | ||
15 | "bytes" | ||
16 | "fmt" | ||
17 | "net/url" | ||
18 | "os/exec" | ||
19 | "regexp" | ||
20 | "syscall" | ||
21 | ) | ||
22 | |||
23 | // Getter defines the interface that schemes must implement to download | ||
24 | // things. | ||
25 | type Getter interface { | ||
26 | // Get downloads the given URL into the given directory. This always | ||
27 | // assumes that we're updating and gets the latest version that it can. | ||
28 | // | ||
29 | // The directory may already exist (if we're updating). If it is in a | ||
30 | // format that isn't understood, an error should be returned. Get shouldn't | ||
31 | // simply nuke the directory. | ||
32 | Get(string, *url.URL) error | ||
33 | |||
34 | // GetFile downloads the give URL into the given path. The URL must | ||
35 | // reference a single file. If possible, the Getter should check if | ||
36 | // the remote end contains the same file and no-op this operation. | ||
37 | GetFile(string, *url.URL) error | ||
38 | |||
39 | // ClientMode returns the mode based on the given URL. This is used to | ||
40 | // allow clients to let the getters decide which mode to use. | ||
41 | ClientMode(*url.URL) (ClientMode, error) | ||
42 | } | ||
43 | |||
44 | // Getters is the mapping of scheme to the Getter implementation that will | ||
45 | // be used to get a dependency. | ||
46 | var Getters map[string]Getter | ||
47 | |||
48 | // forcedRegexp is the regular expression that finds forced getters. This | ||
49 | // syntax is schema::url, example: git::https://foo.com | ||
50 | var forcedRegexp = regexp.MustCompile(`^([A-Za-z0-9]+)::(.+)$`) | ||
51 | |||
52 | func init() { | ||
53 | httpGetter := &HttpGetter{Netrc: true} | ||
54 | |||
55 | Getters = map[string]Getter{ | ||
56 | "file": new(FileGetter), | ||
57 | "git": new(GitGetter), | ||
58 | "hg": new(HgGetter), | ||
59 | "s3": new(S3Getter), | ||
60 | "http": httpGetter, | ||
61 | "https": httpGetter, | ||
62 | } | ||
63 | } | ||
64 | |||
65 | // Get downloads the directory specified by src into the folder specified by | ||
66 | // dst. If dst already exists, Get will attempt to update it. | ||
67 | // | ||
68 | // src is a URL, whereas dst is always just a file path to a folder. This | ||
69 | // folder doesn't need to exist. It will be created if it doesn't exist. | ||
70 | func Get(dst, src string) error { | ||
71 | return (&Client{ | ||
72 | Src: src, | ||
73 | Dst: dst, | ||
74 | Dir: true, | ||
75 | Getters: Getters, | ||
76 | }).Get() | ||
77 | } | ||
78 | |||
79 | // GetAny downloads a URL into the given destination. Unlike Get or | ||
80 | // GetFile, both directories and files are supported. | ||
81 | // | ||
82 | // dst must be a directory. If src is a file, it will be downloaded | ||
83 | // into dst with the basename of the URL. If src is a directory or | ||
84 | // archive, it will be unpacked directly into dst. | ||
85 | func GetAny(dst, src string) error { | ||
86 | return (&Client{ | ||
87 | Src: src, | ||
88 | Dst: dst, | ||
89 | Mode: ClientModeAny, | ||
90 | Getters: Getters, | ||
91 | }).Get() | ||
92 | } | ||
93 | |||
94 | // GetFile downloads the file specified by src into the path specified by | ||
95 | // dst. | ||
96 | func GetFile(dst, src string) error { | ||
97 | return (&Client{ | ||
98 | Src: src, | ||
99 | Dst: dst, | ||
100 | Dir: false, | ||
101 | Getters: Getters, | ||
102 | }).Get() | ||
103 | } | ||
104 | |||
105 | // getRunCommand is a helper that will run a command and capture the output | ||
106 | // in the case an error happens. | ||
107 | func getRunCommand(cmd *exec.Cmd) error { | ||
108 | var buf bytes.Buffer | ||
109 | cmd.Stdout = &buf | ||
110 | cmd.Stderr = &buf | ||
111 | err := cmd.Run() | ||
112 | if err == nil { | ||
113 | return nil | ||
114 | } | ||
115 | if exiterr, ok := err.(*exec.ExitError); ok { | ||
116 | // The program has exited with an exit code != 0 | ||
117 | if status, ok := exiterr.Sys().(syscall.WaitStatus); ok { | ||
118 | return fmt.Errorf( | ||
119 | "%s exited with %d: %s", | ||
120 | cmd.Path, | ||
121 | status.ExitStatus(), | ||
122 | buf.String()) | ||
123 | } | ||
124 | } | ||
125 | |||
126 | return fmt.Errorf("error running %s: %s", cmd.Path, buf.String()) | ||
127 | } | ||
128 | |||
129 | // getForcedGetter takes a source and returns the tuple of the forced | ||
130 | // getter and the raw URL (without the force syntax). | ||
131 | func getForcedGetter(src string) (string, string) { | ||
132 | var forced string | ||
133 | if ms := forcedRegexp.FindStringSubmatch(src); ms != nil { | ||
134 | forced = ms[1] | ||
135 | src = ms[2] | ||
136 | } | ||
137 | |||
138 | return forced, src | ||
139 | } | ||