@@ -19,10 +19,13 @@ import (
19
19
"github.com/aws/aws-sdk-go/aws/credentials"
20
20
"github.com/aws/aws-sdk-go/aws/endpoints"
21
21
"github.com/aws/aws-sdk-go/aws/session"
22
+ "github.com/aws/aws-sdk-go/service/s3"
22
23
"github.com/aws/aws-sdk-go/service/s3/s3manager"
23
24
)
24
25
25
26
var defaultS3Bucket = "static.buffer.com"
27
+ var uploader * s3manager.Uploader
28
+ var svc * s3.S3
26
29
27
30
func fatal (format string , a ... interface {}) {
28
31
s := "Error: " + format + "\n "
@@ -76,10 +79,8 @@ func GetFilesFromGlobsList(globList string) ([]string, error) {
76
79
return files , nil
77
80
}
78
81
79
- // GetS3Uploader returns a configured Uploader
80
- func GetS3Uploader () (* s3manager.Uploader , error ) {
81
- var uploader * s3manager.Uploader
82
-
82
+ // SetupS3Uploader configures and assigns the global "uploader" and "svc" variables
83
+ func SetupS3Uploader () {
83
84
awsAccessKeyID := os .Getenv ("AWS_ACCESS_KEY_ID" )
84
85
awsSecretAccessKey := os .Getenv ("AWS_SECRET_ACCESS_KEY" )
85
86
@@ -89,14 +90,63 @@ func GetS3Uploader() (*s3manager.Uploader, error) {
89
90
Credentials : creds ,
90
91
Region : aws .String (endpoints .UsEast1RegionID ),
91
92
}))
92
-
93
93
_ , err := creds .Get ()
94
94
if err != nil {
95
95
fatal ("failed to load AWS credentials %s" , err )
96
96
}
97
97
98
98
uploader = s3manager .NewUploader (sess )
99
- return uploader , nil
99
+ svc = s3 .New (sess )
100
+ }
101
+
102
+ // HasPreviousUpload performs a HEAD request to check if a file has been uploaded already
103
+ func HasPreviousUpload (svc * s3.S3 , bucket string , filename string ) bool {
104
+ req , _ := svc .HeadObjectRequest (& s3.HeadObjectInput {
105
+ Bucket : aws .String (bucket ),
106
+ Key : aws .String (filename ),
107
+ })
108
+ err := req .Send ()
109
+ if err == nil {
110
+ return true
111
+ }
112
+ return false
113
+ }
114
+
115
+ // GetFileURL returns the final url of the file
116
+ func GetFileURL (filename string , bucket string ) string {
117
+ // the static.buffer.com bucket has a domain alias
118
+ if bucket == defaultS3Bucket {
119
+ return "https://" + path .Join (bucket , filename )
120
+ }
121
+ return "https://s3.amazonaws.com" + path .Join ("/" , filename )
122
+ }
123
+
124
+ // UploadFile ensures a given file is uploaded to the s3 bucket and returns
125
+ // the filename
126
+ func UploadFile (file * os.File , filename string , bucket string ) (fileURL string , err error ) {
127
+ mimeType := GetFileMimeType (filename )
128
+
129
+ var action string
130
+ if ! HasPreviousUpload (svc , bucket , filename ) {
131
+ _ , err := uploader .Upload (& s3manager.UploadInput {
132
+ Bucket : aws .String (bucket ),
133
+ Key : aws .String (filename ),
134
+ ContentType : aws .String (mimeType ),
135
+ CacheControl : aws .String ("public, max-age=31520626" ),
136
+ Expires : aws .Time (time .Now ().AddDate (10 , 0 , 0 )),
137
+ Body : file ,
138
+ })
139
+ if err != nil {
140
+ return fileURL , err
141
+ }
142
+ action = "Uploaded"
143
+ } else {
144
+ action = "Skipped"
145
+ }
146
+
147
+ fileURL = GetFileURL (filename , bucket )
148
+ fmt .Printf ("%-10s %s\n " , action , fileURL )
149
+ return fileURL , nil
100
150
}
101
151
102
152
// VersionAndUploadFiles will verion files and upload them to s3 and return
@@ -108,11 +158,6 @@ func VersionAndUploadFiles(
108
158
) (map [string ]string , error ) {
109
159
fileVersions := map [string ]string {}
110
160
111
- uploader , err := GetS3Uploader ()
112
- if err != nil {
113
- return fileVersions , err
114
- }
115
-
116
161
for _ , filename := range filenames {
117
162
file , err := os .Open (filename )
118
163
if err != nil {
@@ -130,27 +175,12 @@ func VersionAndUploadFiles(
130
175
uploadFilename = GetVersionedFilename (filename , checksum )
131
176
}
132
177
bucketFilename := path .Join (directory , uploadFilename )
133
- mimeType := GetFileMimeType (filename )
134
178
135
- result , err := uploader .Upload (& s3manager.UploadInput {
136
- Bucket : aws .String (bucket ),
137
- Key : aws .String (bucketFilename ),
138
- ContentType : aws .String (mimeType ),
139
- CacheControl : aws .String ("public, max-age=31520626" ),
140
- Expires : aws .Time (time .Now ().AddDate (10 , 0 , 0 )),
141
- Body : file ,
142
- })
179
+ fileURL , err := UploadFile (file , bucketFilename , bucket )
143
180
if err != nil {
144
181
return fileVersions , err
145
182
}
146
-
147
- // the static.buffer.com bucket has a domain alias
148
- if bucket == defaultS3Bucket {
149
- fileVersions [filename ] = "https://" + path .Join (bucket , bucketFilename )
150
- } else {
151
- fileVersions [filename ] = result .Location
152
- }
153
- fmt .Printf ("Uploaded %s\n " , fileVersions [filename ])
183
+ fileVersions [filename ] = fileURL
154
184
}
155
185
156
186
return fileVersions , nil
@@ -173,6 +203,7 @@ func main() {
173
203
}
174
204
fmt .Printf ("Found %d files to upload and version:\n " , len (files ))
175
205
206
+ SetupS3Uploader ()
176
207
fileVersions , err := VersionAndUploadFiles (* s3Bucket , * directory , files )
177
208
if err != nil {
178
209
fatal ("failed to upload files %s" , err )
0 commit comments