engineyard-serverside 2.0.0 → 2.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (36) hide show
  1. data/lib/engineyard-serverside/paths.rb +0 -1
  2. data/lib/engineyard-serverside/version.rb +1 -1
  3. data/lib/vendor/thor/{LICENSE → LICENSE.md} +2 -2
  4. data/lib/vendor/thor/README.md +28 -0
  5. data/lib/vendor/thor/lib/thor.rb +183 -48
  6. data/lib/vendor/thor/lib/thor/actions.rb +66 -23
  7. data/lib/vendor/thor/lib/thor/actions/create_file.rb +5 -3
  8. data/lib/vendor/thor/lib/thor/actions/create_link.rb +57 -0
  9. data/lib/vendor/thor/lib/thor/actions/directory.rb +14 -7
  10. data/lib/vendor/thor/lib/thor/actions/empty_directory.rb +24 -5
  11. data/lib/vendor/thor/lib/thor/actions/file_manipulation.rb +106 -21
  12. data/lib/vendor/thor/lib/thor/actions/inject_into_file.rb +15 -10
  13. data/lib/vendor/thor/lib/thor/base.rb +144 -43
  14. data/lib/vendor/thor/lib/thor/core_ext/dir_escape.rb +0 -0
  15. data/lib/vendor/thor/lib/thor/core_ext/hash_with_indifferent_access.rb +1 -1
  16. data/lib/vendor/thor/lib/thor/error.rb +6 -1
  17. data/lib/vendor/thor/lib/thor/group.rb +41 -27
  18. data/lib/vendor/thor/lib/thor/invocation.rb +48 -58
  19. data/lib/vendor/thor/lib/thor/parser/argument.rb +29 -22
  20. data/lib/vendor/thor/lib/thor/parser/arguments.rb +26 -5
  21. data/lib/vendor/thor/lib/thor/parser/option.rb +42 -49
  22. data/lib/vendor/thor/lib/thor/parser/options.rb +39 -30
  23. data/lib/vendor/thor/lib/thor/rake_compat.rb +13 -8
  24. data/lib/vendor/thor/lib/thor/runner.rb +27 -20
  25. data/lib/vendor/thor/lib/thor/shell.rb +10 -5
  26. data/lib/vendor/thor/lib/thor/shell/basic.rb +228 -78
  27. data/lib/vendor/thor/lib/thor/shell/color.rb +40 -4
  28. data/lib/vendor/thor/lib/thor/shell/html.rb +123 -0
  29. data/lib/vendor/thor/lib/thor/task.rb +83 -53
  30. data/lib/vendor/thor/lib/thor/util.rb +57 -21
  31. data/lib/vendor/thor/lib/thor/version.rb +1 -1
  32. data/lib/vendor/thor/thor.gemspec +21 -115
  33. metadata +109 -217
  34. data/lib/vendor/thor/CHANGELOG.rdoc +0 -89
  35. data/lib/vendor/thor/README.rdoc +0 -297
  36. data/lib/vendor/thor/Thorfile +0 -69
@@ -1,4 +1,5 @@
1
1
  require 'rake'
2
+ require 'rake/dsl_definition'
2
3
 
3
4
  class Thor
4
5
  # Adds a compatibility layer to your Thor classes which allows you to use
@@ -16,6 +17,8 @@ class Thor
16
17
  # end
17
18
  #
18
19
  module RakeCompat
20
+ include Rake::DSL if defined?(Rake::DSL)
21
+
19
22
  def self.rake_classes
20
23
  @rake_classes ||= []
21
24
  end
@@ -29,12 +32,12 @@ class Thor
29
32
  end
30
33
  end
31
34
 
32
- class Object #:nodoc:
33
- alias :rake_task :task
34
- alias :rake_namespace :namespace
35
+ # override task on (main), for compatibility with Rake 0.9
36
+ self.instance_eval do
37
+ alias rake_namespace namespace
35
38
 
36
- def task(*args, &block)
37
- task = rake_task(*args, &block)
39
+ def task(*)
40
+ task = super
38
41
 
39
42
  if klass = Thor::RakeCompat.rake_classes.last
40
43
  non_namespaced_name = task.name.split(':').last
@@ -43,7 +46,8 @@ class Object #:nodoc:
43
46
  description << task.arg_names.map{ |n| n.to_s.upcase }.join(' ')
44
47
  description.strip!
45
48
 
46
- klass.desc description, task.comment || non_namespaced_name
49
+ klass.desc description, Rake.application.last_description || non_namespaced_name
50
+ Rake.application.last_description = nil
47
51
  klass.send :define_method, non_namespaced_name do |*args|
48
52
  Rake::Task[task.name.to_sym].invoke(*args)
49
53
  end
@@ -52,7 +56,7 @@ class Object #:nodoc:
52
56
  task
53
57
  end
54
58
 
55
- def namespace(name, &block)
59
+ def namespace(name)
56
60
  if klass = Thor::RakeCompat.rake_classes.last
57
61
  const_name = Thor::Util.camel_case(name.to_s).to_sym
58
62
  klass.const_set(const_name, Class.new(Thor))
@@ -60,7 +64,8 @@ class Object #:nodoc:
60
64
  Thor::RakeCompat.rake_classes << new_klass
61
65
  end
62
66
 
63
- rake_namespace(name, &block)
67
+ super
64
68
  Thor::RakeCompat.rake_classes.pop
65
69
  end
66
70
  end
71
+
@@ -13,10 +13,11 @@ class Thor::Runner < Thor #:nodoc:
13
13
 
14
14
  # Override Thor#help so it can give information about any class and any method.
15
15
  #
16
- def help(meth=nil)
16
+ def help(meth = nil)
17
17
  if meth && !self.respond_to?(meth)
18
18
  initialize_thorfiles(meth)
19
- klass, task = Thor::Util.find_class_and_task_by_namespace!(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?
20
21
  klass.start(["-h", task].compact, :shell => self.shell)
21
22
  else
22
23
  super
@@ -29,7 +30,8 @@ class Thor::Runner < Thor #:nodoc:
29
30
  def method_missing(meth, *args)
30
31
  meth = meth.to_s
31
32
  initialize_thorfiles(meth)
32
- klass, task = Thor::Util.find_class_and_task_by_namespace!(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?
33
35
  args.unshift(task) if task
34
36
  klass.start(args, :shell => self.shell)
35
37
  end
@@ -39,15 +41,15 @@ class Thor::Runner < Thor #:nodoc:
39
41
  def install(name)
40
42
  initialize_thorfiles
41
43
 
42
- # If a directory name is provided as the argument, look for a 'main.thor'
44
+ # If a directory name is provided as the argument, look for a 'main.thor'
43
45
  # task in said directory.
44
46
  begin
45
47
  if File.directory?(File.expand_path(name))
46
48
  base, package = File.join(name, "main.thor"), :directory
47
- contents = open(base).read
49
+ contents = open(base) {|input| input.read }
48
50
  else
49
51
  base, package = name, :file
50
- contents = open(name).read
52
+ contents = open(name) {|input| input.read }
51
53
  end
52
54
  rescue OpenURI::HTTPError
53
55
  raise Error, "Error opening URI '#{name}'"
@@ -73,7 +75,7 @@ class Thor::Runner < Thor #:nodoc:
73
75
  as = basename if as.empty?
74
76
  end
75
77
 
76
- location = if options[:relative] || name =~ /^http:\/\//
78
+ location = if options[:relative] || name =~ /^https?:\/\//
77
79
  name
78
80
  else
79
81
  File.expand_path(name)
@@ -124,7 +126,17 @@ class Thor::Runner < Thor #:nodoc:
124
126
 
125
127
  old_filename = thor_yaml[name][:filename]
126
128
  self.options = self.options.merge("as" => name)
127
- filename = install(thor_yaml[name][:location])
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
128
140
 
129
141
  unless filename == old_filename
130
142
  File.delete(File.join(thor_root, old_filename))
@@ -139,7 +151,7 @@ class Thor::Runner < Thor #:nodoc:
139
151
  end
140
152
 
141
153
  desc "list [SEARCH]", "List the available thor tasks (--substring means .*SEARCH)"
142
- method_options :substring => :boolean, :group => :string, :all => :boolean
154
+ method_options :substring => :boolean, :group => :string, :all => :boolean, :debug => :boolean
143
155
  def list(search="")
144
156
  initialize_thorfiles
145
157
 
@@ -156,8 +168,8 @@ class Thor::Runner < Thor #:nodoc:
156
168
 
157
169
  private
158
170
 
159
- def self.banner(task)
160
- "thor " + task.formatted_usage(self, false)
171
+ def self.banner(task, all = false, subcommand = false)
172
+ "thor " + task.formatted_usage(self, all, subcommand)
161
173
  end
162
174
 
163
175
  def thor_root
@@ -190,7 +202,7 @@ class Thor::Runner < Thor #:nodoc:
190
202
  true
191
203
  end
192
204
 
193
- # Load the thorfiles. If relevant_to is supplied, looks for specific files
205
+ # Load the Thorfiles. If relevant_to is supplied, looks for specific files
194
206
  # in the thor_root instead of loading them all.
195
207
  #
196
208
  # By default, it also traverses the current path until find Thor files, as
@@ -199,7 +211,7 @@ class Thor::Runner < Thor #:nodoc:
199
211
  #
200
212
  def initialize_thorfiles(relevant_to=nil, skip_lookup=false)
201
213
  thorfiles(relevant_to, skip_lookup).each do |f|
202
- Thor::Util.load_thorfile(f) unless Thor::Base.subclass_files.keys.include?(File.expand_path(f))
214
+ Thor::Util.load_thorfile(f, nil, options[:debug]) unless Thor::Base.subclass_files.keys.include?(File.expand_path(f))
203
215
  end
204
216
  end
205
217
 
@@ -244,7 +256,7 @@ class Thor::Runner < Thor #:nodoc:
244
256
  end
245
257
  end
246
258
 
247
- # Load thorfiles relevant to the given method. If you provide "foo:bar" it
259
+ # Load Thorfiles relevant to the given method. If you provide "foo:bar" it
248
260
  # will load all thor files in the thor.yaml that has "foo" e "foo:bar"
249
261
  # namespaces registered.
250
262
  #
@@ -267,16 +279,11 @@ class Thor::Runner < Thor #:nodoc:
267
279
  raise Error, "No Thor tasks available" if klasses.empty?
268
280
  show_modules if with_modules && !thor_yaml.empty?
269
281
 
270
- # Remove subclasses
271
- klasses.dup.each do |klass|
272
- klasses -= Thor::Util.thor_classes_in(klass)
273
- end
274
-
275
282
  list = Hash.new { |h,k| h[k] = [] }
276
283
  groups = klasses.select { |k| k.ancestors.include?(Thor::Group) }
277
284
 
278
285
  # Get classes which inherit from Thor
279
- (klasses - groups).each { |k| list[k.namespace] += k.printable_tasks(false) }
286
+ (klasses - groups).each { |k| list[k.namespace.split(":").first] += k.printable_tasks(false) }
280
287
 
281
288
  # Get classes which inherit from Thor::Base
282
289
  groups.map! { |k| k.printable_tasks(false).first }
@@ -1,5 +1,4 @@
1
1
  require 'rbconfig'
2
- require 'thor/shell/color'
3
2
 
4
3
  class Thor
5
4
  module Base
@@ -7,7 +6,9 @@ class Thor
7
6
  # it will use a colored log, otherwise it will use a basic one without color.
8
7
  #
9
8
  def self.shell
10
- @shell ||= if Config::CONFIG['host_os'] =~ /mswin|mingw/
9
+ @shell ||= if ENV['THOR_SHELL'] && ENV['THOR_SHELL'].size > 0
10
+ Thor::Shell.const_get(ENV['THOR_SHELL'])
11
+ elsif ((RbConfig::CONFIG['host_os'] =~ /mswin|mingw/) && !(ENV['ANSICON']))
11
12
  Thor::Shell::Basic
12
13
  else
13
14
  Thor::Shell::Color
@@ -22,7 +23,11 @@ class Thor
22
23
  end
23
24
 
24
25
  module Shell
25
- SHELL_DELEGATED_METHODS = [:ask, :yes?, :no?, :say, :say_status, :print_table]
26
+ SHELL_DELEGATED_METHODS = [:ask, :error, :set_color, :yes?, :no?, :say, :say_status, :print_in_columns, :print_table, :print_wrapped, :file_collision, :terminal_width]
27
+
28
+ autoload :Basic, 'thor/shell/basic'
29
+ autoload :Color, 'thor/shell/color'
30
+ autoload :HTML, 'thor/shell/html'
26
31
 
27
32
  # Add shell to initialize config values.
28
33
  #
@@ -57,8 +62,8 @@ class Thor
57
62
  # Common methods that are delegated to the shell.
58
63
  SHELL_DELEGATED_METHODS.each do |method|
59
64
  module_eval <<-METHOD, __FILE__, __LINE__
60
- def #{method}(*args)
61
- shell.#{method}(*args)
65
+ def #{method}(*args,&block)
66
+ shell.#{method}(*args,&block)
62
67
  end
63
68
  METHOD
64
69
  end
@@ -3,12 +3,28 @@ require 'tempfile'
3
3
  class Thor
4
4
  module Shell
5
5
  class Basic
6
- attr_accessor :base, :padding
6
+ attr_accessor :base
7
+ attr_reader :padding
7
8
 
8
- # Initialize base and padding to nil.
9
+ # Initialize base, mute and padding to nil.
9
10
  #
10
11
  def initialize #:nodoc:
11
- @base, @padding = nil, 0
12
+ @base, @mute, @padding = nil, false, 0
13
+ end
14
+
15
+ # Mute everything that's inside given block
16
+ #
17
+ def mute
18
+ @mute = true
19
+ yield
20
+ ensure
21
+ @mute = false
22
+ end
23
+
24
+ # Check if base is muted
25
+ #
26
+ def mute?
27
+ @mute
12
28
  end
13
29
 
14
30
  # Sets the output padding, not allowing less than zero values.
@@ -17,14 +33,22 @@ class Thor
17
33
  @padding = [0, value].max
18
34
  end
19
35
 
20
- # Ask something to the user and receives a response.
36
+ # Asks something to the user and receives a response.
37
+ #
38
+ # If asked to limit the correct responses, you can pass in an
39
+ # array of acceptable answers. If one of those is not supplied,
40
+ # they will be shown a message stating that one of those answers
41
+ # must be given and re-asked the question.
21
42
  #
22
43
  # ==== Example
23
44
  # ask("What is your name?")
24
45
  #
25
- def ask(statement, color=nil)
26
- say("#{statement} ", color)
27
- $stdin.gets.strip
46
+ # ask("What is your favorite Neopolitan flavor?", :limited_to => ["strawberry", "chocolate", "vanilla"])
47
+ #
48
+ def ask(statement, *args)
49
+ options = args.last.is_a?(Hash) ? args.pop : {}
50
+
51
+ options[:limited_to] ? ask_filtered(statement, options[:limited_to], *args) : ask_simply(statement, *args)
28
52
  end
29
53
 
30
54
  # Say (print) something to the user. If the sentence ends with a whitespace
@@ -35,15 +59,18 @@ class Thor
35
59
  # say("I know you knew that.")
36
60
  #
37
61
  def say(message="", color=nil, force_new_line=(message.to_s !~ /( |\t)$/))
38
- message = message.to_s
39
- message = set_color(message, color) if color
62
+ message = message.to_s
63
+
64
+ message = set_color(message, *color) if color
65
+
66
+ spaces = " " * padding
40
67
 
41
68
  if force_new_line
42
- $stdout.puts(message)
69
+ stdout.puts(spaces + message)
43
70
  else
44
- $stdout.print(message)
45
- $stdout.flush
71
+ stdout.print(spaces + message)
46
72
  end
73
+ stdout.flush
47
74
  end
48
75
 
49
76
  # Say a status with the given color and appends the message. Since this
@@ -58,14 +85,16 @@ class Thor
58
85
 
59
86
  status = status.to_s.rjust(12)
60
87
  status = set_color status, color, true if color
61
- say "#{status}#{spaces}#{message}", nil, true
88
+
89
+ stdout.puts "#{status}#{spaces}#{message}"
90
+ stdout.flush
62
91
  end
63
92
 
64
93
  # Make a question the to user and returns true if the user replies "y" or
65
94
  # "yes".
66
95
  #
67
96
  def yes?(statement, color=nil)
68
- ask(statement, color) =~ is?(:yes)
97
+ !!(ask(statement, color) =~ is?(:yes))
69
98
  end
70
99
 
71
100
  # Make a question the to user and returns true if the user replies "n" or
@@ -75,42 +104,114 @@ class Thor
75
104
  !yes?(statement, color)
76
105
  end
77
106
 
107
+ # Prints values in columns
108
+ #
109
+ # ==== Parameters
110
+ # Array[String, String, ...]
111
+ #
112
+ def print_in_columns(array)
113
+ return if array.empty?
114
+ colwidth = (array.map{|el| el.to_s.size}.max || 0) + 2
115
+ array.each_with_index do |value, index|
116
+ # Don't output trailing spaces when printing the last column
117
+ if ((((index + 1) % (terminal_width / colwidth))).zero? && !index.zero?) || index + 1 == array.length
118
+ stdout.puts value
119
+ else
120
+ stdout.printf("%-#{colwidth}s", value)
121
+ end
122
+ end
123
+ end
124
+
78
125
  # Prints a table.
79
126
  #
80
127
  # ==== Parameters
81
128
  # Array[Array[String, String, ...]]
82
129
  #
83
130
  # ==== Options
84
- # ident<Integer>:: Ident the first column by ident value.
131
+ # indent<Integer>:: Indent the first column by indent value.
132
+ # colwidth<Integer>:: Force the first column to colwidth spaces wide.
85
133
  #
86
- def print_table(table, options={})
87
- return if table.empty?
134
+ def print_table(array, options={})
135
+ return if array.empty?
88
136
 
89
- formats, ident = [], options[:ident].to_i
137
+ formats, indent, colwidth = [], options[:indent].to_i, options[:colwidth]
90
138
  options[:truncate] = terminal_width if options[:truncate] == true
91
139
 
92
- 0.upto(table.first.length - 2) do |i|
93
- maxima = table.max{ |a,b| a[i].size <=> b[i].size }[i].size
94
- formats << "%-#{maxima + 2}s"
140
+ formats << "%-#{colwidth + 2}s" if colwidth
141
+ start = colwidth ? 1 : 0
142
+
143
+ colcount = array.max{|a,b| a.size <=> b.size }.size
144
+
145
+ maximas = []
146
+
147
+ start.upto(colcount - 1) do |index|
148
+ maxima = array.map {|row| row[index] ? row[index].to_s.size : 0 }.max
149
+ maximas << maxima
150
+ if index == colcount - 1
151
+ # Don't output 2 trailing spaces when printing the last column
152
+ formats << "%-s"
153
+ else
154
+ formats << "%-#{maxima + 2}s"
155
+ end
95
156
  end
96
157
 
97
- formats[0] = formats[0].insert(0, " " * ident)
158
+ formats[0] = formats[0].insert(0, " " * indent)
98
159
  formats << "%s"
99
160
 
100
- table.each do |row|
161
+ array.each do |row|
101
162
  sentence = ""
102
163
 
103
- row.each_with_index do |column, i|
104
- sentence << formats[i] % column.to_s
164
+ row.each_with_index do |column, index|
165
+ maxima = maximas[index]
166
+
167
+ if column.is_a?(Numeric)
168
+ if index == row.size - 1
169
+ # Don't output 2 trailing spaces when printing the last column
170
+ f = "%#{maxima}s"
171
+ else
172
+ f = "%#{maxima}s "
173
+ end
174
+ else
175
+ f = formats[index]
176
+ end
177
+ sentence << f % column.to_s
105
178
  end
106
179
 
107
180
  sentence = truncate(sentence, options[:truncate]) if options[:truncate]
108
- $stdout.puts sentence
181
+ stdout.puts sentence
182
+ end
183
+ end
184
+
185
+ # Prints a long string, word-wrapping the text to the current width of the
186
+ # terminal display. Ideal for printing heredocs.
187
+ #
188
+ # ==== Parameters
189
+ # String
190
+ #
191
+ # ==== Options
192
+ # indent<Integer>:: Indent each line of the printed paragraph by indent value.
193
+ #
194
+ def print_wrapped(message, options={})
195
+ indent = options[:indent] || 0
196
+ width = terminal_width - indent
197
+ paras = message.split("\n\n")
198
+
199
+ paras.map! do |unwrapped|
200
+ unwrapped.strip.gsub(/\n/, " ").squeeze(" ").
201
+ gsub(/.{1,#{width}}(?:\s|\Z)/){($& + 5.chr).
202
+ gsub(/\n\005/,"\n").gsub(/\005/,"\n")}
203
+ end
204
+
205
+ paras.each do |para|
206
+ para.split("\n").each do |line|
207
+ stdout.puts line.insert(0, " " * indent)
208
+ end
209
+ stdout.puts unless para == paras.last
109
210
  end
110
211
  end
111
212
 
112
213
  # Deals with file collision and returns true if the file should be
113
- # overwriten and false otherwise. If a block is given, it uses the block
214
+ # overwritten and false otherwise. If a block is given, it uses the block
114
215
  # response as the content for the diff.
115
216
  #
116
217
  # ==== Parameters
@@ -143,35 +244,65 @@ class Thor
143
244
  end
144
245
  end
145
246
 
247
+ # This code was copied from Rake, available under MIT-LICENSE
248
+ # Copyright (c) 2003, 2004 Jim Weirich
249
+ def terminal_width
250
+ if ENV['THOR_COLUMNS']
251
+ result = ENV['THOR_COLUMNS'].to_i
252
+ else
253
+ result = unix? ? dynamic_width : 80
254
+ end
255
+ (result < 10) ? 80 : result
256
+ rescue
257
+ 80
258
+ end
259
+
146
260
  # Called if something goes wrong during the execution. This is used by Thor
147
- # internally and should not be used inside your scripts. If someone went
261
+ # internally and should not be used inside your scripts. If something went
148
262
  # wrong, you can always raise an exception. If you raise a Thor::Error, it
149
263
  # will be rescued and wrapped in the method below.
150
264
  #
151
265
  def error(statement)
152
- $stderr.puts statement
266
+ stderr.puts statement
153
267
  end
154
268
 
155
269
  # Apply color to the given string with optional bold. Disabled in the
156
270
  # Thor::Shell::Basic class.
157
271
  #
158
- def set_color(string, color, bold=false) #:nodoc:
272
+ def set_color(string, *args) #:nodoc:
159
273
  string
160
274
  end
161
275
 
162
- protected
276
+ protected
163
277
 
164
- def is?(value) #:nodoc:
165
- value = value.to_s
278
+ def lookup_color(color)
279
+ return color unless color.is_a?(Symbol)
280
+ self.class.const_get(color.to_s.upcase)
281
+ end
166
282
 
167
- if value.size == 1
168
- /\A#{value}\z/i
169
- else
170
- /\A(#{value}|#{value[0,1]})\z/i
171
- end
283
+ def stdout
284
+ $stdout
285
+ end
286
+
287
+ def stdin
288
+ $stdin
289
+ end
290
+
291
+ def stderr
292
+ $stderr
293
+ end
294
+
295
+ def is?(value) #:nodoc:
296
+ value = value.to_s
297
+
298
+ if value.size == 1
299
+ /\A#{value}\z/i
300
+ else
301
+ /\A(#{value}|#{value[0,1]})\z/i
172
302
  end
303
+ end
173
304
 
174
- def file_collision_help #:nodoc:
305
+ def file_collision_help #:nodoc:
175
306
  <<HELP
176
307
  Y - yes, overwrite
177
308
  n - no, do not overwrite
@@ -180,59 +311,78 @@ q - quit, abort
180
311
  d - diff, show the differences between the old and the new
181
312
  h - help, show this help
182
313
  HELP
183
- end
314
+ end
184
315
 
185
- def show_diff(destination, content) #:nodoc:
186
- diff_cmd = ENV['THOR_DIFF'] || ENV['RAILS_DIFF'] || 'diff -u'
316
+ def show_diff(destination, content) #:nodoc:
317
+ diff_cmd = ENV['THOR_DIFF'] || ENV['RAILS_DIFF'] || 'diff -u'
187
318
 
188
- Tempfile.open(File.basename(destination), File.dirname(destination)) do |temp|
189
- temp.write content
190
- temp.rewind
191
- system %(#{diff_cmd} "#{destination}" "#{temp.path}")
192
- end
319
+ Tempfile.open(File.basename(destination), File.dirname(destination)) do |temp|
320
+ temp.write content
321
+ temp.rewind
322
+ system %(#{diff_cmd} "#{destination}" "#{temp.path}")
193
323
  end
324
+ end
194
325
 
195
- def quiet? #:nodoc:
196
- base && base.options[:quiet]
197
- end
326
+ def quiet? #:nodoc:
327
+ mute? || (base && base.options[:quiet])
328
+ end
329
+
330
+ # Calculate the dynamic width of the terminal
331
+ def dynamic_width
332
+ @dynamic_width ||= (dynamic_width_stty.nonzero? || dynamic_width_tput)
333
+ end
334
+
335
+ def dynamic_width_stty
336
+ %x{stty size 2>/dev/null}.split[1].to_i
337
+ end
198
338
 
199
- # This code was copied from Rake, available under MIT-LICENSE
200
- # Copyright (c) 2003, 2004 Jim Weirich
201
- def terminal_width
202
- if ENV['THOR_COLUMNS']
203
- result = ENV['THOR_COLUMNS'].to_i
339
+ def dynamic_width_tput
340
+ %x{tput cols 2>/dev/null}.to_i
341
+ end
342
+
343
+ def unix?
344
+ RUBY_PLATFORM =~ /(aix|darwin|linux|(net|free|open)bsd|cygwin|solaris|irix|hpux)/i
345
+ end
346
+
347
+ def truncate(string, width)
348
+ as_unicode do
349
+ chars = string.chars.to_a
350
+ if chars.length <= width
351
+ chars.join
204
352
  else
205
- result = unix? ? dynamic_width : 80
353
+ ( chars[0, width-3].join ) + "..."
206
354
  end
207
- (result < 10) ? 80 : result
208
- rescue
209
- 80
210
- end
211
-
212
- # Calculate the dynamic width of the terminal
213
- def dynamic_width
214
- @dynamic_width ||= (dynamic_width_stty.nonzero? || dynamic_width_tput)
215
355
  end
356
+ end
216
357
 
217
- def dynamic_width_stty
218
- %x{stty size 2>/dev/null}.split[1].to_i
358
+ if "".respond_to?(:encode)
359
+ def as_unicode
360
+ yield
219
361
  end
220
-
221
- def dynamic_width_tput
222
- %x{tput cols 2>/dev/null}.to_i
362
+ else
363
+ def as_unicode
364
+ old, $KCODE = $KCODE, "U"
365
+ yield
366
+ ensure
367
+ $KCODE = old
223
368
  end
369
+ end
224
370
 
225
- def unix?
226
- RUBY_PLATFORM =~ /(aix|darwin|linux|(net|free|open)bsd|cygwin|solaris|irix|hpux)/i
227
- end
371
+ def ask_simply(statement, color=nil)
372
+ say("#{statement} ", color)
373
+ stdin.gets.strip
374
+ end
228
375
 
229
- def truncate(string, width)
230
- if string.length <= width
231
- string
232
- else
233
- ( string[0, width-3] || "" ) + "..."
234
- end
376
+ def ask_filtered(statement, answer_set, *args)
377
+ correct_answer = nil
378
+ until correct_answer
379
+ answer = ask_simply("#{statement} #{answer_set.inspect}", *args)
380
+ correct_answer = answer_set.include?(answer) ? answer : nil
381
+ answers = answer_set.map(&:inspect).join(", ")
382
+ say("Your response must be one of: [#{answers}]. Please try again.") unless correct_answer
235
383
  end
384
+ correct_answer
385
+ end
236
386
 
237
387
  end
238
388
  end