s3_website 2.7.3 → 2.7.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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