s3_website 2.7.3 → 2.7.4

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 0d697820d3714dc4f00c997a1424c199d8786691
4
- data.tar.gz: 9929b4a2e0d951b8bb58556b0aebca80ee36a82c
3
+ metadata.gz: 30adad59b826ea4b90e8f5caafd9a203ccfdf053
4
+ data.tar.gz: 6e3db53bfcfe0d88d5567300831062bb3f6672de
5
5
  SHA512:
6
- metadata.gz: f8c31db585bdc5d527b90dba36a21e73ec8520eb074feab11ba19aef1a6e01dc7b3faba1c209e720dc7cf0b2768c5cebeb1b97fff8314c8e3675ca3f4ea28766
7
- data.tar.gz: 9057ccc704fcd6a31348b4acb36d85cb7f4e23c5236b5e22f2ae63689b4ba5e2c379ddbb0d5595ca1e1caab2b8a055f885a0d1c9317539cc639aea4b73f21bc3
6
+ metadata.gz: 20b06946d5644940c64c9817c8e1710b80d2c5ee83078bbf34796d828ca090585a246f6e255509a1b7b83512d906dc5fc46b27a2e79408678e75ffee84e34ca3
7
+ data.tar.gz: 349e3aebe7e012b497d08612b50156f23fc35fd2ca6f8969da4599250aa8f74602306c9871843acf3e3ff89c5362830b4d40af470d165123affbaf935f9ba5d6
data/changelog.md CHANGED
@@ -2,6 +2,12 @@
2
2
 
3
3
  This project uses [Semantic Versioning](http://semver.org).
4
4
 
5
+ ## 2.7.4
6
+
7
+ * Show a helpful error message if the configured site is missing
8
+
9
+ See <https://github.com/laurilehmijoki/s3_website/issues/144> for discussion.
10
+
5
11
  ## 2.7.3
6
12
 
7
13
  * Support valid URI characters in max_age glob
@@ -1,3 +1,3 @@
1
1
  module S3Website
2
- VERSION = '2.7.3'
2
+ VERSION = '2.7.4'
3
3
  end
@@ -1,8 +1,6 @@
1
1
  package s3.website
2
2
 
3
- import scala.util.Try
4
-
5
- class Logger(val verboseOutput: Boolean) {
3
+ class Logger(val verboseOutput: Boolean, onLog: Option[(String) => _] = None) {
6
4
  def debug(msg: String) = if (verboseOutput) log(Debug, msg)
7
5
  def info(msg: String) = log(Info, msg)
8
6
  def fail(msg: String) = log(Failure, msg)
@@ -12,9 +10,11 @@ class Logger(val verboseOutput: Boolean) {
12
10
 
13
11
  def pending(msg: String) = log(Wait, msg)
14
12
 
15
- private def log(logType: LogType, msgRaw: String): Try[Unit] = {
13
+ private def log(logType: LogType, msgRaw: String) = {
16
14
  val msg = msgRaw.replaceAll("\\n", "\n ") // Indent new lines, so that they arrange nicely with other log lines
17
- Try(println(s"[$logType] $msg"))
15
+ val decoratedLogMessage = s"[$logType] $msg"
16
+ onLog.foreach(_(decoratedLogMessage))
17
+ println(decoratedLogMessage)
18
18
  }
19
19
 
20
20
  sealed trait LogType {
@@ -32,9 +32,11 @@ object Push {
32
32
 
33
33
  def main(args: Array[String]) {
34
34
  implicit val cliArgs = parseArguments(classOf[CliArgs], args:_*)
35
+ implicit val logger: Logger = new Logger(cliArgs.verbose)
35
36
  implicit val s3Settings = S3Setting()
36
37
  implicit val cloudFrontSettings = CloudFrontSetting()
37
38
  implicit val workingDirectory = new File(System.getProperty("user.dir")).getAbsoluteFile
39
+
38
40
  System exit push
39
41
  }
40
42
 
@@ -48,8 +50,7 @@ object Push {
48
50
  @Option(longName = Array("force")) def force: Boolean
49
51
  }
50
52
 
51
- def push(implicit cliArgs: CliArgs, s3Settings: S3Setting, cloudFrontSettings: CloudFrontSetting, workingDirectory: File): ExitCode = {
52
- implicit val logger: Logger = new Logger(cliArgs.verbose)
53
+ def push(implicit cliArgs: CliArgs, s3Settings: S3Setting, cloudFrontSettings: CloudFrontSetting, workingDirectory: File, logger: Logger): ExitCode = {
53
54
  implicit val pushOptions = new PushOptions {
54
55
  def dryRun = cliArgs.dryRun
55
56
  def force = cliArgs.force
@@ -86,30 +86,61 @@ object Site {
86
86
  def loadSite(implicit yamlConfig: S3_website_yml, cliArgs: CliArgs, workingDirectory: File, logger: Logger): Either[ErrorReport, Site] =
87
87
  parseConfig.right.flatMap { cfg =>
88
88
  implicit val config: Config = cfg
89
- val errorOrSiteDir = resolveSiteDir.fold(Left(ErrorReport(noSiteFound)): Either[ErrorReport, File])(Right(_))
90
- errorOrSiteDir.right.map(Site(_, config))
89
+ resolveSiteDir.right.map(Site(_, config))
91
90
  }
92
91
 
93
- val noSiteFound =
94
- """|Could not find a website.
95
- |Either use the --site=DIR command-line argument or define the location of the site in s3_website.yml.
96
- |
97
- |Here's an example of how you can define the site directory in s3_website.yml:
98
- | site: dist/website""".stripMargin
92
+ def noSiteFound(explanation: String) =
93
+ s"""|
94
+ |$explanation.
95
+ |Either use the --site=DIR command-line argument or define the location of the site in s3_website.yml.
96
+ |
97
+ |Here's an example of how you can define the site directory in s3_website.yml:
98
+ | site: dist/website""".stripMargin
99
99
 
100
- def resolveSiteDir(implicit yamlConfig: S3_website_yml, config: Config, cliArgs: CliArgs, workingDirectory: File): Option[File] = {
100
+ def resolveSiteDir(implicit yamlConfig: S3_website_yml, config: Config, cliArgs: CliArgs, workingDirectory: File): Either[ErrorReport, File] = {
101
101
  val siteFromAutoDetect = autodetectSiteDir(workingDirectory)
102
- val siteFromCliArgs = Option(cliArgs.site).map(new File(_))
102
+ val errOrSiteFromCliArgs: Either[ErrorReport, Option[File]] = Option(cliArgs.site) match {
103
+ case Some(siteDirFromCliArgs) =>
104
+ val f = new File(siteDirFromCliArgs)
105
+ if (f.exists())
106
+ Right(Some(f))
107
+ else
108
+ Left(ErrorReport(noSiteFound(s"Could not find a site at $siteDirFromCliArgs. Check the --site argument.")))
109
+ case None => Right(None)
110
+ }
103
111
 
104
- siteFromCliArgs orElse siteFromConfig orElse siteFromAutoDetect
112
+ val errOrAvailableSiteDirs: Either[ErrorReport, List[File]] = for {
113
+ s1 <- errOrSiteFromCliArgs.right
114
+ s2 <- siteFromConfig.right
115
+ s3 <- Right(siteFromAutoDetect).right
116
+ } yield {
117
+ (s1 :: s2 :: s3 :: Nil) collect {
118
+ case Some(file) => file
119
+ }
120
+ }
121
+ errOrAvailableSiteDirs.right.flatMap {
122
+ case mostPreferredSiteDir :: xs => Right(mostPreferredSiteDir)
123
+ case Nil => Left(ErrorReport(noSiteFound("Could not find a website.")))
124
+ }
105
125
  }
106
126
 
107
- def siteFromConfig(implicit yamlConfig: S3_website_yml, config: Config, workingDirectory: File): Option[File] =
108
- config
127
+ def siteFromConfig(implicit yamlConfig: S3_website_yml, config: Config, workingDirectory: File): Either[ErrorReport, Option[File]] = {
128
+ val siteConfig = config
109
129
  .site
110
130
  .map(new File(_))
111
131
  .map { siteDir =>
112
132
  if (siteDir.isAbsolute) siteDir
113
133
  else new File(yamlConfig.file.getParentFile, siteDir.getPath)
114
134
  }
135
+
136
+ siteConfig match {
137
+ case s @ Some(siteDir) =>
138
+ if (siteDir.exists())
139
+ Right(s)
140
+ else
141
+ Left(ErrorReport(noSiteFound(s"Could not find a website. (The site setting in s3_website.yml points to a non-existing file $siteDir)")))
142
+ case None =>
143
+ Right(None)
144
+ }
145
+ }
115
146
  }
@@ -26,6 +26,7 @@ import s3.website.model.Ssg.automaticallySupportedSiteGenerators
26
26
  import s3.website.model._
27
27
 
28
28
  import scala.collection.JavaConversions._
29
+ import scala.collection.mutable
29
30
  import scala.concurrent.duration._
30
31
  import scala.util.Random
31
32
 
@@ -36,7 +37,7 @@ class S3WebsiteSpec extends Specification {
36
37
  config = "gzip: true"
37
38
  setLocalFileWithContent(("styles.css", "<h1>hi again</h1>"))
38
39
  setS3File("styles.css", "1c5117e5839ad8fc00ce3c41296255a1" /* md5 of the gzip of the file contents */)
39
- push
40
+ push()
40
41
  sentPutObjectRequest.getKey must equalTo("styles.css")
41
42
  }
42
43
 
@@ -44,7 +45,7 @@ class S3WebsiteSpec extends Specification {
44
45
  config = "gzip: true"
45
46
  setLocalFileWithContent(("styles.css", "<h1>hi</h1>"))
46
47
  setS3File("styles.css", "1c5117e5839ad8fc00ce3c41296255a1" /* md5 of the gzip of the file contents */)
47
- push
48
+ push()
48
49
  noUploadsOccurred must beTrue
49
50
  }
50
51
  }
@@ -60,7 +61,7 @@ class S3WebsiteSpec extends Specification {
60
61
  """.stripMargin
61
62
  setLocalFileWithContent(("file.xml", "<h1>hi again</h1>"))
62
63
  setS3File("file.xml", "1c5117e5839ad8fc00ce3c41296255a1" /* md5 of the gzip of the file contents */)
63
- push
64
+ push()
64
65
  sentPutObjectRequest.getKey must equalTo("file.xml")
65
66
  }
66
67
  }
@@ -69,33 +70,33 @@ class S3WebsiteSpec extends Specification {
69
70
  "not upload a file if it has not changed" in new BasicSetup {
70
71
  setLocalFileWithContent(("index.html", "<div>hello</div>"))
71
72
  setS3File("index.html", md5Hex("<div>hello</div>"))
72
- push
73
+ push()
73
74
  noUploadsOccurred must beTrue
74
75
  }
75
76
 
76
77
  "update a file if it has changed" in new BasicSetup {
77
78
  setLocalFileWithContent(("index.html", "<h1>old text</h1>"))
78
79
  setS3File("index.html", md5Hex("<h1>new text</h1>"))
79
- push
80
+ push()
80
81
  sentPutObjectRequest.getKey must equalTo("index.html")
81
82
  }
82
83
 
83
84
  "create a file if does not exist on S3" in new BasicSetup {
84
85
  setLocalFile("index.html")
85
- push
86
+ push()
86
87
  sentPutObjectRequest.getKey must equalTo("index.html")
87
88
  }
88
89
 
89
90
  "delete files that are on S3 but not on local file system" in new BasicSetup {
90
91
  setS3File("old.html", md5Hex("<h1>old text</h1>"))
91
- push
92
+ push()
92
93
  sentDelete must equalTo("old.html")
93
94
  }
94
95
 
95
96
  "try again if the upload fails" in new BasicSetup {
96
97
  setLocalFile("index.html")
97
98
  uploadFailsAndThenSucceeds(howManyFailures = 5)
98
- push
99
+ push()
99
100
  verify(amazonS3Client, times(6)).putObject(Matchers.any(classOf[PutObjectRequest]))
100
101
  }
101
102
 
@@ -106,7 +107,7 @@ class S3WebsiteSpec extends Specification {
106
107
  e.setStatusCode(403)
107
108
  e
108
109
  }
109
- push
110
+ push()
110
111
  verify(amazonS3Client, times(1)).putObject(Matchers.any(classOf[PutObjectRequest]))
111
112
  }
112
113
 
@@ -126,21 +127,21 @@ class S3WebsiteSpec extends Specification {
126
127
  }
127
128
  }
128
129
  setLocalFile("index.html")
129
- val exitStatus = push
130
+ val exitStatus = push()
130
131
  verify(amazonS3Client, times(2)).putObject(Matchers.any(classOf[PutObjectRequest]))
131
132
  }
132
133
 
133
134
  "try again if the delete fails" in new BasicSetup {
134
135
  setS3File("old.html", md5Hex("<h1>old text</h1>"))
135
136
  deleteFailsAndThenSucceeds(howManyFailures = 5)
136
- push
137
+ push()
137
138
  verify(amazonS3Client, times(6)).deleteObject(Matchers.anyString(), Matchers.anyString())
138
139
  }
139
140
 
140
141
  "try again if the object listing fails" in new BasicSetup {
141
142
  setS3File("old.html", md5Hex("<h1>old text</h1>"))
142
143
  objectListingFailsAndThenSucceeds(howManyFailures = 5)
143
- push
144
+ push()
144
145
  verify(amazonS3Client, times(6)).listObjects(Matchers.any(classOf[ListObjectsRequest]))
145
146
  }
146
147
  }
@@ -150,14 +151,14 @@ class S3WebsiteSpec extends Specification {
150
151
  config = "cloudfront_distribution_id: EGM1J2JJX9Z"
151
152
  setLocalFiles("css/test.css", "articles/index.html")
152
153
  setOutdatedS3Keys("css/test.css", "articles/index.html")
153
- push
154
+ push()
154
155
  sentInvalidationRequest.getInvalidationBatch.getPaths.getItems.toSeq.sorted must equalTo(("/css/test.css" :: "/articles/index.html" :: Nil).sorted)
155
156
  }
156
157
 
157
158
  "not send CloudFront invalidation requests on new objects" in new BasicSetup {
158
159
  config = "cloudfront_distribution_id: EGM1J2JJX9Z"
159
160
  setLocalFile("newfile.js")
160
- push
161
+ push()
161
162
  noInvalidationsOccurred must beTrue
162
163
  }
163
164
 
@@ -167,7 +168,7 @@ class S3WebsiteSpec extends Specification {
167
168
  |redirects:
168
169
  | /index.php: index.html
169
170
  """.stripMargin
170
- push
171
+ push()
171
172
  noInvalidationsOccurred must beTrue
172
173
  }
173
174
 
@@ -176,7 +177,7 @@ class S3WebsiteSpec extends Specification {
176
177
  config = "cloudfront_distribution_id: EGM1J2JJX9Z"
177
178
  setLocalFile("test.css")
178
179
  setOutdatedS3Keys("test.css")
179
- push must equalTo(0) // The retries should finally result in a success
180
+ push() must equalTo(0) // The retries should finally result in a success
180
181
  sentInvalidationRequests.length must equalTo(4)
181
182
  }
182
183
 
@@ -185,7 +186,7 @@ class S3WebsiteSpec extends Specification {
185
186
  config = "cloudfront_distribution_id: EGM1J2JJX9Z"
186
187
  setLocalFile("test.css")
187
188
  setOutdatedS3Keys("test.css")
188
- push
189
+ push()
189
190
  sentInvalidationRequests.length must equalTo(6)
190
191
  }
191
192
 
@@ -193,7 +194,7 @@ class S3WebsiteSpec extends Specification {
193
194
  config = "cloudfront_distribution_id: EGM1J2JJX9Z"
194
195
  setLocalFile("articles/arnold's file.html")
195
196
  setOutdatedS3Keys("articles/arnold's file.html")
196
- push
197
+ push()
197
198
  sentInvalidationRequest.getInvalidationBatch.getPaths.getItems.toSeq.sorted must equalTo(("/articles/arnold's%20file.html" :: Nil).sorted)
198
199
  }
199
200
 
@@ -201,7 +202,7 @@ class S3WebsiteSpec extends Specification {
201
202
  config = "cloudfront_distribution_id: EGM1J2JJX9Z"
202
203
  setLocalFile("maybe-index.html")
203
204
  setOutdatedS3Keys("maybe-index.html")
204
- push
205
+ push()
205
206
  sentInvalidationRequest.getInvalidationBatch.getPaths.getItems.toSeq.sorted must equalTo(("/" :: "/maybe-index.html" :: Nil).sorted)
206
207
  }
207
208
  }
@@ -214,7 +215,7 @@ class S3WebsiteSpec extends Specification {
214
215
  """.stripMargin
215
216
  setLocalFile("articles/index.html")
216
217
  setOutdatedS3Keys("articles/index.html")
217
- push
218
+ push()
218
219
  sentInvalidationRequest.getInvalidationBatch.getPaths.getItems.toSeq must contain("/articles/")
219
220
  }
220
221
 
@@ -225,7 +226,7 @@ class S3WebsiteSpec extends Specification {
225
226
  """.stripMargin
226
227
  setLocalFile("articles/index.html")
227
228
  setOutdatedS3Keys("articles/index.html")
228
- push
229
+ push()
229
230
  sentInvalidationRequest.getInvalidationBatch.getPaths.getItems.toSeq must contain("/index.html")
230
231
  }
231
232
  }
@@ -236,7 +237,7 @@ class S3WebsiteSpec extends Specification {
236
237
  config = "cloudfront_distribution_id: EGM1J2JJX9Z"
237
238
  setLocalFiles(files:_*)
238
239
  setOutdatedS3Keys(files:_*)
239
- push
240
+ push()
240
241
  sentInvalidationRequests.length must equalTo(2)
241
242
  sentInvalidationRequests(0).getInvalidationBatch.getPaths.getItems.length must equalTo(1000)
242
243
  sentInvalidationRequests(1).getInvalidationBatch.getPaths.getItems.length must equalTo(2)
@@ -246,13 +247,13 @@ class S3WebsiteSpec extends Specification {
246
247
  "push exit status" should {
247
248
  "be 0 all uploads succeed" in new BasicSetup {
248
249
  setLocalFiles("file.txt")
249
- push must equalTo(0)
250
+ push() must equalTo(0)
250
251
  }
251
252
 
252
253
  "be 1 if any of the uploads fails" in new BasicSetup {
253
254
  setLocalFiles("file.txt")
254
255
  when(amazonS3Client.putObject(Matchers.any(classOf[PutObjectRequest]))).thenThrow(new AmazonServiceException("AWS failed"))
255
- push must equalTo(1)
256
+ push() must equalTo(1)
256
257
  }
257
258
 
258
259
  "be 1 if any of the redirects fails" in new BasicSetup {
@@ -261,14 +262,14 @@ class S3WebsiteSpec extends Specification {
261
262
  | index.php: /index.html
262
263
  """.stripMargin
263
264
  when(amazonS3Client.putObject(Matchers.any(classOf[PutObjectRequest]))).thenThrow(new AmazonServiceException("AWS failed"))
264
- push must equalTo(1)
265
+ push() must equalTo(1)
265
266
  }
266
267
 
267
268
  "be 0 if CloudFront invalidations and uploads succeed"in new BasicSetup {
268
269
  config = "cloudfront_distribution_id: EGM1J2JJX9Z"
269
270
  setLocalFile("test.css")
270
271
  setOutdatedS3Keys("test.css")
271
- push must equalTo(0)
272
+ push() must equalTo(0)
272
273
  }
273
274
 
274
275
  "be 1 if CloudFront is unreachable or broken"in new BasicSetup {
@@ -276,32 +277,32 @@ class S3WebsiteSpec extends Specification {
276
277
  config = "cloudfront_distribution_id: EGM1J2JJX9Z"
277
278
  setLocalFile("test.css")
278
279
  setOutdatedS3Keys("test.css")
279
- push must equalTo(1)
280
+ push() must equalTo(1)
280
281
  }
281
282
 
282
283
  "be 0 if upload retry succeeds" in new BasicSetup {
283
284
  setLocalFile("index.html")
284
285
  uploadFailsAndThenSucceeds(howManyFailures = 1)
285
- push must equalTo(0)
286
+ push() must equalTo(0)
286
287
  }
287
288
 
288
289
  "be 1 if delete retry fails" in new BasicSetup {
289
290
  setLocalFile("index.html")
290
291
  uploadFailsAndThenSucceeds(howManyFailures = 6)
291
- push must equalTo(1)
292
+ push() must equalTo(1)
292
293
  }
293
294
 
294
295
  "be 1 if an object listing fails" in new BasicSetup {
295
296
  setS3File("old.html", md5Hex("<h1>old text</h1>"))
296
297
  objectListingFailsAndThenSucceeds(howManyFailures = 6)
297
- push must equalTo(1)
298
+ push() must equalTo(1)
298
299
  }
299
300
  }
300
301
 
301
302
  "s3_website.yml file" should {
302
303
  "never be uploaded" in new BasicSetup {
303
304
  setLocalFile("s3_website.yml")
304
- push
305
+ push()
305
306
  noUploadsOccurred must beTrue
306
307
  }
307
308
  }
@@ -309,7 +310,7 @@ class S3WebsiteSpec extends Specification {
309
310
  ".env file" should { // The .env file is the https://github.com/bkeepers/dotenv file
310
311
  "never be uploaded" in new BasicSetup {
311
312
  setLocalFile(".env")
312
- push
313
+ push()
313
314
  noUploadsOccurred must beTrue
314
315
  }
315
316
  }
@@ -318,7 +319,7 @@ class S3WebsiteSpec extends Specification {
318
319
  "result in matching files not being uploaded" in new BasicSetup {
319
320
  config = "exclude_from_upload: .DS_.*?"
320
321
  setLocalFile(".DS_Store")
321
- push
322
+ push()
322
323
  noUploadsOccurred must beTrue
323
324
  }
324
325
  }
@@ -335,7 +336,7 @@ class S3WebsiteSpec extends Specification {
335
336
  | - logs
336
337
  """.stripMargin
337
338
  setLocalFiles(".DS_Store", "logs/test.log")
338
- push
339
+ push()
339
340
  noUploadsOccurred must beTrue
340
341
  }
341
342
  }
@@ -344,14 +345,14 @@ class S3WebsiteSpec extends Specification {
344
345
  "not delete the S3 objects that match the ignore value" in new BasicSetup {
345
346
  config = "ignore_on_server: logs"
346
347
  setS3File("logs/log.txt")
347
- push
348
+ push()
348
349
  noDeletesOccurred must beTrue
349
350
  }
350
351
 
351
352
  "support non-US-ASCII files" in new BasicSetup {
352
353
  setS3File("tags/笔记/test.html", "")
353
354
  config = "ignore_on_server: tags/笔记/test.html"
354
- push
355
+ push()
355
356
  noDeletesOccurred must beTrue
356
357
  }
357
358
  }
@@ -362,7 +363,7 @@ class S3WebsiteSpec extends Specification {
362
363
  |ignore_on_server: $DELETE_NOTHING_MAGIC_WORD
363
364
  """.stripMargin
364
365
  setS3File("file.txt")
365
- push
366
+ push()
366
367
  noDeletesOccurred
367
368
  }
368
369
  }
@@ -378,7 +379,7 @@ class S3WebsiteSpec extends Specification {
378
379
  | - .*txt
379
380
  """.stripMargin
380
381
  setS3File("logs/log.txt", "")
381
- push
382
+ push()
382
383
  noDeletesOccurred must beTrue
383
384
  }
384
385
 
@@ -388,11 +389,24 @@ class S3WebsiteSpec extends Specification {
388
389
  |ignore_on_server:
389
390
  | - tags/笔记/test.html
390
391
  """.stripMargin
391
- push
392
+ push()
392
393
  noDeletesOccurred must beTrue
393
394
  }
394
395
  }
395
396
 
397
+ "error message" should {
398
+ "be helpful when the site directory is missing" in new BasicSetup {
399
+ config = "site: nonexisting_site_dir"
400
+ val logEntries = new mutable.MutableList[String]
401
+ push(logCapturer = Some((logEntry: String) =>
402
+ logEntries += logEntry
403
+ ))
404
+ logEntries must contain(
405
+ s"Could not find a website. (The site setting in s3_website.yml points to a non-existing file $siteDirectory/nonexisting_site_dir)"
406
+ )
407
+ }
408
+ }
409
+
396
410
  "site in config" should {
397
411
  "let the user deploy a site from a custom location" in new CustomSiteDirectory with EmptySite with MockAWS with DefaultRunMode {
398
412
  config = s"site: $siteDirectory"
@@ -401,14 +415,14 @@ class S3WebsiteSpec extends Specification {
401
415
  new File(siteDirectory, ".vimrc").exists() must beTrue // Sanity check
402
416
  siteDirectory must not equalTo workingDirectory // Sanity check
403
417
 
404
- push
418
+ push()
405
419
  sentPutObjectRequest.getKey must equalTo(".vimrc")
406
420
  }
407
421
 
408
422
  "not override the --site command-line switch" in new BasicSetup {
409
- config = s"site: dir-that-does-not-exist"
423
+ config = s"site: ${System.getProperty("java.io.tmpdir")}"
410
424
  setLocalFile(".vimrc") // This creates a file in the directory into which the --site CLI arg points
411
- push
425
+ push()
412
426
  sentPutObjectRequest.getKey must equalTo(".vimrc")
413
427
  }
414
428
 
@@ -417,7 +431,7 @@ class S3WebsiteSpec extends Specification {
417
431
  addContentToAutomaticallyDetectedSite(workingDirectory)
418
432
  config = s"site: $siteDirectory"
419
433
  setLocalFile(".vimrc") // Add content to the custom site directory
420
- push
434
+ push()
421
435
  sentPutObjectRequest.getKey must equalTo(".vimrc")
422
436
  }
423
437
 
@@ -433,7 +447,7 @@ class S3WebsiteSpec extends Specification {
433
447
  "be applied to all files" in new BasicSetup {
434
448
  config = "max_age: 60"
435
449
  setLocalFile("index.html")
436
- push
450
+ push()
437
451
  sentPutObjectRequest.getMetadata.getCacheControl must equalTo("max-age=60")
438
452
  }
439
453
 
@@ -444,7 +458,7 @@ class S3WebsiteSpec extends Specification {
444
458
  """.stripMargin
445
459
  val allValidUrlCharacters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~:/?#[]@!$&'()*+,;=" // See http://stackoverflow.com/a/1547940/990356 for discussion
446
460
  setLocalFile(s"$allValidUrlCharacters.html")
447
- push
461
+ push()
448
462
  sentPutObjectRequest.getMetadata.getCacheControl must equalTo("max-age=90")
449
463
  }
450
464
 
@@ -454,7 +468,7 @@ class S3WebsiteSpec extends Specification {
454
468
  | "*.html": 90
455
469
  """.stripMargin
456
470
  setLocalFile("index.html")
457
- push
471
+ push()
458
472
  sentPutObjectRequest.getMetadata.getCacheControl must equalTo("max-age=90")
459
473
  }
460
474
 
@@ -464,7 +478,7 @@ class S3WebsiteSpec extends Specification {
464
478
  | "assets/**/*.js": 90
465
479
  """.stripMargin
466
480
  setLocalFile("assets/lib/jquery.js")
467
- push
481
+ push()
468
482
  sentPutObjectRequest.getMetadata.getCacheControl must equalTo("max-age=90")
469
483
  }
470
484
 
@@ -474,14 +488,14 @@ class S3WebsiteSpec extends Specification {
474
488
  | "*.js": 90
475
489
  """.stripMargin
476
490
  setLocalFile("index.html")
477
- push
491
+ push()
478
492
  sentPutObjectRequest.getMetadata.getCacheControl must beNull
479
493
  }
480
494
 
481
495
  "be used to disable caching" in new BasicSetup {
482
496
  config = "max_age: 0"
483
497
  setLocalFile("index.html")
484
- push
498
+ push()
485
499
  sentPutObjectRequest.getMetadata.getCacheControl must equalTo("no-cache; max-age=0")
486
500
  }
487
501
 
@@ -491,7 +505,7 @@ class S3WebsiteSpec extends Specification {
491
505
  | "*": 21600
492
506
  """.stripMargin
493
507
  setLocalFile("tags/笔记/index.html")
494
- push must equalTo(0)
508
+ push() must equalTo(0)
495
509
  }
496
510
  }
497
511
 
@@ -503,7 +517,7 @@ class S3WebsiteSpec extends Specification {
503
517
  | "assets/*.gif": 86400
504
518
  """.stripMargin
505
519
  setLocalFiles("assets/jquery.js", "assets/picture.gif")
506
- push
520
+ push()
507
521
  sentPutObjectRequests.find(_.getKey == "assets/jquery.js").get.getMetadata.getCacheControl must equalTo("max-age=150")
508
522
  sentPutObjectRequests.find(_.getKey == "assets/picture.gif").get.getMetadata.getCacheControl must equalTo("max-age=86400")
509
523
  }
@@ -513,7 +527,7 @@ class S3WebsiteSpec extends Specification {
513
527
  "result in uploads being marked with reduced redundancy" in new BasicSetup {
514
528
  config = "s3_reduced_redundancy: true"
515
529
  setLocalFile("file.exe")
516
- push
530
+ push()
517
531
  sentPutObjectRequest.getStorageClass must equalTo("REDUCED_REDUNDANCY")
518
532
  }
519
533
  }
@@ -522,7 +536,7 @@ class S3WebsiteSpec extends Specification {
522
536
  "result in uploads being marked with the default storage class" in new BasicSetup {
523
537
  config = "s3_reduced_redundancy: false"
524
538
  setLocalFile("file.exe")
525
- push
539
+ push()
526
540
  sentPutObjectRequest.getStorageClass must beNull
527
541
  }
528
542
  }
@@ -533,7 +547,7 @@ class S3WebsiteSpec extends Specification {
533
547
  |redirects:
534
548
  | index.php: /index.html
535
549
  """.stripMargin
536
- push
550
+ push()
537
551
  sentPutObjectRequest.getRedirectLocation must equalTo("/index.html")
538
552
  }
539
553
 
@@ -542,7 +556,7 @@ class S3WebsiteSpec extends Specification {
542
556
  |redirects:
543
557
  | index.php: index.html
544
558
  """.stripMargin
545
- push
559
+ push()
546
560
  sentPutObjectRequest.getRedirectLocation must equalTo("/index.html")
547
561
  }
548
562
 
@@ -551,7 +565,7 @@ class S3WebsiteSpec extends Specification {
551
565
  |redirects:
552
566
  | index.php: http://www.youtube.com/watch?v=dQw4w9WgXcQ
553
567
  """.stripMargin
554
- push
568
+ push()
555
569
  sentPutObjectRequest.getRedirectLocation must equalTo("http://www.youtube.com/watch?v=dQw4w9WgXcQ")
556
570
  }
557
571
 
@@ -560,7 +574,7 @@ class S3WebsiteSpec extends Specification {
560
574
  |redirects:
561
575
  | index.php: https://www.youtube.com/watch?v=dQw4w9WgXcQ
562
576
  """.stripMargin
563
- push
577
+ push()
564
578
  sentPutObjectRequest.getRedirectLocation must equalTo("https://www.youtube.com/watch?v=dQw4w9WgXcQ")
565
579
  }
566
580
 
@@ -569,7 +583,7 @@ class S3WebsiteSpec extends Specification {
569
583
  |redirects:
570
584
  | index.php: /index.html
571
585
  """.stripMargin
572
- push
586
+ push()
573
587
  sentPutObjectRequest.getMetadata.getCacheControl must equalTo("max-age=0, no-cache")
574
588
  }
575
589
  }
@@ -582,7 +596,7 @@ class S3WebsiteSpec extends Specification {
582
596
  """.stripMargin
583
597
  setLocalFile("index.php")
584
598
  setS3File("index.php", "md5")
585
- push
599
+ push()
586
600
  noDeletesOccurred must beTrue
587
601
  }
588
602
  }
@@ -590,7 +604,7 @@ class S3WebsiteSpec extends Specification {
590
604
  "dotfiles" should {
591
605
  "be included in the pushed files" in new BasicSetup {
592
606
  setLocalFile(".vimrc")
593
- push
607
+ push()
594
608
  sentPutObjectRequest.getKey must equalTo(".vimrc")
595
609
  }
596
610
  }
@@ -598,25 +612,25 @@ class S3WebsiteSpec extends Specification {
598
612
  "content type inference" should {
599
613
  "add charset=utf-8 to all html documents" in new BasicSetup {
600
614
  setLocalFile("index.html")
601
- push
615
+ push()
602
616
  sentPutObjectRequest.getMetadata.getContentType must equalTo("text/html; charset=utf-8")
603
617
  }
604
618
 
605
619
  "add charset=utf-8 to all text documents" in new BasicSetup {
606
620
  setLocalFile("index.txt")
607
- push
621
+ push()
608
622
  sentPutObjectRequest.getMetadata.getContentType must equalTo("text/plain; charset=utf-8")
609
623
  }
610
624
 
611
625
  "add charset=utf-8 to all json documents" in new BasicSetup {
612
626
  setLocalFile("data.json")
613
- push
627
+ push()
614
628
  sentPutObjectRequest.getMetadata.getContentType must equalTo("application/json; charset=utf-8")
615
629
  }
616
630
 
617
631
  "resolve the content type from file contents" in new BasicSetup {
618
632
  setLocalFileWithContent(("index", "<html><body><h1>hi</h1></body></html>"))
619
- push
633
+ push()
620
634
  sentPutObjectRequest.getMetadata.getContentType must equalTo("text/html; charset=utf-8")
621
635
  }
622
636
  }
@@ -627,7 +641,7 @@ class S3WebsiteSpec extends Specification {
627
641
  |redirects:
628
642
  |<%= ('a'..'f').to_a.map do |t| ' '+t+ ': /'+t+'.html' end.join('\n')%>
629
643
  """.stripMargin
630
- push
644
+ push()
631
645
  sentPutObjectRequests.length must equalTo(6)
632
646
  sentPutObjectRequests.forall(_.getRedirectLocation != null) must beTrue
633
647
  }
@@ -637,7 +651,7 @@ class S3WebsiteSpec extends Specification {
637
651
  "push all the files whether they have changed or not" in new ForcePush {
638
652
  setLocalFileWithContent(("index.html", "<h1>hi</h1>"))
639
653
  setS3File("index.html", "1c5117e5839ad8fc00ce3c41296255a1" /* md5 of the gzip of the file contents */)
640
- push
654
+ push()
641
655
  sentPutObjectRequest.getKey must equalTo("index.html")
642
656
  }
643
657
  }
@@ -646,7 +660,7 @@ class S3WebsiteSpec extends Specification {
646
660
  "not push updates" in new DryRun {
647
661
  setLocalFileWithContent(("index.html", "<div>new</div>"))
648
662
  setS3File("index.html", md5Hex("<div>old</div>"))
649
- push
663
+ push()
650
664
  noUploadsOccurred must beTrue
651
665
  }
652
666
 
@@ -656,26 +670,26 @@ class S3WebsiteSpec extends Specification {
656
670
  |redirects:
657
671
  | index.php: /index.html
658
672
  """.stripMargin
659
- push
673
+ push()
660
674
  noUploadsOccurred must beTrue
661
675
  }
662
676
 
663
677
  "not push deletes" in new DryRun {
664
678
  setS3File("index.html", md5Hex("<div>old</div>"))
665
- push
679
+ push()
666
680
  noUploadsOccurred must beTrue
667
681
  }
668
682
 
669
683
  "not push new files" in new DryRun {
670
684
  setLocalFile("index.html")
671
- push
685
+ push()
672
686
  noUploadsOccurred must beTrue
673
687
  }
674
688
 
675
689
  "not invalidate files" in new DryRun {
676
690
  config = "cloudfront_invalidation_id: AABBCC"
677
691
  setS3File("index.html", md5Hex("<div>old</div>"))
678
- push
692
+ push()
679
693
  noInvalidationsOccurred must beTrue
680
694
  }
681
695
  }
@@ -683,7 +697,7 @@ class S3WebsiteSpec extends Specification {
683
697
  "Jekyll site" should {
684
698
  "be detected automatically" in new JekyllSite with EmptySite with MockAWS with DefaultRunMode {
685
699
  setLocalFile("index.html")
686
- push
700
+ push()
687
701
  sentPutObjectRequests.length must equalTo(1)
688
702
  }
689
703
  }
@@ -691,7 +705,7 @@ class S3WebsiteSpec extends Specification {
691
705
  "Nanoc site" should {
692
706
  "be detected automatically" in new NanocSite with EmptySite with MockAWS with DefaultRunMode {
693
707
  setLocalFile("index.html")
694
- push
708
+ push()
695
709
  sentPutObjectRequests.length must equalTo(1)
696
710
  }
697
711
  }
@@ -705,7 +719,7 @@ class S3WebsiteSpec extends Specification {
705
719
  | index.php: /index.html
706
720
  """.stripMargin
707
721
  setRedirectObject("index.php")
708
- push
722
+ push()
709
723
  noUploadsOccurred
710
724
  }
711
725
 
@@ -717,7 +731,7 @@ class S3WebsiteSpec extends Specification {
717
731
  | index.php: /index.html
718
732
  """.stripMargin
719
733
  setRedirectObject("index.php")
720
- push
734
+ push()
721
735
  noDeletesOccurred
722
736
  }
723
737
 
@@ -728,7 +742,7 @@ class S3WebsiteSpec extends Specification {
728
742
  |redirects:
729
743
  | index.php: /index.html
730
744
  """.stripMargin
731
- push
745
+ push()
732
746
  sentPutObjectRequest.getRedirectLocation must equalTo("/index.html")
733
747
  }
734
748
 
@@ -740,7 +754,7 @@ class S3WebsiteSpec extends Specification {
740
754
  | index.php: /index.html
741
755
  """.stripMargin
742
756
  setRedirectObject("index.php")
743
- push
757
+ push()
744
758
  sentPutObjectRequest.getRedirectLocation must equalTo("/index.html")
745
759
  }
746
760
  }
@@ -1000,13 +1014,14 @@ class S3WebsiteSpec extends Specification {
1000
1014
  }
1001
1015
  }
1002
1016
 
1003
- def push(implicit
1017
+ def push(logCapturer: Option[(String) => _] = None)(implicit
1004
1018
  emptyYamlConfig: S3_website_yml,
1005
1019
  configString: ConfigString,
1006
1020
  cliArgs: CliArgs,
1007
1021
  s3Settings: S3Setting,
1008
1022
  cloudFrontSettings: CloudFrontSetting,
1009
1023
  workingDirectory: File) = {
1024
+ implicit val logger = new Logger(verboseOutput = true, logCapturer)
1010
1025
  write(emptyYamlConfig.file, configString.yaml) // Write the yaml config lazily, so that the tests can override the default yaml config
1011
1026
  Push.push
1012
1027
  }
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: s3_website
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.7.3
4
+ version: 2.7.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Lauri Lehmijoki
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-01-05 00:00:00.000000000 Z
11
+ date: 2015-01-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: thor