]> git.immae.eu Git - github/fretlink/terraform-provider-statuscake.git/blame - vendor/github.com/hashicorp/go-getter/get.go
Upgrade to 0.12
[github/fretlink/terraform-provider-statuscake.git] / vendor / github.com / hashicorp / go-getter / get.go
CommitLineData
bae9f6d2
JC
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.
12package getter
13
14import (
15 "bytes"
16 "fmt"
17 "net/url"
18 "os/exec"
19 "regexp"
20 "syscall"
15c0b25d
AP
21
22 cleanhttp "github.com/hashicorp/go-cleanhttp"
bae9f6d2
JC
23)
24
25// Getter defines the interface that schemes must implement to download
26// things.
27type Getter interface {
28 // Get downloads the given URL into the given directory. This always
29 // assumes that we're updating and gets the latest version that it can.
30 //
31 // The directory may already exist (if we're updating). If it is in a
32 // format that isn't understood, an error should be returned. Get shouldn't
33 // simply nuke the directory.
34 Get(string, *url.URL) error
35
36 // GetFile downloads the give URL into the given path. The URL must
37 // reference a single file. If possible, the Getter should check if
38 // the remote end contains the same file and no-op this operation.
39 GetFile(string, *url.URL) error
40
41 // ClientMode returns the mode based on the given URL. This is used to
42 // allow clients to let the getters decide which mode to use.
43 ClientMode(*url.URL) (ClientMode, error)
107c1cdb
ND
44
45 // SetClient allows a getter to know it's client
46 // in order to access client's Get functions or
47 // progress tracking.
48 SetClient(*Client)
bae9f6d2
JC
49}
50
51// Getters is the mapping of scheme to the Getter implementation that will
52// be used to get a dependency.
53var Getters map[string]Getter
54
55// forcedRegexp is the regular expression that finds forced getters. This
56// syntax is schema::url, example: git::https://foo.com
57var forcedRegexp = regexp.MustCompile(`^([A-Za-z0-9]+)::(.+)$`)
58
15c0b25d
AP
59// httpClient is the default client to be used by HttpGetters.
60var httpClient = cleanhttp.DefaultClient()
61
bae9f6d2 62func init() {
15c0b25d
AP
63 httpGetter := &HttpGetter{
64 Netrc: true,
65 }
bae9f6d2
JC
66
67 Getters = map[string]Getter{
68 "file": new(FileGetter),
69 "git": new(GitGetter),
107c1cdb 70 "gcs": new(GCSGetter),
bae9f6d2
JC
71 "hg": new(HgGetter),
72 "s3": new(S3Getter),
73 "http": httpGetter,
74 "https": httpGetter,
75 }
76}
77
78// Get downloads the directory specified by src into the folder specified by
79// dst. If dst already exists, Get will attempt to update it.
80//
81// src is a URL, whereas dst is always just a file path to a folder. This
82// folder doesn't need to exist. It will be created if it doesn't exist.
107c1cdb 83func Get(dst, src string, opts ...ClientOption) error {
bae9f6d2
JC
84 return (&Client{
85 Src: src,
86 Dst: dst,
87 Dir: true,
107c1cdb 88 Options: opts,
bae9f6d2
JC
89 }).Get()
90}
91
92// GetAny downloads a URL into the given destination. Unlike Get or
93// GetFile, both directories and files are supported.
94//
95// dst must be a directory. If src is a file, it will be downloaded
96// into dst with the basename of the URL. If src is a directory or
97// archive, it will be unpacked directly into dst.
107c1cdb 98func GetAny(dst, src string, opts ...ClientOption) error {
bae9f6d2
JC
99 return (&Client{
100 Src: src,
101 Dst: dst,
102 Mode: ClientModeAny,
107c1cdb 103 Options: opts,
bae9f6d2
JC
104 }).Get()
105}
106
107// GetFile downloads the file specified by src into the path specified by
108// dst.
107c1cdb 109func GetFile(dst, src string, opts ...ClientOption) error {
bae9f6d2
JC
110 return (&Client{
111 Src: src,
112 Dst: dst,
113 Dir: false,
107c1cdb 114 Options: opts,
bae9f6d2
JC
115 }).Get()
116}
117
118// getRunCommand is a helper that will run a command and capture the output
119// in the case an error happens.
120func getRunCommand(cmd *exec.Cmd) error {
121 var buf bytes.Buffer
122 cmd.Stdout = &buf
123 cmd.Stderr = &buf
124 err := cmd.Run()
125 if err == nil {
126 return nil
127 }
128 if exiterr, ok := err.(*exec.ExitError); ok {
129 // The program has exited with an exit code != 0
130 if status, ok := exiterr.Sys().(syscall.WaitStatus); ok {
131 return fmt.Errorf(
132 "%s exited with %d: %s",
133 cmd.Path,
134 status.ExitStatus(),
135 buf.String())
136 }
137 }
138
139 return fmt.Errorf("error running %s: %s", cmd.Path, buf.String())
140}
141
142// getForcedGetter takes a source and returns the tuple of the forced
143// getter and the raw URL (without the force syntax).
144func getForcedGetter(src string) (string, string) {
145 var forced string
146 if ms := forcedRegexp.FindStringSubmatch(src); ms != nil {
147 forced = ms[1]
148 src = ms[2]
149 }
150
151 return forced, src
152}