baboon 1.0.9 → 1.5.5

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
@@ -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
@@ -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