bundler 1.14.6 → 1.15.0.pre.1

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of bundler might be problematic. Click here for more details.

Files changed (131) hide show
  1. checksums.yaml +5 -5
  2. data/.rubocop.yml +1 -1
  3. data/.rubocop_todo.yml +131 -43
  4. data/.travis.yml +5 -5
  5. data/CHANGELOG.md +52 -8
  6. data/CONTRIBUTING.md +10 -29
  7. data/README.md +13 -6
  8. data/Rakefile +4 -2
  9. data/bin/rubocop +1 -1
  10. data/doc/README.md +30 -0
  11. data/doc/TROUBLESHOOTING.md +64 -0
  12. data/doc/contributing/BUG_TRIAGE.md +36 -0
  13. data/doc/contributing/COMMUNITY.md +13 -0
  14. data/doc/contributing/GETTING_HELP.md +11 -0
  15. data/doc/contributing/HOW_YOU_CAN_HELP.md +27 -0
  16. data/doc/contributing/ISSUES.md +51 -0
  17. data/doc/contributing/README.md +38 -0
  18. data/doc/development/NEW_FEATURES.md +10 -0
  19. data/doc/development/PULL_REQUESTS.md +40 -0
  20. data/doc/development/README.md +19 -0
  21. data/doc/development/RELEASING.md +9 -0
  22. data/doc/development/SETUP.md +29 -0
  23. data/doc/documentation/README.md +29 -0
  24. data/doc/documentation/VISION.md +26 -0
  25. data/doc/documentation/WRITING.md +54 -0
  26. data/exe/bundle +4 -1
  27. data/lib/bundler.rb +20 -13
  28. data/lib/bundler/cli.rb +67 -3
  29. data/lib/bundler/cli/add.rb +26 -0
  30. data/lib/bundler/cli/config.rb +24 -6
  31. data/lib/bundler/cli/gem.rb +13 -8
  32. data/lib/bundler/cli/info.rb +51 -0
  33. data/lib/bundler/cli/inject.rb +8 -2
  34. data/lib/bundler/cli/install.rb +1 -1
  35. data/lib/bundler/cli/issue.rb +40 -0
  36. data/lib/bundler/cli/outdated.rb +16 -18
  37. data/lib/bundler/cli/pristine.rb +33 -0
  38. data/lib/bundler/cli/viz.rb +1 -1
  39. data/lib/bundler/definition.rb +64 -48
  40. data/lib/bundler/dsl.rb +6 -0
  41. data/lib/bundler/endpoint_specification.rb +3 -9
  42. data/lib/bundler/env.rb +3 -3
  43. data/lib/bundler/errors.rb +1 -1
  44. data/lib/bundler/fetcher/downloader.rb +3 -2
  45. data/lib/bundler/gem_helper.rb +5 -0
  46. data/lib/bundler/index.rb +9 -3
  47. data/lib/bundler/injector.rb +32 -11
  48. data/lib/bundler/installer.rb +1 -1
  49. data/lib/bundler/installer/parallel_installer.rb +15 -1
  50. data/lib/bundler/lazy_specification.rb +6 -0
  51. data/lib/bundler/lockfile_parser.rb +42 -34
  52. data/lib/bundler/mirror.rb +2 -0
  53. data/lib/bundler/plugin.rb +5 -1
  54. data/lib/bundler/plugin/api/source.rb +1 -1
  55. data/lib/bundler/plugin/index.rb +2 -0
  56. data/lib/bundler/remote_specification.rb +16 -7
  57. data/lib/bundler/resolver.rb +13 -3
  58. data/lib/bundler/rubygems_ext.rb +8 -3
  59. data/lib/bundler/rubygems_integration.rb +85 -36
  60. data/lib/bundler/runtime.rb +4 -1
  61. data/lib/bundler/settings.rb +2 -1
  62. data/lib/bundler/setup.rb +1 -1
  63. data/lib/bundler/shared_helpers.rb +26 -1
  64. data/lib/bundler/source.rb +17 -1
  65. data/lib/bundler/source/git.rb +16 -0
  66. data/lib/bundler/source/path.rb +13 -3
  67. data/lib/bundler/source/path/installer.rb +2 -2
  68. data/lib/bundler/source/rubygems.rb +5 -2
  69. data/lib/bundler/spec_set.rb +22 -13
  70. data/lib/bundler/stub_specification.rb +64 -2
  71. data/lib/bundler/templates/Executable +1 -1
  72. data/lib/bundler/templates/Executable.standalone +5 -5
  73. data/lib/bundler/templates/newgem/Gemfile.tt +2 -2
  74. data/lib/bundler/templates/newgem/LICENSE.txt.tt +1 -1
  75. data/lib/bundler/templates/newgem/README.md.tt +12 -6
  76. data/lib/bundler/templates/newgem/Rakefile.tt +5 -5
  77. data/lib/bundler/templates/newgem/ext/newgem/newgem.c.tt +4 -4
  78. data/lib/bundler/templates/newgem/ext/newgem/newgem.h.tt +3 -3
  79. data/lib/bundler/templates/newgem/lib/newgem.rb.tt +6 -6
  80. data/lib/bundler/templates/newgem/lib/newgem/version.rb.tt +4 -4
  81. data/lib/bundler/templates/newgem/newgem.gemspec.tt +9 -9
  82. data/lib/bundler/templates/newgem/spec/spec_helper.rb.tt +3 -0
  83. data/lib/bundler/templates/newgem/test/newgem_test.rb.tt +1 -1
  84. data/lib/bundler/templates/newgem/test/test_helper.rb.tt +3 -3
  85. data/lib/bundler/ui/shell.rb +9 -6
  86. data/lib/bundler/vendor/thor/lib/thor.rb +31 -23
  87. data/lib/bundler/vendor/thor/lib/thor/actions.rb +21 -22
  88. data/lib/bundler/vendor/thor/lib/thor/actions/create_file.rb +1 -1
  89. data/lib/bundler/vendor/thor/lib/thor/actions/create_link.rb +1 -1
  90. data/lib/bundler/vendor/thor/lib/thor/actions/directory.rb +2 -2
  91. data/lib/bundler/vendor/thor/lib/thor/actions/empty_directory.rb +8 -8
  92. data/lib/bundler/vendor/thor/lib/thor/actions/file_manipulation.rb +23 -12
  93. data/lib/bundler/vendor/thor/lib/thor/actions/inject_into_file.rb +10 -14
  94. data/lib/bundler/vendor/thor/lib/thor/base.rb +30 -30
  95. data/lib/bundler/vendor/thor/lib/thor/command.rb +9 -9
  96. data/lib/bundler/vendor/thor/lib/thor/core_ext/hash_with_indifferent_access.rb +9 -1
  97. data/lib/bundler/vendor/thor/lib/thor/core_ext/io_binary_read.rb +7 -5
  98. data/lib/bundler/vendor/thor/lib/thor/core_ext/ordered_hash.rb +94 -63
  99. data/lib/bundler/vendor/thor/lib/thor/error.rb +3 -3
  100. data/lib/bundler/vendor/thor/lib/thor/group.rb +12 -12
  101. data/lib/bundler/vendor/thor/lib/thor/invocation.rb +4 -5
  102. data/lib/bundler/vendor/thor/lib/thor/parser/argument.rb +4 -7
  103. data/lib/bundler/vendor/thor/lib/thor/parser/arguments.rb +16 -16
  104. data/lib/bundler/vendor/thor/lib/thor/parser/option.rb +40 -19
  105. data/lib/bundler/vendor/thor/lib/thor/parser/options.rb +7 -5
  106. data/lib/bundler/vendor/thor/lib/thor/runner.rb +25 -25
  107. data/lib/bundler/vendor/thor/lib/thor/shell.rb +1 -1
  108. data/lib/bundler/vendor/thor/lib/thor/shell/basic.rb +41 -26
  109. data/lib/bundler/vendor/thor/lib/thor/shell/color.rb +1 -1
  110. data/lib/bundler/vendor/thor/lib/thor/shell/html.rb +4 -4
  111. data/lib/bundler/vendor/thor/lib/thor/util.rb +8 -7
  112. data/lib/bundler/vendor/thor/lib/thor/version.rb +1 -1
  113. data/lib/bundler/version.rb +14 -1
  114. data/lib/bundler/version_ranges.rb +75 -0
  115. data/lib/bundler/worker.rb +2 -1
  116. data/man/bundle-check.ronn +26 -0
  117. data/man/bundle-clean.ronn +18 -0
  118. data/man/bundle-config.ronn +4 -1
  119. data/man/bundle-info.ronn +17 -0
  120. data/man/bundle-init.ronn +18 -0
  121. data/man/bundle-inject.ronn +22 -0
  122. data/man/bundle-open.ronn +19 -0
  123. data/man/bundle-show.ronn +20 -0
  124. data/man/bundle-update.ronn +5 -2
  125. data/man/bundle-viz.ronn +30 -0
  126. data/man/bundle.ronn +3 -0
  127. data/man/gemfile.5.ronn +24 -64
  128. data/task/release.rake +115 -0
  129. metadata +49 -5
  130. data/DEVELOPMENT.md +0 -150
  131. data/ISSUES.md +0 -117
@@ -1,4 +1,4 @@
1
- $LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
2
- require '<%= config[:namespaced_path] %>'
1
+ $LOAD_PATH.unshift File.expand_path("../../lib", __FILE__)
2
+ require "<%= config[:namespaced_path] %>"
3
3
 
4
- require 'minitest/autorun'
4
+ require "minitest/autorun"
@@ -40,16 +40,15 @@ module Bundler
40
40
  end
41
41
 
42
42
  def debug(msg, newline = nil)
43
- tell_me(msg, nil, newline) if level("debug")
43
+ tell_me(msg, nil, newline) if debug?
44
44
  end
45
45
 
46
46
  def debug?
47
- # needs to be false instead of nil to be newline param to other methods
48
- level("debug") ? true : false
47
+ level("debug")
49
48
  end
50
49
 
51
50
  def quiet?
52
- LEVELS.index(@level) <= LEVELS.index("warn")
51
+ level("quiet")
53
52
  end
54
53
 
55
54
  def ask(msg)
@@ -66,11 +65,15 @@ module Bundler
66
65
 
67
66
  def level=(level)
68
67
  raise ArgumentError unless LEVELS.include?(level.to_s)
69
- @level = level
68
+ @level = level.to_s
70
69
  end
71
70
 
72
71
  def level(name = nil)
73
- name ? LEVELS.index(name) <= LEVELS.index(@level) : @level
72
+ return @level unless name
73
+ unless index = LEVELS.index(name)
74
+ raise "#{name.inspect} is not a valid level"
75
+ end
76
+ index <= LEVELS.index(@level)
74
77
  end
75
78
 
76
79
  def trace(e, newline = nil, force = false)
@@ -1,7 +1,7 @@
1
1
  require "set"
2
2
  require "bundler/vendor/thor/lib/thor/base"
3
3
 
4
- class Bundler::Thor # rubocop:disable ClassLength
4
+ class Bundler::Thor
5
5
  class << self
6
6
  # Allows for custom "Command" package naming.
7
7
  #
@@ -9,7 +9,7 @@ class Bundler::Thor # rubocop:disable ClassLength
9
9
  # name<String>
10
10
  # options<Hash>
11
11
  #
12
- def package_name(name, options = {})
12
+ def package_name(name, _ = {})
13
13
  @package_name = name.nil? || name == "" ? nil : name
14
14
  end
15
15
 
@@ -57,7 +57,9 @@ class Bundler::Thor # rubocop:disable ClassLength
57
57
  command.usage = usage if usage
58
58
  command.description = description if description
59
59
  else
60
- @usage, @desc, @hide = usage, description, options[:hide] || false
60
+ @usage = usage
61
+ @desc = description
62
+ @hide = options[:hide] || false
61
63
  end
62
64
  end
63
65
 
@@ -156,6 +158,10 @@ class Bundler::Thor # rubocop:disable ClassLength
156
158
  end
157
159
  alias_method :option, :method_option
158
160
 
161
+ def disable_class_options
162
+ @disable_class_options = true
163
+ end
164
+
159
165
  # Prints help information for the given command.
160
166
  #
161
167
  # ==== Parameters
@@ -170,7 +176,7 @@ class Bundler::Thor # rubocop:disable ClassLength
170
176
  shell.say "Usage:"
171
177
  shell.say " #{banner(command)}"
172
178
  shell.say
173
- class_options_help(shell, nil => command.options.map { |_, o| o })
179
+ class_options_help(shell, nil => command.options.values)
174
180
  if command.long_description
175
181
  shell.say "Description:"
176
182
  shell.print_wrapped(command.long_description, :indent => 2)
@@ -231,8 +237,9 @@ class Bundler::Thor # rubocop:disable ClassLength
231
237
 
232
238
  define_method(subcommand) do |*args|
233
239
  args, opts = Bundler::Thor::Arguments.split(args)
234
- args.unshift("help") if opts.include? "--help" or opts.include? "-h"
235
- invoke subcommand_class, args, opts, :invoked_via_subcommand => true, :class_options => options
240
+ invoke_args = [args, opts, {:invoked_via_subcommand => true, :class_options => options}]
241
+ invoke_args.unshift "help" if opts.delete("--help") || opts.delete("-h")
242
+ invoke subcommand_class, *invoke_args
236
243
  end
237
244
  end
238
245
  alias_method :subtask, :subcommand
@@ -320,6 +327,7 @@ class Bundler::Thor # rubocop:disable ClassLength
320
327
  end
321
328
 
322
329
  protected
330
+
323
331
  def stop_on_unknown_option #:nodoc:
324
332
  @stop_on_unknown_option ||= Set.new
325
333
  end
@@ -345,12 +353,14 @@ class Bundler::Thor # rubocop:disable ClassLength
345
353
  opts.clear
346
354
  end
347
355
  else
348
- args, opts = given_args, nil
356
+ args = given_args
357
+ opts = nil
349
358
  command = dynamic_command_class.new(meth)
350
359
  end
351
360
 
352
361
  opts = given_opts || opts || []
353
- config.merge!(:current_command => command, :command_options => command.options)
362
+ config[:current_command] = command
363
+ config[:command_options] = command.options
354
364
 
355
365
  instance = new(args, opts, config)
356
366
  yield instance if block_given?
@@ -380,17 +390,18 @@ class Bundler::Thor # rubocop:disable ClassLength
380
390
  @usage ||= nil
381
391
  @desc ||= nil
382
392
  @long_desc ||= nil
393
+ @disable_class_options ||= nil
383
394
 
384
395
  if @usage && @desc
385
396
  base_class = @hide ? Bundler::Thor::HiddenCommand : Bundler::Thor::Command
386
- commands[meth] = base_class.new(meth, @desc, @long_desc, @usage, method_options)
387
- @usage, @desc, @long_desc, @method_options, @hide = nil
397
+ commands[meth] = base_class.new(meth, @desc, @long_desc, @usage, method_options, @disable_class_options)
398
+ @usage, @desc, @long_desc, @method_options, @hide, @disable_class_options = nil
388
399
  true
389
400
  elsif all_commands[meth] || meth == "method_missing"
390
401
  true
391
402
  else
392
- puts "[WARNING] Attempted to create command #{meth.inspect} without usage or description. " <<
393
- "Call desc if you want this method to be available as command or declare it inside a " <<
403
+ puts "[WARNING] Attempted to create command #{meth.inspect} without usage or description. " \
404
+ "Call desc if you want this method to be available as command or declare it inside a " \
394
405
  "no_commands{} block. Invoked from #{caller[1].inspect}."
395
406
  false
396
407
  end
@@ -405,11 +416,7 @@ class Bundler::Thor # rubocop:disable ClassLength
405
416
  # Retrieve the command name from given args.
406
417
  def retrieve_command_name(args) #:nodoc:
407
418
  meth = args.first.to_s unless args.empty?
408
- if meth && (map[meth] || meth !~ /^\-/)
409
- args.shift
410
- else
411
- nil
412
- end
419
+ args.shift if meth && (map[meth] || meth !~ /^\-/)
413
420
  end
414
421
  alias_method :retrieve_task_name, :retrieve_command_name
415
422
 
@@ -421,20 +428,20 @@ class Bundler::Thor # rubocop:disable ClassLength
421
428
  # +normalize_command_name+ also converts names like +animal-prison+
422
429
  # into +animal_prison+.
423
430
  def normalize_command_name(meth) #:nodoc:
424
- return default_command.to_s.gsub("-", "_") unless meth
431
+ return default_command.to_s.tr("-", "_") unless meth
425
432
 
426
433
  possibilities = find_command_possibilities(meth)
427
- if possibilities.size > 1
428
- fail AmbiguousTaskError, "Ambiguous command #{meth} matches [#{possibilities.join(', ')}]"
429
- elsif possibilities.size < 1
430
- meth = meth || default_command
434
+ raise AmbiguousTaskError, "Ambiguous command #{meth} matches [#{possibilities.join(', ')}]" if possibilities.size > 1
435
+
436
+ if possibilities.empty?
437
+ meth ||= default_command
431
438
  elsif map[meth]
432
439
  meth = map[meth]
433
440
  else
434
441
  meth = possibilities.first
435
442
  end
436
443
 
437
- meth.to_s.gsub("-", "_") # treat foo-bar as foo_bar
444
+ meth.to_s.tr("-", "_") # treat foo-bar as foo_bar
438
445
  end
439
446
  alias_method :normalize_task_name, :normalize_command_name
440
447
 
@@ -470,6 +477,7 @@ class Bundler::Thor # rubocop:disable ClassLength
470
477
  map HELP_MAPPINGS => :help
471
478
 
472
479
  desc "help [COMMAND]", "Describe available commands or one specific command"
480
+ disable_class_options
473
481
  def help(command = nil, subcommand = false)
474
482
  if command
475
483
  if self.class.subcommands.include? command
@@ -73,14 +73,15 @@ class Bundler::Thor
73
73
  #
74
74
  def initialize(args = [], options = {}, config = {})
75
75
  self.behavior = case config[:behavior].to_s
76
- when "force", "skip"
77
- _cleanup_options_and_set(options, config[:behavior])
78
- :invoke
79
- when "revoke"
80
- :revoke
81
- else
82
- :invoke
83
- end
76
+ when "force", "skip"
77
+ _cleanup_options_and_set(options, config[:behavior])
78
+ :invoke
79
+ when "revoke"
80
+ :revoke
81
+ else
82
+ :invoke
83
+ end
84
+
84
85
  super
85
86
  self.destination_root = config[:destination_root]
86
87
  end
@@ -129,7 +130,7 @@ class Bundler::Thor
129
130
 
130
131
  # Receives a file or directory and search for it in the source paths.
131
132
  #
132
- def find_in_source_paths(file) # rubocop:disable MethodLength
133
+ def find_in_source_paths(file)
133
134
  possible_files = [file, file + TEMPLATE_EXTNAME]
134
135
  relative_root = relative_to_original_destination_root(destination_root, false)
135
136
 
@@ -146,13 +147,13 @@ class Bundler::Thor
146
147
  message << "Please invoke #{self.class.name}.source_root(PATH) with the PATH containing your templates. "
147
148
  end
148
149
 
149
- if source_paths.empty?
150
- message << "Currently you have no source paths."
151
- else
152
- message << "Your current source paths are: \n#{source_paths.join("\n")}"
153
- end
150
+ message << if source_paths.empty?
151
+ "Currently you have no source paths."
152
+ else
153
+ "Your current source paths are: \n#{source_paths.join("\n")}"
154
+ end
154
155
 
155
- fail Error, message
156
+ raise Error, message
156
157
  end
157
158
 
158
159
  # Do something in the root or on a provided subfolder. If a relative path
@@ -214,10 +215,10 @@ class Bundler::Thor
214
215
  say_status :apply, path, verbose
215
216
  shell.padding += 1 if verbose
216
217
 
217
- if is_uri
218
- contents = open(path, "Accept" => "application/x-thor-template") { |io| io.read }
218
+ contents = if is_uri
219
+ open(path, "Accept" => "application/x-thor-template", &:read)
219
220
  else
220
- contents = open(path) { |io| io.read }
221
+ open(path, &:read)
221
222
  end
222
223
 
223
224
  instance_eval(contents, path)
@@ -250,9 +251,7 @@ class Bundler::Thor
250
251
 
251
252
  say_status :run, desc, config.fetch(:verbose, true)
252
253
 
253
- unless options[:pretend]
254
- config[:capture] ? `#{command}` : system("#{command}")
255
- end
254
+ !options[:pretend] && config[:capture] ? `#{command}` : system(command.to_s)
256
255
  end
257
256
 
258
257
  # Executes a ruby script (taking into account WIN32 platform quirks).
@@ -308,7 +307,7 @@ class Bundler::Thor
308
307
  def _cleanup_options_and_set(options, key) #:nodoc:
309
308
  case options
310
309
  when Array
311
- %w[--force -f --skip -s].each { |i| options.delete(i) }
310
+ %w(--force -f --skip -s).each { |i| options.delete(i) }
312
311
  options << "--#{key}"
313
312
  when Hash
314
313
  [:force, :skip, "force", "skip"].each { |i| options.delete(i) }
@@ -84,7 +84,7 @@ class Bundler::Thor
84
84
  def force_or_skip_or_conflict(force, skip, &block)
85
85
  if force
86
86
  say_status :force, :yellow
87
- block.call unless pretend?
87
+ yield unless pretend?
88
88
  elsif skip
89
89
  say_status :skip, :yellow
90
90
  else
@@ -14,7 +14,7 @@ class Bundler::Thor
14
14
  #
15
15
  # create_link "config/apache.conf", "/etc/apache.conf"
16
16
  #
17
- def create_link(destination, *args, &block)
17
+ def create_link(destination, *args)
18
18
  config = args.last.is_a?(Hash) ? args.pop : {}
19
19
  source = args.first
20
20
  action CreateLink.new(self, destination, source, config)
@@ -72,7 +72,7 @@ class Bundler::Thor
72
72
 
73
73
  protected
74
74
 
75
- def execute! # rubocop:disable MethodLength
75
+ def execute!
76
76
  lookup = Util.escape_globs(source)
77
77
  lookup = config[:recursive] ? File.join(lookup, "**") : lookup
78
78
  lookup = file_level_lookup(lookup)
@@ -85,7 +85,7 @@ class Bundler::Thor
85
85
 
86
86
  case file_source
87
87
  when /\.empty_directory$/
88
- dirname = File.dirname(file_destination).gsub(/\/\.$/, "")
88
+ dirname = File.dirname(file_destination).gsub(%r{/\.$}, "")
89
89
  next if dirname == given_destination
90
90
  base.empty_directory(dirname, config)
91
91
  when /#{TEMPLATE_EXTNAME}$/
@@ -32,7 +32,8 @@ class Bundler::Thor
32
32
  # config<Hash>:: give :verbose => false to not log the status.
33
33
  #
34
34
  def initialize(base, destination, config = {})
35
- @base, @config = base, {:verbose => true}.merge(config)
35
+ @base = base
36
+ @config = {:verbose => true}.merge(config)
36
37
  self.destination = destination
37
38
  end
38
39
 
@@ -80,11 +81,10 @@ class Bundler::Thor
80
81
  # given_destination #=> baz
81
82
  #
82
83
  def destination=(destination)
83
- if destination
84
- @given_destination = convert_encoded_instructions(destination.to_s)
85
- @destination = ::File.expand_path(@given_destination, base.destination_root)
86
- @relative_destination = base.relative_to_original_destination_root(@destination)
87
- end
84
+ return unless destination
85
+ @given_destination = convert_encoded_instructions(destination.to_s)
86
+ @destination = ::File.expand_path(@given_destination, base.destination_root)
87
+ @relative_destination = base.relative_to_original_destination_root(@destination)
88
88
  end
89
89
 
90
90
  # Filenames in the encoded form are converted. If you have a file:
@@ -113,7 +113,7 @@ class Bundler::Thor
113
113
  on_conflict_behavior(&block)
114
114
  else
115
115
  say_status :create, :green
116
- block.call unless pretend?
116
+ yield unless pretend?
117
117
  end
118
118
 
119
119
  destination
@@ -121,7 +121,7 @@ class Bundler::Thor
121
121
 
122
122
  # What to do when the destination file already exists.
123
123
  #
124
- def on_conflict_behavior(&block)
124
+ def on_conflict_behavior
125
125
  say_status :exist, :blue
126
126
  end
127
127
 
@@ -26,7 +26,7 @@ class Bundler::Thor
26
26
 
27
27
  create_file destination, nil, config do
28
28
  content = File.binread(source)
29
- content = block.call(content) if block
29
+ content = yield(content) if block
30
30
  content
31
31
  end
32
32
  if config[:mode] == :preserve
@@ -49,7 +49,7 @@ class Bundler::Thor
49
49
  #
50
50
  # link_file "doc/README"
51
51
  #
52
- def link_file(source, *args, &block)
52
+ def link_file(source, *args)
53
53
  config = args.last.is_a?(Hash) ? args.pop : {}
54
54
  destination = args.first || source
55
55
  source = File.expand_path(find_in_source_paths(source.to_s))
@@ -82,7 +82,7 @@ class Bundler::Thor
82
82
  render = open(source) { |input| input.binmode.read }
83
83
 
84
84
  destination ||= if block_given?
85
- block.arity == 1 ? block.call(render) : block.call
85
+ block.arity == 1 ? yield(render) : yield
86
86
  else
87
87
  File.basename(source)
88
88
  end
@@ -110,11 +110,11 @@ class Bundler::Thor
110
110
  destination = args.first || source.sub(/#{TEMPLATE_EXTNAME}$/, "")
111
111
 
112
112
  source = File.expand_path(find_in_source_paths(source.to_s))
113
- context = instance_eval("binding")
113
+ context = config.delete(:context) || instance_eval("binding")
114
114
 
115
115
  create_file destination, nil, config do
116
- content = ERB.new(::File.binread(source), nil, "-", "@output_buffer").result(context)
117
- content = block.call(content) if block
116
+ content = CapturableERB.new(::File.binread(source), nil, "-", "@output_buffer").result(context)
117
+ content = yield(content) if block
118
118
  content
119
119
  end
120
120
  end
@@ -154,7 +154,7 @@ class Bundler::Thor
154
154
  #
155
155
  def prepend_to_file(path, *args, &block)
156
156
  config = args.last.is_a?(Hash) ? args.pop : {}
157
- config.merge!(:after => /\A/)
157
+ config[:after] = /\A/
158
158
  insert_into_file(path, *(args << config), &block)
159
159
  end
160
160
  alias_method :prepend_file, :prepend_to_file
@@ -176,7 +176,7 @@ class Bundler::Thor
176
176
  #
177
177
  def append_to_file(path, *args, &block)
178
178
  config = args.last.is_a?(Hash) ? args.pop : {}
179
- config.merge!(:before => /\z/)
179
+ config[:before] = /\z/
180
180
  insert_into_file(path, *(args << config), &block)
181
181
  end
182
182
  alias_method :append_file, :append_to_file
@@ -200,7 +200,7 @@ class Bundler::Thor
200
200
  #
201
201
  def inject_into_class(path, klass, *args, &block)
202
202
  config = args.last.is_a?(Hash) ? args.pop : {}
203
- config.merge!(:after => /class #{klass}\n|class #{klass} .*\n/)
203
+ config[:after] = /class #{klass}\n|class #{klass} .*\n/
204
204
  insert_into_file(path, *(args << config), &block)
205
205
  end
206
206
 
@@ -285,7 +285,7 @@ class Bundler::Thor
285
285
  #
286
286
  def remove_file(path, config = {})
287
287
  return unless behavior == :invoke
288
- path = File.expand_path(path, destination_root)
288
+ path = File.expand_path(path, destination_root)
289
289
 
290
290
  say_status :remove, relative_to_original_destination_root(path), config.fetch(:verbose, true)
291
291
  ::FileUtils.rm_rf(path) if !options[:pretend] && File.exist?(path)
@@ -301,8 +301,8 @@ class Bundler::Thor
301
301
  @output_buffer.concat(string)
302
302
  end
303
303
 
304
- def capture(*args, &block)
305
- with_output_buffer { block.call(*args) }
304
+ def capture(*args)
305
+ with_output_buffer { yield(*args) }
306
306
  end
307
307
 
308
308
  def with_output_buffer(buf = "") #:nodoc:
@@ -312,5 +312,16 @@ class Bundler::Thor
312
312
  ensure
313
313
  self.output_buffer = old_buffer
314
314
  end
315
+
316
+ # Bundler::Thor::Actions#capture depends on what kind of buffer is used in ERB.
317
+ # Thus CapturableERB fixes ERB to use String buffer.
318
+ class CapturableERB < ERB
319
+ def set_eoutvar(compiler, eoutvar = "_erbout")
320
+ compiler.put_cmd = "#{eoutvar}.concat"
321
+ compiler.insert_cmd = "#{eoutvar}.concat"
322
+ compiler.pre_cmd = ["#{eoutvar} = ''"]
323
+ compiler.post_cmd = [eoutvar]
324
+ end
325
+ end
315
326
  end
316
327
  end