thor 0.19.1 → 0.19.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.
Files changed (105) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +24 -0
  3. data/CONTRIBUTING.md +15 -0
  4. data/README.md +7 -1
  5. data/lib/thor.rb +31 -23
  6. data/lib/thor/actions.rb +21 -22
  7. data/lib/thor/actions/create_file.rb +1 -1
  8. data/lib/thor/actions/create_link.rb +1 -1
  9. data/lib/thor/actions/directory.rb +2 -2
  10. data/lib/thor/actions/empty_directory.rb +8 -8
  11. data/lib/thor/actions/file_manipulation.rb +23 -12
  12. data/lib/thor/actions/inject_into_file.rb +10 -14
  13. data/lib/thor/base.rb +33 -33
  14. data/lib/thor/command.rb +9 -9
  15. data/lib/thor/core_ext/hash_with_indifferent_access.rb +9 -1
  16. data/lib/thor/core_ext/io_binary_read.rb +7 -5
  17. data/lib/thor/core_ext/ordered_hash.rb +94 -63
  18. data/lib/thor/error.rb +3 -3
  19. data/lib/thor/group.rb +12 -12
  20. data/lib/thor/invocation.rb +4 -5
  21. data/lib/thor/parser/argument.rb +4 -7
  22. data/lib/thor/parser/arguments.rb +16 -16
  23. data/lib/thor/parser/option.rb +39 -19
  24. data/lib/thor/parser/options.rb +7 -5
  25. data/lib/thor/runner.rb +25 -25
  26. data/lib/thor/shell.rb +1 -1
  27. data/lib/thor/shell/basic.rb +41 -26
  28. data/lib/thor/shell/color.rb +1 -1
  29. data/lib/thor/shell/html.rb +4 -4
  30. data/lib/thor/util.rb +8 -7
  31. data/lib/thor/version.rb +1 -1
  32. data/thor.gemspec +6 -9
  33. metadata +6 -148
  34. data/Thorfile +0 -29
  35. data/spec/actions/create_file_spec.rb +0 -168
  36. data/spec/actions/create_link_spec.rb +0 -96
  37. data/spec/actions/directory_spec.rb +0 -169
  38. data/spec/actions/empty_directory_spec.rb +0 -129
  39. data/spec/actions/file_manipulation_spec.rb +0 -392
  40. data/spec/actions/inject_into_file_spec.rb +0 -135
  41. data/spec/actions_spec.rb +0 -331
  42. data/spec/base_spec.rb +0 -298
  43. data/spec/command_spec.rb +0 -79
  44. data/spec/core_ext/hash_with_indifferent_access_spec.rb +0 -48
  45. data/spec/core_ext/ordered_hash_spec.rb +0 -115
  46. data/spec/exit_condition_spec.rb +0 -19
  47. data/spec/fixtures/application.rb +0 -2
  48. data/spec/fixtures/app{1}/README +0 -3
  49. data/spec/fixtures/bundle/execute.rb +0 -6
  50. data/spec/fixtures/bundle/main.thor +0 -1
  51. data/spec/fixtures/command.thor +0 -10
  52. data/spec/fixtures/doc/%file_name%.rb.tt +0 -1
  53. data/spec/fixtures/doc/COMMENTER +0 -11
  54. data/spec/fixtures/doc/README +0 -3
  55. data/spec/fixtures/doc/block_helper.rb +0 -3
  56. data/spec/fixtures/doc/config.rb +0 -1
  57. data/spec/fixtures/doc/config.yaml.tt +0 -1
  58. data/spec/fixtures/doc/excluding/%file_name%.rb.tt +0 -1
  59. data/spec/fixtures/enum.thor +0 -10
  60. data/spec/fixtures/group.thor +0 -128
  61. data/spec/fixtures/invoke.thor +0 -131
  62. data/spec/fixtures/path with spaces b/data/spec/fixtures/path with → spaces +0 -0
  63. data/spec/fixtures/preserve/script.sh +0 -3
  64. data/spec/fixtures/script.thor +0 -220
  65. data/spec/fixtures/subcommand.thor +0 -17
  66. data/spec/group_spec.rb +0 -222
  67. data/spec/helper.rb +0 -80
  68. data/spec/invocation_spec.rb +0 -120
  69. data/spec/line_editor/basic_spec.rb +0 -28
  70. data/spec/line_editor/readline_spec.rb +0 -69
  71. data/spec/line_editor_spec.rb +0 -43
  72. data/spec/parser/argument_spec.rb +0 -53
  73. data/spec/parser/arguments_spec.rb +0 -66
  74. data/spec/parser/option_spec.rb +0 -210
  75. data/spec/parser/options_spec.rb +0 -414
  76. data/spec/quality_spec.rb +0 -75
  77. data/spec/rake_compat_spec.rb +0 -72
  78. data/spec/register_spec.rb +0 -227
  79. data/spec/runner_spec.rb +0 -246
  80. data/spec/sandbox/application.rb +0 -2
  81. data/spec/sandbox/app{1}/README +0 -3
  82. data/spec/sandbox/bundle/execute.rb +0 -6
  83. data/spec/sandbox/bundle/main.thor +0 -1
  84. data/spec/sandbox/command.thor +0 -10
  85. data/spec/sandbox/doc/%file_name%.rb.tt +0 -1
  86. data/spec/sandbox/doc/COMMENTER +0 -11
  87. data/spec/sandbox/doc/README +0 -3
  88. data/spec/sandbox/doc/block_helper.rb +0 -3
  89. data/spec/sandbox/doc/config.rb +0 -1
  90. data/spec/sandbox/doc/config.yaml.tt +0 -1
  91. data/spec/sandbox/doc/excluding/%file_name%.rb.tt +0 -1
  92. data/spec/sandbox/enum.thor +0 -10
  93. data/spec/sandbox/group.thor +0 -128
  94. data/spec/sandbox/invoke.thor +0 -131
  95. data/spec/sandbox/path with spaces b/data/spec/sandbox/path with → spaces +0 -0
  96. data/spec/sandbox/preserve/script.sh +0 -3
  97. data/spec/sandbox/script.thor +0 -220
  98. data/spec/sandbox/subcommand.thor +0 -17
  99. data/spec/shell/basic_spec.rb +0 -337
  100. data/spec/shell/color_spec.rb +0 -119
  101. data/spec/shell/html_spec.rb +0 -31
  102. data/spec/shell_spec.rb +0 -47
  103. data/spec/subcommand_spec.rb +0 -48
  104. data/spec/thor_spec.rb +0 -505
  105. data/spec/util_spec.rb +0 -196
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 3a362ea0b9b3cf1f41649c522ddc312925cf1e47
4
- data.tar.gz: 9267cf56eb7c014270c8077b1ed4b2c95fcaa7ea
3
+ metadata.gz: d79526592b82cfff9374125c0e1970b1d1c2451a
4
+ data.tar.gz: 89a9df6fcc69297cb7567cec0138a7be787c4197
5
5
  SHA512:
6
- metadata.gz: c659d6a5020fa953ec51394089c5a49a4fae9afefc2190a088a8e481a6ac586fbe2c268a47204d66b19ca660468f1e3e87f4e5be9b509faf83fc3992b2b7eb42
7
- data.tar.gz: fac520f0a428f1cf3ba627b47285c04534e11633599d82c7b15596eb76c1e1762d66b32195e8519252c58a061ccb54e37e8bfa4ba98684c6b0efc8f208cd66f4
6
+ metadata.gz: 2abe2eca78a2fc55f6ed8e28ac066594ebf45ab938fb434b844e7293b6001400652c79e30567a14e511ef81c024d3ac4a4de9682c385079d7f5eb1ef4390d1af
7
+ data.tar.gz: 366ab438925df78b9ecf8d783a3aa6d7a5a4c6eee2357c1110e7668ad9a711659b5f7967408c22d81f61860ff0be75fd69e91d475eb0a2cf61159fb2a0ac324a
@@ -1,3 +1,27 @@
1
+ ## 0.19.1, release 2014-03-24
2
+ * Fix `say` non-String break regression
3
+
4
+ ## 0.19.0, release 2014-03-22
5
+ * Add support for a default to #ask
6
+ * Avoid @namespace not initialized warning
7
+ * Avoid private attribute? warning
8
+ * Fix initializing with unknown options
9
+ * Loosen required_rubygems_version for compatibility with Ubuntu 10.04
10
+ * Shell#ask: support a noecho option for stdin
11
+ * Shell#ask: change API to be :echo => false
12
+ * Display a message without a stack trace for ambiguous commands
13
+ * Make say and say_status thread safe
14
+ * Dependency for console io version check
15
+ * Alias --help to help on subcommands
16
+ * Use mime-types 1.x for Ruby 1.8.7 compatibility for Ruby 1.8 only
17
+ * Accept .tt files as templates
18
+ * Check if numeric value is in enum
19
+ * Use Readline for user input
20
+ * Fix dispatching of subcommands (concerning :help and *args)
21
+ * Fix warnings when running specs with `$VERBOSE = true`
22
+ * Make subcommand help more consistent
23
+ * Make the current command chain accessible in command
24
+
1
25
  ## 0.18.1, release 2013-03-30
2
26
  * Revert regressions found in 0.18.0
3
27
 
@@ -0,0 +1,15 @@
1
+ Pull Requests
2
+ -------------
3
+ Here are some reasons why a pull request may not be merged:
4
+
5
+ 1. It hasn’t been reviewed.
6
+ 2. It doesn’t include specs for new functionality.
7
+ 3. It doesn’t include documentation for new functionality.
8
+ 4. It changes behavior without changing the relevant documentation, comments, or specs.
9
+ 5. It changes behavior of an existing public API, breaking backward compatibility.
10
+ 6. It breaks the tests on a supported platform.
11
+ 7. It doesn’t merge cleanly (requiring Git rebasing and conflict resolution).
12
+
13
+ If you would like to help in this process, you can start by evaluating open pull requests against the criteria above. For example, if a pull request does not include specs for new functionality, you can add a comment like: “If you would like this feature to be added to Thor, please add specs to ensure that it does not break in the future.” This will help move a pull request closer to being merged.
14
+
15
+ Include this emoji in the top of your ticket to signal to us that you read this file: 🌈
data/README.md CHANGED
@@ -21,7 +21,7 @@ utilities. It removes the pain of parsing command line options, writing
21
21
  build tool. The syntax is Rake-like, so it should be familiar to most Rake
22
22
  users.
23
23
 
24
- [rake]: https://github.com/jimweirich/rake
24
+ [rake]: https://github.com/ruby/rake
25
25
 
26
26
  Installation
27
27
  ------------
@@ -34,6 +34,12 @@ Please see the [wiki][] for basic usage and other documentation on using Thor. Y
34
34
  [wiki]: https://github.com/erikhuda/thor/wiki
35
35
  [homepage]: http://whatisthor.com/
36
36
 
37
+ Contributing
38
+ ------------
39
+ If you would like to help, please read the [CONTRIBUTING][] file for suggestions.
40
+
41
+ [contributing]: CONTRIBUTING.md
42
+
37
43
  License
38
44
  -------
39
45
  Released under the MIT License. See the [LICENSE][] file for further details.
@@ -1,7 +1,7 @@
1
1
  require "set"
2
2
  require "thor/base"
3
3
 
4
- class Thor # rubocop:disable ClassLength
4
+ class Thor
5
5
  class << self
6
6
  # Allows for custom "Command" package naming.
7
7
  #
@@ -9,7 +9,7 @@ class 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 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 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 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 Thor # rubocop:disable ClassLength
231
237
 
232
238
  define_method(subcommand) do |*args|
233
239
  args, opts = 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 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 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 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 ? Thor::HiddenCommand : 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 Thor
312
312
  ensure
313
313
  self.output_buffer = old_buffer
314
314
  end
315
+
316
+ # 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