engineyard 2.0.0.pre1 → 2.0.0.pre2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (43) hide show
  1. data/README.rdoc +39 -136
  2. data/bin/ey_perftools +12 -0
  3. data/lib/engineyard.rb +0 -2
  4. data/lib/engineyard/cli.rb +3 -4
  5. data/lib/engineyard/cli/api.rb +3 -2
  6. data/lib/engineyard/commands/deploy.rb +0 -0
  7. data/lib/engineyard/thor.rb +7 -3
  8. data/lib/engineyard/version.rb +1 -1
  9. data/spec/engineyard/cli/api_spec.rb +6 -0
  10. data/spec/ey/deploy_spec.rb +6 -0
  11. data/spec/ey/ssh_spec.rb +6 -6
  12. metadata +24 -37
  13. data/lib/vendor/thor/LICENSE.md +0 -20
  14. data/lib/vendor/thor/README.md +0 -26
  15. data/lib/vendor/thor/lib/thor.rb +0 -379
  16. data/lib/vendor/thor/lib/thor/actions.rb +0 -318
  17. data/lib/vendor/thor/lib/thor/actions/create_file.rb +0 -105
  18. data/lib/vendor/thor/lib/thor/actions/create_link.rb +0 -57
  19. data/lib/vendor/thor/lib/thor/actions/directory.rb +0 -97
  20. data/lib/vendor/thor/lib/thor/actions/empty_directory.rb +0 -153
  21. data/lib/vendor/thor/lib/thor/actions/file_manipulation.rb +0 -308
  22. data/lib/vendor/thor/lib/thor/actions/inject_into_file.rb +0 -109
  23. data/lib/vendor/thor/lib/thor/base.rb +0 -611
  24. data/lib/vendor/thor/lib/thor/core_ext/file_binary_read.rb +0 -9
  25. data/lib/vendor/thor/lib/thor/core_ext/hash_with_indifferent_access.rb +0 -75
  26. data/lib/vendor/thor/lib/thor/core_ext/ordered_hash.rb +0 -100
  27. data/lib/vendor/thor/lib/thor/error.rb +0 -35
  28. data/lib/vendor/thor/lib/thor/group.rb +0 -285
  29. data/lib/vendor/thor/lib/thor/invocation.rb +0 -170
  30. data/lib/vendor/thor/lib/thor/parser.rb +0 -4
  31. data/lib/vendor/thor/lib/thor/parser/argument.rb +0 -67
  32. data/lib/vendor/thor/lib/thor/parser/arguments.rb +0 -165
  33. data/lib/vendor/thor/lib/thor/parser/option.rb +0 -121
  34. data/lib/vendor/thor/lib/thor/parser/options.rb +0 -181
  35. data/lib/vendor/thor/lib/thor/rake_compat.rb +0 -71
  36. data/lib/vendor/thor/lib/thor/runner.rb +0 -321
  37. data/lib/vendor/thor/lib/thor/shell.rb +0 -88
  38. data/lib/vendor/thor/lib/thor/shell/basic.rb +0 -331
  39. data/lib/vendor/thor/lib/thor/shell/color.rb +0 -108
  40. data/lib/vendor/thor/lib/thor/shell/html.rb +0 -121
  41. data/lib/vendor/thor/lib/thor/task.rb +0 -132
  42. data/lib/vendor/thor/lib/thor/util.rb +0 -248
  43. data/lib/vendor/thor/lib/thor/version.rb +0 -3
@@ -1,181 +0,0 @@
1
- class Thor
2
- # This is a modified version of Daniel Berger's Getopt::Long class, licensed
3
- # under Ruby's license.
4
- #
5
- class Options < Arguments #:nodoc:
6
- LONG_RE = /^(--\w+(?:-\w+)*)$/
7
- SHORT_RE = /^(-[a-z])$/i
8
- EQ_RE = /^(--\w+(?:-\w+)*|-[a-z])=(.*)$/i
9
- SHORT_SQ_RE = /^-([a-z]{2,})$/i # Allow either -x -v or -xv style for single char args
10
- SHORT_NUM = /^(-[a-z])#{NUMERIC}$/i
11
-
12
- # Receives a hash and makes it switches.
13
- def self.to_switches(options)
14
- options.map do |key, value|
15
- case value
16
- when true
17
- "--#{key}"
18
- when Array
19
- "--#{key} #{value.map{ |v| v.inspect }.join(' ')}"
20
- when Hash
21
- "--#{key} #{value.map{ |k,v| "#{k}:#{v}" }.join(' ')}"
22
- when nil, false
23
- ""
24
- else
25
- "--#{key} #{value.inspect}"
26
- end
27
- end.join(" ")
28
- end
29
-
30
- # Takes a hash of Thor::Option and a hash with defaults.
31
- def initialize(hash_options={}, defaults={})
32
- options = hash_options.values
33
- super(options)
34
-
35
- # Add defaults
36
- defaults.each do |key, value|
37
- @assigns[key.to_s] = value
38
- @non_assigned_required.delete(hash_options[key])
39
- end
40
-
41
- @shorts, @switches, @extra = {}, {}, []
42
-
43
- options.each do |option|
44
- @switches[option.switch_name] = option
45
-
46
- option.aliases.each do |short|
47
- @shorts[short.to_s] ||= option.switch_name
48
- end
49
- end
50
- end
51
-
52
- def remaining
53
- @extra
54
- end
55
-
56
- def parse(args)
57
- @pile = args.dup
58
-
59
- while peek
60
- match, is_switch = current_is_switch?
61
- shifted = shift
62
-
63
- if is_switch
64
- case shifted
65
- when SHORT_SQ_RE
66
- unshift($1.split('').map { |f| "-#{f}" })
67
- next
68
- when EQ_RE, SHORT_NUM
69
- unshift($2)
70
- switch = $1
71
- when LONG_RE, SHORT_RE
72
- switch = $1
73
- end
74
-
75
- switch = normalize_switch(switch)
76
- option = switch_option(switch)
77
- @assigns[option.human_name] = parse_peek(switch, option)
78
- elsif match
79
- @extra << shifted
80
- @extra << shift while peek && peek !~ /^-/
81
- else
82
- @extra << shifted
83
- end
84
- end
85
-
86
- check_requirement!
87
-
88
- assigns = Thor::CoreExt::HashWithIndifferentAccess.new(@assigns)
89
- assigns.freeze
90
- assigns
91
- end
92
-
93
- def check_unknown!
94
- # an unknown option starts with - or -- and has no more --'s afterward.
95
- unknown = @extra.select { |str| str =~ /^--?(?:(?!--).)*$/ }
96
- raise UnknownArgumentError, "Unknown switches '#{unknown.join(', ')}'" unless unknown.empty?
97
- end
98
-
99
- protected
100
-
101
- # Returns true if the current value in peek is a registered switch.
102
- #
103
- def current_is_switch?
104
- case peek
105
- when LONG_RE, SHORT_RE, EQ_RE, SHORT_NUM
106
- [true, switch?($1)]
107
- when SHORT_SQ_RE
108
- [true, $1.split('').any? { |f| switch?("-#{f}") }]
109
- else
110
- [false, false]
111
- end
112
- end
113
-
114
- def current_is_switch_formatted?
115
- case peek
116
- when LONG_RE, SHORT_RE, EQ_RE, SHORT_NUM, SHORT_SQ_RE
117
- true
118
- else
119
- false
120
- end
121
- end
122
-
123
- def switch?(arg)
124
- switch_option(normalize_switch(arg))
125
- end
126
-
127
- def switch_option(arg)
128
- if match = no_or_skip?(arg)
129
- @switches[arg] || @switches["--#{match}"]
130
- else
131
- @switches[arg]
132
- end
133
- end
134
-
135
- # Check if the given argument is actually a shortcut.
136
- #
137
- def normalize_switch(arg)
138
- (@shorts[arg] || arg).tr('_', '-')
139
- end
140
-
141
- # Parse boolean values which can be given as --foo=true, --foo or --no-foo.
142
- #
143
- def parse_boolean(switch)
144
- if current_is_value?
145
- if ["true", "TRUE", "t", "T", true].include?(peek)
146
- shift
147
- true
148
- elsif ["false", "FALSE", "f", "F", false].include?(peek)
149
- shift
150
- false
151
- else
152
- true
153
- end
154
- else
155
- @switches.key?(switch) || !no_or_skip?(switch)
156
- end
157
- end
158
-
159
- # Parse the value at the peek analyzing if it requires an input or not.
160
- #
161
- def parse_peek(switch, option)
162
- if current_is_switch_formatted? || last?
163
- if option.boolean?
164
- # No problem for boolean types
165
- elsif no_or_skip?(switch)
166
- return nil # User set value to nil
167
- elsif option.string? && !option.required?
168
- # Return the default if there is one, else the human name
169
- return option.lazy_default || option.default || option.human_name
170
- elsif option.lazy_default
171
- return option.lazy_default
172
- else
173
- raise MalformattedArgumentError, "No value provided for option '#{switch}'"
174
- end
175
- end
176
-
177
- @non_assigned_required.delete(option)
178
- send(:"parse_#{option.type}", switch)
179
- end
180
- end
181
- end
@@ -1,71 +0,0 @@
1
- require 'rake'
2
- require 'rake/dsl_definition'
3
-
4
- class Thor
5
- # Adds a compatibility layer to your Thor classes which allows you to use
6
- # rake package tasks. For example, to use rspec rake tasks, one can do:
7
- #
8
- # require 'thor/rake_compat'
9
- #
10
- # class Default < Thor
11
- # include Thor::RakeCompat
12
- #
13
- # Spec::Rake::SpecTask.new(:spec) do |t|
14
- # t.spec_opts = ['--options', "spec/spec.opts"]
15
- # t.spec_files = FileList['spec/**/*_spec.rb']
16
- # end
17
- # end
18
- #
19
- module RakeCompat
20
- include Rake::DSL if defined?(Rake::DSL)
21
-
22
- def self.rake_classes
23
- @rake_classes ||= []
24
- end
25
-
26
- def self.included(base)
27
- # Hack. Make rakefile point to invoker, so rdoc task is generated properly.
28
- rakefile = File.basename(caller[0].match(/(.*):\d+/)[1])
29
- Rake.application.instance_variable_set(:@rakefile, rakefile)
30
- self.rake_classes << base
31
- end
32
- end
33
- end
34
-
35
- # override task on (main), for compatibility with Rake 0.9
36
- self.instance_eval do
37
- alias rake_namespace namespace
38
-
39
- def task(*)
40
- task = super
41
-
42
- if klass = Thor::RakeCompat.rake_classes.last
43
- non_namespaced_name = task.name.split(':').last
44
-
45
- description = non_namespaced_name
46
- description << task.arg_names.map{ |n| n.to_s.upcase }.join(' ')
47
- description.strip!
48
-
49
- klass.desc description, Rake.application.last_description || non_namespaced_name
50
- Rake.application.last_description = nil
51
- klass.send :define_method, non_namespaced_name do |*args|
52
- Rake::Task[task.name.to_sym].invoke(*args)
53
- end
54
- end
55
-
56
- task
57
- end
58
-
59
- def namespace(name)
60
- if klass = Thor::RakeCompat.rake_classes.last
61
- const_name = Thor::Util.camel_case(name.to_s).to_sym
62
- klass.const_set(const_name, Class.new(Thor))
63
- new_klass = klass.const_get(const_name)
64
- Thor::RakeCompat.rake_classes << new_klass
65
- end
66
-
67
- super
68
- Thor::RakeCompat.rake_classes.pop
69
- end
70
- end
71
-
@@ -1,321 +0,0 @@
1
- require 'thor'
2
- require 'thor/group'
3
- require 'thor/core_ext/file_binary_read'
4
-
5
- require 'fileutils'
6
- require 'open-uri'
7
- require 'yaml'
8
- require 'digest/md5'
9
- require 'pathname'
10
-
11
- class Thor::Runner < Thor #:nodoc:
12
- map "-T" => :list, "-i" => :install, "-u" => :update, "-v" => :version
13
-
14
- # Override Thor#help so it can give information about any class and any method.
15
- #
16
- def help(meth = nil)
17
- if meth && !self.respond_to?(meth)
18
- initialize_thorfiles(meth)
19
- klass, task = Thor::Util.find_class_and_task_by_namespace(meth)
20
- self.class.handle_no_task_error(task, false) if klass.nil?
21
- klass.start(["-h", task].compact, :shell => self.shell)
22
- else
23
- super
24
- end
25
- end
26
-
27
- # If a task is not found on Thor::Runner, method missing is invoked and
28
- # Thor::Runner is then responsable for finding the task in all classes.
29
- #
30
- def method_missing(meth, *args)
31
- meth = meth.to_s
32
- initialize_thorfiles(meth)
33
- klass, task = Thor::Util.find_class_and_task_by_namespace(meth)
34
- self.class.handle_no_task_error(task, false) if klass.nil?
35
- args.unshift(task) if task
36
- klass.start(args, :shell => self.shell)
37
- end
38
-
39
- desc "install NAME", "Install an optionally named Thor file into your system tasks"
40
- method_options :as => :string, :relative => :boolean, :force => :boolean
41
- def install(name)
42
- initialize_thorfiles
43
-
44
- # If a directory name is provided as the argument, look for a 'main.thor'
45
- # task in said directory.
46
- begin
47
- if File.directory?(File.expand_path(name))
48
- base, package = File.join(name, "main.thor"), :directory
49
- contents = open(base) {|input| input.read }
50
- else
51
- base, package = name, :file
52
- contents = open(name) {|input| input.read }
53
- end
54
- rescue OpenURI::HTTPError
55
- raise Error, "Error opening URI '#{name}'"
56
- rescue Errno::ENOENT
57
- raise Error, "Error opening file '#{name}'"
58
- end
59
-
60
- say "Your Thorfile contains:"
61
- say contents
62
-
63
- unless options["force"]
64
- return false if no?("Do you wish to continue [y/N]?")
65
- end
66
-
67
- as = options["as"] || begin
68
- first_line = contents.split("\n")[0]
69
- (match = first_line.match(/\s*#\s*module:\s*([^\n]*)/)) ? match[1].strip : nil
70
- end
71
-
72
- unless as
73
- basename = File.basename(name)
74
- as = ask("Please specify a name for #{name} in the system repository [#{basename}]:")
75
- as = basename if as.empty?
76
- end
77
-
78
- location = if options[:relative] || name =~ /^https?:\/\//
79
- name
80
- else
81
- File.expand_path(name)
82
- end
83
-
84
- thor_yaml[as] = {
85
- :filename => Digest::MD5.hexdigest(name + as),
86
- :location => location,
87
- :namespaces => Thor::Util.namespaces_in_content(contents, base)
88
- }
89
-
90
- save_yaml(thor_yaml)
91
- say "Storing thor file in your system repository"
92
- destination = File.join(thor_root, thor_yaml[as][:filename])
93
-
94
- if package == :file
95
- File.open(destination, "w") { |f| f.puts contents }
96
- else
97
- FileUtils.cp_r(name, destination)
98
- end
99
-
100
- thor_yaml[as][:filename] # Indicate success
101
- end
102
-
103
- desc "version", "Show Thor version"
104
- def version
105
- require 'thor/version'
106
- say "Thor #{Thor::VERSION}"
107
- end
108
-
109
- desc "uninstall NAME", "Uninstall a named Thor module"
110
- def uninstall(name)
111
- raise Error, "Can't find module '#{name}'" unless thor_yaml[name]
112
- say "Uninstalling #{name}."
113
- FileUtils.rm_rf(File.join(thor_root, "#{thor_yaml[name][:filename]}"))
114
-
115
- thor_yaml.delete(name)
116
- save_yaml(thor_yaml)
117
-
118
- puts "Done."
119
- end
120
-
121
- desc "update NAME", "Update a Thor file from its original location"
122
- def update(name)
123
- raise Error, "Can't find module '#{name}'" if !thor_yaml[name] || !thor_yaml[name][:location]
124
-
125
- say "Updating '#{name}' from #{thor_yaml[name][:location]}"
126
-
127
- old_filename = thor_yaml[name][:filename]
128
- self.options = self.options.merge("as" => name)
129
-
130
- if File.directory? File.expand_path(name)
131
- FileUtils.rm_rf(File.join(thor_root, old_filename))
132
-
133
- thor_yaml.delete(old_filename)
134
- save_yaml(thor_yaml)
135
-
136
- filename = install(name)
137
- else
138
- filename = install(thor_yaml[name][:location])
139
- end
140
-
141
- unless filename == old_filename
142
- File.delete(File.join(thor_root, old_filename))
143
- end
144
- end
145
-
146
- desc "installed", "List the installed Thor modules and tasks"
147
- method_options :internal => :boolean
148
- def installed
149
- initialize_thorfiles(nil, true)
150
- display_klasses(true, options["internal"])
151
- end
152
-
153
- desc "list [SEARCH]", "List the available thor tasks (--substring means .*SEARCH)"
154
- method_options :substring => :boolean, :group => :string, :all => :boolean, :debug => :boolean
155
- def list(search="")
156
- initialize_thorfiles
157
-
158
- search = ".*#{search}" if options["substring"]
159
- search = /^#{search}.*/i
160
- group = options[:group] || "standard"
161
-
162
- klasses = Thor::Base.subclasses.select do |k|
163
- (options[:all] || k.group == group) && k.namespace =~ search
164
- end
165
-
166
- display_klasses(false, false, klasses)
167
- end
168
-
169
- private
170
-
171
- def self.banner(task, all = false, subcommand = false)
172
- "thor " + task.formatted_usage(self, all, subcommand)
173
- end
174
-
175
- def thor_root
176
- Thor::Util.thor_root
177
- end
178
-
179
- def thor_yaml
180
- @thor_yaml ||= begin
181
- yaml_file = File.join(thor_root, "thor.yml")
182
- yaml = YAML.load_file(yaml_file) if File.exists?(yaml_file)
183
- yaml || {}
184
- end
185
- end
186
-
187
- # Save the yaml file. If none exists in thor root, creates one.
188
- #
189
- def save_yaml(yaml)
190
- yaml_file = File.join(thor_root, "thor.yml")
191
-
192
- unless File.exists?(yaml_file)
193
- FileUtils.mkdir_p(thor_root)
194
- yaml_file = File.join(thor_root, "thor.yml")
195
- FileUtils.touch(yaml_file)
196
- end
197
-
198
- File.open(yaml_file, "w") { |f| f.puts yaml.to_yaml }
199
- end
200
-
201
- def self.exit_on_failure?
202
- true
203
- end
204
-
205
- # Load the Thorfiles. If relevant_to is supplied, looks for specific files
206
- # in the thor_root instead of loading them all.
207
- #
208
- # By default, it also traverses the current path until find Thor files, as
209
- # described in thorfiles. This look up can be skipped by suppliying
210
- # skip_lookup true.
211
- #
212
- def initialize_thorfiles(relevant_to=nil, skip_lookup=false)
213
- thorfiles(relevant_to, skip_lookup).each do |f|
214
- Thor::Util.load_thorfile(f, nil, options[:debug]) unless Thor::Base.subclass_files.keys.include?(File.expand_path(f))
215
- end
216
- end
217
-
218
- # Finds Thorfiles by traversing from your current directory down to the root
219
- # directory of your system. If at any time we find a Thor file, we stop.
220
- #
221
- # We also ensure that system-wide Thorfiles are loaded first, so local
222
- # Thorfiles can override them.
223
- #
224
- # ==== Example
225
- #
226
- # If we start at /Users/wycats/dev/thor ...
227
- #
228
- # 1. /Users/wycats/dev/thor
229
- # 2. /Users/wycats/dev
230
- # 3. /Users/wycats <-- we find a Thorfile here, so we stop
231
- #
232
- # Suppose we start at c:\Documents and Settings\james\dev\thor ...
233
- #
234
- # 1. c:\Documents and Settings\james\dev\thor
235
- # 2. c:\Documents and Settings\james\dev
236
- # 3. c:\Documents and Settings\james
237
- # 4. c:\Documents and Settings
238
- # 5. c:\ <-- no Thorfiles found!
239
- #
240
- def thorfiles(relevant_to=nil, skip_lookup=false)
241
- thorfiles = []
242
-
243
- unless skip_lookup
244
- Pathname.pwd.ascend do |path|
245
- thorfiles = Thor::Util.globs_for(path).map { |g| Dir[g] }.flatten
246
- break unless thorfiles.empty?
247
- end
248
- end
249
-
250
- files = (relevant_to ? thorfiles_relevant_to(relevant_to) : Thor::Util.thor_root_glob)
251
- files += thorfiles
252
- files -= ["#{thor_root}/thor.yml"]
253
-
254
- files.map! do |file|
255
- File.directory?(file) ? File.join(file, "main.thor") : file
256
- end
257
- end
258
-
259
- # Load Thorfiles relevant to the given method. If you provide "foo:bar" it
260
- # will load all thor files in the thor.yaml that has "foo" e "foo:bar"
261
- # namespaces registered.
262
- #
263
- def thorfiles_relevant_to(meth)
264
- lookup = [ meth, meth.split(":")[0...-1].join(":") ]
265
-
266
- files = thor_yaml.select do |k, v|
267
- v[:namespaces] && !(v[:namespaces] & lookup).empty?
268
- end
269
-
270
- files.map { |k, v| File.join(thor_root, "#{v[:filename]}") }
271
- end
272
-
273
- # Display information about the given klasses. If with_module is given,
274
- # it shows a table with information extracted from the yaml file.
275
- #
276
- def display_klasses(with_modules=false, show_internal=false, klasses=Thor::Base.subclasses)
277
- klasses -= [Thor, Thor::Runner, Thor::Group] unless show_internal
278
-
279
- raise Error, "No Thor tasks available" if klasses.empty?
280
- show_modules if with_modules && !thor_yaml.empty?
281
-
282
- list = Hash.new { |h,k| h[k] = [] }
283
- groups = klasses.select { |k| k.ancestors.include?(Thor::Group) }
284
-
285
- # Get classes which inherit from Thor
286
- (klasses - groups).each { |k| list[k.namespace.split(":").first] += k.printable_tasks(false) }
287
-
288
- # Get classes which inherit from Thor::Base
289
- groups.map! { |k| k.printable_tasks(false).first }
290
- list["root"] = groups
291
-
292
- # Order namespaces with default coming first
293
- list = list.sort{ |a,b| a[0].sub(/^default/, '') <=> b[0].sub(/^default/, '') }
294
- list.each { |n, tasks| display_tasks(n, tasks) unless tasks.empty? }
295
- end
296
-
297
- def display_tasks(namespace, list) #:nodoc:
298
- list.sort!{ |a,b| a[0] <=> b[0] }
299
-
300
- say shell.set_color(namespace, :blue, true)
301
- say "-" * namespace.size
302
-
303
- print_table(list, :truncate => true)
304
- say
305
- end
306
-
307
- def show_modules #:nodoc:
308
- info = []
309
- labels = ["Modules", "Namespaces"]
310
-
311
- info << labels
312
- info << [ "-" * labels[0].size, "-" * labels[1].size ]
313
-
314
- thor_yaml.each do |name, hash|
315
- info << [ name, hash[:namespaces].join(", ") ]
316
- end
317
-
318
- print_table info
319
- say ""
320
- end
321
- end