thor 0.19.1 → 0.19.2

Sign up to get free protection for your applications and to get access to all the features.
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