qthor 0.19.1.5

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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: b7e3ac9dc21e933700afba3e9f20d7d630394051
4
+ data.tar.gz: f40cb64d0cc3d82a4209af1bf7bd5f82fd09b068
5
+ SHA512:
6
+ metadata.gz: 32497418fddf5aa9d3807c988c27b74a950597ba803d13b052375dbaed063227a115a8cb9123cd9b5951a9cb54b8d9e823c0ade2326d525f5be62cdf32be127c
7
+ data.tar.gz: be5f0f346289d18ba669e11477400378b6df6a78540533089d37ae27533861b9aafc679bb4f034dbcaf838b171e7348a35899c76d8d644e2f91189bfc062aa68
@@ -0,0 +1,5 @@
1
+ lib/*.rb
2
+ lib/**/*.rb
3
+ -
4
+ CHANGELOG.rdoc
5
+ LICENSE.md
@@ -0,0 +1,163 @@
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
+
25
+ ## 0.18.1, release 2013-03-30
26
+ * Revert regressions found in 0.18.0
27
+
28
+ ## 0.18.0, release 2013-03-26
29
+ * Remove rake2thor
30
+ * Only display colors if output medium supports colors
31
+ * Pass parent_options to subcommands
32
+ * Fix non-dash-prefixed aliases
33
+ * Make error messages more helpful
34
+ * Rename "task" to "command"
35
+ * Add the method to allow for custom package name
36
+
37
+ ## 0.17.0, release 2013-01-24
38
+ * Add better support for tasks that accept arbitrary additional arguments (e.g. things like `bundle exec`)
39
+ * Add #stop_on_unknown_option!
40
+ * Only strip from stdin.gets if it wasn't ended with EOF
41
+ * Allow "send" as a task name
42
+ * Allow passing options as arguments after "--"
43
+ * Autoload Thor::Group
44
+
45
+ ## 0.16.0, release 2012-08-14
46
+ * Add enum to string arguments
47
+
48
+ ## 0.15.4, release 2012-06-29
49
+ * Fix regression when destination root contains reserved regexp characters
50
+
51
+ ## 0.15.3, release 2012-06-18
52
+ * Support strict_args_position! for backwards compatibility
53
+ * Escape Dir glob characters in paths
54
+
55
+ ## 0.15.2, released 2012-05-07
56
+ * Added print_in_columns
57
+ * Exposed terminal_width as a public API
58
+
59
+ ## 0.15.1, release 2012-05-06
60
+ * Fix Ruby 1.8 truncation bug with unicode chars
61
+ * Fix shell delegate methods to pass their block
62
+ * Don't output trailing spaces when printing the last column in a table
63
+
64
+ ## 0.15, released 2012-04-29
65
+ * Alias method_options to options
66
+ * Refactor say to allow multiple colors
67
+ * Exposed error as a public API
68
+ * Exposed file_collision as a public API
69
+ * Exposed print_wrapped as a public API
70
+ * Exposed set_color as a public API
71
+ * Fix number-formatting bugs in print_table
72
+ * Fix "indent" typo in print_table
73
+ * Fix Errno::EPIPE when piping tasks to `head`
74
+ * More friendly error messages
75
+
76
+ ## 0.14, released 2010-07-25
77
+ * Added CreateLink class and #link_file method
78
+ * Made Thor::Actions#run use system as default method for system calls
79
+ * Allow use of private methods from superclass as tasks
80
+ * Added mute(&block) method which allows to run block without any output
81
+ * Removed config[:pretend]
82
+ * Enabled underscores for command line switches
83
+ * Added Thor::Base.basename which is used by both Thor.banner and Thor::Group.banner
84
+ * Deprecated invoke() without arguments
85
+ * Added :only and :except to check_unknown_options
86
+
87
+ ## 0.13, released 2010-02-03
88
+ * Added :lazy_default which is only triggered if a switch is given
89
+ * Added Thor::Shell::HTML
90
+ * Added subcommands
91
+ * Decoupled Thor::Group and Thor, so it's easier to vendor
92
+ * Added check_unknown_options! in case you want error messages to be raised in valid switches
93
+ * run(command) should return the results of command
94
+
95
+ ## 0.12, released 2010-01-02
96
+ * Methods generated by attr_* are automatically not marked as tasks
97
+ * inject_into_file does not add the same content twice, unless :force is set
98
+ * Removed rr in favor to rspec mock framework
99
+ * Improved output for thor -T
100
+ * [#7] Do not force white color on status
101
+ * [#8] Yield a block with the filename on directory
102
+
103
+ ## 0.11, released 2009-07-01
104
+ * Added a rake compatibility layer. It allows you to use spec and rdoc tasks on
105
+ Thor classes.
106
+ * BACKWARDS INCOMPATIBLE: aliases are not generated automatically anymore
107
+ since it may cause wrong behavior in the invocation system.
108
+ * thor help now show information about any class/task. All those calls are
109
+ possible:
110
+
111
+ thor help describe
112
+ thor help describe:amazing
113
+ Or even with default namespaces:
114
+
115
+ thor help :spec
116
+ * Thor::Runner now invokes the default task if none is supplied:
117
+
118
+ thor describe # invokes the default task, usually help
119
+ * Thor::Runner now works with mappings:
120
+
121
+ thor describe -h
122
+ * Added some documentation and code refactoring.
123
+
124
+ ## 0.9.8, released 2008-10-20
125
+ * Fixed some tiny issues that were introduced lately.
126
+
127
+ ## 0.9.7, released 2008-10-13
128
+ * Setting global method options on the initialize method works as expected:
129
+ All other tasks will accept these global options in addition to their own.
130
+ * Added 'group' notion to Thor task sets (class Thor); by default all tasks
131
+ are in the 'standard' group. Running 'thor -T' will only show the standard
132
+ tasks - adding --all will show all tasks. You can also filter on a specific
133
+ group using the --group option: thor -T --group advanced
134
+
135
+ ## 0.9.6, released 2008-09-13
136
+ * Generic improvements
137
+
138
+ ## 0.9.5, released 2008-08-27
139
+ * Improve Windows compatibility
140
+ * Update (incorrect) README and task.thor sample file
141
+ * Options hash is now frozen (once returned)
142
+ * Allow magic predicates on options object. For instance: `options.force?`
143
+ * Add support for :numeric type
144
+ * BACKWARDS INCOMPATIBLE: Refactor Thor::Options. You cannot access shorthand forms in options hash anymore (for instance, options[:f])
145
+ * Allow specifying optional args with default values: method_options(:user => "mislav")
146
+ * Don't write options for nil or false values. This allows, for example, turning color off when running specs.
147
+ * Exit with the status of the spec command to help CI stuff out some.
148
+
149
+ ## 0.9.4, released 2008-08-13
150
+ * Try to add Windows compatibility.
151
+ * BACKWARDS INCOMPATIBLE: options hash is now accessed as a property in your class and is not passed as last argument anymore
152
+ * Allow options at the beginning of the argument list as well as the end.
153
+ * Make options available with symbol keys in addition to string keys.
154
+ * Allow true to be passed to Thor#method_options to denote a boolean option.
155
+ * If loading a thor file fails, don't give up, just print a warning and keep going.
156
+ * Make sure that we re-raise errors if they happened further down the pipe than we care about.
157
+ * Only delete the old file on updating when the installation of the new one is a success
158
+ * Make it Ruby 1.8.5 compatible.
159
+ * Don't raise an error if a boolean switch is defined multiple times.
160
+ * Thor::Options now doesn't parse through things that look like options but aren't.
161
+ * Add URI detection to install task, and make sure we don't append ".thor" to URIs
162
+ * Add rake2thor to the gem binfiles.
163
+ * Make sure local Thorfiles override system-wide ones.
@@ -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: 🌈
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2008 Yehuda Katz, Eric Hodel, et al.
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,47 @@
1
+ Thor
2
+ ====
3
+
4
+ [![Gem Version](http://img.shields.io/gem/v/thor.svg)][gem]
5
+ [![Build Status](http://img.shields.io/travis/erikhuda/thor.svg)][travis]
6
+ [![Dependency Status](http://img.shields.io/gemnasium/erikhuda/thor.svg)][gemnasium]
7
+ [![Code Climate](http://img.shields.io/codeclimate/github/erikhuda/thor.svg)][codeclimate]
8
+ [![Coverage Status](http://img.shields.io/coveralls/erikhuda/thor.svg)][coveralls]
9
+
10
+ [gem]: https://rubygems.org/gems/thor
11
+ [travis]: http://travis-ci.org/erikhuda/thor
12
+ [gemnasium]: https://gemnasium.com/erikhuda/thor
13
+ [codeclimate]: https://codeclimate.com/github/erikhuda/thor
14
+ [coveralls]: https://coveralls.io/r/erikhuda/thor
15
+
16
+ Description
17
+ -----------
18
+ Thor is a simple and efficient tool for building self-documenting command line
19
+ utilities. It removes the pain of parsing command line options, writing
20
+ "USAGE:" banners, and can also be used as an alternative to the [Rake][rake]
21
+ build tool. The syntax is Rake-like, so it should be familiar to most Rake
22
+ users.
23
+
24
+ [rake]: https://github.com/ruby/rake
25
+
26
+ Installation
27
+ ------------
28
+ gem install thor
29
+
30
+ Usage and documentation
31
+ -----------------------
32
+ Please see the [wiki][] for basic usage and other documentation on using Thor. You can also checkout the [official homepage][homepage].
33
+
34
+ [wiki]: https://github.com/erikhuda/thor/wiki
35
+ [homepage]: http://whatisthor.com/
36
+
37
+ Contributing
38
+ ------------
39
+ If you would like to help, please read the [CONTRIBUTING][] file for suggestions.
40
+
41
+ [contributing]: CONTRIBUTING.md
42
+
43
+ License
44
+ -------
45
+ Released under the MIT License. See the [LICENSE][] file for further details.
46
+
47
+ [license]: LICENSE.md
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env ruby
2
+ # -*- mode: ruby -*-
3
+
4
+ require "thor/runner"
5
+ $thor_runner = true
6
+ Thor::Runner.start
@@ -0,0 +1,490 @@
1
+ require "set"
2
+ require "thor/base"
3
+
4
+ class Thor # rubocop:disable ClassLength
5
+ class << self
6
+ # Allows for custom "Command" package naming.
7
+ #
8
+ # === Parameters
9
+ # name<String>
10
+ # options<Hash>
11
+ #
12
+ def package_name(name, options = {})
13
+ @package_name = name.nil? || name == "" ? nil : name
14
+ end
15
+
16
+ # Sets the default command when thor is executed without an explicit command to be called.
17
+ #
18
+ # ==== Parameters
19
+ # meth<Symbol>:: name of the default command
20
+ #
21
+ def default_command(meth = nil)
22
+ if meth
23
+ @default_command = meth == :none ? "help" : meth.to_s
24
+ else
25
+ @default_command ||= from_superclass(:default_command, "help")
26
+ end
27
+ end
28
+ alias_method :default_task, :default_command
29
+
30
+ # Registers another Thor subclass as a command.
31
+ #
32
+ # ==== Parameters
33
+ # klass<Class>:: Thor subclass to register
34
+ # command<String>:: Subcommand name to use
35
+ # usage<String>:: Short usage for the subcommand
36
+ # description<String>:: Description for the subcommand
37
+ def register(klass, subcommand_name, usage, description, options = {})
38
+ if klass <= Thor::Group
39
+ desc usage, description, options
40
+ define_method(subcommand_name) { |*args| invoke(klass, args) }
41
+ else
42
+ desc usage, description, options
43
+ subcommand subcommand_name, klass
44
+ end
45
+ end
46
+
47
+ # Defines the usage and the description of the next command.
48
+ #
49
+ # ==== Parameters
50
+ # usage<String>
51
+ # description<String>
52
+ # options<String>
53
+ #
54
+ def desc(usage, description, options = {})
55
+ if options[:for]
56
+ command = find_and_refresh_command(options[:for])
57
+ command.usage = usage if usage
58
+ command.description = description if description
59
+ else
60
+ @usage, @desc, @hide = usage, description, options[:hide] || false
61
+ end
62
+ end
63
+
64
+ # Defines the long description of the next command.
65
+ #
66
+ # ==== Parameters
67
+ # long description<String>
68
+ #
69
+ def long_desc(long_description, options = {})
70
+ if options[:for]
71
+ command = find_and_refresh_command(options[:for])
72
+ command.long_description = long_description if long_description
73
+ else
74
+ @long_desc = long_description
75
+ end
76
+ end
77
+
78
+ # Maps an input to a command. If you define:
79
+ #
80
+ # map "-T" => "list"
81
+ #
82
+ # Running:
83
+ #
84
+ # thor -T
85
+ #
86
+ # Will invoke the list command.
87
+ #
88
+ # ==== Parameters
89
+ # Hash[String|Array => Symbol]:: Maps the string or the strings in the array to the given command.
90
+ #
91
+ def map(mappings = nil)
92
+ @map ||= from_superclass(:map, {})
93
+
94
+ if mappings
95
+ mappings.each do |key, value|
96
+ if key.respond_to?(:each)
97
+ key.each { |subkey| @map[subkey] = value }
98
+ else
99
+ @map[key] = value
100
+ end
101
+ end
102
+ end
103
+
104
+ @map
105
+ end
106
+
107
+ # Declares the options for the next command to be declared.
108
+ #
109
+ # ==== Parameters
110
+ # Hash[Symbol => Object]:: The hash key is the name of the option and the value
111
+ # is the type of the option. Can be :string, :array, :hash, :boolean, :numeric
112
+ # or :required (string). If you give a value, the type of the value is used.
113
+ #
114
+ def method_options(options = nil)
115
+ @method_options ||= {}
116
+ build_options(options, @method_options) if options
117
+ @method_options
118
+ end
119
+
120
+ alias_method :options, :method_options
121
+
122
+ # Adds an option to the set of method options. If :for is given as option,
123
+ # it allows you to change the options from a previous defined command.
124
+ #
125
+ # def previous_command
126
+ # # magic
127
+ # end
128
+ #
129
+ # method_option :foo => :bar, :for => :previous_command
130
+ #
131
+ # def next_command
132
+ # # magic
133
+ # end
134
+ #
135
+ # ==== Parameters
136
+ # name<Symbol>:: The name of the argument.
137
+ # options<Hash>:: Described below.
138
+ #
139
+ # ==== Options
140
+ # :desc - Description for the argument.
141
+ # :required - If the argument is required or not.
142
+ # :default - Default value for this argument. It cannot be required and have default values.
143
+ # :aliases - Aliases for this option.
144
+ # :type - The type of the argument, can be :string, :hash, :array, :numeric or :boolean.
145
+ # :banner - String to show on usage notes.
146
+ # :hide - If you want to hide this option from the help.
147
+ #
148
+ def method_option(name, options = {})
149
+ scope = if options[:for]
150
+ find_and_refresh_command(options[:for]).options
151
+ else
152
+ method_options
153
+ end
154
+
155
+ build_option(name, options, scope)
156
+ end
157
+ alias_method :option, :method_option
158
+
159
+ def disable_class_options
160
+ @disable_class_options = true
161
+ end
162
+
163
+ # Prints help information for the given command.
164
+ #
165
+ # ==== Parameters
166
+ # shell<Thor::Shell>
167
+ # command_name<String>
168
+ #
169
+ def command_help(shell, command_name)
170
+ meth = normalize_command_name(command_name)
171
+ command = all_commands[meth]
172
+ handle_no_command_error(meth) unless command
173
+
174
+ shell.say "Usage:"
175
+ shell.say " #{banner(command)}"
176
+ shell.say
177
+ class_options_help(shell, nil => command.options.values)
178
+ if command.long_description
179
+ shell.say "Description:"
180
+ shell.print_wrapped(command.long_description, :indent => 2)
181
+ else
182
+ shell.say command.description
183
+ end
184
+ end
185
+ alias_method :task_help, :command_help
186
+
187
+ # Prints help information for this class.
188
+ #
189
+ # ==== Parameters
190
+ # shell<Thor::Shell>
191
+ #
192
+ def help(shell, subcommand = false)
193
+ list = printable_commands(true, subcommand)
194
+ Thor::Util.thor_classes_in(self).each do |klass|
195
+ list += klass.printable_commands(false)
196
+ end
197
+ list.sort! { |a, b| a[0] <=> b[0] }
198
+
199
+ if defined?(@package_name) && @package_name
200
+ shell.say "#{@package_name} commands:"
201
+ else
202
+ shell.say "Commands:"
203
+ end
204
+
205
+ shell.print_table(list, :indent => 2, :truncate => true)
206
+ shell.say
207
+ class_options_help(shell)
208
+ end
209
+
210
+ # Returns commands ready to be printed.
211
+ def printable_commands(all = true, subcommand = false)
212
+ (all ? all_commands : commands).map do |_, command|
213
+ next if command.hidden?
214
+ item = []
215
+ item << banner(command, false, subcommand)
216
+ item << (command.description ? "# #{command.description.gsub(/\s+/m, ' ')}" : "")
217
+ item
218
+ end.compact
219
+ end
220
+ alias_method :printable_tasks, :printable_commands
221
+
222
+ def subcommands
223
+ @subcommands ||= from_superclass(:subcommands, [])
224
+ end
225
+ alias_method :subtasks, :subcommands
226
+
227
+ def subcommand_classes
228
+ @subcommand_classes ||= {}
229
+ end
230
+
231
+ def subcommand(subcommand, subcommand_class)
232
+ subcommands << subcommand.to_s
233
+ subcommand_class.subcommand_help subcommand
234
+ subcommand_classes[subcommand.to_s] = subcommand_class
235
+
236
+ define_method(subcommand) do |*args|
237
+ args, opts = Thor::Arguments.split(args)
238
+ args.unshift("help") if opts.include? "--help" or opts.include? "-h"
239
+ invoke subcommand_class, args, opts, :invoked_via_subcommand => true, :class_options => options
240
+ end
241
+ end
242
+ alias_method :subtask, :subcommand
243
+
244
+ # Extend check unknown options to accept a hash of conditions.
245
+ #
246
+ # === Parameters
247
+ # options<Hash>: A hash containing :only and/or :except keys
248
+ def check_unknown_options!(options = {})
249
+ @check_unknown_options ||= {}
250
+ options.each do |key, value|
251
+ if value
252
+ @check_unknown_options[key] = Array(value)
253
+ else
254
+ @check_unknown_options.delete(key)
255
+ end
256
+ end
257
+ @check_unknown_options
258
+ end
259
+
260
+ # Overwrite check_unknown_options? to take subcommands and options into account.
261
+ def check_unknown_options?(config) #:nodoc:
262
+ options = check_unknown_options
263
+ return false unless options
264
+
265
+ command = config[:current_command]
266
+ return true unless command
267
+
268
+ name = command.name
269
+
270
+ if subcommands.include?(name)
271
+ false
272
+ elsif options[:except]
273
+ !options[:except].include?(name.to_sym)
274
+ elsif options[:only]
275
+ options[:only].include?(name.to_sym)
276
+ else
277
+ true
278
+ end
279
+ end
280
+
281
+ # Stop parsing of options as soon as an unknown option or a regular
282
+ # argument is encountered. All remaining arguments are passed to the command.
283
+ # This is useful if you have a command that can receive arbitrary additional
284
+ # options, and where those additional options should not be handled by
285
+ # Thor.
286
+ #
287
+ # ==== Example
288
+ #
289
+ # To better understand how this is useful, let's consider a command that calls
290
+ # an external command. A user may want to pass arbitrary options and
291
+ # arguments to that command. The command itself also accepts some options,
292
+ # which should be handled by Thor.
293
+ #
294
+ # class_option "verbose", :type => :boolean
295
+ # stop_on_unknown_option! :exec
296
+ # check_unknown_options! :except => :exec
297
+ #
298
+ # desc "exec", "Run a shell command"
299
+ # def exec(*args)
300
+ # puts "diagnostic output" if options[:verbose]
301
+ # Kernel.exec(*args)
302
+ # end
303
+ #
304
+ # Here +exec+ can be called with +--verbose+ to get diagnostic output,
305
+ # e.g.:
306
+ #
307
+ # $ thor exec --verbose echo foo
308
+ # diagnostic output
309
+ # foo
310
+ #
311
+ # But if +--verbose+ is given after +echo+, it is passed to +echo+ instead:
312
+ #
313
+ # $ thor exec echo --verbose foo
314
+ # --verbose foo
315
+ #
316
+ # ==== Parameters
317
+ # Symbol ...:: A list of commands that should be affected.
318
+ def stop_on_unknown_option!(*command_names)
319
+ stop_on_unknown_option.merge(command_names)
320
+ end
321
+
322
+ def stop_on_unknown_option?(command) #:nodoc:
323
+ command && stop_on_unknown_option.include?(command.name.to_sym)
324
+ end
325
+
326
+ protected
327
+ def stop_on_unknown_option #:nodoc:
328
+ @stop_on_unknown_option ||= Set.new
329
+ end
330
+
331
+ # The method responsible for dispatching given the args.
332
+ def dispatch(meth, given_args, given_opts, config) #:nodoc: # rubocop:disable MethodLength
333
+ meth ||= retrieve_command_name(given_args)
334
+ command = all_commands[normalize_command_name(meth)]
335
+
336
+ if !command && config[:invoked_via_subcommand]
337
+ # We're a subcommand and our first argument didn't match any of our
338
+ # commands. So we put it back and call our default command.
339
+ given_args.unshift(meth)
340
+ command = all_commands[normalize_command_name(default_command)]
341
+ end
342
+
343
+ if command
344
+ args, opts = Thor::Options.split(given_args)
345
+ if stop_on_unknown_option?(command) && !args.empty?
346
+ # given_args starts with a non-option, so we treat everything as
347
+ # ordinary arguments
348
+ args.concat opts
349
+ opts.clear
350
+ end
351
+ else
352
+ args, opts = given_args, nil
353
+ command = dynamic_command_class.new(meth)
354
+ end
355
+
356
+ opts = given_opts || opts || []
357
+ config.merge!(:current_command => command, :command_options => command.options)
358
+
359
+ instance = new(args, opts, config)
360
+ yield instance if block_given?
361
+ args = instance.args
362
+ trailing = args[Range.new(arguments.size, -1)]
363
+ instance.invoke_command(command, trailing || [])
364
+ end
365
+
366
+ # The banner for this class. You can customize it if you are invoking the
367
+ # thor class by another ways which is not the Thor::Runner. It receives
368
+ # the command that is going to be invoked and a boolean which indicates if
369
+ # the namespace should be displayed as arguments.
370
+ #
371
+ def banner(command, namespace = nil, subcommand = false)
372
+ "#{basename} #{command.formatted_usage(self, $thor_runner, subcommand)}"
373
+ end
374
+
375
+ def baseclass #:nodoc:
376
+ Thor
377
+ end
378
+
379
+ def dynamic_command_class #:nodoc:
380
+ Thor::DynamicCommand
381
+ end
382
+
383
+ def create_command(meth) #:nodoc:
384
+ @usage ||= nil
385
+ @desc ||= nil
386
+ @long_desc ||= nil
387
+ @disable_class_options ||= nil
388
+
389
+ if @usage && @desc
390
+ base_class = @hide ? Thor::HiddenCommand : Thor::Command
391
+ commands[meth] = base_class.new(meth, @desc, @long_desc, @usage, method_options, @disable_class_options)
392
+ @usage, @desc, @long_desc, @method_options, @hide, @disable_class_options = nil
393
+ true
394
+ elsif all_commands[meth] || meth == "method_missing"
395
+ true
396
+ else
397
+ puts "[WARNING] Attempted to create command #{meth.inspect} without usage or description. " <<
398
+ "Call desc if you want this method to be available as command or declare it inside a " <<
399
+ "no_commands{} block. Invoked from #{caller[1].inspect}."
400
+ false
401
+ end
402
+ end
403
+ alias_method :create_task, :create_command
404
+
405
+ def initialize_added #:nodoc:
406
+ class_options.merge!(method_options)
407
+ @method_options = nil
408
+ end
409
+
410
+ # Retrieve the command name from given args.
411
+ def retrieve_command_name(args) #:nodoc:
412
+ meth = args.first.to_s unless args.empty?
413
+ if meth && (map[meth] || meth !~ /^\-/)
414
+ args.shift
415
+ else
416
+ nil
417
+ end
418
+ end
419
+ alias_method :retrieve_task_name, :retrieve_command_name
420
+
421
+ # receives a (possibly nil) command name and returns a name that is in
422
+ # the commands hash. In addition to normalizing aliases, this logic
423
+ # will determine if a shortened command is an unambiguous substring of
424
+ # a command or alias.
425
+ #
426
+ # +normalize_command_name+ also converts names like +animal-prison+
427
+ # into +animal_prison+.
428
+ def normalize_command_name(meth) #:nodoc:
429
+ return default_command.to_s.gsub("-", "_") unless meth
430
+
431
+ possibilities = find_command_possibilities(meth)
432
+ if possibilities.size > 1
433
+ fail AmbiguousTaskError, "Ambiguous command #{meth} matches [#{possibilities.join(', ')}]"
434
+ elsif possibilities.size < 1
435
+ meth = meth || default_command
436
+ elsif map[meth]
437
+ meth = map[meth]
438
+ else
439
+ meth = possibilities.first
440
+ end
441
+
442
+ meth.to_s.gsub("-", "_") # treat foo-bar as foo_bar
443
+ end
444
+ alias_method :normalize_task_name, :normalize_command_name
445
+
446
+ # this is the logic that takes the command name passed in by the user
447
+ # and determines whether it is an unambiguous substrings of a command or
448
+ # alias name.
449
+ def find_command_possibilities(meth)
450
+ len = meth.to_s.length
451
+ possibilities = all_commands.merge(map).keys.select { |n| meth == n[0, len] }.sort
452
+ unique_possibilities = possibilities.map { |k| map[k] || k }.uniq
453
+
454
+ if possibilities.include?(meth)
455
+ [meth]
456
+ elsif unique_possibilities.size == 1
457
+ unique_possibilities
458
+ else
459
+ possibilities
460
+ end
461
+ end
462
+ alias_method :find_task_possibilities, :find_command_possibilities
463
+
464
+ def subcommand_help(cmd)
465
+ desc "help [COMMAND]", "Describe subcommands or one specific subcommand"
466
+ class_eval "
467
+ def help(command = nil, subcommand = true); super; end
468
+ "
469
+ end
470
+ alias_method :subtask_help, :subcommand_help
471
+ end
472
+
473
+ include Thor::Base
474
+
475
+ map HELP_MAPPINGS => :help
476
+
477
+ desc "help [COMMAND]", "Describe available commands or one specific command"
478
+ disable_class_options
479
+ def help(command = nil, subcommand = false)
480
+ if command
481
+ if self.class.subcommands.include? command
482
+ self.class.subcommand_classes[command].help(shell, true)
483
+ else
484
+ self.class.command_help(shell, command)
485
+ end
486
+ else
487
+ self.class.help(shell, subcommand)
488
+ end
489
+ end
490
+ end