skynet-deploy 0.9.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.
data/.gitignore ADDED
@@ -0,0 +1,5 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
5
+ spec/test.log
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --color
data/.rvmrc ADDED
@@ -0,0 +1,41 @@
1
+ #!/usr/bin/env bash
2
+
3
+ # This is an RVM Project .rvmrc file, used to automatically load the ruby
4
+ # development environment upon cd'ing into the directory
5
+
6
+ # First we specify our desired <ruby>[@<gemset>], the @gemset name is optional.
7
+ environment_id="ruby-1.9.2-p290@skynet"
8
+
9
+ #
10
+ # First we attempt to load the desired environment directly from the environment
11
+ # file. This is very fast and efficient compared to running through the entire
12
+ # CLI and selector. If you want feedback on which environment was used then
13
+ # insert the word 'use' after --create as this triggers verbose mode.
14
+ #
15
+ if [[ -d "${rvm_path:-$HOME/.rvm}/environments" \
16
+ && -s "${rvm_path:-$HOME/.rvm}/environments/$environment_id" ]]
17
+ then
18
+ \. "${rvm_path:-$HOME/.rvm}/environments/$environment_id"
19
+
20
+ if [[ -s ".rvm/hooks/after_use" ]]
21
+ then
22
+ . ".rvm/hooks/after_use"
23
+ fi
24
+ else
25
+ # If the environment file has not yet been created, use the RVM CLI to select.
26
+ if ! rvm --create "$environment_id"
27
+ then
28
+ echo "Failed to create RVM environment ''."
29
+ fi
30
+ fi
31
+
32
+ #
33
+ # If you use an RVM gemset file to install a list of gems (*.gems), you can have
34
+ # it be automatically loaded. Uncomment the following and adjust the filename if
35
+ # necessary.
36
+ #
37
+ # filename=".gems"
38
+ # if [[ -s "$filename" ]] ; then
39
+ # rvm gemset import "$filename" | grep -v already | grep -v listed | grep -v complete | sed '/^$/d'
40
+ # fi
41
+
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source :rubygems
2
+
3
+ gemspec
data/README.md ADDED
@@ -0,0 +1,20 @@
1
+ Skynet
2
+ ======
3
+
4
+ GitHub-aware website builder
5
+
6
+ Skynet builds and deploys web sites on your VPS or bare metal server. It is triggered by the post-receive hook.
7
+
8
+ Current Builder Types
9
+ ---------------------
10
+
11
+ 1. Static. Just copies entire repository to proper location
12
+ 1. Jekyll. Run jekyll on your repository. Entirely controlled by
13
+ site's `_config.yml`
14
+
15
+ Usage
16
+ -----
17
+ * Install Skynet: `$ gem install skynet-deploy`
18
+ * Install basic config file: `$ skynet config <first project name>`
19
+ * edit config file to add your repositories
20
+ * Start server: `$ skynet server`
data/Rakefile ADDED
@@ -0,0 +1,9 @@
1
+ require 'bundler'
2
+ Bundler::GemHelper.install_tasks
3
+
4
+ require 'rspec/core/rake_task'
5
+ RSpec::Core::RakeTask.new do |t|
6
+ t.verbose = false
7
+ end
8
+
9
+ task :default => [:spec, :build]
data/bin/skynet ADDED
@@ -0,0 +1,9 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'rubygems'
4
+
5
+ $:.unshift File.expand_path('../../lib', __FILE__)
6
+
7
+ require 'skynet'
8
+
9
+ Skynet::CLI.start
data/lib/skynet/app.rb ADDED
@@ -0,0 +1,34 @@
1
+ require 'sinatra/base'
2
+ require 'json'
3
+
4
+ module Skynet
5
+
6
+ class App < Sinatra::Base
7
+
8
+ get '/' do
9
+ %[Hello. Check <a href="https://github.com/coshx/skynet">github</a> for more infomation on skynet]
10
+ end
11
+
12
+ post '/:app_name' do |app_name|
13
+ Skynet.logger.debug "params: #{params.inspect}"
14
+ payload = JSON.parse params[:payload]
15
+ config = settings.config[app_name]
16
+ if deployable? config, payload
17
+ Builder.build app_name, config
18
+ else
19
+ Skynet.logger.warn "#{app_name} is not deployable"
20
+ end
21
+ "42"
22
+ end
23
+
24
+ private
25
+
26
+ def deployable?(config, payload)
27
+ !config.nil? &&
28
+ config[:url] == payload['repository']['url'] &&
29
+ payload['ref'] == "refs/heads/#{config[:branch]}" &&
30
+ payload['after'] !~ /^0{40}$/
31
+ end
32
+ end
33
+
34
+ end
@@ -0,0 +1,59 @@
1
+ require 'active_model'
2
+
3
+ module Skynet
4
+ module Builder
5
+
6
+ ALLOWED_BUILDERS = Dir.entries(File.dirname(__FILE__)).select { |f| f =~ /^\w+(?<!base)\.rb$/ }.map { |f| f.chomp '.rb' }
7
+
8
+ class Base
9
+ include ActiveModel::Validations
10
+
11
+ attr_accessor :app, :url, :branch, :destination, :type
12
+ attr_reader :source
13
+
14
+ validates_presence_of :app, :url, :branch, :destination
15
+ validates_inclusion_of :type,
16
+ in: ALLOWED_BUILDERS,
17
+ message: "must be one of #{ALLOWED_BUILDERS}"
18
+
19
+ def initialize(app, config)
20
+ self.app = app
21
+ @config = config
22
+ self.url = config[:url]
23
+ self.branch = config[:branch]
24
+ self.destination = config[:destination]
25
+ self.type = config[:type]
26
+ @source = File.join Dir.pwd, app, '.'
27
+ end
28
+
29
+ def build
30
+ unless valid?
31
+ Skynet.logger.error "Configuration error for #{app}"
32
+ Skynet.logger.error errors.full_messages.join '. '
33
+ raise ArgumentError
34
+ end
35
+ end
36
+
37
+ private
38
+
39
+ def build_repository
40
+ repo_exists? ? update_repo : create_repo
41
+ end
42
+
43
+ def create_repo
44
+ Skynet.logger.debug "Creating repository for #{app}"
45
+ Skynet.logger.debug `rm -rf #{source}`
46
+ Skynet.logger.info `git clone #{url} #{app}; cd #{source}; git checkout #{branch}`
47
+ end
48
+
49
+ def update_repo
50
+ Skynet.logger.debug "Updating repository for #{app}"
51
+ Skynet.logger.info `cd #{source}; git checkout #{branch}; git pull`
52
+ end
53
+
54
+ def repo_exists?
55
+ File.exist? File.join(source, '.git')
56
+ end
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,21 @@
1
+ # File updater using jekyll for processing
2
+
3
+ module Skynet
4
+ module Builder
5
+ class Jekyll < Base
6
+
7
+ def build
8
+ super
9
+
10
+ Skynet.logger.info "Jekyll running for #{app}..."
11
+ build_repository
12
+
13
+ Skynet.logger.debug "PWD: #{Dir.pwd} Source: #{source} Destination: #{destination}"
14
+ Skynet.logger.info `jekyll #{source} #{destination}`
15
+
16
+ Skynet.logger.info 'Jekyll finished'
17
+ end
18
+
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,24 @@
1
+ # Static files updater
2
+
3
+ module Skynet
4
+ module Builder
5
+ class Static < Base
6
+
7
+ def build
8
+ super
9
+
10
+ Skynet.logger.info "Static running for #{app}..."
11
+ build_repository
12
+
13
+ Skynet.logger.debug "Copying #{source} to #{destination}"
14
+ FileUtils.cp_r source, destination
15
+
16
+ Skynet.logger.debug "Removing #{destination}/.git"
17
+ FileUtils.remove_entry_secure File.join(destination, '.git')
18
+
19
+ Skynet.logger.info 'Static build finished'
20
+ end
21
+
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,20 @@
1
+ module Skynet
2
+ module Builder
3
+
4
+ autoload :Base, 'skynet/builder/base'
5
+ autoload :Static, 'skynet/builder/static'
6
+ autoload :Jekyll, 'skynet/builder/jekyll'
7
+
8
+ def self.build(app, config)
9
+ for_app(app, config).build
10
+ end
11
+
12
+ def self.for_app(app, config, type=nil)
13
+ type ||= config[:type] || 'base'
14
+ const_get("#{type[0].upcase}#{type.reverse.chop.reverse}").new app, config
15
+ rescue NameError
16
+ for_app(app, config, 'base')
17
+ end
18
+
19
+ end
20
+ end
data/lib/skynet/cli.rb ADDED
@@ -0,0 +1,98 @@
1
+ require 'thor'
2
+ require 'thin'
3
+ require 'yaml'
4
+ require 'active_support/core_ext/hash/indifferent_access'
5
+
6
+ module Skynet
7
+ class CLI < Thor
8
+ include Thor::Actions
9
+
10
+ def self.source_root
11
+ File.join File.dirname(__FILE__), 'templates'
12
+ end
13
+
14
+ desc "version", "display the current version"
15
+ def version
16
+ puts "Skynet #{Skynet::VERSION}"
17
+ end
18
+
19
+ desc "server", "starts the skynet server"
20
+ method_option :port, type: :numeric, default: 7575, aliases: '-p', desc: 'Port to listen on'
21
+ method_option :host, type: :string, default: '0.0.0.0', aliases: '-h', desc: 'Interface to listen on'
22
+ method_option :file, type: :string, default: './config.yml', aliases: '-f', desc: 'Configuration file'
23
+ method_option :log, type: :string, default: 'skynet.log', aliases: '-l', desc: 'Log file'
24
+ def server
25
+ Skynet.logger = Logger.new options[:log], 'weekly'
26
+
27
+ unless File.exist? options[:file]
28
+ Skynet.logger.fatal "Configuration file #{options[:file]} cannot be found"
29
+ raise ArgumentError.new "Cannot find configuration file"
30
+ end
31
+
32
+ Skynet::App.configure do |app|
33
+ app.set :config, load_configuration(options[:file])
34
+ end
35
+
36
+ server = Thin::Server.new(options[:host], options[:port]) do
37
+ run Skynet::App
38
+ end
39
+
40
+ begin
41
+ server.start!
42
+ rescue => ex
43
+ Skynet.logger.fatal ex.message
44
+ Skynet.logger.fatal ex.backtrace.join("\n")
45
+ raise ex
46
+ end
47
+ end
48
+
49
+ desc "build [PROJECT_NAME]", "Builds all applications, or PROJECT_NAME only if given"
50
+ method_option :file, type: :string, default: './config.yml', aliases: '-f', desc: 'Configuration file'
51
+ def build(name=nil)
52
+ all_apps = load_configuration options[:file]
53
+
54
+ if name.nil?
55
+ all_apps.each do |app, config|
56
+ begin
57
+ Builder.build app, config
58
+ rescue ArgumentError
59
+ next
60
+ end
61
+ end
62
+ else
63
+ config = all_apps[name]
64
+ if config.nil?
65
+ Skynet.logger.error "Could not find configuration for #{name}"
66
+ else
67
+ Builder.build name, config
68
+ end
69
+ end
70
+ end
71
+
72
+ desc "check", "Verifies correctness of config.yml"
73
+ method_option :file, type: :string, default: './config.yml', aliases: '-f', desc: 'File to check'
74
+ def check
75
+ all_apps = load_configuration options[:file]
76
+ all_apps.each do |app, config|
77
+ builder = Builder.for_app app, config
78
+ if builder.valid?
79
+ puts "#{app} configuration is valid"
80
+ else
81
+ puts "#{app} configuration errors: #{builder.errors.full_messages.join '. '}"
82
+ end
83
+ end
84
+ end
85
+
86
+ desc "config [PROJECT_NAME]", "Generate config.yml, stubbed out for for PROJECT_NAME"
87
+ def config(name="PROJECT_NAME")
88
+ @project_name = name
89
+ template('config.yml', 'config.yml')
90
+ end
91
+
92
+ private
93
+
94
+ def load_configuration(file)
95
+ YAML.load_file(file).with_indifferent_access
96
+ end
97
+ end
98
+ end
@@ -0,0 +1,15 @@
1
+ # Base configuration for SkyNet
2
+ #
3
+ # Example project:
4
+ #
5
+ # project_name:
6
+ # url: git@github.com:project_name.git
7
+ # branch: master
8
+ # type: jekyll
9
+ # destination: /var/www/project_name
10
+
11
+ <%= @project_name %>:
12
+ url: https://github.com/ORGANIZATION/<%= @project_name %>
13
+ branch: master
14
+ type:
15
+ destination:
@@ -0,0 +1,3 @@
1
+ module Skynet
2
+ VERSION = "0.9.0"
3
+ end
data/lib/skynet.rb ADDED
@@ -0,0 +1,18 @@
1
+ require 'skynet/version'
2
+ require 'logger'
3
+
4
+ module Skynet
5
+
6
+ autoload :Builder, 'skynet/builder'
7
+ autoload :App, 'skynet/app'
8
+ autoload :CLI, 'skynet/cli'
9
+
10
+ def self.logger
11
+ @logger ||= Logger.new(STDOUT)
12
+ end
13
+
14
+ def self.logger=(logger)
15
+ @logger = logger
16
+ end
17
+
18
+ end
data/skynet.gemspec ADDED
@@ -0,0 +1,33 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "skynet/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "skynet-deploy"
7
+ s.version = Skynet::VERSION
8
+ s.platform = Gem::Platform::RUBY
9
+ s.authors = ["Ryan Ahearn"]
10
+ s.email = ["ryan@coshx.com"]
11
+ s.homepage = ""
12
+ s.summary = %q{Sinatra app that listens for GitHub post-receive callbacks and deploys your code}
13
+ s.description = %q{Sinatra app that listens for GitHub post-receive callbacks and deploys your code}
14
+
15
+ s.required_rubygems_version = ">= 1.3.6"
16
+
17
+ s.files = `git ls-files`.split("\n")
18
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
19
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
20
+ s.require_paths = ["lib"]
21
+
22
+ s.add_runtime_dependency 'sinatra', '~> 1.3'
23
+ s.add_runtime_dependency 'thin', '~> 1.4'
24
+ s.add_runtime_dependency 'json', '~> 1.7'
25
+ s.add_runtime_dependency 'jekyll', '~> 0.11'
26
+ s.add_runtime_dependency 'thor', '~> 0.16'
27
+ s.add_runtime_dependency 'activesupport', '~> 3.2'
28
+ s.add_runtime_dependency 'activemodel', '~> 3.2'
29
+
30
+ s.add_development_dependency 'rake', '~> 0.9'
31
+ s.add_development_dependency 'rspec', '~> 2.11'
32
+ s.add_development_dependency 'shoulda-matchers', '~> 1.2'
33
+ end
@@ -0,0 +1,73 @@
1
+ require 'spec_helper'
2
+ require 'active_model'
3
+ require 'shoulda-matchers'
4
+
5
+ describe Skynet::Builder::Base do
6
+
7
+ let(:source) { File.join Dir.pwd, 'app', '.' }
8
+ let(:repo) { 'git@github.com:app.git' }
9
+ let(:options) { {url: repo, branch: 'master', destination: '/var/www', type: 'static'} }
10
+ subject { described_class.new 'app', options }
11
+
12
+ describe ".validations" do
13
+ it { should validate_presence_of :app }
14
+ it { should validate_presence_of :url }
15
+ it { should validate_presence_of :branch }
16
+ it { should validate_presence_of :destination }
17
+ it { should ensure_inclusion_of(:type).in_array(%w[static jekyll]).allow_nil(false).allow_blank(false) }
18
+ it { should_not allow_value('base').for :type }
19
+ end
20
+
21
+ describe "#build" do
22
+ context "when valid" do
23
+ it { expect { subject.build }.to_not raise_error }
24
+ end
25
+ context "when invalid" do
26
+ let(:options) { {} }
27
+ it { expect { subject.build }.to raise_error ArgumentError }
28
+ end
29
+ end
30
+
31
+ describe "#build_repository" do
32
+ context "repo already exists" do
33
+ before(:each) { subject.stub(:repo_exists?).and_return true }
34
+
35
+ it "updates the repository" do
36
+ subject.should_receive(:update_repo).with no_args
37
+ subject.send :build_repository
38
+ end
39
+ end
40
+
41
+ context "repo does not exist" do
42
+ before(:each) { subject.stub(:repo_exists?).and_return false }
43
+
44
+ it "creates a new repository" do
45
+ subject.should_receive(:create_repo).with no_args
46
+ subject.send :build_repository
47
+ end
48
+ end
49
+ end
50
+
51
+ describe "#create_repo" do
52
+ before(:each) do
53
+ subject.should_receive(:`).with "rm -rf #{source}"
54
+ subject.should_receive(:`).with "git clone #{repo} app; cd #{source}; git checkout master"
55
+ end
56
+
57
+ it { subject.send :create_repo }
58
+ end
59
+
60
+ describe "#update_repo" do
61
+ before(:each) { subject.should_receive(:`).with "cd #{source}; git checkout master; git pull" }
62
+
63
+ it { subject.send :update_repo }
64
+ end
65
+
66
+ describe "#repo_exists?" do
67
+ before(:each) do
68
+ File.should_receive(:exist?).with File.join(source, '.git')
69
+ end
70
+
71
+ it { subject.send :repo_exists? }
72
+ end
73
+ end
@@ -0,0 +1,22 @@
1
+ require 'spec_helper'
2
+
3
+ describe Skynet::Builder::Jekyll do
4
+
5
+ let(:app) { 'app' }
6
+ let(:dest) { '/var/www/app' }
7
+ let(:options) { {destination: dest} }
8
+ let(:source) { File.join Dir.pwd, app, '.' }
9
+ subject { described_class.new app, options }
10
+
11
+ describe "#build" do
12
+ before(:each) do
13
+ subject.should_receive :build_repository
14
+ subject.stub(:valid?).and_return true
15
+ end
16
+
17
+ it "runs jekyll with the source and destination" do
18
+ subject.should_receive(:`).with "jekyll #{source} #{dest}"
19
+ subject.build
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,29 @@
1
+ require 'spec_helper'
2
+
3
+ describe Skynet::Builder::Static do
4
+
5
+ let(:app) { 'app' }
6
+ let(:dest) { '/var/www/app' }
7
+ let(:options) { {destination: dest} }
8
+ let(:source) { File.join Dir.pwd, app, '.' }
9
+ subject { described_class.new app, options }
10
+
11
+ describe "#build" do
12
+ before(:each) do
13
+ subject.should_receive :build_repository
14
+ subject.stub(:valid?).and_return true
15
+ end
16
+
17
+ it "copies files to the destination" do
18
+ FileUtils.stub :remove_entry_secure
19
+ FileUtils.should_receive(:cp_r).with(source, dest)
20
+ subject.build
21
+ end
22
+
23
+ it "removes .git from the destination" do
24
+ FileUtils.stub :cp_r
25
+ FileUtils.should_receive(:remove_entry_secure).with "#{dest}/.git"
26
+ subject.build
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,27 @@
1
+ require 'spec_helper'
2
+
3
+ describe Skynet::Builder do
4
+
5
+ let(:builder) { mock('builder').as_null_object }
6
+ let(:mock_class) { mock('builder class').as_null_object }
7
+ let(:config) { {type: 'static'} }
8
+ let(:args) { [:app, config] }
9
+
10
+ describe ".for_app" do
11
+ it "initializes a new builder class" do
12
+ described_class.should_receive(:const_get).with('Static').and_return mock_class
13
+ mock_class.should_receive(:new).with(:app, config).and_return builder
14
+
15
+ described_class.for_app *args
16
+ end
17
+ end
18
+
19
+ describe ".build" do
20
+ it "calls build on the new builder" do
21
+ described_class.stub(:for_app).and_return builder
22
+ builder.should_receive(:build).with no_args
23
+
24
+ described_class.build *args
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,9 @@
1
+ require 'bundler/setup'
2
+
3
+ require 'skynet'
4
+
5
+ Skynet.logger = Logger.new File.join(File.dirname(__FILE__), 'test.log')
6
+
7
+ RSpec.configure do |config|
8
+ config.mock_with :rspec
9
+ end
metadata ADDED
@@ -0,0 +1,235 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: skynet-deploy
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.9.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Ryan Ahearn
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-08-22 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: sinatra
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: '1.3'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ~>
28
+ - !ruby/object:Gem::Version
29
+ version: '1.3'
30
+ - !ruby/object:Gem::Dependency
31
+ name: thin
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ~>
36
+ - !ruby/object:Gem::Version
37
+ version: '1.4'
38
+ type: :runtime
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ~>
44
+ - !ruby/object:Gem::Version
45
+ version: '1.4'
46
+ - !ruby/object:Gem::Dependency
47
+ name: json
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ~>
52
+ - !ruby/object:Gem::Version
53
+ version: '1.7'
54
+ type: :runtime
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ~>
60
+ - !ruby/object:Gem::Version
61
+ version: '1.7'
62
+ - !ruby/object:Gem::Dependency
63
+ name: jekyll
64
+ requirement: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ~>
68
+ - !ruby/object:Gem::Version
69
+ version: '0.11'
70
+ type: :runtime
71
+ prerelease: false
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ~>
76
+ - !ruby/object:Gem::Version
77
+ version: '0.11'
78
+ - !ruby/object:Gem::Dependency
79
+ name: thor
80
+ requirement: !ruby/object:Gem::Requirement
81
+ none: false
82
+ requirements:
83
+ - - ~>
84
+ - !ruby/object:Gem::Version
85
+ version: '0.16'
86
+ type: :runtime
87
+ prerelease: false
88
+ version_requirements: !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - ~>
92
+ - !ruby/object:Gem::Version
93
+ version: '0.16'
94
+ - !ruby/object:Gem::Dependency
95
+ name: activesupport
96
+ requirement: !ruby/object:Gem::Requirement
97
+ none: false
98
+ requirements:
99
+ - - ~>
100
+ - !ruby/object:Gem::Version
101
+ version: '3.2'
102
+ type: :runtime
103
+ prerelease: false
104
+ version_requirements: !ruby/object:Gem::Requirement
105
+ none: false
106
+ requirements:
107
+ - - ~>
108
+ - !ruby/object:Gem::Version
109
+ version: '3.2'
110
+ - !ruby/object:Gem::Dependency
111
+ name: activemodel
112
+ requirement: !ruby/object:Gem::Requirement
113
+ none: false
114
+ requirements:
115
+ - - ~>
116
+ - !ruby/object:Gem::Version
117
+ version: '3.2'
118
+ type: :runtime
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ none: false
122
+ requirements:
123
+ - - ~>
124
+ - !ruby/object:Gem::Version
125
+ version: '3.2'
126
+ - !ruby/object:Gem::Dependency
127
+ name: rake
128
+ requirement: !ruby/object:Gem::Requirement
129
+ none: false
130
+ requirements:
131
+ - - ~>
132
+ - !ruby/object:Gem::Version
133
+ version: '0.9'
134
+ type: :development
135
+ prerelease: false
136
+ version_requirements: !ruby/object:Gem::Requirement
137
+ none: false
138
+ requirements:
139
+ - - ~>
140
+ - !ruby/object:Gem::Version
141
+ version: '0.9'
142
+ - !ruby/object:Gem::Dependency
143
+ name: rspec
144
+ requirement: !ruby/object:Gem::Requirement
145
+ none: false
146
+ requirements:
147
+ - - ~>
148
+ - !ruby/object:Gem::Version
149
+ version: '2.11'
150
+ type: :development
151
+ prerelease: false
152
+ version_requirements: !ruby/object:Gem::Requirement
153
+ none: false
154
+ requirements:
155
+ - - ~>
156
+ - !ruby/object:Gem::Version
157
+ version: '2.11'
158
+ - !ruby/object:Gem::Dependency
159
+ name: shoulda-matchers
160
+ requirement: !ruby/object:Gem::Requirement
161
+ none: false
162
+ requirements:
163
+ - - ~>
164
+ - !ruby/object:Gem::Version
165
+ version: '1.2'
166
+ type: :development
167
+ prerelease: false
168
+ version_requirements: !ruby/object:Gem::Requirement
169
+ none: false
170
+ requirements:
171
+ - - ~>
172
+ - !ruby/object:Gem::Version
173
+ version: '1.2'
174
+ description: Sinatra app that listens for GitHub post-receive callbacks and deploys
175
+ your code
176
+ email:
177
+ - ryan@coshx.com
178
+ executables:
179
+ - skynet
180
+ extensions: []
181
+ extra_rdoc_files: []
182
+ files:
183
+ - .gitignore
184
+ - .rspec
185
+ - .rvmrc
186
+ - Gemfile
187
+ - README.md
188
+ - Rakefile
189
+ - bin/skynet
190
+ - lib/skynet.rb
191
+ - lib/skynet/app.rb
192
+ - lib/skynet/builder.rb
193
+ - lib/skynet/builder/base.rb
194
+ - lib/skynet/builder/jekyll.rb
195
+ - lib/skynet/builder/static.rb
196
+ - lib/skynet/cli.rb
197
+ - lib/skynet/templates/config.yml
198
+ - lib/skynet/version.rb
199
+ - skynet.gemspec
200
+ - spec/skynet/builder/base_spec.rb
201
+ - spec/skynet/builder/jekyll_spec.rb
202
+ - spec/skynet/builder/static_spec.rb
203
+ - spec/skynet/builder_spec.rb
204
+ - spec/spec_helper.rb
205
+ homepage: ''
206
+ licenses: []
207
+ post_install_message:
208
+ rdoc_options: []
209
+ require_paths:
210
+ - lib
211
+ required_ruby_version: !ruby/object:Gem::Requirement
212
+ none: false
213
+ requirements:
214
+ - - ! '>='
215
+ - !ruby/object:Gem::Version
216
+ version: '0'
217
+ required_rubygems_version: !ruby/object:Gem::Requirement
218
+ none: false
219
+ requirements:
220
+ - - ! '>='
221
+ - !ruby/object:Gem::Version
222
+ version: 1.3.6
223
+ requirements: []
224
+ rubyforge_project:
225
+ rubygems_version: 1.8.21
226
+ signing_key:
227
+ specification_version: 3
228
+ summary: Sinatra app that listens for GitHub post-receive callbacks and deploys your
229
+ code
230
+ test_files:
231
+ - spec/skynet/builder/base_spec.rb
232
+ - spec/skynet/builder/jekyll_spec.rb
233
+ - spec/skynet/builder/static_spec.rb
234
+ - spec/skynet/builder_spec.rb
235
+ - spec/spec_helper.rb