baboon 1.0.9 → 1.5.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.coveralls.yml +1 -0
- data/.gitignore +19 -0
- data/.rspec +4 -0
- data/.ruby-gemset +1 -0
- data/.ruby-version +1 -0
- data/.travis.yml +4 -0
- data/Gemfile +24 -0
- data/LICENSE +22 -0
- data/README.md +113 -33
- data/Rakefile +2 -2
- data/baboon.gemspec +25 -0
- data/lib/baboon.rb +4 -4
- data/lib/baboon/cli.rb +155 -51
- data/lib/baboon/instructions/rails.rb +4 -2
- data/lib/baboon/util.rb +21 -15
- data/lib/baboon/version.rb +2 -2
- data/lib/generators/baboon/install/templates/baboon.yml +36 -17
- data/media/baboon.psd +0 -0
- data/spec/baboon.yml +30 -0
- data/spec/lib/baboon/cli_spec.rb +37 -28
- data/spec/lib/baboon/util_spec.rb +19 -0
- data/spec/lib/baboon_spec.rb +11 -3
- data/spec/spec_helper.rb +40 -3
- metadata +36 -220
- data/lib/baboon/cli/options.rb +0 -241
- data/lib/baboon/configuration.rb +0 -38
- data/lib/baboon/logger.rb +0 -153
- data/lib/generators/baboon/config/config_generator.rb +0 -17
- data/lib/generators/baboon/config/templates/baboon.yml +0 -11
- data/spec/lib/baboon/configuration_spec.rb +0 -115
data/lib/baboon/cli/options.rb
DELETED
@@ -1,241 +0,0 @@
|
|
1
|
-
require 'optparse'
|
2
|
-
require 'baboon/version'
|
3
|
-
|
4
|
-
module Baboon
|
5
|
-
class CLI
|
6
|
-
module Options
|
7
|
-
def self.included(base)
|
8
|
-
base.extend(ClassMethods)
|
9
|
-
end
|
10
|
-
|
11
|
-
module ClassMethods
|
12
|
-
# Return a new CLI instance with the given arguments pre-parsed and
|
13
|
-
# ready for execution.
|
14
|
-
def parse(args)
|
15
|
-
cli = new(args)
|
16
|
-
cli.parse_options!
|
17
|
-
cli
|
18
|
-
end
|
19
|
-
end
|
20
|
-
|
21
|
-
# The hash of (parsed) command-line options
|
22
|
-
attr_reader :options
|
23
|
-
|
24
|
-
def option_parser #:nodoc:
|
25
|
-
@logger = Logger.new
|
26
|
-
@option_parser ||= OptionParser.new do |opts|
|
27
|
-
opts.banner = "Usage: #{File.basename($0)} [options] action ..."
|
28
|
-
|
29
|
-
opts.on("-d", "--debug",
|
30
|
-
"Prompts before each remote command execution."
|
31
|
-
) { |value| options[:debug] = true }
|
32
|
-
|
33
|
-
opts.on("-e", "--explain TASK",
|
34
|
-
"Displays help (if available) for the task."
|
35
|
-
) { |value| options[:explain] = value }
|
36
|
-
|
37
|
-
opts.on("-F", "--default-config",
|
38
|
-
"Always use default config, even with -f."
|
39
|
-
) { options[:default_config] = true }
|
40
|
-
|
41
|
-
opts.on("-f", "--file FILE",
|
42
|
-
"A recipe file to load. May be given more than once."
|
43
|
-
) { |value| options[:recipes] << value }
|
44
|
-
|
45
|
-
opts.on("-H", "--long-help", "Explain these options and environment variables.") do
|
46
|
-
long_help
|
47
|
-
exit
|
48
|
-
end
|
49
|
-
|
50
|
-
opts.on("-h", "--help", "Display this help message.") do
|
51
|
-
puts opts
|
52
|
-
exit
|
53
|
-
end
|
54
|
-
|
55
|
-
opts.on("-l", "--logger [STDERR|STDOUT|file]",
|
56
|
-
"Choose logger method. STDERR used by default."
|
57
|
-
) do |value|
|
58
|
-
options[:output] = if value.nil? || value.upcase == 'STDERR'
|
59
|
-
# Using default logger.
|
60
|
-
nil
|
61
|
-
elsif value.upcase == 'STDOUT'
|
62
|
-
$stdout
|
63
|
-
else
|
64
|
-
value
|
65
|
-
end
|
66
|
-
end
|
67
|
-
|
68
|
-
opts.on("-n", "--dry-run",
|
69
|
-
"Prints out commands without running them."
|
70
|
-
) { |value| options[:dry_run] = true }
|
71
|
-
|
72
|
-
opts.on("-p", "--password",
|
73
|
-
"Immediately prompt for the password."
|
74
|
-
) { options[:password] = nil }
|
75
|
-
|
76
|
-
opts.on("-q", "--quiet",
|
77
|
-
"Make the output as quiet as possible."
|
78
|
-
) { options[:verbose] = 0 }
|
79
|
-
|
80
|
-
opts.on("-r", "--preserve-roles",
|
81
|
-
"Preserve task roles"
|
82
|
-
) { options[:preserve_roles] = true }
|
83
|
-
|
84
|
-
opts.on("-S", "--set-before NAME=VALUE",
|
85
|
-
"Set a variable before the recipes are loaded."
|
86
|
-
) do |pair|
|
87
|
-
name, value = pair.split(/=/, 2)
|
88
|
-
options[:pre_vars][name.to_sym] = value
|
89
|
-
end
|
90
|
-
|
91
|
-
opts.on("-s", "--set NAME=VALUE",
|
92
|
-
"Set a variable after the recipes are loaded."
|
93
|
-
) do |pair|
|
94
|
-
name, value = pair.split(/=/, 2)
|
95
|
-
options[:vars][name.to_sym] = value
|
96
|
-
end
|
97
|
-
|
98
|
-
opts.on("-T", "--tasks [PATTERN]",
|
99
|
-
"List all tasks (matching optional PATTERN) in the loaded recipe files."
|
100
|
-
) do |value|
|
101
|
-
options[:tasks] = if value
|
102
|
-
value
|
103
|
-
else
|
104
|
-
true
|
105
|
-
end
|
106
|
-
options[:verbose] ||= 0
|
107
|
-
end
|
108
|
-
|
109
|
-
opts.on("-t", "--tool",
|
110
|
-
"Abbreviates the output of -T for tool integration."
|
111
|
-
) { options[:tool] = true }
|
112
|
-
|
113
|
-
opts.on("-V", "--version",
|
114
|
-
"Display the Baboon version, and exit."
|
115
|
-
) do
|
116
|
-
require 'baboon/version'
|
117
|
-
puts "Baboon v#{Baboon::Version}"
|
118
|
-
exit
|
119
|
-
end
|
120
|
-
|
121
|
-
opts.on("-v", "--verbose",
|
122
|
-
"Be more verbose. May be given more than once."
|
123
|
-
) do
|
124
|
-
options[:verbose] ||= 0
|
125
|
-
options[:verbose] += 1
|
126
|
-
end
|
127
|
-
|
128
|
-
opts.on("-X", "--skip-system-config",
|
129
|
-
"Don't load the system config file (Baboon.configuration)"
|
130
|
-
) { options.delete(:sysconf) }
|
131
|
-
|
132
|
-
opts.on("-x", "--skip-user-config",
|
133
|
-
"Don't load the user config file (.caprc)"
|
134
|
-
) { options.delete(:dotfile) }
|
135
|
-
end
|
136
|
-
end
|
137
|
-
|
138
|
-
# If the arguments to the command are empty, this will print the
|
139
|
-
# allowed options and exit. Otherwise, it will parse the command
|
140
|
-
# line and set up any default options.
|
141
|
-
def parse_options! #:nodoc:
|
142
|
-
@options = { :recipes => [], :actions => [],
|
143
|
-
:vars => {}, :pre_vars => {},
|
144
|
-
:sysconf => default_sysconf, :dotfile => default_dotfile }
|
145
|
-
|
146
|
-
if args.empty?
|
147
|
-
warn "Please specify at least one action to execute."
|
148
|
-
warn option_parser
|
149
|
-
exit
|
150
|
-
end
|
151
|
-
|
152
|
-
option_parser.parse!(args)
|
153
|
-
|
154
|
-
coerce_variable_types!
|
155
|
-
|
156
|
-
# if no verbosity has been specified, be verbose
|
157
|
-
options[:verbose] = 3 if !options.has_key?(:verbose)
|
158
|
-
|
159
|
-
look_for_default_recipe_file! if options[:default_config] || options[:recipes].empty?
|
160
|
-
extract_environment_variables!
|
161
|
-
|
162
|
-
options[:actions].concat(args)
|
163
|
-
|
164
|
-
password = options.has_key?(:password)
|
165
|
-
options[:password] = Proc.new { self.class.password_prompt }
|
166
|
-
options[:password] = options[:password].call if password
|
167
|
-
end
|
168
|
-
|
169
|
-
# Extracts name=value pairs from the remaining command-line arguments
|
170
|
-
# and assigns them as environment variables.
|
171
|
-
def extract_environment_variables! #:nodoc:
|
172
|
-
args.delete_if do |arg|
|
173
|
-
next unless arg.match(/^(\w+)=(.*)$/)
|
174
|
-
ENV[$1] = $2
|
175
|
-
end
|
176
|
-
end
|
177
|
-
|
178
|
-
# Looks for a default recipe file in the current directory.
|
179
|
-
def look_for_default_recipe_file! #:nodoc:
|
180
|
-
current = Dir.pwd
|
181
|
-
|
182
|
-
loop do
|
183
|
-
%w(Capfile capfile).each do |file|
|
184
|
-
if File.file?(file)
|
185
|
-
options[:recipes] << file
|
186
|
-
@logger.info "Using recipes from #{File.join(current,file)}"
|
187
|
-
return
|
188
|
-
end
|
189
|
-
end
|
190
|
-
|
191
|
-
pwd = Dir.pwd
|
192
|
-
Dir.chdir("..")
|
193
|
-
break if pwd == Dir.pwd # if changing the directory made no difference, then we're at the top
|
194
|
-
end
|
195
|
-
|
196
|
-
Dir.chdir(current)
|
197
|
-
end
|
198
|
-
|
199
|
-
def default_sysconf #:nodoc:
|
200
|
-
File.join(sysconf_directory, "Baboon.configuration")
|
201
|
-
end
|
202
|
-
|
203
|
-
def default_dotfile #:nodoc:
|
204
|
-
File.join(home_directory, ".caprc")
|
205
|
-
end
|
206
|
-
|
207
|
-
def sysconf_directory #:nodoc:
|
208
|
-
# TODO if anyone cares, feel free to submit a patch that uses a more
|
209
|
-
# appropriate location for this file in Windows.
|
210
|
-
ENV["SystemRoot"] || '/etc'
|
211
|
-
end
|
212
|
-
|
213
|
-
def home_directory #:nodoc:
|
214
|
-
ENV["HOME"] ||
|
215
|
-
(ENV["HOMEPATH"] && "#{ENV["HOMEDRIVE"]}#{ENV["HOMEPATH"]}") ||
|
216
|
-
"/"
|
217
|
-
end
|
218
|
-
|
219
|
-
def coerce_variable_types!
|
220
|
-
[:pre_vars, :vars].each do |collection|
|
221
|
-
options[collection].keys.each do |key|
|
222
|
-
options[collection][key] = coerce_variable(options[collection][key])
|
223
|
-
end
|
224
|
-
end
|
225
|
-
end
|
226
|
-
|
227
|
-
def coerce_variable(value)
|
228
|
-
case value
|
229
|
-
when /^"(.*)"$/ then $1
|
230
|
-
when /^'(.*)'$/ then $1
|
231
|
-
when /^\d+$/ then value.to_i
|
232
|
-
when /^\d+\.\d*$/ then value.to_f
|
233
|
-
when "true" then true
|
234
|
-
when "false" then false
|
235
|
-
when "nil" then nil
|
236
|
-
else value
|
237
|
-
end
|
238
|
-
end
|
239
|
-
end
|
240
|
-
end
|
241
|
-
end
|
data/lib/baboon/configuration.rb
DELETED
@@ -1,38 +0,0 @@
|
|
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
|
data/lib/baboon/logger.rb
DELETED
@@ -1,153 +0,0 @@
|
|
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
|
@@ -1,17 +0,0 @@
|
|
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
|