thor 0.19.4 → 0.20.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 5fd71663b46487af27e6f0b6a0206f5140d0d196
4
- data.tar.gz: d67e482d506417552648630f8a7bc4b1886fc06c
3
+ metadata.gz: 7fddac6c27d0c13187204ad4a00467eb10abce93
4
+ data.tar.gz: 5839be67e757fd66707de47fe1f0c051376e958f
5
5
  SHA512:
6
- metadata.gz: f15702a93adea15d623fd708962193b42bc38bf2b86dff66fe43f1078971fc38f5dedff0d6a78bd1bf9241315e83ede0c216ffedea8c452c55b57aff17d0d051
7
- data.tar.gz: 1e7093648f0913e9c7e32c796ea795e819ca59331588885059bfcae9867172ea50144033c342d22c4d5c8ab628f135821bb9a0ab8645f7784c396482370b98c0
6
+ metadata.gz: 24d622cda205874c6ffa47ae8cb616b8f454f05cb3c56d14f6078e6509c6553111a7669c08776c5914c17f8e261296fd0827f59f778e62d48aa00bca6bacb58d
7
+ data.tar.gz: bcb09ac8cfa598b845897068ea707f0b6d7686a327dc7e6caa37c073dc2efc581fd95731cfdf16ca4f1d7b606990984652e9e726e2144df6ad4b68bebd7c8797
@@ -1,3 +1,33 @@
1
+ ## 0.20.0
2
+ * Add `check_default_type!` to check if the default value of an option matches the defined type.
3
+ It removes the warning on usage and gives the command authors the possibility to check for programming errors.
4
+
5
+ * Add `disable_required_check!` to disable check for required options in some commands.
6
+ It is a substitute of `disable_class_options` that was not working as intended.
7
+
8
+ * Add `inject_into_module`.
9
+
10
+ ## 0.19.4, release 2016-11-28
11
+ * Rename `Thor::Base#thor_reserved_word?` to `#is_thor_reserved_word?`
12
+
13
+ ## 0.19.3, release 2016-11-27
14
+ * Output a warning instead of raising an exception when a default option value doesn't match its specified type
15
+
16
+ ## 0.19.2, release 2016-11-26
17
+ * Fix bug with handling of colors passed to `ask` (and methods like `yes?` and `no?` which it underpins)
18
+ * Allow numeric arguments to be negative
19
+ * Ensure that default option values are of the specified type (e.g. you can't specify `"foo"` as the default for a numeric option), but make symbols and strings interchangeable
20
+ * Add `Thor::Shell::Basic#indent` method for intending output
21
+ * Fix `remove_command` for an inherited command (see #451)
22
+ * Allow hash arguments to only have each key provided once (see #455)
23
+ * Allow commands to disable class options, for instance for "help" commands (see #363)
24
+ * Do not generate a negative option (`--no-no-foo`) for already negative boolean options (`--no-foo`)
25
+ * Improve compatibility of `Thor::CoreExt::HashWithIndifferentAccess` with Ruby standard library `Hash`
26
+ * Allow specifying a custom binding for template evaluation (e.g. `#key?` and `#fetch`)
27
+ * Fix support for subcommand-specific "help"s
28
+ * Use a string buffer when handling ERB for Ruby 2.3 compatibility
29
+ * Update dependencies
30
+
1
31
  ## 0.19.1, release 2014-03-24
2
32
  * Fix `say` non-String break regression
3
33
 
@@ -158,10 +158,6 @@ class Thor
158
158
  end
159
159
  alias_method :option, :method_option
160
160
 
161
- def disable_class_options
162
- @disable_class_options = true
163
- end
164
-
165
161
  # Prints help information for the given command.
166
162
  #
167
163
  # ==== Parameters
@@ -241,6 +237,9 @@ class Thor
241
237
  invoke_args.unshift "help" if opts.delete("--help") || opts.delete("-h")
242
238
  invoke subcommand_class, *invoke_args
243
239
  end
240
+ subcommand_class.commands.each do |_meth, command|
241
+ command.ancestor_name = subcommand
242
+ end
244
243
  end
245
244
  alias_method :subtask, :subcommand
246
245
 
@@ -326,12 +325,31 @@ class Thor
326
325
  command && stop_on_unknown_option.include?(command.name.to_sym)
327
326
  end
328
327
 
328
+ # Disable the check for required options for the given commands.
329
+ # This is useful if you have a command that does not need the required options
330
+ # to work, like help.
331
+ #
332
+ # ==== Parameters
333
+ # Symbol ...:: A list of commands that should be affected.
334
+ def disable_required_check!(*command_names)
335
+ disable_required_check.merge(command_names)
336
+ end
337
+
338
+ def disable_required_check?(command) #:nodoc:
339
+ command && disable_required_check.include?(command.name.to_sym)
340
+ end
341
+
329
342
  protected
330
343
 
331
344
  def stop_on_unknown_option #:nodoc:
332
345
  @stop_on_unknown_option ||= Set.new
333
346
  end
334
347
 
348
+ # help command has the required check disabled by default.
349
+ def disable_required_check #:nodoc:
350
+ @disable_required_check ||= Set.new([:help])
351
+ end
352
+
335
353
  # The method responsible for dispatching given the args.
336
354
  def dispatch(meth, given_args, given_opts, config) #:nodoc: # rubocop:disable MethodLength
337
355
  meth ||= retrieve_command_name(given_args)
@@ -390,12 +408,12 @@ class Thor
390
408
  @usage ||= nil
391
409
  @desc ||= nil
392
410
  @long_desc ||= nil
393
- @disable_class_options ||= nil
411
+ @hide ||= nil
394
412
 
395
413
  if @usage && @desc
396
414
  base_class = @hide ? Thor::HiddenCommand : Thor::Command
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
415
+ commands[meth] = base_class.new(meth, @desc, @long_desc, @usage, method_options)
416
+ @usage, @desc, @long_desc, @method_options, @hide = nil
399
417
  true
400
418
  elsif all_commands[meth] || meth == "method_missing"
401
419
  true
@@ -477,7 +495,6 @@ class Thor
477
495
  map HELP_MAPPINGS => :help
478
496
 
479
497
  desc "help [COMMAND]", "Describe available commands or one specific command"
480
- disable_class_options
481
498
  def help(command = nil, subcommand = false)
482
499
  if command
483
500
  if self.class.subcommands.include? command
@@ -1,4 +1,3 @@
1
- require "fileutils"
2
1
  require "uri"
3
2
  require "thor/core_ext/io_binary_read"
4
3
  require "thor/actions/create_file"
@@ -141,7 +140,7 @@ class Thor
141
140
  end
142
141
  end
143
142
 
144
- message = "Could not find #{file.inspect} in any of your source paths. "
143
+ message = "Could not find #{file.inspect} in any of your source paths. ".dup
145
144
 
146
145
  unless self.class.source_root
147
146
  message << "Please invoke #{self.class.name}.source_root(PATH) with the PATH containing your templates. "
@@ -175,6 +174,7 @@ class Thor
175
174
 
176
175
  # If the directory doesnt exist and we're not pretending
177
176
  if !File.exist?(destination_root) && !pretend
177
+ require "fileutils"
178
178
  FileUtils.mkdir_p(destination_root)
179
179
  end
180
180
 
@@ -182,6 +182,7 @@ class Thor
182
182
  # In pretend mode, just yield down to the block
183
183
  block.arity == 1 ? yield(destination_root) : yield
184
184
  else
185
+ require "fileutils"
185
186
  FileUtils.cd(destination_root) { block.arity == 1 ? yield(destination_root) : yield }
186
187
  end
187
188
 
@@ -251,7 +252,9 @@ class Thor
251
252
 
252
253
  say_status :run, desc, config.fetch(:verbose, true)
253
254
 
254
- !options[:pretend] && config[:capture] ? `#{command}` : system(command.to_s)
255
+ unless options[:pretend]
256
+ config[:capture] ? `#{command}` : system(command.to_s)
257
+ end
255
258
  end
256
259
 
257
260
  # Executes a ruby script (taking into account WIN32 platform quirks).
@@ -58,6 +58,7 @@ class Thor
58
58
 
59
59
  def invoke!
60
60
  invoke_with_conflict_check do
61
+ require "fileutils"
61
62
  FileUtils.mkdir_p(File.dirname(destination))
62
63
  File.open(destination, "wb") { |f| f.write render }
63
64
  end
@@ -38,6 +38,7 @@ class Thor
38
38
 
39
39
  def invoke!
40
40
  invoke_with_conflict_check do
41
+ require "fileutils"
41
42
  FileUtils.mkdir_p(File.dirname(destination))
42
43
  # Create a symlink by default
43
44
  config[:symbolic] = true if config[:symbolic].nil?
@@ -48,12 +48,14 @@ class Thor
48
48
 
49
49
  def invoke!
50
50
  invoke_with_conflict_check do
51
+ require "fileutils"
51
52
  ::FileUtils.mkdir_p(destination)
52
53
  end
53
54
  end
54
55
 
55
56
  def revoke!
56
57
  say_status :remove, :red
58
+ require "fileutils"
57
59
  ::FileUtils.rm_rf(destination) if !pretend? && exists?
58
60
  given_destination
59
61
  end
@@ -112,11 +114,17 @@ class Thor
112
114
  if exists?
113
115
  on_conflict_behavior(&block)
114
116
  else
115
- say_status :create, :green
116
117
  yield unless pretend?
118
+ say_status :create, :green
117
119
  end
118
120
 
119
121
  destination
122
+ rescue Errno::EISDIR, Errno::EEXIST
123
+ on_file_clash_behavior
124
+ end
125
+
126
+ def on_file_clash_behavior
127
+ say_status :file_clash, :red
120
128
  end
121
129
 
122
130
  # What to do when the destination file already exists.
@@ -1,5 +1,4 @@
1
1
  require "erb"
2
- require "open-uri"
3
2
 
4
3
  class Thor
5
4
  module Actions
@@ -78,7 +77,12 @@ class Thor
78
77
  config = args.last.is_a?(Hash) ? args.pop : {}
79
78
  destination = args.first
80
79
 
81
- source = File.expand_path(find_in_source_paths(source.to_s)) unless source =~ %r{^https?\://}
80
+ if source =~ %r{^https?\://}
81
+ require "open-uri"
82
+ else
83
+ source = File.expand_path(find_in_source_paths(source.to_s))
84
+ end
85
+
82
86
  render = open(source) { |input| input.binmode.read }
83
87
 
84
88
  destination ||= if block_given?
@@ -113,7 +117,9 @@ class Thor
113
117
  context = config.delete(:context) || instance_eval("binding")
114
118
 
115
119
  create_file destination, nil, config do
116
- content = CapturableERB.new(::File.binread(source), nil, "-", "@output_buffer").result(context)
120
+ content = CapturableERB.new(::File.binread(source), nil, "-", "@output_buffer").tap do |erb|
121
+ erb.filename = source
122
+ end.result(context)
117
123
  content = yield(content) if block
118
124
  content
119
125
  end
@@ -134,7 +140,10 @@ class Thor
134
140
  return unless behavior == :invoke
135
141
  path = File.expand_path(path, destination_root)
136
142
  say_status :chmod, relative_to_original_destination_root(path), config.fetch(:verbose, true)
137
- FileUtils.chmod_R(mode, path) unless options[:pretend]
143
+ unless options[:pretend]
144
+ require "fileutils"
145
+ FileUtils.chmod_R(mode, path)
146
+ end
138
147
  end
139
148
 
140
149
  # Prepend text to a file. Since it depends on insert_into_file, it's reversible.
@@ -204,6 +213,29 @@ class Thor
204
213
  insert_into_file(path, *(args << config), &block)
205
214
  end
206
215
 
216
+ # Injects text right after the module definition. Since it depends on
217
+ # insert_into_file, it's reversible.
218
+ #
219
+ # ==== Parameters
220
+ # path<String>:: path of the file to be changed
221
+ # module_name<String|Class>:: the module to be manipulated
222
+ # data<String>:: the data to append to the class, can be also given as a block.
223
+ # config<Hash>:: give :verbose => false to not log the status.
224
+ #
225
+ # ==== Examples
226
+ #
227
+ # inject_into_module "app/helpers/application_helper.rb", ApplicationHelper, " def help; 'help'; end\n"
228
+ #
229
+ # inject_into_module "app/helpers/application_helper.rb", ApplicationHelper do
230
+ # " def help; 'help'; end\n"
231
+ # end
232
+ #
233
+ def inject_into_module(path, module_name, *args, &block)
234
+ config = args.last.is_a?(Hash) ? args.pop : {}
235
+ config[:after] = /module #{module_name}\n|module #{module_name} .*\n/
236
+ insert_into_file(path, *(args << config), &block)
237
+ end
238
+
207
239
  # Run a regular expression replacement on a file.
208
240
  #
209
241
  # ==== Parameters
@@ -288,7 +320,10 @@ class Thor
288
320
  path = File.expand_path(path, destination_root)
289
321
 
290
322
  say_status :remove, relative_to_original_destination_root(path), config.fetch(:verbose, true)
291
- ::FileUtils.rm_rf(path) if !options[:pretend] && File.exist?(path)
323
+ if !options[:pretend] && File.exist?(path)
324
+ require "fileutils"
325
+ ::FileUtils.rm_rf(path)
326
+ end
292
327
  end
293
328
  alias_method :remove_dir, :remove_file
294
329
 
@@ -305,8 +340,10 @@ class Thor
305
340
  with_output_buffer { yield(*args) }
306
341
  end
307
342
 
308
- def with_output_buffer(buf = "") #:nodoc:
309
- self.output_buffer, old_buffer = buf, output_buffer
343
+ def with_output_buffer(buf = "".dup) #:nodoc:
344
+ raise ArgumentError, "Buffer can not be a frozen object" if buf.frozen?
345
+ old_buffer = output_buffer
346
+ self.output_buffer = buf
310
347
  yield
311
348
  output_buffer
312
349
  ensure
@@ -319,7 +356,7 @@ class Thor
319
356
  def set_eoutvar(compiler, eoutvar = "_erbout")
320
357
  compiler.put_cmd = "#{eoutvar}.concat"
321
358
  compiler.insert_cmd = "#{eoutvar}.concat"
322
- compiler.pre_cmd = ["#{eoutvar} = ''"]
359
+ compiler.pre_cmd = ["#{eoutvar} = ''.dup"]
323
360
  compiler.post_cmd = [eoutvar]
324
361
  end
325
362
  end
@@ -53,7 +53,13 @@ class Thor
53
53
  replacement + '\0'
54
54
  end
55
55
 
56
- replace!(/#{flag}/, content, config[:force])
56
+ if exists?
57
+ replace!(/#{flag}/, content, config[:force])
58
+ else
59
+ unless pretend?
60
+ raise Thor::Error, "The file #{ destination } does not appear to exist"
61
+ end
62
+ end
57
63
  end
58
64
 
59
65
  def revoke!
@@ -91,8 +97,8 @@ class Thor
91
97
  # Adds the content to the file.
92
98
  #
93
99
  def replace!(regexp, string, force)
94
- return if base.options[:pretend]
95
- content = File.binread(destination)
100
+ return if pretend?
101
+ content = File.read(destination)
96
102
  if force || !content.include?(replacement)
97
103
  content.gsub!(regexp, string)
98
104
  File.open(destination, "wb") { |file| file.write(content) }
@@ -42,7 +42,7 @@ class Thor
42
42
  # config<Hash>:: Configuration for this Thor class.
43
43
  #
44
44
  def initialize(args = [], local_options = {}, config = {})
45
- parse_options = config[:current_command] && config[:current_command].disable_class_options ? {} : self.class.class_options
45
+ parse_options = self.class.class_options
46
46
 
47
47
  # The start method splits inbound arguments at the first argument
48
48
  # that looks like an option (starts with - or --). It then calls
@@ -65,7 +65,8 @@ class Thor
65
65
  # declared options from the array. This will leave us with
66
66
  # a list of arguments that weren't declared.
67
67
  stop_on_unknown = self.class.stop_on_unknown_option? config[:current_command]
68
- opts = Thor::Options.new(parse_options, hash_options, stop_on_unknown)
68
+ disable_required_check = self.class.disable_required_check? config[:current_command]
69
+ opts = Thor::Options.new(parse_options, hash_options, stop_on_unknown, disable_required_check)
69
70
  self.options = opts.parse(array_options)
70
71
  self.options = config[:class_options].merge(options) if config[:class_options]
71
72
 
@@ -150,6 +151,21 @@ class Thor
150
151
  !!check_unknown_options
151
152
  end
152
153
 
154
+ # If you want to raise an error when the default value of an option does not match
155
+ # the type call check_default_type!
156
+ # This is disabled by default for compatibility.
157
+ def check_default_type!
158
+ @check_default_type = true
159
+ end
160
+
161
+ def check_default_type #:nodoc:
162
+ @check_default_type ||= from_superclass(:check_default_type, false)
163
+ end
164
+
165
+ def check_default_type? #:nodoc:
166
+ !!check_default_type
167
+ end
168
+
153
169
  # If true, option parsing is suspended as soon as an unknown option or a
154
170
  # regular argument is encountered. All remaining arguments are passed to
155
171
  # the command as regular arguments.
@@ -157,6 +173,12 @@ class Thor
157
173
  false
158
174
  end
159
175
 
176
+ # If true, option set will not suspend the execution of the command when
177
+ # a required option is not provided.
178
+ def disable_required_check?(command_name) #:nodoc:
179
+ false
180
+ end
181
+
160
182
  # If you want only strict string args (useful when cascading thor classes),
161
183
  # call strict_args_position! This is disabled by default to allow dynamic
162
184
  # invocations.
@@ -477,7 +499,8 @@ class Thor
477
499
  alias_method :handle_no_task_error, :handle_no_command_error
478
500
 
479
501
  def handle_argument_error(command, error, args, arity) #:nodoc:
480
- msg = "ERROR: \"#{basename} #{command.name}\" was called with "
502
+ name = [command.ancestor_name, command.name].compact.join(" ")
503
+ msg = "ERROR: \"#{basename} #{name}\" was called with ".dup
481
504
  msg << "no arguments" if args.empty?
482
505
  msg << "arguments " << args.inspect unless args.empty?
483
506
  msg << "\nUsage: #{banner(command).inspect}"
@@ -541,7 +564,7 @@ class Thor
541
564
  # options<Hash>:: Described in both class_option and method_option.
542
565
  # scope<Hash>:: Options hash that is being built up
543
566
  def build_option(name, options, scope) #:nodoc:
544
- scope[name] = Thor::Option.new(name, options)
567
+ scope[name] = Thor::Option.new(name, options.merge(:check_default_type => check_default_type?))
545
568
  end
546
569
 
547
570
  # Receives a hash of options, parse them and add to the scope. This is a
@@ -1,9 +1,9 @@
1
1
  class Thor
2
- class Command < Struct.new(:name, :description, :long_description, :usage, :options, :disable_class_options)
2
+ class Command < Struct.new(:name, :description, :long_description, :usage, :options, :ancestor_name)
3
3
  FILE_REGEXP = /^#{Regexp.escape(File.dirname(__FILE__))}/
4
4
 
5
- def initialize(name, description, long_description, usage, options = nil, disable_class_options = false)
6
- super(name.to_s, description, long_description, usage, options || {}, disable_class_options)
5
+ def initialize(name, description, long_description, usage, options = nil)
6
+ super(name.to_s, description, long_description, usage, options || {})
7
7
  end
8
8
 
9
9
  def initialize_copy(other) #:nodoc:
@@ -39,13 +39,15 @@ class Thor
39
39
  # Returns the formatted usage by injecting given required arguments
40
40
  # and required options into the given usage.
41
41
  def formatted_usage(klass, namespace = true, subcommand = false)
42
- if namespace
42
+ if ancestor_name
43
+ formatted = "#{ancestor_name} ".dup # add space
44
+ elsif namespace
43
45
  namespace = klass.namespace
44
- formatted = "#{namespace.gsub(/^(default)/, '')}:"
46
+ formatted = "#{namespace.gsub(/^(default)/, '')}:".dup
45
47
  end
46
- formatted = "#{klass.namespace.split(':').last} " if subcommand
48
+ formatted ||= "#{klass.namespace.split(':').last} ".dup if subcommand
47
49
 
48
- formatted ||= ""
50
+ formatted ||= "".dup
49
51
 
50
52
  # Add usage with required arguments
51
53
  formatted << if klass && !klass.arguments.empty?
@@ -51,6 +51,18 @@ class Thor
51
51
  self
52
52
  end
53
53
 
54
+ def reverse_merge(other)
55
+ self.class.new(other).merge(self)
56
+ end
57
+
58
+ def reverse_merge!(other_hash)
59
+ replace(reverse_merge(other_hash))
60
+ end
61
+
62
+ def replace(other_hash)
63
+ super(other_hash)
64
+ end
65
+
54
66
  # Convert to a Hash with String keys.
55
67
  def to_hash
56
68
  Hash.new(default).merge!(self)
@@ -205,7 +205,7 @@ class Thor::Group
205
205
  alias_method :printable_tasks, :printable_commands
206
206
 
207
207
  def handle_argument_error(command, error, _args, arity) #:nodoc:
208
- msg = "#{basename} #{command.name} takes #{arity} argument"
208
+ msg = "#{basename} #{command.name} takes #{arity} argument".dup
209
209
  msg << "s" if arity > 1
210
210
  msg << ", but it should not."
211
211
  raise error, msg
@@ -23,6 +23,8 @@ class Thor
23
23
  if echo?
24
24
  $stdin.gets
25
25
  else
26
+ # Lazy-load io/console since it is gem-ified as of 2.3
27
+ require "io/console" if RUBY_VERSION > "1.9.2"
26
28
  $stdin.noecho(&:gets)
27
29
  end
28
30
  end
@@ -5,6 +5,7 @@ class Thor
5
5
  VALID_TYPES = [:boolean, :numeric, :hash, :array, :string]
6
6
 
7
7
  def initialize(name, options = {})
8
+ @check_default_type = options[:check_default_type]
8
9
  options[:required] = false unless options.key?(:required)
9
10
  super
10
11
  @lazy_default = options[:lazy_default]
@@ -80,12 +81,12 @@ class Thor
80
81
 
81
82
  def usage(padding = 0)
82
83
  sample = if banner && !banner.to_s.empty?
83
- "#{switch_name}=#{banner}"
84
+ "#{switch_name}=#{banner}".dup
84
85
  else
85
86
  switch_name
86
87
  end
87
88
 
88
- sample = "[#{sample}]" unless required?
89
+ sample = "[#{sample}]".dup unless required?
89
90
 
90
91
  if boolean?
91
92
  sample << ", [#{dasherize('no-' + human_name)}]" unless (name == "force") || name.start_with?("no-")
@@ -110,7 +111,7 @@ class Thor
110
111
 
111
112
  def validate!
112
113
  raise ArgumentError, "An option cannot be boolean and required." if boolean? && required?
113
- validate_default_type!
114
+ validate_default_type! if @check_default_type
114
115
  end
115
116
 
116
117
  def validate_default_type!
@@ -127,8 +128,7 @@ class Thor
127
128
  @default.class.name.downcase.to_sym
128
129
  end
129
130
 
130
- # TODO: This should raise an ArgumentError in a future version of Thor
131
- warn "Expected #{@type} default value for '#{switch_name}'; got #{@default.inspect} (#{default_type})" unless default_type == @type
131
+ raise ArgumentError, "Expected #{@type} default value for '#{switch_name}'; got #{@default.inspect} (#{default_type})" unless default_type == @type
132
132
  end
133
133
 
134
134
  def dasherized?
@@ -18,19 +18,20 @@ class Thor
18
18
  when Hash
19
19
  "--#{key} #{value.map { |k, v| "#{k}:#{v}" }.join(' ')}"
20
20
  when nil, false
21
- ""
21
+ nil
22
22
  else
23
23
  "--#{key} #{value.inspect}"
24
24
  end
25
- end.join(" ")
25
+ end.compact.join(" ")
26
26
  end
27
27
 
28
28
  # Takes a hash of Thor::Option and a hash with defaults.
29
29
  #
30
30
  # If +stop_on_unknown+ is true, #parse will stop as soon as it encounters
31
31
  # an unknown option or a regular argument.
32
- def initialize(hash_options = {}, defaults = {}, stop_on_unknown = false)
32
+ def initialize(hash_options = {}, defaults = {}, stop_on_unknown = false, disable_required_check = false)
33
33
  @stop_on_unknown = stop_on_unknown
34
+ @disable_required_check = disable_required_check
34
35
  options = hash_options.values
35
36
  super(options)
36
37
 
@@ -111,7 +112,7 @@ class Thor
111
112
  end
112
113
  end
113
114
 
114
- check_requirement!
115
+ check_requirement! unless @disable_required_check
115
116
 
116
117
  assigns = Thor::CoreExt::HashWithIndifferentAccess.new(@assigns)
117
118
  assigns.freeze
@@ -188,7 +189,7 @@ class Thor
188
189
  shift
189
190
  false
190
191
  else
191
- true
192
+ !no_or_skip?(switch)
192
193
  end
193
194
  else
194
195
  @switches.key?(switch) || !no_or_skip?(switch)
@@ -2,8 +2,6 @@ require "thor"
2
2
  require "thor/group"
3
3
  require "thor/core_ext/io_binary_read"
4
4
 
5
- require "fileutils"
6
- require "open-uri"
7
5
  require "yaml"
8
6
  require "digest/md5"
9
7
  require "pathname"
@@ -104,6 +102,7 @@ class Thor::Runner < Thor #:nodoc: # rubocop:disable ClassLength
104
102
  if package == :file
105
103
  File.open(destination, "w") { |f| f.puts contents }
106
104
  else
105
+ require "fileutils"
107
106
  FileUtils.cp_r(name, destination)
108
107
  end
109
108
 
@@ -120,6 +119,7 @@ class Thor::Runner < Thor #:nodoc: # rubocop:disable ClassLength
120
119
  def uninstall(name)
121
120
  raise Error, "Can't find module '#{name}'" unless thor_yaml[name]
122
121
  say "Uninstalling #{name}."
122
+ require "fileutils"
123
123
  FileUtils.rm_rf(File.join(thor_root, (thor_yaml[name][:filename]).to_s))
124
124
 
125
125
  thor_yaml.delete(name)
@@ -138,6 +138,7 @@ class Thor::Runner < Thor #:nodoc: # rubocop:disable ClassLength
138
138
  self.options = options.merge("as" => name)
139
139
 
140
140
  if File.directory? File.expand_path(name)
141
+ require "fileutils"
141
142
  FileUtils.rm_rf(File.join(thor_root, old_filename))
142
143
 
143
144
  thor_yaml.delete(old_filename)
@@ -194,6 +195,7 @@ private
194
195
  yaml_file = File.join(thor_root, "thor.yml")
195
196
 
196
197
  unless File.exist?(yaml_file)
198
+ require "fileutils"
197
199
  FileUtils.mkdir_p(thor_root)
198
200
  yaml_file = File.join(thor_root, "thor.yml")
199
201
  FileUtils.touch(yaml_file)
@@ -1,6 +1,3 @@
1
- require "tempfile"
2
- require "io/console" if RUBY_VERSION > "1.9.2"
3
-
4
1
  class Thor
5
2
  module Shell
6
3
  class Basic
@@ -110,7 +107,7 @@ class Thor
110
107
  status = set_color status, color, true if color
111
108
 
112
109
  buffer = "#{status}#{spaces}#{message}"
113
- buffer << "\n" unless buffer.end_with?("\n")
110
+ buffer = "#{buffer}\n" unless buffer.end_with?("\n")
114
111
 
115
112
  stdout.print(buffer)
116
113
  stdout.flush
@@ -165,7 +162,7 @@ class Thor
165
162
  colwidth = options[:colwidth]
166
163
  options[:truncate] = terminal_width if options[:truncate] == true
167
164
 
168
- formats << "%-#{colwidth + 2}s" if colwidth
165
+ formats << "%-#{colwidth + 2}s".dup if colwidth
169
166
  start = colwidth ? 1 : 0
170
167
 
171
168
  colcount = array.max { |a, b| a.size <=> b.size }.size
@@ -177,9 +174,9 @@ class Thor
177
174
  maximas << maxima
178
175
  formats << if index == colcount - 1
179
176
  # Don't output 2 trailing spaces when printing the last column
180
- "%-s"
177
+ "%-s".dup
181
178
  else
182
- "%-#{maxima + 2}s"
179
+ "%-#{maxima + 2}s".dup
183
180
  end
184
181
  end
185
182
 
@@ -187,7 +184,7 @@ class Thor
187
184
  formats << "%s"
188
185
 
189
186
  array.each do |row|
190
- sentence = ""
187
+ sentence = "".dup
191
188
 
192
189
  row.each_with_index do |column, index|
193
190
  maxima = maximas[index]
@@ -255,6 +252,9 @@ class Thor
255
252
  )
256
253
 
257
254
  case answer
255
+ when nil
256
+ say ""
257
+ return true
258
258
  when is?(:yes), is?(:force), ""
259
259
  return true
260
260
  when is?(:no), is?(:skip)
@@ -350,6 +350,7 @@ class Thor
350
350
  def show_diff(destination, content) #:nodoc:
351
351
  diff_cmd = ENV["THOR_DIFF"] || ENV["RAILS_DIFF"] || "diff -u"
352
352
 
353
+ require "tempfile"
353
354
  Tempfile.open(File.basename(destination), File.dirname(destination)) do |temp|
354
355
  temp.write content
355
356
  temp.rewind
@@ -411,7 +412,7 @@ class Thor
411
412
 
412
413
  return unless result
413
414
 
414
- result.strip!
415
+ result = result.strip
415
416
 
416
417
  if default && result == ""
417
418
  default
@@ -1,3 +1,3 @@
1
1
  class Thor
2
- VERSION = "0.19.4"
2
+ VERSION = "0.20.0"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: thor
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.19.4
4
+ version: 0.20.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Yehuda Katz
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2016-11-28 00:00:00.000000000 Z
12
+ date: 2017-08-16 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: bundler
@@ -91,7 +91,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
91
91
  version: 1.3.5
92
92
  requirements: []
93
93
  rubyforge_project:
94
- rubygems_version: 2.5.2
94
+ rubygems_version: 2.6.12
95
95
  signing_key:
96
96
  specification_version: 4
97
97
  summary: Thor is a toolkit for building powerful command-line interfaces.