Permalink
Browse files

Initial commit

  • Loading branch information...
pcreux committed Apr 2, 2011
0 parents commit 798920d5334a29d263f4ebdc9876f0e5010542f9
Showing with 306 additions and 0 deletions.
  1. +5 −0 .gitignore
  2. +4 −0 Gemfile
  3. +2 −0 Rakefile
  4. +5 −0 bin/jekyll-s3
  5. +87 −0 features/jekyll-s3.feature
  6. +22 −0 features/support/env.rb
  7. +25 −0 jekyll-s3.gemspec
  8. +12 −0 lib/jekyll-s3.rb
  9. +12 −0 lib/jekyll-s3/cli.rb
  10. +25 −0 lib/jekyll-s3/errors.rb
  11. +102 −0 lib/jekyll-s3/uploader.rb
  12. +5 −0 lib/jekyll-s3/version.rb
@@ -0,0 +1,5 @@
+*.gem
+.bundle
+Gemfile.lock
+pkg/*
+tmp
@@ -0,0 +1,4 @@
+source "http://rubygems.org"
+
+# Specify your gem's dependencies in jekyll-s3.gemspec
+gemspec
@@ -0,0 +1,2 @@
+require 'bundler'
+Bundler::GemHelper.install_tasks
@@ -0,0 +1,5 @@
+#!/usr/bin/env ruby
+
+require File.dirname(__FILE__) + '/../lib/jekyll-s3'
+
+Jekyll::S3::CLI.run!
@@ -0,0 +1,87 @@
+Feature: jekyll-s3
+
+ In order to push my jekyll site to s3
+ As a blogger
+ I want to run jekyll-s3 and say OMG it just worked!
+
+ Scenario: Run jekyll-s3 in the wrong directory
+ When I run "jekyll-s3"
+ Then the output should contain:
+ """
+ I can't find any directory called _site. Are you in the right directory?
+ """
+
+ Scenario: Run jekyll-s3 for the first time
+ Given a directory named "_site"
+ When I run "jekyll-s3"
+ Then the output should contain:
+ """
+ I've just generated a file called _jekyll_s3.yml. Go put your details in it!
+ """
+ Then the file "_jekyll_s3.yml" should contain:
+ """
+ s3_id: YOUR_AWS_S3_ACCESS_KEY_ID
+ s3_secret: YOUR_AWS_S3_SECRET_ACCESS_KEY
+ s3_bucket: your.blog.bucket.com
+ """
+
+ Scenario: Run jekyll-s3 with an empty configuration file
+ Given a directory named "_site"
+ And an empty file named "_jekyll_s3.yml"
+ When I run "jekyll-s3"
+ Then the output should contain:
+ """
+ I can't parse the file _jekyll_s3.yml. It should look like this:
+ s3_id: YOUR_AWS_S3_ACCESS_KEY_ID
+ s3_secret: YOUR_AWS_S3_SECRET_ACCESS_KEY
+ s3_bucket: your.blog.bucket.com
+ """
+
+ Scenario: Run jekyll-s3 with a malformed configuration file
+ Given a directory named "_site"
+ And a file named "_jekyll_s3.yml" with:
+ """
+ s3_id: YOUR_AWS_S3_ACCESS_KEY_ID
+ this is not yaml
+ """
+ When I run "jekyll-s3"
+ Then the output should contain:
+ """
+ I can't parse the file _jekyll_s3.yml. It should look like this:
+ s3_id: YOUR_AWS_S3_ACCESS_KEY_ID
+ s3_secret: YOUR_AWS_S3_SECRET_ACCESS_KEY
+ s3_bucket: your.blog.bucket.com
+ """
+
+ Scenario: Run jekyll-s3 with a configuration file that does not contain a bucket
+ Given a directory named "_site"
+ And a file named "_jekyll_s3.yml" with:
+ """
+ s3_id: YOUR_AWS_S3_ACCESS_KEY_ID
+ s3_secret: YOUR_AWS_S3_SECRET_ACCESS_KEY
+ s3_bucket:
+ """
+ When I run "jekyll-s3"
+ Then the output should contain:
+ """
+ I can't parse the file _jekyll_s3.yml. It should look like this:
+ s3_id: YOUR_AWS_S3_ACCESS_KEY_ID
+ s3_secret: YOUR_AWS_S3_SECRET_ACCESS_KEY
+ s3_bucket: your.blog.bucket.com
+ """
+
+ Scenario: Run jekyll-s3
+ Given a directory named "_site"
+ And a file named "_jekyll_s3.yml" with:
+ """
+ s3_id: YOUR_AWS_S3_ACCESS_KEY_ID
+ s3_secret: YOUR_AWS_S3_SECRET_ACCESS_KEY
+ s3_bucket: your.blog.bucket.com
+ """
+ When I run "jekyll-s3"
+ Then the output should contain:
+ """
+ Uploading _site/* to your.blog.bucket.com
+ """
+
+
@@ -0,0 +1,22 @@
+require 'rubygems'
+require 'bundler'
+
+Bundler.require
+
+require 'aruba/cucumber'
+
+# Following from 'aruba/cucumber'
+Before do
+ @__aruba_original_paths = (ENV['PATH'] || '').split(File::PATH_SEPARATOR)
+ ENV['PATH'] = ([File.expand_path('bin')] + @__aruba_original_paths).join(File::PATH_SEPARATOR)
+end
+
+After do
+ ENV['PATH'] = @__aruba_original_paths.join(File::PATH_SEPARATOR)
+end
+# End of following from 'aruba/cucumber'
+
+Then /^the file "([^"]*)" should contain:$/ do |file, exact_content|
+ check_file_content(file, exact_content, true)
+end
+
@@ -0,0 +1,25 @@
+# -*- encoding: utf-8 -*-
+$:.push File.expand_path("../lib", __FILE__)
+require "jekyll-s3/version"
+
+Gem::Specification.new do |s|
+ s.name = "jekyll-s3"
+ s.version = Jekyll::S3::VERSION
+ s.platform = Gem::Platform::RUBY
+ s.authors = ["Philippe Creux"]
+ s.email = ["pcreux@gmail.com"]
+ s.homepage = ""
+ s.summary = %q{Push your jekyll blog to S3"}
+ s.description = %q{Push your jekyll blog to AWS S3}
+
+ s.add_dependency 'aws-s3'
+
+ s.add_development_dependency 'rspec'
+ s.add_development_dependency 'cucumber'
+ s.add_development_dependency 'aruba'
+
+ s.files = `git ls-files`.split("\n")
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
+ s.require_paths = ["lib"]
+end
@@ -0,0 +1,12 @@
+require 'rubygems'
+require 'yaml'
+require 'aws/s3'
+
+module Jekyll
+ module S3
+ end
+end
+
+%w{errors uploader cli}.each do |file|
+ require File.dirname(__FILE__) + "/jekyll-s3/#{file}"
+end
@@ -0,0 +1,12 @@
+module Jekyll
+ module S3
+ class CLI
+ def self.run!
+ Uploader.run!
+ rescue JekyllS3Error => e
+ puts e.message
+ exit 1
+ end
+ end
+ end
+end
@@ -0,0 +1,25 @@
+module Jekyll
+ module S3
+ class JekyllS3Error < StandardError
+ end
+
+ class NotAJekyllProjectError < JekyllS3Error
+ def initialize(message = "I can't find any directory called _site. Are you in the right directory?")
+ super(message)
+ end
+ end
+
+ class NoConfigurationFileError < JekyllS3Error
+ def initialize(message = "I've just generated a file called _jekyll_s3.yml. Go put your details in it!")
+ super(message)
+ end
+ end
+
+ class MalformedConfigurationFileError < JekyllS3Error
+ def initialize(message = "I can't parse the file _jekyll_s3.yml. It should look like this:\n#{Uploader::CONFIGURATION_FILE_TEMPLATE}")
+ super(message)
+ end
+ end
+
+ end
+end
@@ -0,0 +1,102 @@
+module Jekyll
+ module S3
+ class Uploader
+
+ SITE_DIR = "_site"
+ CONFIGURATION_FILE = '_jekyll_s3.yml'
+ CONFIGURATION_FILE_TEMPLATE = <<-EOF
+s3_id: YOUR_AWS_S3_ACCESS_KEY_ID
+s3_secret: YOUR_AWS_S3_SECRET_ACCESS_KEY
+s3_bucket: your.blog.bucket.com
+ EOF
+
+
+ def self.run!
+ new.run!
+ end
+
+ def run!
+ check_jekyll_project!
+ check_s3_configuration!
+ upload_to_s3!
+ end
+
+ protected
+
+ include AWS::S3
+
+ def upload_to_s3!
+ puts "Uploading _site/* to #{@s3_bucket}"
+
+ AWS::S3::Base.establish_connection!(
+ :access_key_id => @s3_id,
+ :secret_access_key => @s3_secret,
+ :use_ssl => true
+ )
+ unless Service.buckets.map(&:name).include?(@s3_bucket)
+ puts("Creating bucket #{@s3_bucket}")
+ Bucket.create(@s3_bucket)
+ end
+
+ bucket = Bucket.find(@s3_bucket)
+
+ local_files = Dir[SITE_DIR + '/**/*'].
+ delete_if { |f| File.directory?(f) }.
+ map { |f| f.gsub(SITE_DIR + '/', '') }
+
+ remote_files = bucket.objects.map { |f| f.key }
+
+ to_upload = local_files
+ to_upload.each do |f|
+ if S3Object.store(f, open("#{SITE_DIR}/#{f}"), @s3_bucket, :access => 'public-read')
+ puts("Upload #{f}: Success!")
+ else
+ puts("Upload #{f}: FAILURE!")
+ end
+ end
+
+ to_delete = remote_files - local_files
+ to_delete.each do |f|
+ if S3Object.delete(f, @s3_bucket)
+ puts("Delete #{f}: Success!")
+ else
+ puts("Delete #{f}: FAILURE!")
+ end
+ end
+ end
+
+ def check_jekyll_project!
+ raise NotAJekyllProjectError unless File.directory?(SITE_DIR)
+ end
+
+ # Raise NoConfigurationFileError if the configuration file does not exists
+ # Raise MalformedConfigurationFileError if the configuration file does not contain the keys we expect
+ # Loads the configuration if everything looks cool
+ def check_s3_configuration!
+ unless File.exists?(CONFIGURATION_FILE)
+ create_template_configuration_file
+ raise NoConfigurationFileError
+ end
+ raise MalformedConfigurationFileError unless load_configuration
+ end
+
+ # Load configuration from _jekyll_s3.yml
+ # Return true if all values are set and not emtpy
+ def load_configuration
+ config = YAML.load_file(CONFIGURATION_FILE) rescue nil
+ return false unless config
+
+ @s3_id = config['s3_id']
+ @s3_secret = config['s3_secret']
+ @s3_bucket = config['s3_bucket']
+
+ [@s3_id, @s3_secret, @s3_bucket].select { |k| k.nil? || k == '' }.empty?
+ end
+
+ def create_template_configuration_file
+ File.open(CONFIGURATION_FILE, 'w') { |f| f.write(CONFIGURATION_FILE_TEMPLATE) }
+
+ end
+ end
+ end
+end
@@ -0,0 +1,5 @@
+module Jekyll
+ module S3
+ VERSION = "0.0.1"
+ end
+end

0 comments on commit 798920d

Please sign in to comment.