baboon 1.0.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/README.md +97 -0
- data/Rakefile +10 -0
- data/bin/baboon +4 -0
- data/lib/baboon/cli/options.rb +243 -0
- data/lib/baboon/cli.rb +148 -0
- data/lib/baboon/configuration.rb +38 -0
- data/lib/baboon/logger.rb +153 -0
- data/lib/baboon/version.rb +3 -0
- data/lib/baboon.rb +28 -0
- data/lib/core_ext/string.rb +5 -0
- data/lib/generators/baboon/config/config_generator.rb +17 -0
- data/lib/generators/baboon/config/templates/baboon.yml +11 -0
- data/lib/generators/baboon/install/install_generator.rb +17 -0
- data/lib/generators/baboon/install/templates/baboon.rb +9 -0
- data/spec/lib/baboon/configuration_spec.rb +107 -0
- data/spec/lib/baboon_spec.rb +7 -0
- data/spec/lib/generators/baboon/install/install_generator_spec.rb +1 -0
- data/spec/spec_helper.rb +16 -0
- metadata +295 -0
data/README.md
ADDED
@@ -0,0 +1,97 @@
|
|
1
|
+
# Baboon
|
2
|
+

|
3
|
+
|
4
|
+
[](http://travis-ci.org/amanelis/baboon)
|
5
|
+
[](https://gemnasium.com/amanelis/baboon)
|
6
|
+
|
7
|
+
A simple and light weight deployment library for a ruby on rails application 3.0+. No symlinks, no releases, just git and your application.
|
8
|
+
|
9
|
+
|
10
|
+
# How it works
|
11
|
+
Baboon is simple. You provide your server addresses, environments, path, repository, username and Baboon does the rest. By running a simple `baboon deploy {env}` it will do all neccessary operations you intend for it to do on a full deploy to a production staging or development server. All you need is a working rails application on a server with a git repository.
|
12
|
+
|
13
|
+
---
|
14
|
+
# Install
|
15
|
+
This must be installed under a current rails application. We recommend vendoring or installing through bundler.
|
16
|
+
|
17
|
+
gem install baboon
|
18
|
+
|
19
|
+
---
|
20
|
+
# Configure
|
21
|
+
|
22
|
+
In your Gemfile, then `bundle install`.
|
23
|
+
|
24
|
+
group :development do
|
25
|
+
gem 'baboon'
|
26
|
+
end
|
27
|
+
|
28
|
+
Now that the gem is installed, run the config generator
|
29
|
+
|
30
|
+
rails g baboon:install
|
31
|
+
|
32
|
+
This will build a file into your application under `config/initializers/baboon.rb`. Open this file and start editing. Here is an example of the main configuration options:
|
33
|
+
|
34
|
+
Baboon.configure do |config|
|
35
|
+
config.application = 'Vacuum HQ'
|
36
|
+
config.repository = 'git@github.com:amanelis/vacuum.git'
|
37
|
+
config.deploy_path = '/home/rails/vacuum'
|
38
|
+
config.deploy_user = 'rails
|
39
|
+
config.branch = 'master'
|
40
|
+
config.rails_env = 'production'
|
41
|
+
config.servers = ['192.168.1.1', '192.168.1.2']
|
42
|
+
end
|
43
|
+
|
44
|
+
These must be properly filled out so baboon can properly make deploys.
|
45
|
+
|
46
|
+
---
|
47
|
+
# Commands
|
48
|
+
Once everything is setup you can run `baboon` to see availabe tasks. Start by seeing if your configuration was properlly generated.
|
49
|
+
|
50
|
+
baboon configuration
|
51
|
+
|
52
|
+
Once you see and verify your Baboon.configuration you can now go ahead and test a deploy. For now, lets assume you have everything in your config correct and you are deploying to production:
|
53
|
+
|
54
|
+
baboon deploy
|
55
|
+
|
56
|
+
Thats it? Yeah, thats it! You should see your bundle installing and Baboon running all tasks. Custom tasks coming soon.
|
57
|
+
|
58
|
+
The next commands that will be realeased with future versions of baboon are:
|
59
|
+
|
60
|
+
baboon setup # no manually editing of configuration file
|
61
|
+
baboon check # checks the server and config file for proper configuration
|
62
|
+
baboon migrate # runs pending migrations
|
63
|
+
baboon restart # restarts your server
|
64
|
+
baboon rollback # rolls back your to your previous commit, info in ./log/baboon.log
|
65
|
+
baboon rake # run custom rake tasks on server
|
66
|
+
baboon execute # run a single command on the server
|
67
|
+
baboon shell # open a remote shell with the config user
|
68
|
+
|
69
|
+
---
|
70
|
+
# CLI
|
71
|
+
|
72
|
+
This is coming very soon…
|
73
|
+
|
74
|
+
|
75
|
+
---
|
76
|
+
## Dependencies
|
77
|
+
#### Install dependencies using bundler
|
78
|
+
$ bundle
|
79
|
+
|
80
|
+
#### Run rSpec
|
81
|
+
$ rspec spec/
|
82
|
+
|
83
|
+
## Issues
|
84
|
+
None.
|
85
|
+
|
86
|
+
## Changelog
|
87
|
+
#### 1.0.0
|
88
|
+
Intial setup of the CLI and basic deploys are working.
|
89
|
+
|
90
|
+
## How to contribute
|
91
|
+
|
92
|
+
* Fork the project.
|
93
|
+
* Make your feature addition or bug fix, push to a named branch.
|
94
|
+
* Add a test for any code committed.
|
95
|
+
* Send a pull request.
|
96
|
+
|
97
|
+
Copyright (c) 2011 [Alex Manelis](http://twitter.com/amanelis).
|
data/Rakefile
ADDED
data/bin/baboon
ADDED
@@ -0,0 +1,243 @@
|
|
1
|
+
require 'optparse'
|
2
|
+
|
3
|
+
module Baboon
|
4
|
+
class CLI
|
5
|
+
module Options
|
6
|
+
def self.included(base)
|
7
|
+
base.extend(ClassMethods)
|
8
|
+
end
|
9
|
+
|
10
|
+
module ClassMethods
|
11
|
+
# Return a new CLI instance with the given arguments pre-parsed and
|
12
|
+
# ready for execution.
|
13
|
+
def parse(args)
|
14
|
+
cli = new(args)
|
15
|
+
cli.parse_options!
|
16
|
+
cli
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
# The hash of (parsed) command-line options
|
21
|
+
attr_reader :options
|
22
|
+
|
23
|
+
# Return an OptionParser instance that defines the acceptable command
|
24
|
+
# line switches for Capistrano, and what their corresponding behaviors
|
25
|
+
# are.
|
26
|
+
def option_parser #:nodoc:
|
27
|
+
@logger = Logger.new
|
28
|
+
@option_parser ||= OptionParser.new do |opts|
|
29
|
+
opts.banner = "Usage: #{File.basename($0)} [options] action ..."
|
30
|
+
|
31
|
+
opts.on("-d", "--debug",
|
32
|
+
"Prompts before each remote command execution."
|
33
|
+
) { |value| options[:debug] = true }
|
34
|
+
|
35
|
+
opts.on("-e", "--explain TASK",
|
36
|
+
"Displays help (if available) for the task."
|
37
|
+
) { |value| options[:explain] = value }
|
38
|
+
|
39
|
+
opts.on("-F", "--default-config",
|
40
|
+
"Always use default config, even with -f."
|
41
|
+
) { options[:default_config] = true }
|
42
|
+
|
43
|
+
opts.on("-f", "--file FILE",
|
44
|
+
"A recipe file to load. May be given more than once."
|
45
|
+
) { |value| options[:recipes] << value }
|
46
|
+
|
47
|
+
opts.on("-H", "--long-help", "Explain these options and environment variables.") do
|
48
|
+
long_help
|
49
|
+
exit
|
50
|
+
end
|
51
|
+
|
52
|
+
opts.on("-h", "--help", "Display this help message.") do
|
53
|
+
puts opts
|
54
|
+
exit
|
55
|
+
end
|
56
|
+
|
57
|
+
opts.on("-l", "--logger [STDERR|STDOUT|file]",
|
58
|
+
"Choose logger method. STDERR used by default."
|
59
|
+
) do |value|
|
60
|
+
options[:output] = if value.nil? || value.upcase == 'STDERR'
|
61
|
+
# Using default logger.
|
62
|
+
nil
|
63
|
+
elsif value.upcase == 'STDOUT'
|
64
|
+
$stdout
|
65
|
+
else
|
66
|
+
value
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
opts.on("-n", "--dry-run",
|
71
|
+
"Prints out commands without running them."
|
72
|
+
) { |value| options[:dry_run] = true }
|
73
|
+
|
74
|
+
opts.on("-p", "--password",
|
75
|
+
"Immediately prompt for the password."
|
76
|
+
) { options[:password] = nil }
|
77
|
+
|
78
|
+
opts.on("-q", "--quiet",
|
79
|
+
"Make the output as quiet as possible."
|
80
|
+
) { options[:verbose] = 0 }
|
81
|
+
|
82
|
+
opts.on("-r", "--preserve-roles",
|
83
|
+
"Preserve task roles"
|
84
|
+
) { options[:preserve_roles] = true }
|
85
|
+
|
86
|
+
opts.on("-S", "--set-before NAME=VALUE",
|
87
|
+
"Set a variable before the recipes are loaded."
|
88
|
+
) do |pair|
|
89
|
+
name, value = pair.split(/=/, 2)
|
90
|
+
options[:pre_vars][name.to_sym] = value
|
91
|
+
end
|
92
|
+
|
93
|
+
opts.on("-s", "--set NAME=VALUE",
|
94
|
+
"Set a variable after the recipes are loaded."
|
95
|
+
) do |pair|
|
96
|
+
name, value = pair.split(/=/, 2)
|
97
|
+
options[:vars][name.to_sym] = value
|
98
|
+
end
|
99
|
+
|
100
|
+
opts.on("-T", "--tasks [PATTERN]",
|
101
|
+
"List all tasks (matching optional PATTERN) in the loaded recipe files."
|
102
|
+
) do |value|
|
103
|
+
options[:tasks] = if value
|
104
|
+
value
|
105
|
+
else
|
106
|
+
true
|
107
|
+
end
|
108
|
+
options[:verbose] ||= 0
|
109
|
+
end
|
110
|
+
|
111
|
+
opts.on("-t", "--tool",
|
112
|
+
"Abbreviates the output of -T for tool integration."
|
113
|
+
) { options[:tool] = true }
|
114
|
+
|
115
|
+
opts.on("-V", "--version",
|
116
|
+
"Display the Capistrano version, and exit."
|
117
|
+
) do
|
118
|
+
require 'capistrano/version'
|
119
|
+
puts "Capistrano v#{Capistrano::Version}"
|
120
|
+
exit
|
121
|
+
end
|
122
|
+
|
123
|
+
opts.on("-v", "--verbose",
|
124
|
+
"Be more verbose. May be given more than once."
|
125
|
+
) do
|
126
|
+
options[:verbose] ||= 0
|
127
|
+
options[:verbose] += 1
|
128
|
+
end
|
129
|
+
|
130
|
+
opts.on("-X", "--skip-system-config",
|
131
|
+
"Don't load the system config file (capistrano.conf)"
|
132
|
+
) { options.delete(:sysconf) }
|
133
|
+
|
134
|
+
opts.on("-x", "--skip-user-config",
|
135
|
+
"Don't load the user config file (.caprc)"
|
136
|
+
) { options.delete(:dotfile) }
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
# If the arguments to the command are empty, this will print the
|
141
|
+
# allowed options and exit. Otherwise, it will parse the command
|
142
|
+
# line and set up any default options.
|
143
|
+
def parse_options! #:nodoc:
|
144
|
+
@options = { :recipes => [], :actions => [],
|
145
|
+
:vars => {}, :pre_vars => {},
|
146
|
+
:sysconf => default_sysconf, :dotfile => default_dotfile }
|
147
|
+
|
148
|
+
if args.empty?
|
149
|
+
warn "Please specify at least one action to execute."
|
150
|
+
warn option_parser
|
151
|
+
exit
|
152
|
+
end
|
153
|
+
|
154
|
+
option_parser.parse!(args)
|
155
|
+
|
156
|
+
coerce_variable_types!
|
157
|
+
|
158
|
+
# if no verbosity has been specified, be verbose
|
159
|
+
options[:verbose] = 3 if !options.has_key?(:verbose)
|
160
|
+
|
161
|
+
look_for_default_recipe_file! if options[:default_config] || options[:recipes].empty?
|
162
|
+
extract_environment_variables!
|
163
|
+
|
164
|
+
options[:actions].concat(args)
|
165
|
+
|
166
|
+
password = options.has_key?(:password)
|
167
|
+
options[:password] = Proc.new { self.class.password_prompt }
|
168
|
+
options[:password] = options[:password].call if password
|
169
|
+
end
|
170
|
+
|
171
|
+
# Extracts name=value pairs from the remaining command-line arguments
|
172
|
+
# and assigns them as environment variables.
|
173
|
+
def extract_environment_variables! #:nodoc:
|
174
|
+
args.delete_if do |arg|
|
175
|
+
next unless arg.match(/^(\w+)=(.*)$/)
|
176
|
+
ENV[$1] = $2
|
177
|
+
end
|
178
|
+
end
|
179
|
+
|
180
|
+
# Looks for a default recipe file in the current directory.
|
181
|
+
def look_for_default_recipe_file! #:nodoc:
|
182
|
+
current = Dir.pwd
|
183
|
+
|
184
|
+
loop do
|
185
|
+
%w(Capfile capfile).each do |file|
|
186
|
+
if File.file?(file)
|
187
|
+
options[:recipes] << file
|
188
|
+
@logger.info "Using recipes from #{File.join(current,file)}"
|
189
|
+
return
|
190
|
+
end
|
191
|
+
end
|
192
|
+
|
193
|
+
pwd = Dir.pwd
|
194
|
+
Dir.chdir("..")
|
195
|
+
break if pwd == Dir.pwd # if changing the directory made no difference, then we're at the top
|
196
|
+
end
|
197
|
+
|
198
|
+
Dir.chdir(current)
|
199
|
+
end
|
200
|
+
|
201
|
+
def default_sysconf #:nodoc:
|
202
|
+
File.join(sysconf_directory, "capistrano.conf")
|
203
|
+
end
|
204
|
+
|
205
|
+
def default_dotfile #:nodoc:
|
206
|
+
File.join(home_directory, ".caprc")
|
207
|
+
end
|
208
|
+
|
209
|
+
def sysconf_directory #:nodoc:
|
210
|
+
# TODO if anyone cares, feel free to submit a patch that uses a more
|
211
|
+
# appropriate location for this file in Windows.
|
212
|
+
ENV["SystemRoot"] || '/etc'
|
213
|
+
end
|
214
|
+
|
215
|
+
def home_directory #:nodoc:
|
216
|
+
ENV["HOME"] ||
|
217
|
+
(ENV["HOMEPATH"] && "#{ENV["HOMEDRIVE"]}#{ENV["HOMEPATH"]}") ||
|
218
|
+
"/"
|
219
|
+
end
|
220
|
+
|
221
|
+
def coerce_variable_types!
|
222
|
+
[:pre_vars, :vars].each do |collection|
|
223
|
+
options[collection].keys.each do |key|
|
224
|
+
options[collection][key] = coerce_variable(options[collection][key])
|
225
|
+
end
|
226
|
+
end
|
227
|
+
end
|
228
|
+
|
229
|
+
def coerce_variable(value)
|
230
|
+
case value
|
231
|
+
when /^"(.*)"$/ then $1
|
232
|
+
when /^'(.*)'$/ then $1
|
233
|
+
when /^\d+$/ then value.to_i
|
234
|
+
when /^\d+\.\d*$/ then value.to_f
|
235
|
+
when "true" then true
|
236
|
+
when "false" then false
|
237
|
+
when "nil" then nil
|
238
|
+
else value
|
239
|
+
end
|
240
|
+
end
|
241
|
+
end
|
242
|
+
end
|
243
|
+
end
|
data/lib/baboon/cli.rb
ADDED
@@ -0,0 +1,148 @@
|
|
1
|
+
require 'baboon'
|
2
|
+
require 'baboon/configuration'
|
3
|
+
require 'baboon/logger'
|
4
|
+
|
5
|
+
require 'thor'
|
6
|
+
require 'net/ssh'
|
7
|
+
|
8
|
+
module Baboon
|
9
|
+
class Error
|
10
|
+
class << self
|
11
|
+
def stop reason
|
12
|
+
raise StandardError, reason
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
class Util
|
18
|
+
class << self
|
19
|
+
def read_configuration(file)
|
20
|
+
configuration = []
|
21
|
+
line_number = 0
|
22
|
+
text = File.open(file).read
|
23
|
+
text.gsub!(/\r\n?/, '\n')
|
24
|
+
|
25
|
+
text.each_line do |line|
|
26
|
+
next if line.include?('Baboon.configure')
|
27
|
+
next if line.include?('end')
|
28
|
+
line.gsub!(/^(.*)\s=\s/, '')
|
29
|
+
line.gsub!('\'', '')
|
30
|
+
line.strip!
|
31
|
+
|
32
|
+
configuration << { BABOON_CONFIGURATION_OPTIONS[line_number] => line }
|
33
|
+
line_number += 1
|
34
|
+
end
|
35
|
+
|
36
|
+
return configuration.reduce({}, :merge)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
class Cli < Thor
|
42
|
+
attr_accessor :logger, :configuration
|
43
|
+
|
44
|
+
def initialize(*args)
|
45
|
+
super
|
46
|
+
@logger ||= Logger.new({level: 3, disable_formatters: false})
|
47
|
+
|
48
|
+
$stdout.sync = true
|
49
|
+
|
50
|
+
# Load the users baboon configuration
|
51
|
+
if File.exists?("config/initializers/baboon.rb")
|
52
|
+
@configuration = Util.read_configuration("config/initializers/baboon.rb")
|
53
|
+
|
54
|
+
Baboon.configure do |config|
|
55
|
+
config.application = @configuration[:application]
|
56
|
+
config.repository = @configuration[:repository]
|
57
|
+
config.deploy_path = @configuration[:deploy_path]
|
58
|
+
config.deploy_user = @configuration[:deploy_user]
|
59
|
+
config.branch = @configuration[:branch]
|
60
|
+
config.rails_env = @configuration[:rails_env]
|
61
|
+
config.servers = @configuration[:servers]
|
62
|
+
end
|
63
|
+
else
|
64
|
+
#Error.stop("Baboon says there is no configuration file at: config/initializers/baboon.rb. Please run `rails g baboon:install`")
|
65
|
+
printf @logger.format("Baboon says there is no configuration file at config/initializers/baboon.rb, run the following command", "31", 1)
|
66
|
+
printf @logger.format("USAGE: rails g baboon:install", "35", 1)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
desc "deploy", "Starts a real deploy to a server"
|
71
|
+
def deploy
|
72
|
+
printf @logger.format(" == Baboon starting deploy", "32", 1)
|
73
|
+
|
74
|
+
# Essentially these are the instructions we need run for the Ubuntu 11.04
|
75
|
+
instructions = [
|
76
|
+
"cd #{Baboon.configuration.deploy_path} && bundle install",
|
77
|
+
"cd #{Baboon.configuration.deploy_path} && git fetch",
|
78
|
+
"cd #{Baboon.configuration.deploy_path} && git checkout #{Baboon.configuration.branch.to_s}",
|
79
|
+
"cd #{Baboon.configuration.deploy_path} && git merge origin/#{Baboon.configuration.branch.to_s}",
|
80
|
+
"cd #{Baboon.configuration.deploy_path} && touch tmp/restart.txt"
|
81
|
+
]
|
82
|
+
|
83
|
+
# Vars for connecting via ssh to the server
|
84
|
+
credentials = {
|
85
|
+
user: Baboon.configuration.deploy_user.to_s,
|
86
|
+
host: 'ec2-50-19-131-228.compute-1.amazonaws.com'
|
87
|
+
}
|
88
|
+
|
89
|
+
Net::SSH.start(credentials[:host], credentials[:user]) do |session|
|
90
|
+
instructions.each do |instruction|
|
91
|
+
puts "instruction executing: #{instruction}"
|
92
|
+
puts ""
|
93
|
+
session.exec instruction
|
94
|
+
session.loop
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
printf @logger.format(" == Baboon deploy Complete", "31", 1)
|
99
|
+
end
|
100
|
+
|
101
|
+
desc "configuration", "Shows the current configuration for baboon"
|
102
|
+
def configuration
|
103
|
+
printf @logger.format("Baboon[Application]: #{Baboon.configuration.application}", "37", 1)
|
104
|
+
printf @logger.format("Baboon[Repository]: #{Baboon.configuration.repository}", "37", 1)
|
105
|
+
printf @logger.format("Baboon[Deploy_path]: #{Baboon.configuration.deploy_path}", "37", 1)
|
106
|
+
printf @logger.format("Baboon[Deploy_user]: #{Baboon.configuration.deploy_user}", "37", 1)
|
107
|
+
printf @logger.format("Baboon[Branch]: #{Baboon.configuration.branch}", "37", 1)
|
108
|
+
printf @logger.format("Baboon[Rails_env]: #{Baboon.configuration.rails_env}", "37", 1)
|
109
|
+
printf @logger.format("Baboon[Servers]: #{Baboon.configuration.servers}", "37", 1)
|
110
|
+
end
|
111
|
+
|
112
|
+
# desc "init", "Generates deployment customization scripts for your app"
|
113
|
+
# def init
|
114
|
+
# require 'generators/baboon/install/intall_generator'
|
115
|
+
# InstallGenerator::start([])
|
116
|
+
# end
|
117
|
+
#
|
118
|
+
# desc "restart", "Restarts the application on the server"
|
119
|
+
# def restart
|
120
|
+
# run "cd #{deploy_to} && deploy/restart | tee -a log/deploy.log"
|
121
|
+
# end
|
122
|
+
#
|
123
|
+
# desc "rollback", "Rolls back the checkout to before the last push"
|
124
|
+
# def rollback
|
125
|
+
# run "cd #{deploy_to} && git reset --hard ORIG_HEAD"
|
126
|
+
# invoke :restart
|
127
|
+
# end
|
128
|
+
#
|
129
|
+
# desc "log", "Shows the last part of the deploy log on the server"
|
130
|
+
# method_option :tail, :aliases => '-t', :type => :boolean, :default => false
|
131
|
+
# method_option :lines, :aliases => '-l', :type => :numeric, :default => 20
|
132
|
+
# def log(n = nil)
|
133
|
+
# tail_args = options.tail? ? '-f' : "-n#{n || options.lines}"
|
134
|
+
# run "tail #{tail_args} #{deploy_to}/log/deploy.log"
|
135
|
+
# end
|
136
|
+
#
|
137
|
+
# desc "upload <files>", "Copy local files to the remote app"
|
138
|
+
# def upload(*files)
|
139
|
+
# files = files.map { |f| Dir[f.strip] }.flatten
|
140
|
+
# abort "Error: Specify at least one file to upload" if files.empty?
|
141
|
+
#
|
142
|
+
# scp_upload files.inject({}) { |all, file|
|
143
|
+
# all[file] = File.join(deploy_to, file)
|
144
|
+
# all
|
145
|
+
# }
|
146
|
+
# end
|
147
|
+
end
|
148
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require 'baboon'
|
2
|
+
|
3
|
+
module Baboon
|
4
|
+
# Baboon.configuration => output of configuration options
|
5
|
+
class << self
|
6
|
+
attr_accessor :configuration
|
7
|
+
end
|
8
|
+
|
9
|
+
# This method should be called with a block, even though none are given
|
10
|
+
# in the parameters of the method
|
11
|
+
def self.configure
|
12
|
+
self.configuration ||= Configuration.new
|
13
|
+
yield configuration
|
14
|
+
end
|
15
|
+
|
16
|
+
class Configuration
|
17
|
+
def initialize
|
18
|
+
# Cannot call attr inside of class, need to class_eval it
|
19
|
+
class << self
|
20
|
+
self
|
21
|
+
end.class_eval do
|
22
|
+
# Define all of the attributes
|
23
|
+
BABOON_CONFIGURATION_OPTIONS.each do |name|
|
24
|
+
attr_accessor name
|
25
|
+
|
26
|
+
# For each given symbol we generate accessor method that sets option's
|
27
|
+
# value being called with an argument, or returns option's current value
|
28
|
+
# when called without arguments
|
29
|
+
define_method name do |*values|
|
30
|
+
value = values.first
|
31
|
+
value ? self.send("#{name}=", value) : instance_variable_get("@#{name}")
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
# Initialize defaults
|
36
|
+
end # initialize
|
37
|
+
end # class Configuration
|
38
|
+
end # module Baboon
|
@@ -0,0 +1,153 @@
|
|
1
|
+
module Baboon
|
2
|
+
class Logger
|
3
|
+
attr_accessor :level, :device, :disable_formatters
|
4
|
+
|
5
|
+
IMPORTANT = 0
|
6
|
+
INFO = 1
|
7
|
+
DEBUG = 2
|
8
|
+
TRACE = 3
|
9
|
+
|
10
|
+
MAX_LEVEL = 3
|
11
|
+
|
12
|
+
COLORS = {
|
13
|
+
:none => "0",
|
14
|
+
:black => "30",
|
15
|
+
:red => "31",
|
16
|
+
:green => "32",
|
17
|
+
:yellow => "33",
|
18
|
+
:blue => "34",
|
19
|
+
:magenta => "35",
|
20
|
+
:cyan => "36",
|
21
|
+
:white => "37"
|
22
|
+
}
|
23
|
+
|
24
|
+
STYLES = {
|
25
|
+
:bright => 1,
|
26
|
+
:dim => 2,
|
27
|
+
:underscore => 4,
|
28
|
+
:blink => 5,
|
29
|
+
:reverse => 7,
|
30
|
+
:hidden => 8
|
31
|
+
}
|
32
|
+
|
33
|
+
# Set up default formatters
|
34
|
+
@formatters = [
|
35
|
+
# TRACE
|
36
|
+
{ :match => /command finished/, :color => :white, :style => :dim, :level => 3, :priority => -10 },
|
37
|
+
{ :match => /executing locally/, :color => :yellow, :level => 3, :priority => -20 },
|
38
|
+
|
39
|
+
# DEBUG
|
40
|
+
{ :match => /executing `.*/, :color => :green, :level => 2, :priority => -10, :timestamp => true },
|
41
|
+
{ :match => /.*/, :color => :yellow, :level => 2, :priority => -30 },
|
42
|
+
|
43
|
+
# INFO
|
44
|
+
{ :match => /.*out\] (fatal:|ERROR:).*/, :color => :red, :level => 1, :priority => -10 },
|
45
|
+
{ :match => /Permission denied/, :color => :red, :level => 1, :priority => -20 },
|
46
|
+
{ :match => /sh: .+: command not found/, :color => :magenta, :level => 1, :priority => -30 },
|
47
|
+
|
48
|
+
# IMPORTANT
|
49
|
+
{ :match => /^err ::/, :color => :red, :level => 0, :priority => -10 },
|
50
|
+
{ :match => /.*/, :color => :blue, :level => 0, :priority => -20 }
|
51
|
+
]
|
52
|
+
|
53
|
+
class << self
|
54
|
+
def add_formatter(options) #:nodoc:
|
55
|
+
@formatters.push(options)
|
56
|
+
@sorted_formatters = nil
|
57
|
+
end
|
58
|
+
|
59
|
+
def sorted_formatters
|
60
|
+
# Sort matchers in reverse order so we can break if we found a match.
|
61
|
+
@sorted_formatters ||= @formatters.sort_by { |i| -(i[:priority] || i[:prio] || 0) }
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def initialize(options={})
|
66
|
+
output = options[:output] || $stderr
|
67
|
+
if output.respond_to?(:puts)
|
68
|
+
@device = output
|
69
|
+
else
|
70
|
+
@device = File.open(output.to_str, "a")
|
71
|
+
@needs_close = true
|
72
|
+
end
|
73
|
+
|
74
|
+
@options = options
|
75
|
+
@level = options[:level] || 0
|
76
|
+
@disable_formatters = options[:disable_formatters]
|
77
|
+
end
|
78
|
+
|
79
|
+
def close
|
80
|
+
device.close if @needs_close
|
81
|
+
end
|
82
|
+
|
83
|
+
def log(level, message, line_prefix=nil)
|
84
|
+
if level <= self.level
|
85
|
+
# Only format output if device is a TTY or formatters are not disabled
|
86
|
+
if device.tty? && !@disable_formatters
|
87
|
+
color = :none
|
88
|
+
style = nil
|
89
|
+
|
90
|
+
Logger.sorted_formatters.each do |formatter|
|
91
|
+
if (formatter[:level] == level || formatter[:level].nil?)
|
92
|
+
if message =~ formatter[:match] || line_prefix =~ formatter[:match]
|
93
|
+
color = formatter[:color] if formatter[:color]
|
94
|
+
style = formatter[:style] || formatter[:attribute] # (support original cap colors)
|
95
|
+
message.gsub!(formatter[:match], formatter[:replace]) if formatter[:replace]
|
96
|
+
message = formatter[:prepend] + message unless formatter[:prepend].nil?
|
97
|
+
message = message + formatter[:append] unless formatter[:append].nil?
|
98
|
+
message = Time.now.strftime('%Y-%m-%d %T') + ' ' + message if formatter[:timestamp]
|
99
|
+
break unless formatter[:replace]
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
if color == :hide
|
105
|
+
# Don't do anything if color is set to :hide
|
106
|
+
return false
|
107
|
+
end
|
108
|
+
|
109
|
+
term_color = COLORS[color]
|
110
|
+
term_style = STYLES[style]
|
111
|
+
|
112
|
+
# Don't format message if no color or style
|
113
|
+
unless color == :none and style.nil?
|
114
|
+
unless line_prefix.nil?
|
115
|
+
line_prefix = format(line_prefix, term_color, term_style, nil)
|
116
|
+
end
|
117
|
+
message = format(message, term_color, term_style)
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
indent = "%*s" % [MAX_LEVEL, "*" * (MAX_LEVEL - level)]
|
122
|
+
(RUBY_VERSION >= "1.9" ? message.lines : message).each do |line|
|
123
|
+
if line_prefix
|
124
|
+
device.puts "#{indent} [#{line_prefix}] #{line.strip}\n"
|
125
|
+
else
|
126
|
+
device.puts "#{indent} #{line.strip}\n"
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
def important(message, line_prefix=nil)
|
133
|
+
log(IMPORTANT, message, line_prefix)
|
134
|
+
end
|
135
|
+
|
136
|
+
def info(message, line_prefix=nil)
|
137
|
+
log(INFO, message, line_prefix)
|
138
|
+
end
|
139
|
+
|
140
|
+
def debug(message, line_prefix=nil)
|
141
|
+
log(DEBUG, message, line_prefix)
|
142
|
+
end
|
143
|
+
|
144
|
+
def trace(message, line_prefix=nil)
|
145
|
+
log(TRACE, message, line_prefix)
|
146
|
+
end
|
147
|
+
|
148
|
+
def format(message, color, style, nl = "\n")
|
149
|
+
style = "#{style};" if style
|
150
|
+
"\e[#{style}#{color}m" + message.to_s.strip + "\e[0m#{nl}"
|
151
|
+
end
|
152
|
+
end
|
153
|
+
end
|
data/lib/baboon.rb
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
# Standard configuration options for Baboon
|
2
|
+
#
|
3
|
+
# These options are important at this location. Change here and they
|
4
|
+
# are persisted throughout the entire Baboon configuration and as well
|
5
|
+
# as the config initializer baboon.rb file that is generated in the
|
6
|
+
# standing Rails application.
|
7
|
+
#
|
8
|
+
# option[:application] String => Has no berrance to the deployment, call it whatever.
|
9
|
+
# option[:repository] String => For now baboon only supports Git. This should be the actual Git repository of the application baboon will deploy.
|
10
|
+
# option[:deploy_path] String => The actual deploy path the application will sit at on the server. Exactly where the app's .git/ folder would be.
|
11
|
+
# option[:deploy_user] String/Symbol => The user baboon will be authenticating with on the server. Should have your key stored for optimal authentication.
|
12
|
+
# option[:branch] String/Symbol => The branch on your repository baboon will be pulling from.
|
13
|
+
# option[:rails_env] String/Symbol => For rake tasks to be run properly on your server, baboon needs to know what env it will be running on your server.
|
14
|
+
# option[:server] Array[String] => This will be an array of ip addresses of the servers baboon will deploy to.
|
15
|
+
BABOON_CONFIGURATION_OPTIONS = [
|
16
|
+
:application, # => This will be the name of the Application - not the directory
|
17
|
+
:repository, # => This will be the :scm of the repository the application will be cloning
|
18
|
+
:deploy_path, # => This will be the actual deploy path of the application, should have /home/#{user}/app
|
19
|
+
:deploy_user, # => This will be the user the system will authenticate with to do the deploy, should have sudo
|
20
|
+
:branch, # => Branch we will be cloning from on GIT
|
21
|
+
:rails_env, # => The rails environment the sever will be running
|
22
|
+
:servers # => An array of servers baboon will push to
|
23
|
+
]
|
24
|
+
|
25
|
+
require 'baboon/configuration'
|
26
|
+
require 'baboon/cli'
|
27
|
+
require 'baboon/logger'
|
28
|
+
require 'baboon/version'
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'rails/generators/base'
|
2
|
+
|
3
|
+
module Baboon
|
4
|
+
module Generators
|
5
|
+
class ConfigGenerator < Rails::Generators::Base
|
6
|
+
desc 'Creates a yaml for Baboon at config/baboon.yml'
|
7
|
+
|
8
|
+
def self.source_root
|
9
|
+
@source_root ||= File.expand_path(File.join(File.dirname(__FILE__), 'templates'))
|
10
|
+
end
|
11
|
+
|
12
|
+
def create_initializer_file
|
13
|
+
template "baboon.yml", "config/baboon.yml"
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
application: Your Application Name
|
2
|
+
repository: git@github.com:your_project.git
|
3
|
+
deploy_path: /path/to/project
|
4
|
+
deploy_user: rails
|
5
|
+
deploy_branch: master
|
6
|
+
|
7
|
+
environments:
|
8
|
+
production:
|
9
|
+
servers: [192.168.1.100, 192.168.1.101]
|
10
|
+
staging:
|
11
|
+
servers: [10.0.0.1, 10.0.0.2]
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'rails/generators/base'
|
2
|
+
|
3
|
+
module Baboon
|
4
|
+
module Generators
|
5
|
+
class InstallGenerator < Rails::Generators::Base
|
6
|
+
desc 'Creates an initializer for Baboon at config/initializers/baboon.rb'
|
7
|
+
|
8
|
+
def self.source_root
|
9
|
+
@source_root ||= File.expand_path(File.join(File.dirname(__FILE__), 'templates'))
|
10
|
+
end
|
11
|
+
|
12
|
+
def create_initializer_file
|
13
|
+
template "baboon.rb", "config/initializers/baboon.rb"
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,9 @@
|
|
1
|
+
Baboon.configure do |config|
|
2
|
+
config.application = 'NAME OF YOUR APPLICATION'
|
3
|
+
config.repository = 'git@github.com:{some-project}.git'
|
4
|
+
config.deploy_path = '{path_to_application_on_server}'
|
5
|
+
config.deploy_user = 'rails'
|
6
|
+
config.branch = 'master'
|
7
|
+
config.rails_env = 'production'
|
8
|
+
config.servers = ['server_1', 'server_2']
|
9
|
+
end
|
@@ -0,0 +1,107 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Baboon::Configuration do
|
4
|
+
describe 'configuration object should respond accordingly if not configured' do
|
5
|
+
before do
|
6
|
+
Baboon.configure do |config|; end
|
7
|
+
end
|
8
|
+
|
9
|
+
context 'when nothing is given for application' do
|
10
|
+
it 'should not be nil' do
|
11
|
+
Baboon.configuration.application.should == nil
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
context 'when nothing is given for repository' do
|
16
|
+
it 'should not be nil' do
|
17
|
+
Baboon.configuration.repository.should == nil
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
context 'when nothing is given for deploy_path' do
|
22
|
+
it 'should not be nil' do
|
23
|
+
Baboon.configuration.deploy_path.should == nil
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
context 'when nothing is given for deploy_user' do
|
28
|
+
it 'should not be nil' do
|
29
|
+
Baboon.configuration.deploy_user.should == nil
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
context 'when nothing is given for branch' do
|
34
|
+
it 'should not be nil' do
|
35
|
+
Baboon.configuration.branch.should == nil
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
context 'when nothing is given for rails_env' do
|
40
|
+
it 'should not be nil' do
|
41
|
+
Baboon.configuration.rails_env.should == nil
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
context 'when nothing is given for servers' do
|
46
|
+
it 'should not be nil' do
|
47
|
+
Baboon.configuration.servers.should == nil
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
describe 'configuration object should respond accordingly if is configured' do
|
53
|
+
before do
|
54
|
+
Baboon.configure do |config|
|
55
|
+
config.application = 'console'
|
56
|
+
config.repository = 'git@github.com:128lines/console.fm.git'
|
57
|
+
config.deploy_path = '/home/rails/console.fm/'
|
58
|
+
config.deploy_user = :rails
|
59
|
+
config.branch = :master
|
60
|
+
config.rails_env = :production
|
61
|
+
config.servers = ['server_1', 'server_2']
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
context 'when a application is assigned' do
|
66
|
+
it 'should not be nil' do
|
67
|
+
Baboon.configuration.application.should eq('console')
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
context 'when a repository is assigned' do
|
72
|
+
it 'should not be nil' do
|
73
|
+
Baboon.configuration.repository.should eq('git@github.com:128lines/console.fm.git')
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
context 'when a deploy_path is assigned' do
|
78
|
+
it 'should not be nil' do
|
79
|
+
Baboon.configuration.deploy_path.should eq('/home/rails/console.fm/')
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
context 'when a deploy_user is assigned' do
|
84
|
+
it 'should not be nil' do
|
85
|
+
Baboon.configuration.deploy_user.should eq(:rails)
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
context 'when a branch is assigned' do
|
90
|
+
it 'should not be nil' do
|
91
|
+
Baboon.configuration.branch.should eq(:master)
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
context 'when a rails_env is assigned' do
|
96
|
+
it 'should not be nil' do
|
97
|
+
Baboon.configuration.rails_env.should eq(:production)
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
context 'when a server is assigned' do
|
102
|
+
it 'should not be nil' do
|
103
|
+
Baboon.configuration.servers.should eq(['server_1', 'server_2'])
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
require 'spec_helper'
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'simplecov'
|
2
|
+
SimpleCov.start do
|
3
|
+
add_group 'Baboon', 'lib/'
|
4
|
+
end
|
5
|
+
|
6
|
+
ENV['RAILS_ENV'] ||= 'test'
|
7
|
+
require File.expand_path('../../lib/baboon', __FILE__)
|
8
|
+
|
9
|
+
PROJECT_ROOT = File.expand_path('../..', __FILE__)
|
10
|
+
$LOAD_PATH << File.join(PROJECT_ROOT, 'lib')
|
11
|
+
|
12
|
+
RSpec.configure do |config|
|
13
|
+
config.color_enabled = true
|
14
|
+
config.tty = true
|
15
|
+
config.mock_with :rspec
|
16
|
+
end
|
metadata
ADDED
@@ -0,0 +1,295 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: baboon
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Alex Manelis
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2013-02-06 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: thor
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
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: '0'
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: net-ssh
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ! '>='
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '0'
|
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: '0'
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: net-scp
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
51
|
+
- - ! '>='
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '0'
|
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: '0'
|
62
|
+
- !ruby/object:Gem::Dependency
|
63
|
+
name: rake
|
64
|
+
requirement: !ruby/object:Gem::Requirement
|
65
|
+
none: false
|
66
|
+
requirements:
|
67
|
+
- - ! '>='
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '0'
|
70
|
+
type: :development
|
71
|
+
prerelease: false
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ! '>='
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: '0'
|
78
|
+
- !ruby/object:Gem::Dependency
|
79
|
+
name: rails
|
80
|
+
requirement: !ruby/object:Gem::Requirement
|
81
|
+
none: false
|
82
|
+
requirements:
|
83
|
+
- - ! '>='
|
84
|
+
- !ruby/object:Gem::Version
|
85
|
+
version: '0'
|
86
|
+
type: :development
|
87
|
+
prerelease: false
|
88
|
+
version_requirements: !ruby/object:Gem::Requirement
|
89
|
+
none: false
|
90
|
+
requirements:
|
91
|
+
- - ! '>='
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
version: '0'
|
94
|
+
- !ruby/object:Gem::Dependency
|
95
|
+
name: rspec
|
96
|
+
requirement: !ruby/object:Gem::Requirement
|
97
|
+
none: false
|
98
|
+
requirements:
|
99
|
+
- - ! '>='
|
100
|
+
- !ruby/object:Gem::Version
|
101
|
+
version: '0'
|
102
|
+
type: :development
|
103
|
+
prerelease: false
|
104
|
+
version_requirements: !ruby/object:Gem::Requirement
|
105
|
+
none: false
|
106
|
+
requirements:
|
107
|
+
- - ! '>='
|
108
|
+
- !ruby/object:Gem::Version
|
109
|
+
version: '0'
|
110
|
+
- !ruby/object:Gem::Dependency
|
111
|
+
name: rspec-core
|
112
|
+
requirement: !ruby/object:Gem::Requirement
|
113
|
+
none: false
|
114
|
+
requirements:
|
115
|
+
- - ! '>='
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '0'
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
none: false
|
122
|
+
requirements:
|
123
|
+
- - ! '>='
|
124
|
+
- !ruby/object:Gem::Version
|
125
|
+
version: '0'
|
126
|
+
- !ruby/object:Gem::Dependency
|
127
|
+
name: rspec-mocks
|
128
|
+
requirement: !ruby/object:Gem::Requirement
|
129
|
+
none: false
|
130
|
+
requirements:
|
131
|
+
- - ! '>='
|
132
|
+
- !ruby/object:Gem::Version
|
133
|
+
version: '0'
|
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'
|
142
|
+
- !ruby/object:Gem::Dependency
|
143
|
+
name: rspec-rails
|
144
|
+
requirement: !ruby/object:Gem::Requirement
|
145
|
+
none: false
|
146
|
+
requirements:
|
147
|
+
- - ! '>='
|
148
|
+
- !ruby/object:Gem::Version
|
149
|
+
version: '0'
|
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: '0'
|
158
|
+
- !ruby/object:Gem::Dependency
|
159
|
+
name: rspec-expectations
|
160
|
+
requirement: !ruby/object:Gem::Requirement
|
161
|
+
none: false
|
162
|
+
requirements:
|
163
|
+
- - ! '>='
|
164
|
+
- !ruby/object:Gem::Version
|
165
|
+
version: '0'
|
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: '0'
|
174
|
+
- !ruby/object:Gem::Dependency
|
175
|
+
name: shoulda-matchers
|
176
|
+
requirement: !ruby/object:Gem::Requirement
|
177
|
+
none: false
|
178
|
+
requirements:
|
179
|
+
- - ! '>='
|
180
|
+
- !ruby/object:Gem::Version
|
181
|
+
version: '0'
|
182
|
+
type: :development
|
183
|
+
prerelease: false
|
184
|
+
version_requirements: !ruby/object:Gem::Requirement
|
185
|
+
none: false
|
186
|
+
requirements:
|
187
|
+
- - ! '>='
|
188
|
+
- !ruby/object:Gem::Version
|
189
|
+
version: '0'
|
190
|
+
- !ruby/object:Gem::Dependency
|
191
|
+
name: simplecov
|
192
|
+
requirement: !ruby/object:Gem::Requirement
|
193
|
+
none: false
|
194
|
+
requirements:
|
195
|
+
- - ! '>='
|
196
|
+
- !ruby/object:Gem::Version
|
197
|
+
version: '0'
|
198
|
+
type: :development
|
199
|
+
prerelease: false
|
200
|
+
version_requirements: !ruby/object:Gem::Requirement
|
201
|
+
none: false
|
202
|
+
requirements:
|
203
|
+
- - ! '>='
|
204
|
+
- !ruby/object:Gem::Version
|
205
|
+
version: '0'
|
206
|
+
- !ruby/object:Gem::Dependency
|
207
|
+
name: capybara
|
208
|
+
requirement: !ruby/object:Gem::Requirement
|
209
|
+
none: false
|
210
|
+
requirements:
|
211
|
+
- - ! '>='
|
212
|
+
- !ruby/object:Gem::Version
|
213
|
+
version: '0'
|
214
|
+
type: :development
|
215
|
+
prerelease: false
|
216
|
+
version_requirements: !ruby/object:Gem::Requirement
|
217
|
+
none: false
|
218
|
+
requirements:
|
219
|
+
- - ! '>='
|
220
|
+
- !ruby/object:Gem::Version
|
221
|
+
version: '0'
|
222
|
+
- !ruby/object:Gem::Dependency
|
223
|
+
name: faker
|
224
|
+
requirement: !ruby/object:Gem::Requirement
|
225
|
+
none: false
|
226
|
+
requirements:
|
227
|
+
- - ! '>='
|
228
|
+
- !ruby/object:Gem::Version
|
229
|
+
version: '0'
|
230
|
+
type: :development
|
231
|
+
prerelease: false
|
232
|
+
version_requirements: !ruby/object:Gem::Requirement
|
233
|
+
none: false
|
234
|
+
requirements:
|
235
|
+
- - ! '>='
|
236
|
+
- !ruby/object:Gem::Version
|
237
|
+
version: '0'
|
238
|
+
description: A lite deployment package for rails applications.
|
239
|
+
email:
|
240
|
+
- amanelis@gmail.com
|
241
|
+
executables:
|
242
|
+
- baboon
|
243
|
+
extensions: []
|
244
|
+
extra_rdoc_files: []
|
245
|
+
files:
|
246
|
+
- Rakefile
|
247
|
+
- bin/baboon
|
248
|
+
- lib/baboon/cli/options.rb
|
249
|
+
- lib/baboon/cli.rb
|
250
|
+
- lib/baboon/configuration.rb
|
251
|
+
- lib/baboon/logger.rb
|
252
|
+
- lib/baboon/version.rb
|
253
|
+
- lib/baboon.rb
|
254
|
+
- lib/core_ext/string.rb
|
255
|
+
- lib/generators/baboon/config/config_generator.rb
|
256
|
+
- lib/generators/baboon/config/templates/baboon.yml
|
257
|
+
- lib/generators/baboon/install/install_generator.rb
|
258
|
+
- lib/generators/baboon/install/templates/baboon.rb
|
259
|
+
- spec/lib/baboon/configuration_spec.rb
|
260
|
+
- spec/lib/baboon_spec.rb
|
261
|
+
- spec/lib/generators/baboon/install/install_generator_spec.rb
|
262
|
+
- spec/spec_helper.rb
|
263
|
+
- README.md
|
264
|
+
homepage: https://github.com/amanelis/baboon
|
265
|
+
licenses:
|
266
|
+
- MIT
|
267
|
+
post_install_message:
|
268
|
+
rdoc_options: []
|
269
|
+
require_paths:
|
270
|
+
- lib
|
271
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
272
|
+
none: false
|
273
|
+
requirements:
|
274
|
+
- - ! '>='
|
275
|
+
- !ruby/object:Gem::Version
|
276
|
+
version: '0'
|
277
|
+
segments:
|
278
|
+
- 0
|
279
|
+
hash: -1949911459240274034
|
280
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
281
|
+
none: false
|
282
|
+
requirements:
|
283
|
+
- - ! '>='
|
284
|
+
- !ruby/object:Gem::Version
|
285
|
+
version: '0'
|
286
|
+
segments:
|
287
|
+
- 0
|
288
|
+
hash: -1949911459240274034
|
289
|
+
requirements: []
|
290
|
+
rubyforge_project: baboon
|
291
|
+
rubygems_version: 1.8.24
|
292
|
+
signing_key:
|
293
|
+
specification_version: 3
|
294
|
+
summary: Add a configuration file, setup and deploy.
|
295
|
+
test_files: []
|