@@ -19,16 +19,57 @@ import (
19
19
20
20
// Downloader downloads a binary
21
21
type Downloader struct {
22
- OS string `json:"os"`
23
- Arch string `json:"arch"`
24
- URL string `json:"url"`
25
- Checksum string `json:"checksum,omitempty" yaml:",omitempty"`
26
- ArchivePath string `json:"archive_path,omitempty" yaml:"archive_path,omitempty"`
27
- Link bool `json:"link,omitempty" yaml:",omitempty"`
28
- BinName string `json:"bin,omitempty" yaml:"bin,omitempty"`
22
+ OS string `json:"os"`
23
+ Arch string `json:"arch"`
24
+ URL string `json:"url"`
25
+ ArchivePath string `json:"archive_path,omitempty" yaml:"archive_path,omitempty"`
26
+ BinName string `json:"bin,omitempty" yaml:"bin,omitempty"`
27
+ Link bool `json:"link,omitempty" yaml:",omitempty"`
28
+ Checksum string `json:"checksum,omitempty" yaml:",omitempty"`
29
+ Vars map [string ]string `json:"vars,omitempty" yaml:"vars,omitempty"`
30
+
31
+ //set to true by applyTemplates
32
+ tmplApplied bool
33
+ }
34
+
35
+ func (d * Downloader ) clone () * Downloader {
36
+ c := new (Downloader )
37
+ * c = * d
38
+ if c .Vars != nil {
39
+ c .Vars = util .CopyStringMap (c .Vars )
40
+ }
41
+ return c
42
+ }
43
+
44
+ func (d * Downloader ) requireApplyTemplates () {
45
+ if ! d .tmplApplied {
46
+ panic ("templates not applied" )
47
+ }
48
+ }
49
+
50
+ func (d * Downloader ) applyTemplates () error {
51
+ executeTemplate := func (tmpl string ) (string , error ) {
52
+ return util .ExecuteTemplate (tmpl , d .OS , d .Arch , d .Vars )
53
+ }
54
+ var err error
55
+ d .URL , err = executeTemplate (d .URL )
56
+ if err != nil {
57
+ return err
58
+ }
59
+ d .ArchivePath , err = executeTemplate (d .ArchivePath )
60
+ if err != nil {
61
+ return err
62
+ }
63
+ d .BinName , err = executeTemplate (d .BinName )
64
+ if err != nil {
65
+ return err
66
+ }
67
+ d .tmplApplied = true
68
+ return nil
29
69
}
30
70
31
71
func (d * Downloader ) downloadableName () (string , error ) {
72
+ d .requireApplyTemplates ()
32
73
u , err := url .Parse (d .URL )
33
74
if err != nil {
34
75
return "" , err
@@ -37,6 +78,7 @@ func (d *Downloader) downloadableName() (string, error) {
37
78
}
38
79
39
80
func (d * Downloader ) downloadablePath (targetDir string ) (string , error ) {
81
+ d .requireApplyTemplates ()
40
82
name , err := d .downloadableName ()
41
83
if err != nil {
42
84
return "" , err
@@ -45,6 +87,7 @@ func (d *Downloader) downloadablePath(targetDir string) (string, error) {
45
87
}
46
88
47
89
func (d * Downloader ) binPath (targetDir string ) string {
90
+ d .requireApplyTemplates ()
48
91
return filepath .Join (targetDir , d .BinName )
49
92
}
50
93
@@ -53,6 +96,7 @@ func (d *Downloader) chmod(targetDir string) error {
53
96
}
54
97
55
98
func (d * Downloader ) moveOrLinkBin (targetDir , extractDir string ) error {
99
+ d .requireApplyTemplates ()
56
100
archivePath := filepath .FromSlash (d .ArchivePath )
57
101
if archivePath == "" {
58
102
archivePath = filepath .FromSlash (d .BinName )
@@ -103,6 +147,7 @@ func (d *Downloader) moveOrLinkBin(targetDir, extractDir string) error {
103
147
}
104
148
105
149
func (d * Downloader ) extract (downloadDir , extractDir string ) error {
150
+ d .requireApplyTemplates ()
106
151
dlName , err := d .downloadableName ()
107
152
if err != nil {
108
153
return err
@@ -124,6 +169,7 @@ func (d *Downloader) extract(downloadDir, extractDir string) error {
124
169
}
125
170
126
171
func (d * Downloader ) download (downloadDir string ) error {
172
+ d .requireApplyTemplates ()
127
173
dlPath , err := d .downloadablePath (downloadDir )
128
174
if err != nil {
129
175
return err
@@ -149,6 +195,7 @@ func (d *Downloader) setDefaultBinName(defaultName string) {
149
195
}
150
196
151
197
func (d * Downloader ) validateChecksum (targetDir string ) error {
198
+ d .requireApplyTemplates ()
152
199
targetFile , err := d .downloadablePath (targetDir )
153
200
if err != nil {
154
201
return err
@@ -179,12 +226,26 @@ type UpdateChecksumOpts struct {
179
226
180
227
//UpdateChecksum updates the checksum based on a fresh download
181
228
func (d * Downloader ) UpdateChecksum (opts UpdateChecksumOpts ) error {
229
+ sum , err := d .getUpdatedChecksum (opts )
230
+ if err != nil {
231
+ return err
232
+ }
233
+ d .Checksum = sum
234
+ return nil
235
+ }
236
+
237
+ //getUpdatedChecksum downloads the archive and returns its actual checksum.
238
+ func (d * Downloader ) getUpdatedChecksum (opts UpdateChecksumOpts ) (string , error ) {
239
+ d = d .clone ()
240
+ err := d .applyTemplates ()
241
+ if err != nil {
242
+ return "" , err
243
+ }
182
244
cellarDir := opts .CellarDir
183
- var err error
184
245
if cellarDir == "" {
185
246
cellarDir , err = ioutil .TempDir ("" , "bindown" )
186
247
if err != nil {
187
- return err
248
+ return "" , err
188
249
}
189
250
defer func () {
190
251
_ = os .RemoveAll (cellarDir ) //nolint:errcheck
@@ -196,21 +257,15 @@ func (d *Downloader) UpdateChecksum(opts UpdateChecksumOpts) error {
196
257
err = d .download (downloadDir )
197
258
if err != nil {
198
259
log .Printf ("error downloading: %v" , err )
199
- return err
260
+ return "" , err
200
261
}
201
262
202
263
dlPath , err := d .downloadablePath (downloadDir )
203
264
if err != nil {
204
- return err
205
- }
206
-
207
- checkSum , err := fileChecksum (dlPath )
208
- if err != nil {
209
- return err
265
+ return "" , err
210
266
}
211
267
212
- d .Checksum = checkSum
213
- return nil
268
+ return fileChecksum (dlPath )
214
269
}
215
270
216
271
//InstallOpts options for Install
@@ -235,6 +290,10 @@ func (d *Downloader) extractsSubName() string {
235
290
236
291
//Install downloads and installs a bin
237
292
func (d * Downloader ) Install (opts InstallOpts ) error {
293
+ err := d .applyTemplates ()
294
+ if err != nil {
295
+ return err
296
+ }
238
297
d .setDefaultBinName (opts .DownloaderName )
239
298
cellarDir := opts .CellarDir
240
299
if cellarDir == "" {
@@ -245,13 +304,13 @@ func (d *Downloader) Install(opts InstallOpts) error {
245
304
extractDir := filepath .Join (cellarDir , "extracts" , d .extractsSubName ())
246
305
247
306
if opts .Force {
248
- err : = os .RemoveAll (downloadDir )
307
+ err = os .RemoveAll (downloadDir )
249
308
if err != nil {
250
309
return err
251
310
}
252
311
}
253
312
254
- err : = d .download (downloadDir )
313
+ err = d .download (downloadDir )
255
314
if err != nil {
256
315
log .Printf ("error downloading: %v" , err )
257
316
return err
@@ -295,6 +354,10 @@ type ValidateOpts struct {
295
354
//Validate installs the downloader to a temporary directory and returns an error if it was unsuccessful.
296
355
// If cellarDir is "", it will use a temp directory
297
356
func (d * Downloader ) Validate (opts ValidateOpts ) error {
357
+ err := d .applyTemplates ()
358
+ if err != nil {
359
+ return err
360
+ }
298
361
tmpDir , err := ioutil .TempDir ("" , "bindown" )
299
362
if err != nil {
300
363
return err
0 commit comments