vacation 0.1.2
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.
- data/.gitignore +12 -0
- data/.rvmrc +1 -0
- data/Gemfile +9 -0
- data/Gemfile.lock +51 -0
- data/README.md +66 -0
- data/Rakefile +21 -0
- data/bin/vacation +70 -0
- data/lib/tasks/deploy.rake +16 -0
- data/lib/vacation.rb +10 -0
- data/lib/vacation/jekyll.rb +29 -0
- data/lib/vacation/s3.rb +76 -0
- data/spec/spec_helper.rb +20 -0
- data/spec/support/jekyll/_layouts/blog.html +13 -0
- data/spec/support/jekyll/_layouts/default.html +11 -0
- data/spec/support/jekyll/_posts/2011-03-04-i-am-wearing-ramen.markdown +8 -0
- data/spec/support/jekyll/_posts/2011-03-05-about-last-night.markdown +8 -0
- data/spec/support/jekyll/images/geocities.png +0 -0
- data/spec/support/jekyll/index.html +13 -0
- data/spec/support/jekyll/stylesheets/reset.css +260 -0
- data/spec/unit/jekyll_spec.rb +50 -0
- data/spec/unit/s3_spec.rb +89 -0
- data/vacation.gemspec +27 -0
- metadata +132 -0
data/.gitignore
ADDED
data/.rvmrc
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
rvm use --create ruby-1.8.7@vacation
|
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
GEM
|
|
2
|
+
remote: http://rubygems.org/
|
|
3
|
+
specs:
|
|
4
|
+
builder (3.0.0)
|
|
5
|
+
classifier (1.3.3)
|
|
6
|
+
fast-stemmer (>= 1.0.0)
|
|
7
|
+
diff-lcs (1.1.2)
|
|
8
|
+
directory_watcher (1.3.2)
|
|
9
|
+
excon (0.5.6)
|
|
10
|
+
fast-stemmer (1.0.0)
|
|
11
|
+
fog (0.6.0)
|
|
12
|
+
builder
|
|
13
|
+
excon (>= 0.5.5)
|
|
14
|
+
formatador (>= 0.0.16)
|
|
15
|
+
json
|
|
16
|
+
mime-types
|
|
17
|
+
net-ssh (>= 2.0.23)
|
|
18
|
+
nokogiri (>= 1.4.4)
|
|
19
|
+
ruby-hmac
|
|
20
|
+
formatador (0.0.16)
|
|
21
|
+
jekyll (0.10.0)
|
|
22
|
+
classifier (>= 1.3.1)
|
|
23
|
+
directory_watcher (>= 1.1.1)
|
|
24
|
+
liquid (>= 1.9.0)
|
|
25
|
+
maruku (>= 0.5.9)
|
|
26
|
+
json (1.5.1)
|
|
27
|
+
liquid (2.2.2)
|
|
28
|
+
maruku (0.6.0)
|
|
29
|
+
syntax (>= 1.0.0)
|
|
30
|
+
mime-types (1.16)
|
|
31
|
+
net-ssh (2.1.3)
|
|
32
|
+
nokogiri (1.4.4)
|
|
33
|
+
rspec (2.5.0)
|
|
34
|
+
rspec-core (~> 2.5.0)
|
|
35
|
+
rspec-expectations (~> 2.5.0)
|
|
36
|
+
rspec-mocks (~> 2.5.0)
|
|
37
|
+
rspec-core (2.5.1)
|
|
38
|
+
rspec-expectations (2.5.0)
|
|
39
|
+
diff-lcs (~> 1.1.2)
|
|
40
|
+
rspec-mocks (2.5.0)
|
|
41
|
+
ruby-hmac (0.4.0)
|
|
42
|
+
syntax (1.0.0)
|
|
43
|
+
|
|
44
|
+
PLATFORMS
|
|
45
|
+
ruby
|
|
46
|
+
|
|
47
|
+
DEPENDENCIES
|
|
48
|
+
fog
|
|
49
|
+
jekyll
|
|
50
|
+
nokogiri
|
|
51
|
+
rspec
|
data/README.md
ADDED
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
# Vacation
|
|
2
|
+
|
|
3
|
+
Vacation lets you host Jekyll sites on S3. It is a gem. You add it via `gem install vacation`.
|
|
4
|
+
|
|
5
|
+
Then you take a vacation.
|
|
6
|
+
|
|
7
|
+
## Creating a Jekyll site
|
|
8
|
+
|
|
9
|
+
Make site.
|
|
10
|
+
|
|
11
|
+
## Identify your AWS access credentials
|
|
12
|
+
|
|
13
|
+
These should look something like the ones you get from Amazon. Not Rackspace.
|
|
14
|
+
|
|
15
|
+
Full `~/.fog` support will land in a bit.
|
|
16
|
+
|
|
17
|
+
Then identify the name of the bucket you want to hork things into.
|
|
18
|
+
|
|
19
|
+
## Backups
|
|
20
|
+
|
|
21
|
+
Vacation destructively overwrites the contents of the target bucket for now.
|
|
22
|
+
Previous content is (optionally, if you use the `vacation` executable) backed
|
|
23
|
+
up to a secondary bucket.
|
|
24
|
+
|
|
25
|
+
If you deploy to `bucket_name` bucket is called `bucket_name`-vacation-backup.
|
|
26
|
+
|
|
27
|
+
## Deploying
|
|
28
|
+
|
|
29
|
+
Vacation gets invoked via a command line executable script, also called `vacation`!
|
|
30
|
+
|
|
31
|
+
Vacation is a way of deploying Jekyll sites to S3.
|
|
32
|
+
|
|
33
|
+
Basic Command Line Usage:
|
|
34
|
+
vacation <bucket name>
|
|
35
|
+
vacation <bucket name> <path to source>
|
|
36
|
+
|
|
37
|
+
Your AWS information can be read from the environment as
|
|
38
|
+
AWS_ID and AWS_KEY or using the following variables:
|
|
39
|
+
|
|
40
|
+
--[no-]backup Back up the contents of the destination bucket
|
|
41
|
+
--id [ID] Your AWS access key id
|
|
42
|
+
--key [KEY] Your AWS secret key
|
|
43
|
+
--version Display current version
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
## MIT License
|
|
47
|
+
|
|
48
|
+
Copyright (c) 2011 Eric "Doc" Ritezel
|
|
49
|
+
|
|
50
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
51
|
+
of this software and associated documentation files (the 'Software'), to deal
|
|
52
|
+
in the Software without restriction, including without limitation the rights
|
|
53
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
54
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
55
|
+
furnished to do so, subject to the following conditions:
|
|
56
|
+
|
|
57
|
+
The above copyright notice and this permission notice shall be included in all
|
|
58
|
+
copies or substantial portions of the Software.
|
|
59
|
+
|
|
60
|
+
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
61
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
62
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
63
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
64
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
65
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
66
|
+
SOFTWARE.
|
data/Rakefile
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
require 'rspec/core/rake_task'
|
|
2
|
+
import 'lib/tasks/deploy.rake'
|
|
3
|
+
|
|
4
|
+
desc "Run all examples"
|
|
5
|
+
RSpec::Core::RakeTask.new(:spec) do |t|
|
|
6
|
+
t.rspec_path = 'rspec'
|
|
7
|
+
t.rspec_opts = %w[--color]
|
|
8
|
+
t.verbose = false
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
namespace :hammer do
|
|
12
|
+
require 'vacation'
|
|
13
|
+
desc "Fire a given S3 bucket out of a cannon into the sun"
|
|
14
|
+
task :drop, :aws_access_id, :aws_secret_key, :s3_bucket do |t, args|
|
|
15
|
+
s3 = Vacation::S3.new(args[:aws_access_id], args[:aws_secret_key], args[:s3_bucket])
|
|
16
|
+
s3.strip_bucket
|
|
17
|
+
s3.bucket.destroy
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
task :default => [:spec]
|
data/bin/vacation
ADDED
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
|
|
3
|
+
$:.unshift File.expand_path('../../lib', __FILE__)
|
|
4
|
+
|
|
5
|
+
help = <<HELP
|
|
6
|
+
Vacation is a way of deploying Jekyll sites to S3.
|
|
7
|
+
|
|
8
|
+
Basic Command Line Usage:
|
|
9
|
+
vacation <bucket name>
|
|
10
|
+
vacation <bucket name> <path to source>
|
|
11
|
+
|
|
12
|
+
Your AWS information can be read from the environment as
|
|
13
|
+
AWS_ID and AWS_KEY or using the following variables:
|
|
14
|
+
|
|
15
|
+
HELP
|
|
16
|
+
|
|
17
|
+
require 'optparse'
|
|
18
|
+
require 'vacation'
|
|
19
|
+
|
|
20
|
+
options = { 'backup' => true }
|
|
21
|
+
opts = OptionParser.new do |opts|
|
|
22
|
+
opts.banner = help
|
|
23
|
+
|
|
24
|
+
opts.on("--[no-]backup", "Back up the contents of the destination bucket") do |backup|
|
|
25
|
+
options['backup'] = backup
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
opts.on("--id [ID]", "Your AWS access key id") do |id|
|
|
29
|
+
options['access_id'] = id
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
opts.on("--key [KEY]", "Your AWS secret key") do |secret_key|
|
|
33
|
+
options['secret_key'] = secret_key
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
opts.on("--version", "Display current version") do
|
|
37
|
+
puts "Vacation " + Vacation::VERSION
|
|
38
|
+
exit 0
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
opts.parse!
|
|
43
|
+
|
|
44
|
+
# Get source and destintation from command line
|
|
45
|
+
case ARGV.size
|
|
46
|
+
when 1
|
|
47
|
+
options['bucket'] = ARGV[0]
|
|
48
|
+
when 2
|
|
49
|
+
options['bucket'] = ARGV[0]
|
|
50
|
+
options['source'] = ARGV[1]
|
|
51
|
+
else
|
|
52
|
+
puts "Invalid options. Run `vacation --help` for assistance."
|
|
53
|
+
exit(1)
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
options['access_id'] ||= ENV['AWS_ID']
|
|
57
|
+
options['secret_key'] ||= ENV['AWS_KEY']
|
|
58
|
+
|
|
59
|
+
unless options['access_id'] && options['secret_key']
|
|
60
|
+
puts "AWS credentials not found. Run `vacation --help` for assistance."
|
|
61
|
+
exit(1)
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
Dir.mktmpdir do |temp_dir|
|
|
65
|
+
jekyll = Vacation::Jekyll.new(options['source'])
|
|
66
|
+
jekyll.compile_to(temp_dir)
|
|
67
|
+
|
|
68
|
+
s3 = Vacation::S3.new(options['access_id'], options['secret_key'], options['bucket'])
|
|
69
|
+
s3.deploy_to_bucket(temp_dir, :backup => options['backup'])
|
|
70
|
+
end
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
require File.expand_path('../../vacation', __FILE__)
|
|
2
|
+
|
|
3
|
+
namespace :vacation do
|
|
4
|
+
require 'tmpdir'
|
|
5
|
+
|
|
6
|
+
desc 'Compile and deploy a Jekyll directory to S3'
|
|
7
|
+
task :deploy, :aws_access_id, :aws_secret_key, :s3_bucket, :target do |t, args|
|
|
8
|
+
Dir.mktmpdir do |temp_dir|
|
|
9
|
+
jekyll = Vacation::Jekyll.new(args[:target])
|
|
10
|
+
jekyll.compile_to(temp_dir)
|
|
11
|
+
|
|
12
|
+
s3 = Vacation::S3.new(args[:aws_access_id], args[:aws_secret_key], args[:s3_bucket])
|
|
13
|
+
s3.deploy_to_bucket(temp_dir)
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
data/lib/vacation.rb
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
require 'jekyll'
|
|
2
|
+
|
|
3
|
+
module Vacation
|
|
4
|
+
class Jekyll
|
|
5
|
+
attr_accessor :source
|
|
6
|
+
|
|
7
|
+
def initialize(source)
|
|
8
|
+
@source = source
|
|
9
|
+
throw StandardError unless File::readable_real?(source) and File::directory?(source)
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def config_hash
|
|
13
|
+
config_file = File.join(source, '_config.yml')
|
|
14
|
+
begin
|
|
15
|
+
config = YAML.load_file(config_file)
|
|
16
|
+
rescue => err
|
|
17
|
+
config = {}
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
::Jekyll::DEFAULTS.deep_merge(config).deep_merge('source' => source)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def compile_to(destination, options = {})
|
|
24
|
+
options = config_hash.deep_merge('destination' => destination).deep_merge(options)
|
|
25
|
+
site = ::Jekyll::Site.new options
|
|
26
|
+
site.process
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
data/lib/vacation/s3.rb
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
require 'fog'
|
|
2
|
+
require 'tmpdir'
|
|
3
|
+
|
|
4
|
+
module Vacation
|
|
5
|
+
class S3
|
|
6
|
+
attr_reader :access_key_id, :secret_access_key, :storage, :bucket_name
|
|
7
|
+
|
|
8
|
+
def initialize(id, key, bucket)
|
|
9
|
+
@access_key_id = id
|
|
10
|
+
@secret_access_key = key
|
|
11
|
+
@bucket_name = bucket
|
|
12
|
+
@storage = Fog::Storage.new(
|
|
13
|
+
:provider => 'AWS',
|
|
14
|
+
:aws_access_key_id => access_key_id,
|
|
15
|
+
:aws_secret_access_key => secret_access_key
|
|
16
|
+
)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def bucket
|
|
20
|
+
@_bucket ||= storage.directories.create(:key => bucket_name, :privacy => 'public-read')
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def backup_bucket
|
|
24
|
+
@_backup_bucket ||= storage.directories.create(:key => "#{bucket_name}-vacation-backup",
|
|
25
|
+
:privacy => 'private')
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def strip_bucket
|
|
29
|
+
bucket.files.reload.each { |file| file.destroy }
|
|
30
|
+
bucket.files.reload
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def download_from_bucket(path)
|
|
34
|
+
return unless storage.directories.get(bucket_name)
|
|
35
|
+
FileUtils.mkdir_p(path)
|
|
36
|
+
|
|
37
|
+
bucket.files.each do |file|
|
|
38
|
+
location = File.join(path, file.key)
|
|
39
|
+
FileUtils.mkdir_p(File.dirname(location))
|
|
40
|
+
File.open(location, 'w') do |local|
|
|
41
|
+
local.write(file.body)
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def upload_to_bucket(path, is_backup = false)
|
|
47
|
+
return unless File.exists? path
|
|
48
|
+
|
|
49
|
+
strip_bucket unless is_backup
|
|
50
|
+
target = is_backup ? backup_bucket : bucket
|
|
51
|
+
|
|
52
|
+
Dir[File.join(path, '**', '*')].each do |file|
|
|
53
|
+
relative_path = file[path.length + 1..-1]
|
|
54
|
+
target.files.create(:key => relative_path, :body => File.read(file)) if File.file?(file)
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
target.files.reload
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def deploy_to_bucket(path, options = { :backup => true })
|
|
61
|
+
if options[:backup] && options[:backup] == true
|
|
62
|
+
Dir.mktmpdir do |temp_dir|
|
|
63
|
+
backup_dir = File.expand_path(Time.now.strftime("%Y-%m-%d@%H:%M:%S(%Z)"), temp_dir)
|
|
64
|
+
FileUtils.mkdir backup_dir
|
|
65
|
+
|
|
66
|
+
download_from_bucket backup_dir
|
|
67
|
+
upload_to_bucket temp_dir, true
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
upload_to_bucket path
|
|
72
|
+
|
|
73
|
+
storage.put_bucket_website bucket_name, 'index.html', :key => '404.html'
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
end
|
data/spec/spec_helper.rb
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
lib = File.expand_path('../lib/', __FILE__)
|
|
2
|
+
$:.unshift lib unless $:.include?(lib)
|
|
3
|
+
|
|
4
|
+
require 'vacation'
|
|
5
|
+
require 'rspec'
|
|
6
|
+
require 'tmpdir'
|
|
7
|
+
require 'yaml'
|
|
8
|
+
require 'nokogiri'
|
|
9
|
+
|
|
10
|
+
def fake_jekyll
|
|
11
|
+
File.expand_path('../support/jekyll', __FILE__)
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def aws_creds
|
|
15
|
+
YAML.load(File.expand_path('../support/credentials.yml', __FILE__))['aws']
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
RSpec.configure do |c|
|
|
19
|
+
c.mock_with :rspec
|
|
20
|
+
end
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html>
|
|
3
|
+
<head>
|
|
4
|
+
<link rel="stylesheet" href="/stylesheets/reset.css" type="text/css" />
|
|
5
|
+
<title>{{ page.title }}</title>
|
|
6
|
+
</head>
|
|
7
|
+
<body>
|
|
8
|
+
<h1>{{ page.title }}</h1>
|
|
9
|
+
<h2>{{ page.synopsis }}</h2>
|
|
10
|
+
{{ content }}
|
|
11
|
+
<h3 class="posted">Posted by {{ page.author }} on {{ page.date | date_to_long_string }}</h3>
|
|
12
|
+
</body>
|
|
13
|
+
</html>
|
|
Binary file
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
---
|
|
2
|
+
layout: default
|
|
3
|
+
title: Index
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
<h2>Bloggage</h2>
|
|
7
|
+
<img src="/images/geocities.png" class="lulz" />
|
|
8
|
+
|
|
9
|
+
{% for post in site.posts limit:5 %}
|
|
10
|
+
<h3 class="chunk"><a href=".{{ post.url }}">{{ post.title }}</a></h3>
|
|
11
|
+
<q>{{ post.synopsis }}</q>
|
|
12
|
+
<h4>Posted by {{ post.author }} on {{ post.date | date_to_long_string }}.</h4>
|
|
13
|
+
{% endfor %}
|
|
@@ -0,0 +1,260 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HTML5 ✰ Boilerplate
|
|
3
|
+
*
|
|
4
|
+
* style.css contains a reset, font normalization and some base styles.
|
|
5
|
+
*
|
|
6
|
+
* Credit is left where credit is due.
|
|
7
|
+
* Much inspiration was taken from these projects:
|
|
8
|
+
* - yui.yahooapis.com/2.8.1/build/base/base.css
|
|
9
|
+
* - camendesign.com/design/
|
|
10
|
+
* - praegnanz.de/weblog/htmlcssjs-kickstart
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* html5doctor.com Reset Stylesheet (Eric Meyer's Reset Reloaded + HTML5 baseline)
|
|
16
|
+
* v1.6.1 2010-09-17 | Authors: Eric Meyer & Richard Clark
|
|
17
|
+
* html5doctor.com/html-5-reset-stylesheet/
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
html, body, div, span, object, iframe,
|
|
21
|
+
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
|
|
22
|
+
abbr, address, cite, code, del, dfn, em, img, ins, kbd, q, samp,
|
|
23
|
+
small, strong, sub, sup, var, b, i, dl, dt, dd, ol, ul, li,
|
|
24
|
+
fieldset, form, label, legend,
|
|
25
|
+
table, caption, tbody, tfoot, thead, tr, th, td,
|
|
26
|
+
article, aside, canvas, details, figcaption, figure,
|
|
27
|
+
footer, header, hgroup, menu, nav, section, summary,
|
|
28
|
+
time, mark, audio, video {
|
|
29
|
+
margin: 0;
|
|
30
|
+
padding: 0;
|
|
31
|
+
border: 0;
|
|
32
|
+
font-size: 100%;
|
|
33
|
+
font: inherit;
|
|
34
|
+
vertical-align: baseline;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
article, aside, details, figcaption, figure,
|
|
38
|
+
footer, header, hgroup, menu, nav, section {
|
|
39
|
+
display: block;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
blockquote, q { quotes: none; }
|
|
43
|
+
|
|
44
|
+
blockquote:before, blockquote:after,
|
|
45
|
+
q:before, q:after { content: ''; content: none; }
|
|
46
|
+
|
|
47
|
+
ins { background-color: #ff9; color: #000; text-decoration: none; }
|
|
48
|
+
|
|
49
|
+
mark { background-color: #ff9; color: #000; font-style: italic; font-weight: bold; }
|
|
50
|
+
|
|
51
|
+
del { text-decoration: line-through; }
|
|
52
|
+
|
|
53
|
+
abbr[title], dfn[title] { border-bottom: 1px dotted; cursor: help; }
|
|
54
|
+
|
|
55
|
+
table { border-collapse: collapse; border-spacing: 0; }
|
|
56
|
+
|
|
57
|
+
hr { display: block; height: 1px; border: 0; border-top: 1px solid #ccc; margin: 1em 0; padding: 0; }
|
|
58
|
+
|
|
59
|
+
input, select { vertical-align: middle; }
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Font normalization inspired by YUI Library's fonts.css: developer.yahoo.com/yui/
|
|
64
|
+
*/
|
|
65
|
+
|
|
66
|
+
body { font:13px/1.231 sans-serif; *font-size:small; } /* Hack retained to preserve specificity */
|
|
67
|
+
select, input, textarea, button { font:99% sans-serif; }
|
|
68
|
+
|
|
69
|
+
/* Normalize monospace sizing:
|
|
70
|
+
en.wikipedia.org/wiki/MediaWiki_talk:Common.css/Archive_11#Teletype_style_fix_for_Chrome */
|
|
71
|
+
pre, code, kbd, samp { font-family: monospace, sans-serif; }
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Minimal base styles.
|
|
76
|
+
*/
|
|
77
|
+
|
|
78
|
+
/* Always force a scrollbar in non-IE */
|
|
79
|
+
html { overflow-y: scroll; }
|
|
80
|
+
|
|
81
|
+
/* Accessible focus treatment: people.opera.com/patrickl/experiments/keyboard/test */
|
|
82
|
+
a:hover, a:active { outline: none; }
|
|
83
|
+
|
|
84
|
+
ul, ol { margin-left: 2em; }
|
|
85
|
+
ol { list-style-type: decimal; }
|
|
86
|
+
|
|
87
|
+
/* Remove margins for navigation lists */
|
|
88
|
+
nav ul, nav li { margin: 0; list-style:none; list-style-image: none; }
|
|
89
|
+
|
|
90
|
+
small { font-size: 85%; }
|
|
91
|
+
strong, th { font-weight: bold; }
|
|
92
|
+
|
|
93
|
+
td { vertical-align: top; }
|
|
94
|
+
|
|
95
|
+
/* Set sub, sup without affecting line-height: gist.github.com/413930 */
|
|
96
|
+
sub, sup { font-size: 75%; line-height: 0; position: relative; }
|
|
97
|
+
sup { top: -0.5em; }
|
|
98
|
+
sub { bottom: -0.25em; }
|
|
99
|
+
|
|
100
|
+
pre {
|
|
101
|
+
/* www.pathf.com/blogs/2008/05/formatting-quoted-code-in-blog-posts-css21-white-space-pre-wrap/ */
|
|
102
|
+
white-space: pre; white-space: pre-wrap; word-wrap: break-word;
|
|
103
|
+
padding: 15px;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
textarea { overflow: auto; } /* www.sitepoint.com/blogs/2010/08/20/ie-remove-textarea-scrollbars/ */
|
|
107
|
+
|
|
108
|
+
.ie6 legend, .ie7 legend { margin-left: -7px; }
|
|
109
|
+
|
|
110
|
+
/* Align checkboxes, radios, text inputs with their label by: Thierry Koblentz tjkdesign.com/ez-css/css/base.css */
|
|
111
|
+
input[type="radio"] { vertical-align: text-bottom; }
|
|
112
|
+
input[type="checkbox"] { vertical-align: bottom; }
|
|
113
|
+
.ie7 input[type="checkbox"] { vertical-align: baseline; }
|
|
114
|
+
.ie6 input { vertical-align: text-bottom; }
|
|
115
|
+
|
|
116
|
+
/* Hand cursor on clickable input elements */
|
|
117
|
+
label, input[type="button"], input[type="submit"], input[type="image"], button { cursor: pointer; }
|
|
118
|
+
|
|
119
|
+
/* Webkit browsers add a 2px margin outside the chrome of form elements */
|
|
120
|
+
button, input, select, textarea { margin: 0; }
|
|
121
|
+
|
|
122
|
+
/* Colors for form validity */
|
|
123
|
+
input:valid, textarea:valid { }
|
|
124
|
+
input:invalid, textarea:invalid {
|
|
125
|
+
border-radius: 1px; -moz-box-shadow: 0px 0px 5px red; -webkit-box-shadow: 0px 0px 5px red; box-shadow: 0px 0px 5px red;
|
|
126
|
+
}
|
|
127
|
+
.no-boxshadow input:invalid, .no-boxshadow textarea:invalid { background-color: #f0dddd; }
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
/* These selection declarations have to be separate
|
|
131
|
+
No text-shadow: twitter.com/miketaylr/status/12228805301
|
|
132
|
+
Also: hot pink! */
|
|
133
|
+
::-moz-selection{ background: #FF5E99; color:#fff; text-shadow: none; }
|
|
134
|
+
::selection { background:#FF5E99; color:#fff; text-shadow: none; }
|
|
135
|
+
|
|
136
|
+
/* j.mp/webkit-tap-highlight-color */
|
|
137
|
+
a:link { -webkit-tap-highlight-color: #FF5E99; }
|
|
138
|
+
|
|
139
|
+
/* Make buttons play nice in IE:
|
|
140
|
+
www.viget.com/inspire/styling-the-button-element-in-internet-explorer/ */
|
|
141
|
+
button { width: auto; overflow: visible; }
|
|
142
|
+
|
|
143
|
+
/* Bicubic resizing for non-native sized IMG:
|
|
144
|
+
code.flickr.com/blog/2008/11/12/on-ui-quality-the-little-things-client-side-image-resizing/ */
|
|
145
|
+
.ie7 img { -ms-interpolation-mode: bicubic; }
|
|
146
|
+
|
|
147
|
+
/**
|
|
148
|
+
* You might tweak these..
|
|
149
|
+
*/
|
|
150
|
+
|
|
151
|
+
body, select, input, textarea {
|
|
152
|
+
/* #444 looks better than black: twitter.com/H_FJ/statuses/11800719859 */
|
|
153
|
+
color: #444;
|
|
154
|
+
/* Set your base font here, to apply evenly */
|
|
155
|
+
/* font-family: Georgia, serif; */
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
/* Headers (h1, h2, etc) have no default font-size or margin; define those yourself */
|
|
159
|
+
h1, h2, h3, h4, h5, h6 { font-weight: bold; }
|
|
160
|
+
|
|
161
|
+
a, a:active, a:visited { color: #607890; }
|
|
162
|
+
a:hover { color: #036; }
|
|
163
|
+
|
|
164
|
+
|
|
165
|
+
/**
|
|
166
|
+
* Primary styles
|
|
167
|
+
*
|
|
168
|
+
* Author:
|
|
169
|
+
*/
|
|
170
|
+
|
|
171
|
+
|
|
172
|
+
|
|
173
|
+
|
|
174
|
+
|
|
175
|
+
|
|
176
|
+
|
|
177
|
+
|
|
178
|
+
|
|
179
|
+
|
|
180
|
+
|
|
181
|
+
|
|
182
|
+
|
|
183
|
+
|
|
184
|
+
|
|
185
|
+
|
|
186
|
+
/**
|
|
187
|
+
* Non-semantic helper classes: please define your styles before this section.
|
|
188
|
+
*/
|
|
189
|
+
|
|
190
|
+
/* For image replacement */
|
|
191
|
+
.ir { display: block; text-indent: -999em; overflow: hidden; background-repeat: no-repeat; text-align: left; direction: ltr; }
|
|
192
|
+
|
|
193
|
+
/* Hide for both screenreaders and browsers:
|
|
194
|
+
css-discuss.incutio.com/wiki/Screenreader_Visibility */
|
|
195
|
+
.hidden { display: none; visibility: hidden; }
|
|
196
|
+
|
|
197
|
+
/* Hide only visually, but have it available for screenreaders: by Jon Neal.
|
|
198
|
+
www.webaim.org/techniques/css/invisiblecontent/ & j.mp/visuallyhidden */
|
|
199
|
+
.visuallyhidden { border: 0; clip: rect(0 0 0 0); height: 1px; margin: -1px; overflow: hidden; padding: 0; position: absolute; width: 1px; }
|
|
200
|
+
/* Extends the .visuallyhidden class to allow the element to be focusable when navigated to via the keyboard: drupal.org/node/897638 */
|
|
201
|
+
.visuallyhidden.focusable:active,
|
|
202
|
+
.visuallyhidden.focusable:focus { clip: auto; height: auto; margin: 0; overflow: visible; position: static; width: auto; }
|
|
203
|
+
|
|
204
|
+
/* Hide visually and from screenreaders, but maintain layout */
|
|
205
|
+
.invisible { visibility: hidden; }
|
|
206
|
+
|
|
207
|
+
/* The Magnificent Clearfix: Updated to prevent margin-collapsing on child elements.
|
|
208
|
+
j.mp/bestclearfix */
|
|
209
|
+
.clearfix:before, .clearfix:after { content: "\0020"; display: block; height: 0; overflow: hidden; }
|
|
210
|
+
.clearfix:after { clear: both; }
|
|
211
|
+
/* Fix clearfix: blueprintcss.lighthouseapp.com/projects/15318/tickets/5-extra-margin-padding-bottom-of-page */
|
|
212
|
+
.clearfix { zoom: 1; }
|
|
213
|
+
|
|
214
|
+
|
|
215
|
+
|
|
216
|
+
/**
|
|
217
|
+
* Media queries for responsive design.
|
|
218
|
+
*
|
|
219
|
+
* These follow after primary styles so they will successfully override.
|
|
220
|
+
*/
|
|
221
|
+
|
|
222
|
+
@media all and (orientation:portrait) {
|
|
223
|
+
/* Style adjustments for portrait mode goes here */
|
|
224
|
+
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
@media all and (orientation:landscape) {
|
|
228
|
+
/* Style adjustments for landscape mode goes here */
|
|
229
|
+
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
/* Grade-A Mobile Browsers (Opera Mobile, Mobile Safari, Android Chrome)
|
|
233
|
+
consider this: www.cloudfour.com/css-media-query-for-mobile-is-fools-gold/ */
|
|
234
|
+
@media screen and (max-device-width: 480px) {
|
|
235
|
+
|
|
236
|
+
|
|
237
|
+
/* Uncomment if you don't want iOS and WinMobile to mobile-optimize the text for you: j.mp/textsizeadjust */
|
|
238
|
+
/* html { -webkit-text-size-adjust:none; -ms-text-size-adjust:none; } */
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
|
|
242
|
+
/**
|
|
243
|
+
* Print styles.
|
|
244
|
+
*
|
|
245
|
+
* Inlined to avoid required HTTP connection: www.phpied.com/delay-loading-your-print-css/
|
|
246
|
+
*/
|
|
247
|
+
@media print {
|
|
248
|
+
* { background: transparent !important; color: black !important; text-shadow: none !important; filter:none !important;
|
|
249
|
+
-ms-filter: none !important; } /* Black prints faster: sanbeiji.com/archives/953 */
|
|
250
|
+
a, a:visited { color: #444 !important; text-decoration: underline; }
|
|
251
|
+
a[href]:after { content: " (" attr(href) ")"; }
|
|
252
|
+
abbr[title]:after { content: " (" attr(title) ")"; }
|
|
253
|
+
.ir a:after, a[href^="javascript:"]:after, a[href^="#"]:after { content: ""; } /* Don't show links for images, or javascript/internal links */
|
|
254
|
+
pre, blockquote { border: 1px solid #999; page-break-inside: avoid; }
|
|
255
|
+
thead { display: table-header-group; } /* css-discuss.incutio.com/wiki/Printing_Tables */
|
|
256
|
+
tr, img { page-break-inside: avoid; }
|
|
257
|
+
@page { margin: 0.5cm; }
|
|
258
|
+
p, h2, h3 { orphans: 3; widows: 3; }
|
|
259
|
+
h2, h3{ page-break-after: avoid; }
|
|
260
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
require File.expand_path('../../spec_helper', __FILE__)
|
|
2
|
+
|
|
3
|
+
describe Vacation::Jekyll do
|
|
4
|
+
let (:jk) { Vacation::Jekyll.new(fake_jekyll) }
|
|
5
|
+
|
|
6
|
+
describe '#initialize' do
|
|
7
|
+
it 'should assign the path to a Jekyll blog' do
|
|
8
|
+
jk.source.should == fake_jekyll
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
{ 'not valid' => '/trøløløl', 'not readable' => '/var/root', 'not a directory' => __FILE__ }.each do |reason, path|
|
|
12
|
+
it "should bail if the path is #{reason}" do
|
|
13
|
+
lambda {
|
|
14
|
+
Vacation::Jekyll.new(path)
|
|
15
|
+
}.should raise_exception
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
describe '#compile_to' do
|
|
21
|
+
let(:temp_dir) { Dir.mktmpdir }
|
|
22
|
+
let(:index_path) { File.expand_path('index.html', temp_dir) }
|
|
23
|
+
after { FileUtils.remove_entry_secure temp_dir }
|
|
24
|
+
|
|
25
|
+
it 'should compile that sumbitch to a tempdir' do
|
|
26
|
+
jk.compile_to(temp_dir)
|
|
27
|
+
|
|
28
|
+
File.exists?(index_path).should be_true
|
|
29
|
+
index_content = IO.read(index_path)
|
|
30
|
+
|
|
31
|
+
index = Nokogiri::HTML.parse(index_content)
|
|
32
|
+
index.css('title').inner_text.should == 'Index'
|
|
33
|
+
index.css('h4').count.should == 2
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
it 'should create the destination directory if it does not exist' do
|
|
37
|
+
Dir.rmdir(temp_dir)
|
|
38
|
+
File.exists?(temp_dir).should be_false
|
|
39
|
+
|
|
40
|
+
jk.compile_to(temp_dir)
|
|
41
|
+
File.exists?(index_path).should be_true
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
it 'should throw an exception if the destination is not writable' do
|
|
45
|
+
lambda {
|
|
46
|
+
jk.compile_to('/var/root')
|
|
47
|
+
}.should raise_exception
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
require File.expand_path('../../spec_helper', __FILE__)
|
|
2
|
+
|
|
3
|
+
describe Vacation::S3 do
|
|
4
|
+
before { Fog.mock! }
|
|
5
|
+
|
|
6
|
+
let(:bucket_name) { 'pants' }
|
|
7
|
+
let(:s3) { Vacation::S3.new('fake', 'key', bucket_name)}
|
|
8
|
+
let(:file) { s3.bucket.files.create(:key => 'socks/feet', :body => 'toes') }
|
|
9
|
+
before { s3 && file }
|
|
10
|
+
|
|
11
|
+
describe '#initialize' do
|
|
12
|
+
it 'should assign AWS credentials' do
|
|
13
|
+
s3.access_key_id.should == 'fake'
|
|
14
|
+
s3.secret_access_key.should == 'key'
|
|
15
|
+
s3.bucket_name.should == 'pants'
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
describe '#strip_bucket' do
|
|
20
|
+
it 'should destroy existing files' do
|
|
21
|
+
s3.strip_bucket
|
|
22
|
+
s3.bucket.files.count.should == 0
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
describe '#download_from_bucket' do
|
|
27
|
+
let(:temp_dir) { Dir.mktmpdir }
|
|
28
|
+
after { FileUtils.remove_entry_secure temp_dir }
|
|
29
|
+
|
|
30
|
+
it 'should create directories and files existing in the bucket' do
|
|
31
|
+
s3.download_from_bucket temp_dir
|
|
32
|
+
|
|
33
|
+
File.exists?(File.expand_path('socks', temp_dir)).should be_true
|
|
34
|
+
File.exists?(File.expand_path('socks/feet', temp_dir)).should be_true
|
|
35
|
+
File.read(File.expand_path('socks/feet', temp_dir)).should == 'toes'
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
describe '#upload_to_bucket' do
|
|
40
|
+
let(:temp_dir) { Dir.mktmpdir }
|
|
41
|
+
after { FileUtils.remove_entry_secure temp_dir }
|
|
42
|
+
|
|
43
|
+
it 'should pave over existing files' do
|
|
44
|
+
lambda {
|
|
45
|
+
s3.upload_to_bucket temp_dir
|
|
46
|
+
}.should change { s3.bucket.files.reload.count }.by -1
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
it 'should create directories and files existing on the filesystem' do
|
|
50
|
+
FileUtils.mkdir(File.expand_path('pocket', temp_dir))
|
|
51
|
+
File.open(File.expand_path('pocket/chili', temp_dir), 'w') { |local| local.write('beans')}
|
|
52
|
+
|
|
53
|
+
s3.upload_to_bucket temp_dir
|
|
54
|
+
|
|
55
|
+
s3.bucket.files.count.should == 1
|
|
56
|
+
s3.bucket.files.first.key.should == 'pocket/chili'
|
|
57
|
+
s3.bucket.files.first.body.should == 'beans'
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
describe '#deploy_to_bucket' do
|
|
62
|
+
let(:backup_bucket) { s3.storage.directories.create(:key => "#{bucket_name}-vacation-backup") }
|
|
63
|
+
before do
|
|
64
|
+
s3.storage.stub!(:put_bucket_website) do |name, index, opts|
|
|
65
|
+
name.should == s3.bucket.key
|
|
66
|
+
index.should == 'index.html'
|
|
67
|
+
opts[:key].should == '404.html'
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
it 'should deploy to the specified bucket' do
|
|
72
|
+
s3.deploy_to_bucket fake_jekyll
|
|
73
|
+
s3.bucket.files.count.should == 7
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
it 'should obey a no-backup parameter' do
|
|
77
|
+
lambda {
|
|
78
|
+
s3.deploy_to_bucket fake_jekyll, :backup => false
|
|
79
|
+
}.should_not change{ s3.backup_bucket.files.count }
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
it 'should enable the static hosting parameter and pages' do
|
|
83
|
+
pending 'this functionality is not mocked out in Fog yet'
|
|
84
|
+
s3.deploy_to_bucket fake_jekyll, :backup => false
|
|
85
|
+
s3.storage.get_bucket_website(s3.bucket.key).body['IndexDocument']['Suffix'].should == 'index.html'
|
|
86
|
+
s3.storage.get_bucket_website(s3.bucket.key).body['ErrorDocument']['Key'].should == '404.html'
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
end
|
data/vacation.gemspec
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
lib = File.expand_path('../lib/', __FILE__)
|
|
2
|
+
$:.unshift lib unless $:.include?(lib)
|
|
3
|
+
|
|
4
|
+
require 'vacation'
|
|
5
|
+
|
|
6
|
+
Gem::Specification.new do |s|
|
|
7
|
+
s.name = "vacation"
|
|
8
|
+
s.version = Vacation::VERSION
|
|
9
|
+
s.platform = Gem::Platform::RUBY
|
|
10
|
+
s.authors = ["Doc Ritezel"]
|
|
11
|
+
s.email = ['ritezel+doc@gmail.com']
|
|
12
|
+
s.homepage = "http://github.com/ohrite/vacation"
|
|
13
|
+
s.summary = "Send your Jekyll blog on an S3 vacation"
|
|
14
|
+
s.description = "You got your peanut butter on my static file host! You got your static blog content on my chocolate!"
|
|
15
|
+
|
|
16
|
+
s.required_rubygems_version = ">= 1.3.6"
|
|
17
|
+
|
|
18
|
+
s.add_development_dependency "rspec"
|
|
19
|
+
s.add_dependency "fog"
|
|
20
|
+
s.add_dependency "jekyll"
|
|
21
|
+
|
|
22
|
+
s.files = `git ls-files`.split("\n")
|
|
23
|
+
s.test_files = `git ls-files -- {spec}/*`.split("\n")
|
|
24
|
+
s.require_path = 'lib'
|
|
25
|
+
s.executables = %w(vacation)
|
|
26
|
+
s.default_executable = "vacation"
|
|
27
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: vacation
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
hash: 31
|
|
5
|
+
prerelease:
|
|
6
|
+
segments:
|
|
7
|
+
- 0
|
|
8
|
+
- 1
|
|
9
|
+
- 2
|
|
10
|
+
version: 0.1.2
|
|
11
|
+
platform: ruby
|
|
12
|
+
authors:
|
|
13
|
+
- Doc Ritezel
|
|
14
|
+
autorequire:
|
|
15
|
+
bindir: bin
|
|
16
|
+
cert_chain: []
|
|
17
|
+
|
|
18
|
+
date: 2011-03-06 00:00:00 -08:00
|
|
19
|
+
default_executable: vacation
|
|
20
|
+
dependencies:
|
|
21
|
+
- !ruby/object:Gem::Dependency
|
|
22
|
+
name: rspec
|
|
23
|
+
prerelease: false
|
|
24
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
|
25
|
+
none: false
|
|
26
|
+
requirements:
|
|
27
|
+
- - ">="
|
|
28
|
+
- !ruby/object:Gem::Version
|
|
29
|
+
hash: 3
|
|
30
|
+
segments:
|
|
31
|
+
- 0
|
|
32
|
+
version: "0"
|
|
33
|
+
type: :development
|
|
34
|
+
version_requirements: *id001
|
|
35
|
+
- !ruby/object:Gem::Dependency
|
|
36
|
+
name: fog
|
|
37
|
+
prerelease: false
|
|
38
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
|
39
|
+
none: false
|
|
40
|
+
requirements:
|
|
41
|
+
- - ">="
|
|
42
|
+
- !ruby/object:Gem::Version
|
|
43
|
+
hash: 3
|
|
44
|
+
segments:
|
|
45
|
+
- 0
|
|
46
|
+
version: "0"
|
|
47
|
+
type: :runtime
|
|
48
|
+
version_requirements: *id002
|
|
49
|
+
- !ruby/object:Gem::Dependency
|
|
50
|
+
name: jekyll
|
|
51
|
+
prerelease: false
|
|
52
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
|
53
|
+
none: false
|
|
54
|
+
requirements:
|
|
55
|
+
- - ">="
|
|
56
|
+
- !ruby/object:Gem::Version
|
|
57
|
+
hash: 3
|
|
58
|
+
segments:
|
|
59
|
+
- 0
|
|
60
|
+
version: "0"
|
|
61
|
+
type: :runtime
|
|
62
|
+
version_requirements: *id003
|
|
63
|
+
description: You got your peanut butter on my static file host! You got your static blog content on my chocolate!
|
|
64
|
+
email:
|
|
65
|
+
- ritezel+doc@gmail.com
|
|
66
|
+
executables:
|
|
67
|
+
- vacation
|
|
68
|
+
extensions: []
|
|
69
|
+
|
|
70
|
+
extra_rdoc_files: []
|
|
71
|
+
|
|
72
|
+
files:
|
|
73
|
+
- .gitignore
|
|
74
|
+
- .rvmrc
|
|
75
|
+
- Gemfile
|
|
76
|
+
- Gemfile.lock
|
|
77
|
+
- README.md
|
|
78
|
+
- Rakefile
|
|
79
|
+
- bin/vacation
|
|
80
|
+
- lib/tasks/deploy.rake
|
|
81
|
+
- lib/vacation.rb
|
|
82
|
+
- lib/vacation/jekyll.rb
|
|
83
|
+
- lib/vacation/s3.rb
|
|
84
|
+
- spec/spec_helper.rb
|
|
85
|
+
- spec/support/jekyll/_layouts/blog.html
|
|
86
|
+
- spec/support/jekyll/_layouts/default.html
|
|
87
|
+
- spec/support/jekyll/_posts/2011-03-04-i-am-wearing-ramen.markdown
|
|
88
|
+
- spec/support/jekyll/_posts/2011-03-05-about-last-night.markdown
|
|
89
|
+
- spec/support/jekyll/images/geocities.png
|
|
90
|
+
- spec/support/jekyll/index.html
|
|
91
|
+
- spec/support/jekyll/stylesheets/reset.css
|
|
92
|
+
- spec/unit/jekyll_spec.rb
|
|
93
|
+
- spec/unit/s3_spec.rb
|
|
94
|
+
- vacation.gemspec
|
|
95
|
+
has_rdoc: true
|
|
96
|
+
homepage: http://github.com/ohrite/vacation
|
|
97
|
+
licenses: []
|
|
98
|
+
|
|
99
|
+
post_install_message:
|
|
100
|
+
rdoc_options: []
|
|
101
|
+
|
|
102
|
+
require_paths:
|
|
103
|
+
- lib
|
|
104
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
105
|
+
none: false
|
|
106
|
+
requirements:
|
|
107
|
+
- - ">="
|
|
108
|
+
- !ruby/object:Gem::Version
|
|
109
|
+
hash: 3
|
|
110
|
+
segments:
|
|
111
|
+
- 0
|
|
112
|
+
version: "0"
|
|
113
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
114
|
+
none: false
|
|
115
|
+
requirements:
|
|
116
|
+
- - ">="
|
|
117
|
+
- !ruby/object:Gem::Version
|
|
118
|
+
hash: 23
|
|
119
|
+
segments:
|
|
120
|
+
- 1
|
|
121
|
+
- 3
|
|
122
|
+
- 6
|
|
123
|
+
version: 1.3.6
|
|
124
|
+
requirements: []
|
|
125
|
+
|
|
126
|
+
rubyforge_project:
|
|
127
|
+
rubygems_version: 1.6.1
|
|
128
|
+
signing_key:
|
|
129
|
+
specification_version: 3
|
|
130
|
+
summary: Send your Jekyll blog on an S3 vacation
|
|
131
|
+
test_files: []
|
|
132
|
+
|