bundler 1.5.1 → 1.5.2
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.
Potentially problematic release.
This version of bundler might be problematic. Click here for more details.
- data/CHANGELOG.md +26 -2
- data/bin/bundle +1 -3
- data/bundler.gemspec +1 -1
- data/lib/bundler/cli.rb +2 -4
- data/lib/bundler/fetcher.rb +13 -12
- data/lib/bundler/installer.rb +9 -36
- data/lib/bundler/parallel_workers/unix_worker.rb +12 -4
- data/lib/bundler/parallel_workers/worker.rb +1 -0
- data/lib/bundler/rubygems_ext.rb +1 -1
- data/lib/bundler/rubygems_integration.rb +15 -8
- data/lib/bundler/templates/newgem/newgem.gemspec.tt +1 -1
- data/lib/bundler/vendor/thor.rb +63 -56
- data/lib/bundler/vendor/thor/actions.rb +52 -51
- data/lib/bundler/vendor/thor/actions/create_file.rb +35 -37
- data/lib/bundler/vendor/thor/actions/create_link.rb +1 -2
- data/lib/bundler/vendor/thor/actions/directory.rb +36 -37
- data/lib/bundler/vendor/thor/actions/empty_directory.rb +67 -69
- data/lib/bundler/vendor/thor/actions/file_manipulation.rb +11 -12
- data/lib/bundler/vendor/thor/actions/inject_into_file.rb +41 -43
- data/lib/bundler/vendor/thor/base.rb +180 -178
- data/lib/bundler/vendor/thor/command.rb +22 -25
- data/lib/bundler/vendor/thor/core_ext/hash_with_indifferent_access.rb +21 -24
- data/lib/bundler/vendor/thor/core_ext/io_binary_read.rb +1 -3
- data/lib/bundler/vendor/thor/core_ext/ordered_hash.rb +8 -10
- data/lib/bundler/vendor/thor/error.rb +2 -2
- data/lib/bundler/vendor/thor/group.rb +59 -60
- data/lib/bundler/vendor/thor/invocation.rb +39 -38
- data/lib/bundler/vendor/thor/line_editor.rb +17 -0
- data/lib/bundler/vendor/thor/line_editor/basic.rb +35 -0
- data/lib/bundler/vendor/thor/line_editor/readline.rb +88 -0
- data/lib/bundler/vendor/thor/parser/argument.rb +29 -30
- data/lib/bundler/vendor/thor/parser/arguments.rb +102 -98
- data/lib/bundler/vendor/thor/parser/option.rb +25 -25
- data/lib/bundler/vendor/thor/parser/options.rb +85 -85
- data/lib/bundler/vendor/thor/rake_compat.rb +6 -7
- data/lib/bundler/vendor/thor/runner.rb +154 -154
- data/lib/bundler/vendor/thor/shell.rb +23 -30
- data/lib/bundler/vendor/thor/shell/basic.rb +66 -57
- data/lib/bundler/vendor/thor/shell/color.rb +44 -43
- data/lib/bundler/vendor/thor/shell/html.rb +43 -44
- data/lib/bundler/vendor/thor/util.rb +37 -40
- data/lib/bundler/vendor/thor/version.rb +1 -1
- data/lib/bundler/version.rb +1 -1
- data/man/bundle-install.ronn +1 -1
- data/man/gemfile.5.ronn +1 -2
- data/spec/commands/binstubs_spec.rb +13 -0
- data/spec/install/gemfile/git_spec.rb +2 -2
- data/spec/install/gems/dependency_api_spec.rb +34 -0
- data/spec/install/gems/packed_spec.rb +2 -4
- data/spec/quality_spec.rb +2 -2
- data/spec/realworld/parallel_spec.rb +69 -0
- data/spec/runtime/setup_spec.rb +3 -2
- data/spec/spec_helper.rb +1 -0
- data/spec/support/artifice/endpoint_host_redirect.rb +15 -0
- data/spec/support/permissions.rb +11 -0
- metadata +11 -6
- data/spec/realworld/parallel_install_spec.rb +0 -23
- data/spec/realworld/parallel_update_spec.rb +0 -31
@@ -2,28 +2,27 @@ require 'rbconfig'
|
|
2
2
|
|
3
3
|
class Thor
|
4
4
|
module Base
|
5
|
-
|
6
|
-
|
7
|
-
#
|
8
|
-
def self.shell
|
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']))
|
12
|
-
Thor::Shell::Basic
|
13
|
-
else
|
14
|
-
Thor::Shell::Color
|
15
|
-
end
|
16
|
-
end
|
5
|
+
class << self
|
6
|
+
attr_writer :shell
|
17
7
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
8
|
+
# Returns the shell used in all Thor classes. If you are in a Unix platform
|
9
|
+
# it will use a colored log, otherwise it will use a basic one without color.
|
10
|
+
#
|
11
|
+
def shell
|
12
|
+
@shell ||= if ENV['THOR_SHELL'] && ENV['THOR_SHELL'].size > 0
|
13
|
+
Thor::Shell.const_get(ENV['THOR_SHELL'])
|
14
|
+
elsif RbConfig::CONFIG['host_os'] =~ /mswin|mingw/ && !ENV['ANSICON']
|
15
|
+
Thor::Shell::Basic
|
16
|
+
else
|
17
|
+
Thor::Shell::Color
|
18
|
+
end
|
19
|
+
end
|
22
20
|
end
|
23
21
|
end
|
24
22
|
|
25
23
|
module Shell
|
26
24
|
SHELL_DELEGATED_METHODS = [:ask, :error, :set_color, :yes?, :no?, :say, :say_status, :print_in_columns, :print_table, :print_wrapped, :file_collision, :terminal_width]
|
25
|
+
attr_writer :shell
|
27
26
|
|
28
27
|
autoload :Basic, 'thor/shell/basic'
|
29
28
|
autoload :Color, 'thor/shell/color'
|
@@ -42,10 +41,10 @@ class Thor
|
|
42
41
|
#
|
43
42
|
# MyScript.new [1.0], { :foo => :bar }, :shell => Thor::Shell::Basic.new
|
44
43
|
#
|
45
|
-
def initialize(args=[], options={}, config={})
|
44
|
+
def initialize(args = [], options = {}, config = {})
|
46
45
|
super
|
47
46
|
self.shell = config[:shell]
|
48
|
-
|
47
|
+
shell.base ||= self if shell.respond_to?(:base)
|
49
48
|
end
|
50
49
|
|
51
50
|
# Holds the shell for the given Thor instance. If no shell is given,
|
@@ -54,11 +53,6 @@ class Thor
|
|
54
53
|
@shell ||= Thor::Base.shell.new
|
55
54
|
end
|
56
55
|
|
57
|
-
# Sets the shell for this thor class.
|
58
|
-
def shell=(shell)
|
59
|
-
@shell = shell
|
60
|
-
end
|
61
|
-
|
62
56
|
# Common methods that are delegated to the shell.
|
63
57
|
SHELL_DELEGATED_METHODS.each do |method|
|
64
58
|
module_eval <<-METHOD, __FILE__, __LINE__
|
@@ -76,13 +70,12 @@ class Thor
|
|
76
70
|
shell.padding -= 1
|
77
71
|
end
|
78
72
|
|
79
|
-
|
80
|
-
|
81
|
-
# Allow shell to be shared between invocations.
|
82
|
-
#
|
83
|
-
def _shared_configuration #:nodoc:
|
84
|
-
super.merge!(:shell => self.shell)
|
85
|
-
end
|
73
|
+
protected
|
86
74
|
|
75
|
+
# Allow shell to be shared between invocations.
|
76
|
+
#
|
77
|
+
def _shared_configuration #:nodoc:
|
78
|
+
super.merge!(:shell => shell)
|
79
|
+
end
|
87
80
|
end
|
88
81
|
end
|
@@ -2,14 +2,14 @@ require 'tempfile'
|
|
2
2
|
|
3
3
|
class Thor
|
4
4
|
module Shell
|
5
|
-
class Basic
|
5
|
+
class Basic # rubocop:disable ClassLength
|
6
6
|
attr_accessor :base
|
7
7
|
attr_reader :padding
|
8
8
|
|
9
9
|
# Initialize base, mute and padding to nil.
|
10
10
|
#
|
11
11
|
def initialize #:nodoc:
|
12
|
-
@base, @mute, @padding = nil, false, 0
|
12
|
+
@base, @mute, @padding, @always_force = nil, false, 0, false
|
13
13
|
end
|
14
14
|
|
15
15
|
# Mute everything that's inside given block
|
@@ -23,7 +23,7 @@ class Thor
|
|
23
23
|
|
24
24
|
# Check if base is muted
|
25
25
|
#
|
26
|
-
def mute?
|
26
|
+
def mute? # rubocop:disable TrivialAccessors
|
27
27
|
@mute
|
28
28
|
end
|
29
29
|
|
@@ -40,11 +40,23 @@ class Thor
|
|
40
40
|
# they will be shown a message stating that one of those answers
|
41
41
|
# must be given and re-asked the question.
|
42
42
|
#
|
43
|
+
# If asking for sensitive information, the :echo option can be set
|
44
|
+
# to false to mask user input from $stdin.
|
45
|
+
#
|
46
|
+
# If the required input is a path, then set the path option to
|
47
|
+
# true. This will enable tab completion for file paths relative
|
48
|
+
# to the current working directory on systems that support
|
49
|
+
# Readline.
|
50
|
+
#
|
43
51
|
# ==== Example
|
44
52
|
# ask("What is your name?")
|
45
53
|
#
|
46
54
|
# ask("What is your favorite Neopolitan flavor?", :limited_to => ["strawberry", "chocolate", "vanilla"])
|
47
55
|
#
|
56
|
+
# ask("What is your password?", :echo => false)
|
57
|
+
#
|
58
|
+
# ask("Where should the file be saved?", :path => true)
|
59
|
+
#
|
48
60
|
def ask(statement, *args)
|
49
61
|
options = args.last.is_a?(Hash) ? args.pop : {}
|
50
62
|
color = args.first
|
@@ -63,12 +75,8 @@ class Thor
|
|
63
75
|
# ==== Example
|
64
76
|
# say("I know you knew that.")
|
65
77
|
#
|
66
|
-
def say(message=
|
67
|
-
|
68
|
-
message = set_color(message, *color) if color && can_display_colors?
|
69
|
-
|
70
|
-
buffer = " " * padding
|
71
|
-
buffer << message
|
78
|
+
def say(message = '', color = nil, force_new_line = (message.to_s !~ /( |\t)\Z/))
|
79
|
+
buffer = prepare_message(message, *color)
|
72
80
|
buffer << "\n" if force_new_line && !message.end_with?("\n")
|
73
81
|
|
74
82
|
stdout.print(buffer)
|
@@ -80,9 +88,9 @@ class Thor
|
|
80
88
|
# in log_status, avoiding the message from being shown. If a Symbol is
|
81
89
|
# given in log_status, it's used as the color.
|
82
90
|
#
|
83
|
-
def say_status(status, message, log_status=true)
|
91
|
+
def say_status(status, message, log_status = true)
|
84
92
|
return if quiet? || log_status == false
|
85
|
-
spaces =
|
93
|
+
spaces = ' ' * (padding + 1)
|
86
94
|
color = log_status.is_a?(Symbol) ? log_status : :green
|
87
95
|
|
88
96
|
status = status.to_s.rjust(12)
|
@@ -98,15 +106,15 @@ class Thor
|
|
98
106
|
# Make a question the to user and returns true if the user replies "y" or
|
99
107
|
# "yes".
|
100
108
|
#
|
101
|
-
def yes?(statement, color=nil)
|
102
|
-
!!(ask(statement, color) =~ is?(:yes))
|
109
|
+
def yes?(statement, color = nil)
|
110
|
+
!!(ask(statement, color, :add_to_history => false) =~ is?(:yes))
|
103
111
|
end
|
104
112
|
|
105
113
|
# Make a question the to user and returns true if the user replies "n" or
|
106
114
|
# "no".
|
107
115
|
#
|
108
|
-
def no?(statement, color=nil)
|
109
|
-
|
116
|
+
def no?(statement, color = nil)
|
117
|
+
!!(ask(statement, color, :add_to_history => false) =~ is?(:no))
|
110
118
|
end
|
111
119
|
|
112
120
|
# Prints values in columns
|
@@ -116,7 +124,7 @@ class Thor
|
|
116
124
|
#
|
117
125
|
def print_in_columns(array)
|
118
126
|
return if array.empty?
|
119
|
-
colwidth = (array.map{|el| el.to_s.size}.max || 0) + 2
|
127
|
+
colwidth = (array.map { |el| el.to_s.size }.max || 0) + 2
|
120
128
|
array.each_with_index do |value, index|
|
121
129
|
# Don't output trailing spaces when printing the last column
|
122
130
|
if ((((index + 1) % (terminal_width / colwidth))).zero? && !index.zero?) || index + 1 == array.length
|
@@ -136,7 +144,7 @@ class Thor
|
|
136
144
|
# indent<Integer>:: Indent the first column by indent value.
|
137
145
|
# colwidth<Integer>:: Force the first column to colwidth spaces wide.
|
138
146
|
#
|
139
|
-
def print_table(array, options={})
|
147
|
+
def print_table(array, options = {}) # rubocop:disable MethodLength
|
140
148
|
return if array.empty?
|
141
149
|
|
142
150
|
formats, indent, colwidth = [], options[:indent].to_i, options[:colwidth]
|
@@ -145,26 +153,26 @@ class Thor
|
|
145
153
|
formats << "%-#{colwidth + 2}s" if colwidth
|
146
154
|
start = colwidth ? 1 : 0
|
147
155
|
|
148
|
-
colcount = array.max{|a,b| a.size <=> b.size }.size
|
156
|
+
colcount = array.max { |a, b| a.size <=> b.size }.size
|
149
157
|
|
150
158
|
maximas = []
|
151
159
|
|
152
160
|
start.upto(colcount - 1) do |index|
|
153
|
-
maxima = array.map {|row| row[index] ? row[index].to_s.size : 0 }.max
|
161
|
+
maxima = array.map { |row| row[index] ? row[index].to_s.size : 0 }.max
|
154
162
|
maximas << maxima
|
155
163
|
if index == colcount - 1
|
156
164
|
# Don't output 2 trailing spaces when printing the last column
|
157
|
-
formats <<
|
165
|
+
formats << '%-s'
|
158
166
|
else
|
159
167
|
formats << "%-#{maxima + 2}s"
|
160
168
|
end
|
161
169
|
end
|
162
170
|
|
163
|
-
formats[0] = formats[0].insert(0,
|
164
|
-
formats <<
|
171
|
+
formats[0] = formats[0].insert(0, ' ' * indent)
|
172
|
+
formats << '%s'
|
165
173
|
|
166
174
|
array.each do |row|
|
167
|
-
sentence =
|
175
|
+
sentence = ''
|
168
176
|
|
169
177
|
row.each_with_index do |column, index|
|
170
178
|
maxima = maximas[index]
|
@@ -196,20 +204,18 @@ class Thor
|
|
196
204
|
# ==== Options
|
197
205
|
# indent<Integer>:: Indent each line of the printed paragraph by indent value.
|
198
206
|
#
|
199
|
-
def print_wrapped(message, options={})
|
207
|
+
def print_wrapped(message, options = {})
|
200
208
|
indent = options[:indent] || 0
|
201
209
|
width = terminal_width - indent
|
202
210
|
paras = message.split("\n\n")
|
203
211
|
|
204
212
|
paras.map! do |unwrapped|
|
205
|
-
unwrapped.strip.gsub(/\n/,
|
206
|
-
gsub(/.{1,#{width}}(?:\s|\Z)/){($& + 5.chr).
|
207
|
-
gsub(/\n\005/,"\n").gsub(/\005/,"\n")}
|
213
|
+
unwrapped.strip.gsub(/\n/, ' ').squeeze(' ').gsub(/.{1,#{width}}(?:\s|\Z)/) { ($& + 5.chr).gsub(/\n\005/, "\n").gsub(/\005/, "\n") }
|
208
214
|
end
|
209
215
|
|
210
216
|
paras.each do |para|
|
211
217
|
para.split("\n").each do |line|
|
212
|
-
stdout.puts line.insert(0,
|
218
|
+
stdout.puts line.insert(0, ' ' * indent)
|
213
219
|
end
|
214
220
|
stdout.puts unless para == paras.last
|
215
221
|
end
|
@@ -223,15 +229,18 @@ class Thor
|
|
223
229
|
# destination<String>:: the destination file to solve conflicts
|
224
230
|
# block<Proc>:: an optional block that returns the value to be used in diff
|
225
231
|
#
|
226
|
-
def file_collision(destination)
|
232
|
+
def file_collision(destination) # rubocop:disable MethodLength
|
227
233
|
return true if @always_force
|
228
|
-
options = block_given? ?
|
234
|
+
options = block_given? ? '[Ynaqdh]' : '[Ynaqh]'
|
229
235
|
|
230
|
-
|
231
|
-
answer = ask
|
236
|
+
loop do
|
237
|
+
answer = ask(
|
238
|
+
%[Overwrite #{destination}? (enter "h" for help) #{options}],
|
239
|
+
:add_to_history => false
|
240
|
+
)
|
232
241
|
|
233
242
|
case answer
|
234
|
-
when is?(:yes), is?(:force),
|
243
|
+
when is?(:yes), is?(:force), ''
|
235
244
|
return true
|
236
245
|
when is?(:no), is?(:skip)
|
237
246
|
return false
|
@@ -239,7 +248,7 @@ class Thor
|
|
239
248
|
return @always_force = true
|
240
249
|
when is?(:quit)
|
241
250
|
say 'Aborting...'
|
242
|
-
|
251
|
+
fail SystemExit
|
243
252
|
when is?(:diff)
|
244
253
|
show_diff(destination, yield) if block_given?
|
245
254
|
say 'Retrying...'
|
@@ -257,7 +266,7 @@ class Thor
|
|
257
266
|
else
|
258
267
|
result = unix? ? dynamic_width : 80
|
259
268
|
end
|
260
|
-
|
269
|
+
result < 10 ? 80 : result
|
261
270
|
rescue
|
262
271
|
80
|
263
272
|
end
|
@@ -280,6 +289,11 @@ class Thor
|
|
280
289
|
|
281
290
|
protected
|
282
291
|
|
292
|
+
def prepare_message(message, *color)
|
293
|
+
spaces = " " * padding
|
294
|
+
spaces + set_color(message.to_s, *color)
|
295
|
+
end
|
296
|
+
|
283
297
|
def can_display_colors?
|
284
298
|
false
|
285
299
|
end
|
@@ -293,10 +307,6 @@ class Thor
|
|
293
307
|
$stdout
|
294
308
|
end
|
295
309
|
|
296
|
-
def stdin
|
297
|
-
$stdin
|
298
|
-
end
|
299
|
-
|
300
310
|
def stderr
|
301
311
|
$stderr
|
302
312
|
end
|
@@ -307,19 +317,19 @@ class Thor
|
|
307
317
|
if value.size == 1
|
308
318
|
/\A#{value}\z/i
|
309
319
|
else
|
310
|
-
/\A(#{value}|#{value[0,1]})\z/i
|
320
|
+
/\A(#{value}|#{value[0, 1]})\z/i
|
311
321
|
end
|
312
322
|
end
|
313
323
|
|
314
324
|
def file_collision_help #:nodoc:
|
315
|
-
|
316
|
-
Y - yes, overwrite
|
317
|
-
n - no, do not overwrite
|
318
|
-
a - all, overwrite this and all others
|
319
|
-
q - quit, abort
|
320
|
-
d - diff, show the differences between the old and the new
|
321
|
-
h - help, show this help
|
322
|
-
HELP
|
325
|
+
<<-HELP
|
326
|
+
Y - yes, overwrite
|
327
|
+
n - no, do not overwrite
|
328
|
+
a - all, overwrite this and all others
|
329
|
+
q - quit, abort
|
330
|
+
d - diff, show the differences between the old and the new
|
331
|
+
h - help, show this help
|
332
|
+
HELP
|
323
333
|
end
|
324
334
|
|
325
335
|
def show_diff(destination, content) #:nodoc:
|
@@ -359,18 +369,18 @@ HELP
|
|
359
369
|
if chars.length <= width
|
360
370
|
chars.join
|
361
371
|
else
|
362
|
-
( chars[0, width-3].join
|
372
|
+
( chars[0, width - 3].join) + '...'
|
363
373
|
end
|
364
374
|
end
|
365
375
|
end
|
366
376
|
|
367
|
-
if
|
377
|
+
if ''.respond_to?(:encode)
|
368
378
|
def as_unicode
|
369
379
|
yield
|
370
380
|
end
|
371
381
|
else
|
372
382
|
def as_unicode
|
373
|
-
old, $KCODE = $KCODE,
|
383
|
+
old, $KCODE = $KCODE, 'U'
|
374
384
|
yield
|
375
385
|
ensure
|
376
386
|
$KCODE = old
|
@@ -379,15 +389,15 @@ HELP
|
|
379
389
|
|
380
390
|
def ask_simply(statement, color, options)
|
381
391
|
default = options[:default]
|
382
|
-
message = [statement, ("(#{default})" if default), nil].uniq.join(
|
383
|
-
|
384
|
-
result =
|
392
|
+
message = [statement, ("(#{default})" if default), nil].uniq.join(' ')
|
393
|
+
message = prepare_message(message, color)
|
394
|
+
result = Thor::LineEditor.readline(message, options)
|
385
395
|
|
386
396
|
return unless result
|
387
397
|
|
388
398
|
result.strip!
|
389
399
|
|
390
|
-
if default && result ==
|
400
|
+
if default && result == ''
|
391
401
|
default
|
392
402
|
else
|
393
403
|
result
|
@@ -398,14 +408,13 @@ HELP
|
|
398
408
|
answer_set = options[:limited_to]
|
399
409
|
correct_answer = nil
|
400
410
|
until correct_answer
|
401
|
-
answers = answer_set.join(
|
411
|
+
answers = answer_set.join(', ')
|
402
412
|
answer = ask_simply("#{statement} [#{answers}]", color, options)
|
403
413
|
correct_answer = answer_set.include?(answer) ? answer : nil
|
404
414
|
say("Your response must be one of: [#{answers}]. Please try again.") unless correct_answer
|
405
415
|
end
|
406
416
|
correct_answer
|
407
417
|
end
|
408
|
-
|
409
418
|
end
|
410
419
|
end
|
411
420
|
end
|
@@ -77,7 +77,9 @@ class Thor
|
|
77
77
|
# :on_cyan
|
78
78
|
# :on_white
|
79
79
|
def set_color(string, *colors)
|
80
|
-
if colors.
|
80
|
+
if colors.compact.empty? || !can_display_colors?
|
81
|
+
string
|
82
|
+
elsif colors.all? { |color| color.is_a?(Symbol) || color.is_a?(String) }
|
81
83
|
ansi_colors = colors.map { |color| lookup_color(color) }
|
82
84
|
"#{ansi_colors.join}#{string}#{CLEAR}"
|
83
85
|
else
|
@@ -87,62 +89,61 @@ class Thor
|
|
87
89
|
foreground, bold = colors
|
88
90
|
foreground = self.class.const_get(foreground.to_s.upcase) if foreground.is_a?(Symbol)
|
89
91
|
|
90
|
-
bold = bold ? BOLD :
|
92
|
+
bold = bold ? BOLD : ''
|
91
93
|
"#{bold}#{foreground}#{string}#{CLEAR}"
|
92
94
|
end
|
93
95
|
end
|
94
96
|
|
95
|
-
|
97
|
+
protected
|
96
98
|
|
97
|
-
|
98
|
-
|
99
|
-
|
99
|
+
def can_display_colors?
|
100
|
+
stdout.tty?
|
101
|
+
end
|
100
102
|
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
103
|
+
# Overwrite show_diff to show diff with colors if Diff::LCS is
|
104
|
+
# available.
|
105
|
+
#
|
106
|
+
def show_diff(destination, content) #:nodoc:
|
107
|
+
if diff_lcs_loaded? && ENV['THOR_DIFF'].nil? && ENV['RAILS_DIFF'].nil?
|
108
|
+
actual = File.binread(destination).to_s.split("\n")
|
109
|
+
content = content.to_s.split("\n")
|
108
110
|
|
109
|
-
|
110
|
-
|
111
|
-
end
|
112
|
-
else
|
113
|
-
super
|
111
|
+
Diff::LCS.sdiff(actual, content).each do |diff|
|
112
|
+
output_diff_line(diff)
|
114
113
|
end
|
114
|
+
else
|
115
|
+
super
|
115
116
|
end
|
117
|
+
end
|
116
118
|
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
end
|
119
|
+
def output_diff_line(diff) #:nodoc:
|
120
|
+
case diff.action
|
121
|
+
when '-'
|
122
|
+
say "- #{diff.old_element.chomp}", :red, true
|
123
|
+
when '+'
|
124
|
+
say "+ #{diff.new_element.chomp}", :green, true
|
125
|
+
when '!'
|
126
|
+
say "- #{diff.old_element.chomp}", :red, true
|
127
|
+
say "+ #{diff.new_element.chomp}", :green, true
|
128
|
+
else
|
129
|
+
say " #{diff.old_element.chomp}", nil, true
|
129
130
|
end
|
131
|
+
end
|
130
132
|
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
133
|
+
# Check if Diff::LCS is loaded. If it is, use it to create pretty output
|
134
|
+
# for diff.
|
135
|
+
#
|
136
|
+
def diff_lcs_loaded? #:nodoc:
|
137
|
+
return true if defined?(Diff::LCS)
|
138
|
+
return @diff_lcs_loaded unless @diff_lcs_loaded.nil?
|
137
139
|
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
end
|
140
|
+
@diff_lcs_loaded = begin
|
141
|
+
require 'diff/lcs'
|
142
|
+
true
|
143
|
+
rescue LoadError
|
144
|
+
false
|
144
145
|
end
|
145
|
-
|
146
|
+
end
|
146
147
|
end
|
147
148
|
end
|
148
149
|
end
|