s3_website 0.1.0
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 +7 -0
- data/.gitignore +5 -0
- data/.travis.yml +5 -0
- data/Gemfile +3 -0
- data/Gemfile.lock +81 -0
- data/LICENSE +42 -0
- data/README.md +332 -0
- data/Rakefile +18 -0
- data/bin/s3_website +38 -0
- data/changelog.md +7 -0
- data/example-configurations.md +60 -0
- data/features/as-library.feature +29 -0
- data/features/cassettes/cucumber_tags/create-redirect.yml +384 -0
- data/features/cassettes/cucumber_tags/new-and-changed-files.yml +303 -0
- data/features/cassettes/cucumber_tags/new-files-for-sydney.yml +211 -0
- data/features/cassettes/cucumber_tags/new-files.yml +355 -0
- data/features/cassettes/cucumber_tags/no-new-or-changed-files.yml +359 -0
- data/features/cassettes/cucumber_tags/one-file-to-delete.yml +390 -0
- data/features/cassettes/cucumber_tags/only-changed-files.yml +411 -0
- data/features/cassettes/cucumber_tags/s3-and-cloudfront-when-updating-a-file.yml +435 -0
- data/features/cassettes/cucumber_tags/s3-and-cloudfront.yml +290 -0
- data/features/cloudfront.feature +35 -0
- data/features/delete.feature +18 -0
- data/features/instructions-for-new-user.feature +94 -0
- data/features/redirects.feature +16 -0
- data/features/step_definitions/steps.rb +67 -0
- data/features/support/env.rb +26 -0
- data/features/support/test_site_dirs/cdn-powered.blog.fi/_site/css/styles.css +3 -0
- data/features/support/test_site_dirs/cdn-powered.blog.fi/_site/index.html +5 -0
- data/features/support/test_site_dirs/cdn-powered.blog.fi/s3_website.yml +4 -0
- data/features/support/test_site_dirs/cdn-powered.with-one-change.blog.fi/_site/css/styles.css +3 -0
- data/features/support/test_site_dirs/cdn-powered.with-one-change.blog.fi/_site/index.html +10 -0
- data/features/support/test_site_dirs/cdn-powered.with-one-change.blog.fi/s3_website.yml +4 -0
- data/features/support/test_site_dirs/create-redirects/_site/.gitkeep +0 -0
- data/features/support/test_site_dirs/create-redirects/s3_website.yml +6 -0
- data/features/support/test_site_dirs/index-and-assets.blog.fi/_site/assets/picture.gif +0 -0
- data/features/support/test_site_dirs/index-and-assets.blog.fi/_site/css/styles.css +3 -0
- data/features/support/test_site_dirs/index-and-assets.blog.fi/_site/index.html +5 -0
- data/features/support/test_site_dirs/index-and-assets.blog.fi/s3_website.yml +3 -0
- data/features/support/test_site_dirs/my.blog.com/_site/css/styles.css +3 -0
- data/features/support/test_site_dirs/my.blog.com/_site/index.html +5 -0
- data/features/support/test_site_dirs/my.blog.com/s3_website.yml +3 -0
- data/features/support/test_site_dirs/my.sydney.blog.au/_site/css/styles.css +3 -0
- data/features/support/test_site_dirs/my.sydney.blog.au/_site/index.html +5 -0
- data/features/support/test_site_dirs/my.sydney.blog.au/s3_website.yml +4 -0
- data/features/support/test_site_dirs/new-and-changed-files.com/_site/css/styles.css +4 -0
- data/features/support/test_site_dirs/new-and-changed-files.com/_site/index.html +8 -0
- data/features/support/test_site_dirs/new-and-changed-files.com/s3_website.yml +3 -0
- data/features/support/test_site_dirs/no-new-or-changed-files.com/_site/css/styles.css +3 -0
- data/features/support/test_site_dirs/no-new-or-changed-files.com/_site/index.html +5 -0
- data/features/support/test_site_dirs/no-new-or-changed-files.com/s3_website.yml +3 -0
- data/features/support/test_site_dirs/only-changed-files.com/_site/css/styles.css +3 -0
- data/features/support/test_site_dirs/only-changed-files.com/_site/index.html +9 -0
- data/features/support/test_site_dirs/only-changed-files.com/s3_website.yml +3 -0
- data/features/support/test_site_dirs/site.with.css-maxage.com/_site/css/styles.css +3 -0
- data/features/support/test_site_dirs/site.with.css-maxage.com/_site/index.html +5 -0
- data/features/support/test_site_dirs/site.with.css-maxage.com/s3_website.yml +5 -0
- data/features/support/test_site_dirs/site.with.gzipped-and-max-aged-content.com/_site/css/styles.css +3 -0
- data/features/support/test_site_dirs/site.with.gzipped-and-max-aged-content.com/_site/index.html +5 -0
- data/features/support/test_site_dirs/site.with.gzipped-and-max-aged-content.com/s3_website.yml +5 -0
- data/features/support/test_site_dirs/site.with.gzipped-html.com/_site/css/styles.css +3 -0
- data/features/support/test_site_dirs/site.with.gzipped-html.com/_site/index.html +5 -0
- data/features/support/test_site_dirs/site.with.gzipped-html.com/s3_website.yml +5 -0
- data/features/support/test_site_dirs/site.with.maxage.com/_site/css/styles.css +3 -0
- data/features/support/test_site_dirs/site.with.maxage.com/_site/index.html +5 -0
- data/features/support/test_site_dirs/site.with.maxage.com/s3_website.yml +4 -0
- data/features/support/test_site_dirs/unpublish-a-post.com/_site/css/styles.css +3 -0
- data/features/support/test_site_dirs/unpublish-a-post.com/s3_website.yml +3 -0
- data/features/support/vcr.rb +18 -0
- data/features/sync.feature +80 -0
- data/features/website-performance.feature +57 -0
- data/lib/cloudfront/invalidator.rb +22 -0
- data/lib/s3_website.rb +20 -0
- data/lib/s3_website/config_loader.rb +56 -0
- data/lib/s3_website/diff_helper.rb +21 -0
- data/lib/s3_website/endpoint.rb +30 -0
- data/lib/s3_website/errors.rb +28 -0
- data/lib/s3_website/keyboard.rb +27 -0
- data/lib/s3_website/parallelism.rb +18 -0
- data/lib/s3_website/retry.rb +19 -0
- data/lib/s3_website/tasks.rb +42 -0
- data/lib/s3_website/upload.rb +103 -0
- data/lib/s3_website/uploader.rb +160 -0
- data/s3-website.gemspec +39 -0
- data/spec/lib/config_loader_spec.rb +20 -0
- data/spec/lib/endpoint_spec.rb +27 -0
- data/spec/lib/keyboard_spec.rb +59 -0
- data/spec/lib/parallelism_spec.rb +43 -0
- data/spec/lib/retry_spec.rb +34 -0
- data/spec/lib/upload_spec.rb +205 -0
- data/spec/lib/uploader_spec.rb +30 -0
- data/spec/sample_files/hyde_site/_site/.vimrc +5 -0
- data/spec/sample_files/hyde_site/_site/css/styles.css +3 -0
- data/spec/sample_files/hyde_site/_site/index.html +1 -0
- data/spec/sample_files/hyde_site/s3_website.yml +3 -0
- data/spec/sample_files/tokyo_site/_site/.vimrc +5 -0
- data/spec/sample_files/tokyo_site/_site/css/styles.css +3 -0
- data/spec/sample_files/tokyo_site/_site/index.html +1 -0
- data/spec/sample_files/tokyo_site/s3_website.yml +4 -0
- data/spec/spec_helper.rb +1 -0
- metadata +416 -0
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
require 'vcr'
|
|
2
|
+
|
|
3
|
+
VCR.configure do |c|
|
|
4
|
+
c.hook_into :webmock
|
|
5
|
+
c.cassette_library_dir = 'features/cassettes'
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
VCR.cucumber_tags do |t|
|
|
9
|
+
t.tag '@new-files'
|
|
10
|
+
t.tag '@new-files-for-sydney'
|
|
11
|
+
t.tag '@new-and-changed-files'
|
|
12
|
+
t.tag '@only-changed-files'
|
|
13
|
+
t.tag '@no-new-or-changed-files'
|
|
14
|
+
t.tag '@s3-and-cloudfront'
|
|
15
|
+
t.tag '@s3-and-cloudfront-when-updating-a-file'
|
|
16
|
+
t.tag '@one-file-to-delete'
|
|
17
|
+
t.tag '@create-redirect'
|
|
18
|
+
end
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
Feature: upload S3 website to S3
|
|
2
|
+
|
|
3
|
+
In order to push my website to S3
|
|
4
|
+
As a blogger
|
|
5
|
+
I want to run s3_website and say OMG it just worked!
|
|
6
|
+
|
|
7
|
+
@new-files
|
|
8
|
+
Scenario: Push a new S3 website to S3
|
|
9
|
+
When my S3 website is in "features/support/test_site_dirs/my.blog.com"
|
|
10
|
+
Then s3_website will push my blog to S3
|
|
11
|
+
And the output should contain
|
|
12
|
+
"""
|
|
13
|
+
Deploying _site/* to s3-website-test.net
|
|
14
|
+
Uploading 2 new file(s)
|
|
15
|
+
"""
|
|
16
|
+
And the output should contain
|
|
17
|
+
"""
|
|
18
|
+
Upload css/styles.css: Success!
|
|
19
|
+
"""
|
|
20
|
+
And the output should contain
|
|
21
|
+
"""
|
|
22
|
+
Upload index.html: Success!
|
|
23
|
+
"""
|
|
24
|
+
|
|
25
|
+
@new-files-for-sydney
|
|
26
|
+
Scenario: Push a new S3 website to an S3 bucket in Sydney
|
|
27
|
+
When my S3 website is in "features/support/test_site_dirs/my.sydney.blog.au"
|
|
28
|
+
Then s3_website will push my blog to S3
|
|
29
|
+
And the output should contain
|
|
30
|
+
"""
|
|
31
|
+
Done! Go visit: http://s3-website-test.net.s3-website-ap-southeast-2.amazonaws.com/index.html
|
|
32
|
+
"""
|
|
33
|
+
|
|
34
|
+
@new-and-changed-files
|
|
35
|
+
Scenario: Upload a new blog post and change an old post
|
|
36
|
+
When my S3 website is in "features/support/test_site_dirs/new-and-changed-files.com"
|
|
37
|
+
Then s3_website will push my blog to S3
|
|
38
|
+
And the output should contain
|
|
39
|
+
"""
|
|
40
|
+
Deploying _site/* to s3-website-test.net
|
|
41
|
+
Uploading 1 new and 1 changed file(s)
|
|
42
|
+
"""
|
|
43
|
+
And the output should contain
|
|
44
|
+
"""
|
|
45
|
+
Upload css/styles.css: Success!
|
|
46
|
+
"""
|
|
47
|
+
And the output should contain
|
|
48
|
+
"""
|
|
49
|
+
Upload index.html: Success!
|
|
50
|
+
"""
|
|
51
|
+
And the output should contain
|
|
52
|
+
"""
|
|
53
|
+
Done! Go visit: http://s3-website-test.net.s3-website-us-east-1.amazonaws.com/index.html
|
|
54
|
+
|
|
55
|
+
"""
|
|
56
|
+
|
|
57
|
+
@only-changed-files
|
|
58
|
+
Scenario: Update an existing blog post
|
|
59
|
+
When my S3 website is in "features/support/test_site_dirs/only-changed-files.com"
|
|
60
|
+
Then s3_website will push my blog to S3
|
|
61
|
+
And the output should equal
|
|
62
|
+
"""
|
|
63
|
+
Deploying _site/* to s3-website-test.net
|
|
64
|
+
Uploading 1 changed file(s)
|
|
65
|
+
Upload index.html: Success!
|
|
66
|
+
Done! Go visit: http://s3-website-test.net.s3-website-us-east-1.amazonaws.com/index.html
|
|
67
|
+
|
|
68
|
+
"""
|
|
69
|
+
|
|
70
|
+
@no-new-or-changed-files
|
|
71
|
+
Scenario: The user runs s3_website even though he doesn't have new or changed posts
|
|
72
|
+
When my S3 website is in "features/support/test_site_dirs/no-new-or-changed-files.com"
|
|
73
|
+
Then s3_website will push my blog to S3
|
|
74
|
+
And the output should equal
|
|
75
|
+
"""
|
|
76
|
+
Deploying _site/* to s3-website-test.net
|
|
77
|
+
No new or changed files to upload
|
|
78
|
+
Done! Go visit: http://s3-website-test.net.s3-website-us-east-1.amazonaws.com/index.html
|
|
79
|
+
|
|
80
|
+
"""
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
Feature: improve response times of your S3 website website
|
|
2
|
+
|
|
3
|
+
As a blogger
|
|
4
|
+
I want to benefit from HTTP performance optimisations
|
|
5
|
+
So that my readers would not have to wait long for my website to load
|
|
6
|
+
|
|
7
|
+
@new-files
|
|
8
|
+
Scenario: Set Cache-Control: max-age for all uploaded files
|
|
9
|
+
When my S3 website is in "features/support/test_site_dirs/site.with.maxage.com"
|
|
10
|
+
Then s3_website will push my blog to S3
|
|
11
|
+
And the output should contain
|
|
12
|
+
"""
|
|
13
|
+
Upload css/styles.css [max-age=120]: Success!
|
|
14
|
+
"""
|
|
15
|
+
And the output should contain
|
|
16
|
+
"""
|
|
17
|
+
Upload index.html [max-age=120]: Success!
|
|
18
|
+
"""
|
|
19
|
+
|
|
20
|
+
@new-files
|
|
21
|
+
Scenario: Set Cache-Control: max-age for CSS files only
|
|
22
|
+
When my S3 website is in "features/support/test_site_dirs/site.with.css-maxage.com"
|
|
23
|
+
Then s3_website will push my blog to S3
|
|
24
|
+
And the output should contain
|
|
25
|
+
"""
|
|
26
|
+
Upload css/styles.css [max-age=100]: Success!
|
|
27
|
+
"""
|
|
28
|
+
And the output should contain
|
|
29
|
+
"""
|
|
30
|
+
Upload index.html [max-age=0]: Success!
|
|
31
|
+
"""
|
|
32
|
+
|
|
33
|
+
@new-files
|
|
34
|
+
Scenario: Set Content-Encoding: gzip HTTP header for HTML files
|
|
35
|
+
When my S3 website is in "features/support/test_site_dirs/site.with.gzipped-html.com"
|
|
36
|
+
Then s3_website will push my blog to S3
|
|
37
|
+
And the output should contain
|
|
38
|
+
"""
|
|
39
|
+
Upload css/styles.css: Success!
|
|
40
|
+
"""
|
|
41
|
+
And the output should contain
|
|
42
|
+
"""
|
|
43
|
+
Upload index.html [gzipped]: Success!
|
|
44
|
+
"""
|
|
45
|
+
|
|
46
|
+
@new-files
|
|
47
|
+
Scenario: Set both the Content-Encoding: gzip and Cache-Control: max-age headers
|
|
48
|
+
When my S3 website is in "features/support/test_site_dirs/site.with.gzipped-and-max-aged-content.com"
|
|
49
|
+
Then s3_website will push my blog to S3
|
|
50
|
+
And the output should contain
|
|
51
|
+
"""
|
|
52
|
+
Upload css/styles.css [gzipped] [max-age=300]: Success!
|
|
53
|
+
"""
|
|
54
|
+
And the output should contain
|
|
55
|
+
"""
|
|
56
|
+
Upload index.html [gzipped] [max-age=300]: Success!
|
|
57
|
+
"""
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
module S3Website
|
|
2
|
+
module Cloudfront
|
|
3
|
+
class Invalidator
|
|
4
|
+
def self.invalidate(config, changed_files)
|
|
5
|
+
aws_key = config['s3_id']
|
|
6
|
+
aws_secret = config['s3_secret']
|
|
7
|
+
s3_bucket_name = config['s3_bucket']
|
|
8
|
+
cloudfront_distribution_id = config['cloudfront_distribution_id']
|
|
9
|
+
s3 = AWS::S3.new(
|
|
10
|
+
:access_key_id => aws_key,
|
|
11
|
+
:secret_access_key => aws_secret)
|
|
12
|
+
s3_object_keys = changed_files
|
|
13
|
+
s3_object_keys << ""
|
|
14
|
+
report = SimpleCloudfrontInvalidator::CloudfrontClient.new(
|
|
15
|
+
aws_key, aws_secret, cloudfront_distribution_id).invalidate(
|
|
16
|
+
s3_object_keys)
|
|
17
|
+
puts report[:text_report]
|
|
18
|
+
report[:invalidated_items_count]
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
data/lib/s3_website.rb
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
require 'rubygems'
|
|
2
|
+
require 'yaml'
|
|
3
|
+
require 'erubis'
|
|
4
|
+
require 'aws-sdk'
|
|
5
|
+
require 'simple-cloudfront-invalidator'
|
|
6
|
+
require 'filey-diff'
|
|
7
|
+
require 'mime/types'
|
|
8
|
+
require 'thor'
|
|
9
|
+
|
|
10
|
+
module S3Website
|
|
11
|
+
DEFAULT_GZIP_EXTENSIONS = %w(.html .css .js .svg .txt)
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
%w{errors upload uploader tasks config_loader retry keyboard diff_helper endpoint parallelism}.each do |file|
|
|
15
|
+
require File.dirname(__FILE__) + "/s3_website/#{file}"
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
%w{invalidator}.each do |file|
|
|
19
|
+
require File.dirname(__FILE__) + "/cloudfront/#{file}"
|
|
20
|
+
end
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
module S3Website
|
|
2
|
+
class ConfigLoader
|
|
3
|
+
CONFIGURATION_FILE = 's3_website.yml'
|
|
4
|
+
CONFIGURATION_FILE_TEMPLATE = <<-EOF
|
|
5
|
+
s3_id: YOUR_AWS_S3_ACCESS_KEY_ID
|
|
6
|
+
s3_secret: YOUR_AWS_S3_SECRET_ACCESS_KEY
|
|
7
|
+
s3_bucket: your.blog.bucket.com
|
|
8
|
+
EOF
|
|
9
|
+
|
|
10
|
+
def self.check_project(site_dir)
|
|
11
|
+
raise NotAJekyllProjectError unless File.directory?(site_dir)
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
# Raise NoConfigurationFileError if the configuration file does not exists
|
|
15
|
+
def self.check_s3_configuration(site_dir)
|
|
16
|
+
unless File.exists?(get_configuration_file(site_dir))
|
|
17
|
+
create_template_configuration_file site_dir
|
|
18
|
+
raise NoConfigurationFileError
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
private
|
|
23
|
+
|
|
24
|
+
# Load configuration from s3_website.yml
|
|
25
|
+
# Raise MalformedConfigurationFileError if the configuration file does not contain the keys we expect
|
|
26
|
+
def self.load_configuration(site_dir)
|
|
27
|
+
config = load_yaml_file_and_validate site_dir
|
|
28
|
+
return config
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def self.create_template_configuration_file(site_dir)
|
|
32
|
+
File.open(get_configuration_file(site_dir), 'w') { |f|
|
|
33
|
+
f.write(CONFIGURATION_FILE_TEMPLATE)
|
|
34
|
+
}
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def self.load_yaml_file_and_validate(site_dir)
|
|
38
|
+
begin
|
|
39
|
+
config = YAML.load(Erubis::Eruby.new(File.read(get_configuration_file(site_dir))).result)
|
|
40
|
+
rescue Exception
|
|
41
|
+
raise MalformedConfigurationFileError
|
|
42
|
+
end
|
|
43
|
+
raise MalformedConfigurationFileError unless config
|
|
44
|
+
raise MalformedConfigurationFileError if
|
|
45
|
+
['s3_bucket'].any? { |key|
|
|
46
|
+
mandatory_config_value = config[key]
|
|
47
|
+
mandatory_config_value.nil? || mandatory_config_value == ''
|
|
48
|
+
}
|
|
49
|
+
config
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def self.get_configuration_file(site_dir)
|
|
53
|
+
"#{site_dir}/../#{CONFIGURATION_FILE}"
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
module S3Website
|
|
2
|
+
class DiffHelper
|
|
3
|
+
def self.resolve_files_to_upload(s3_bucket, site_dir)
|
|
4
|
+
s3_data_source = Filey::DataSources::AwsSdkS3.new(s3_bucket)
|
|
5
|
+
fs_data_source = Filey::DataSources::FileSystem.new(site_dir)
|
|
6
|
+
changed_local_files =
|
|
7
|
+
Filey::Comparison.list_changed(fs_data_source, s3_data_source)
|
|
8
|
+
new_local_files =
|
|
9
|
+
Filey::Comparison.list_missing(fs_data_source, s3_data_source)
|
|
10
|
+
[ normalise(changed_local_files), normalise(new_local_files) ]
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
private
|
|
14
|
+
|
|
15
|
+
def self.normalise(fileys)
|
|
16
|
+
fileys.map { |filey|
|
|
17
|
+
filey.full_path.sub(/\.\//, '')
|
|
18
|
+
}
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
module S3Website
|
|
2
|
+
class Endpoint
|
|
3
|
+
DEFAULT_LOCATION_CONSTRAINT = 'us-east-1'
|
|
4
|
+
attr_reader :region, :location_constraint, :hostname, :website_hostname
|
|
5
|
+
|
|
6
|
+
def initialize(location_constraint=nil)
|
|
7
|
+
location_constraint = DEFAULT_LOCATION_CONSTRAINT if location_constraint.nil?
|
|
8
|
+
raise "Invalid S3 location constraint #{location_constraint}" unless
|
|
9
|
+
location_constraints.has_key?location_constraint
|
|
10
|
+
@region = location_constraints.fetch(location_constraint)[:region]
|
|
11
|
+
@hostname = location_constraints.fetch(location_constraint)[:endpoint]
|
|
12
|
+
@website_hostname = location_constraints.fetch(location_constraint)[:website_hostname]
|
|
13
|
+
@location_constraint = location_constraint
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
# http://docs.amazonwebservices.com/general/latest/gr/rande.html#s3_region
|
|
17
|
+
def location_constraints
|
|
18
|
+
{
|
|
19
|
+
'us-east-1' => { :region => 'US Standard', :website_hostname => 's3-website-us-east-1.amazonaws.com', :endpoint => 's3.amazonaws.com' },
|
|
20
|
+
'us-west-2' => { :region => 'US West (Oregon)', :website_hostname => 's3-website-us-west-2.amazonaws.com', :endpoint => 's3-us-west-2.amazonaws.com' },
|
|
21
|
+
'us-west-1' => { :region => 'US West (Northern California)', :website_hostname => 's3-website-us-west-1.amazonaws.com', :endpoint => 's3-us-west-1.amazonaws.com' },
|
|
22
|
+
'EU' => { :region => 'EU (Ireland)', :website_hostname => 's3-website-eu-west-1.amazonaws.com', :endpoint => 's3-eu-west-1.amazonaws.com' },
|
|
23
|
+
'ap-southeast-1' => { :region => 'Asia Pacific (Singapore)', :website_hostname => 's3-website-ap-southeast-1.amazonaws.com', :endpoint => 's3-ap-southeast-1.amazonaws.com' },
|
|
24
|
+
'ap-southeast-2' => { :region => 'Asia Pacific (Sydney)', :website_hostname => 's3-website-ap-southeast-2.amazonaws.com', :endpoint => 's3-ap-southeast-2.amazonaws.com' },
|
|
25
|
+
'ap-northeast-1' => { :region => 'Asia Pacific (Tokyo)', :website_hostname => 's3-website-ap-northeast-1.amazonaws.com', :endpoint => 's3-ap-northeast-1.amazonaws.com' },
|
|
26
|
+
'sa-east-1' => { :region => 'South America (Sao Paulo)', :website_hostname => 's3-website-sa-east-1.amazonaws.com', :endpoint => 's3-sa-east-1.amazonaws.com' }
|
|
27
|
+
}
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
module S3Website
|
|
2
|
+
class S3WebsiteError < StandardError
|
|
3
|
+
end
|
|
4
|
+
|
|
5
|
+
class NotAJekyllProjectError < S3WebsiteError
|
|
6
|
+
def initialize(message = "I can't find any directory called _site. Are you in the right directory?")
|
|
7
|
+
super(message)
|
|
8
|
+
end
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
class NoConfigurationFileError < S3WebsiteError
|
|
12
|
+
def initialize(message = "I've just generated a file called s3_website.yml. Go put your details in it!")
|
|
13
|
+
super(message)
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
class MalformedConfigurationFileError < S3WebsiteError
|
|
18
|
+
def initialize(message = "I can't parse the file s3_website.yml. It should look like this:\n#{ConfigLoader::CONFIGURATION_FILE_TEMPLATE}")
|
|
19
|
+
super(message)
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
class RetryAttemptsExhaustedError < S3WebsiteError
|
|
24
|
+
def initialize(message = "Operation failed even though we tried to recover from it")
|
|
25
|
+
super(message)
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
module S3Website
|
|
2
|
+
class Keyboard
|
|
3
|
+
def self.if_user_confirms_delete(to_delete, standard_input=STDIN)
|
|
4
|
+
delete_all = false
|
|
5
|
+
keep_all = false
|
|
6
|
+
confirmed_deletes = to_delete.map do |f|
|
|
7
|
+
delete = false
|
|
8
|
+
keep = false
|
|
9
|
+
until delete || delete_all || keep || keep_all
|
|
10
|
+
puts "#{f} is on S3 but not in your _site directory anymore. Do you want to [d]elete, [D]elete all, [k]eep, [K]eep all?"
|
|
11
|
+
case standard_input.gets.chomp
|
|
12
|
+
when 'd' then delete = true
|
|
13
|
+
when 'D' then delete_all = true
|
|
14
|
+
when 'k' then keep = true
|
|
15
|
+
when 'K' then keep_all = true
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
if (delete_all || delete) && !(keep_all || keep)
|
|
19
|
+
f
|
|
20
|
+
end
|
|
21
|
+
end.select { |f| f }
|
|
22
|
+
Parallelism.each_in_parallel_or_sequentially(confirmed_deletes) { |f|
|
|
23
|
+
yield f
|
|
24
|
+
}
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|