jedi 0.0.1

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 (45) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +16 -0
  3. data/Gemfile +4 -0
  4. data/LICENSE.txt +22 -0
  5. data/README.md +31 -0
  6. data/Rakefile +2 -0
  7. data/bin/jedi +6 -0
  8. data/jedi.gemspec +23 -0
  9. data/lib/jedi.rb +5 -0
  10. data/lib/jedi/cli.rb +27 -0
  11. data/lib/jedi/vendor/thor-0.19.1/lib/thor.rb +484 -0
  12. data/lib/jedi/vendor/thor-0.19.1/lib/thor/actions.rb +319 -0
  13. data/lib/jedi/vendor/thor-0.19.1/lib/thor/actions/create_file.rb +103 -0
  14. data/lib/jedi/vendor/thor-0.19.1/lib/thor/actions/create_link.rb +59 -0
  15. data/lib/jedi/vendor/thor-0.19.1/lib/thor/actions/directory.rb +118 -0
  16. data/lib/jedi/vendor/thor-0.19.1/lib/thor/actions/empty_directory.rb +135 -0
  17. data/lib/jedi/vendor/thor-0.19.1/lib/thor/actions/file_manipulation.rb +316 -0
  18. data/lib/jedi/vendor/thor-0.19.1/lib/thor/actions/inject_into_file.rb +107 -0
  19. data/lib/jedi/vendor/thor-0.19.1/lib/thor/base.rb +656 -0
  20. data/lib/jedi/vendor/thor-0.19.1/lib/thor/command.rb +133 -0
  21. data/lib/jedi/vendor/thor-0.19.1/lib/thor/core_ext/hash_with_indifferent_access.rb +77 -0
  22. data/lib/jedi/vendor/thor-0.19.1/lib/thor/core_ext/io_binary_read.rb +10 -0
  23. data/lib/jedi/vendor/thor-0.19.1/lib/thor/core_ext/ordered_hash.rb +98 -0
  24. data/lib/jedi/vendor/thor-0.19.1/lib/thor/error.rb +32 -0
  25. data/lib/jedi/vendor/thor-0.19.1/lib/thor/group.rb +281 -0
  26. data/lib/jedi/vendor/thor-0.19.1/lib/thor/invocation.rb +178 -0
  27. data/lib/jedi/vendor/thor-0.19.1/lib/thor/line_editor.rb +17 -0
  28. data/lib/jedi/vendor/thor-0.19.1/lib/thor/line_editor/basic.rb +35 -0
  29. data/lib/jedi/vendor/thor-0.19.1/lib/thor/line_editor/readline.rb +88 -0
  30. data/lib/jedi/vendor/thor-0.19.1/lib/thor/parser.rb +4 -0
  31. data/lib/jedi/vendor/thor-0.19.1/lib/thor/parser/argument.rb +73 -0
  32. data/lib/jedi/vendor/thor-0.19.1/lib/thor/parser/arguments.rb +175 -0
  33. data/lib/jedi/vendor/thor-0.19.1/lib/thor/parser/option.rb +125 -0
  34. data/lib/jedi/vendor/thor-0.19.1/lib/thor/parser/options.rb +218 -0
  35. data/lib/jedi/vendor/thor-0.19.1/lib/thor/rake_compat.rb +71 -0
  36. data/lib/jedi/vendor/thor-0.19.1/lib/thor/runner.rb +322 -0
  37. data/lib/jedi/vendor/thor-0.19.1/lib/thor/shell.rb +81 -0
  38. data/lib/jedi/vendor/thor-0.19.1/lib/thor/shell/basic.rb +421 -0
  39. data/lib/jedi/vendor/thor-0.19.1/lib/thor/shell/color.rb +149 -0
  40. data/lib/jedi/vendor/thor-0.19.1/lib/thor/shell/html.rb +126 -0
  41. data/lib/jedi/vendor/thor-0.19.1/lib/thor/util.rb +267 -0
  42. data/lib/jedi/vendor/thor-0.19.1/lib/thor/version.rb +3 -0
  43. data/lib/jedi/vendored_thor.rb +5 -0
  44. data/lib/jedi/version.rb +3 -0
  45. metadata +116 -0
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 46f9aef4b205c2eb32bad2e2ad14b5e4bafd0b40
4
+ data.tar.gz: cc4a421868510470068255254de63e10a50d57b5
5
+ SHA512:
6
+ metadata.gz: 1bd447e8e914da445ac08728260350175cc1f4b2c604bbc0c8f95be46902607685fb9ef9f8a59f2dea16e333b579e0d49a977804e00c9e8bc879206e76182e7f
7
+ data.tar.gz: d1478f300bf3ad57a4ac5f001793a15ca685b4404560cbeaaa1487db8cc708fa07c22bfcbe730f9e09386f36295059a2bc957ffe36b454dd3660a927fe4c4ea1
@@ -0,0 +1,16 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ *.bundle
11
+ *.so
12
+ *.o
13
+ *.a
14
+ mkmf.log
15
+
16
+ /.idea
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in jedi.gemspec
4
+ gemspec
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2015 Tim Guibord
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,31 @@
1
+ # Jedi
2
+
3
+ TODO: Write a gem description
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ ```ruby
10
+ gem 'jedi'
11
+ ```
12
+
13
+ And then execute:
14
+
15
+ $ bundle
16
+
17
+ Or install it yourself as:
18
+
19
+ $ gem install jedi
20
+
21
+ ## Usage
22
+
23
+ TODO: Write usage instructions here
24
+
25
+ ## Contributing
26
+
27
+ 1. Fork it ( https://github.com/[my-github-username]/jedi/fork )
28
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
29
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
30
+ 4. Push to the branch (`git push origin my-new-feature`)
31
+ 5. Create a new Pull Request
@@ -0,0 +1,2 @@
1
+ require "bundler/gem_tasks"
2
+
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ Signal.trap("INT") { exit 1 }
4
+
5
+ require 'jedi/cli'
6
+ Jedi::CLI.start(ARGV)
@@ -0,0 +1,23 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'jedi/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "jedi"
8
+ spec.version = Jedi::VERSION
9
+ spec.authors = ["Tim Guibord"]
10
+ spec.email = ["timguibord@gmail.com"]
11
+ spec.summary = %q{Force.com Application Goodness}
12
+ spec.description = %q{Long Dexcription}
13
+ spec.homepage = ""
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files -z`.split("\x0")
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_development_dependency "bundler", "~> 1.7"
22
+ spec.add_development_dependency "rake", "~> 10.0"
23
+ end
@@ -0,0 +1,5 @@
1
+ require "jedi/version"
2
+
3
+ module Jedi
4
+ # Your code goes here...
5
+ end
@@ -0,0 +1,27 @@
1
+ require 'jedi'
2
+ require 'jedi/vendored_thor'
3
+ require 'fileutils'
4
+
5
+ module Jedi
6
+
7
+ class CLI < Thor
8
+ include Thor::Actions
9
+
10
+
11
+ def self.start(*)
12
+ super
13
+ rescue Exception => e
14
+ raise e
15
+ end
16
+
17
+ desc 'new APP_NAME', 'generate a new Force.com app'
18
+ def new(name)
19
+ base_dir = File.expand_path(File.dirname(__FILE__))
20
+ FileUtils.mkdir name
21
+ FileUtils.cp_r "#{base_dir}/template/.", name
22
+ puts "Hello #{name}"
23
+ end
24
+
25
+
26
+ end
27
+ end
@@ -0,0 +1,484 @@
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
+ # Prints help information for the given command.
160
+ #
161
+ # ==== Parameters
162
+ # shell<Thor::Shell>
163
+ # command_name<String>
164
+ #
165
+ def command_help(shell, command_name)
166
+ meth = normalize_command_name(command_name)
167
+ command = all_commands[meth]
168
+ handle_no_command_error(meth) unless command
169
+
170
+ shell.say "Usage:"
171
+ shell.say " #{banner(command)}"
172
+ shell.say
173
+ class_options_help(shell, nil => command.options.map { |_, o| o })
174
+ if command.long_description
175
+ shell.say "Description:"
176
+ shell.print_wrapped(command.long_description, :indent => 2)
177
+ else
178
+ shell.say command.description
179
+ end
180
+ end
181
+ alias_method :task_help, :command_help
182
+
183
+ # Prints help information for this class.
184
+ #
185
+ # ==== Parameters
186
+ # shell<Thor::Shell>
187
+ #
188
+ def help(shell, subcommand = false)
189
+ list = printable_commands(true, subcommand)
190
+ Thor::Util.thor_classes_in(self).each do |klass|
191
+ list += klass.printable_commands(false)
192
+ end
193
+ list.sort! { |a, b| a[0] <=> b[0] }
194
+
195
+ if defined?(@package_name) && @package_name
196
+ shell.say "#{@package_name} commands:"
197
+ else
198
+ shell.say "Commands:"
199
+ end
200
+
201
+ shell.print_table(list, :indent => 2, :truncate => true)
202
+ shell.say
203
+ class_options_help(shell)
204
+ end
205
+
206
+ # Returns commands ready to be printed.
207
+ def printable_commands(all = true, subcommand = false)
208
+ (all ? all_commands : commands).map do |_, command|
209
+ next if command.hidden?
210
+ item = []
211
+ item << banner(command, false, subcommand)
212
+ item << (command.description ? "# #{command.description.gsub(/\s+/m, ' ')}" : "")
213
+ item
214
+ end.compact
215
+ end
216
+ alias_method :printable_tasks, :printable_commands
217
+
218
+ def subcommands
219
+ @subcommands ||= from_superclass(:subcommands, [])
220
+ end
221
+ alias_method :subtasks, :subcommands
222
+
223
+ def subcommand_classes
224
+ @subcommand_classes ||= {}
225
+ end
226
+
227
+ def subcommand(subcommand, subcommand_class)
228
+ subcommands << subcommand.to_s
229
+ subcommand_class.subcommand_help subcommand
230
+ subcommand_classes[subcommand.to_s] = subcommand_class
231
+
232
+ define_method(subcommand) do |*args|
233
+ 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
236
+ end
237
+ end
238
+ alias_method :subtask, :subcommand
239
+
240
+ # Extend check unknown options to accept a hash of conditions.
241
+ #
242
+ # === Parameters
243
+ # options<Hash>: A hash containing :only and/or :except keys
244
+ def check_unknown_options!(options = {})
245
+ @check_unknown_options ||= {}
246
+ options.each do |key, value|
247
+ if value
248
+ @check_unknown_options[key] = Array(value)
249
+ else
250
+ @check_unknown_options.delete(key)
251
+ end
252
+ end
253
+ @check_unknown_options
254
+ end
255
+
256
+ # Overwrite check_unknown_options? to take subcommands and options into account.
257
+ def check_unknown_options?(config) #:nodoc:
258
+ options = check_unknown_options
259
+ return false unless options
260
+
261
+ command = config[:current_command]
262
+ return true unless command
263
+
264
+ name = command.name
265
+
266
+ if subcommands.include?(name)
267
+ false
268
+ elsif options[:except]
269
+ !options[:except].include?(name.to_sym)
270
+ elsif options[:only]
271
+ options[:only].include?(name.to_sym)
272
+ else
273
+ true
274
+ end
275
+ end
276
+
277
+ # Stop parsing of options as soon as an unknown option or a regular
278
+ # argument is encountered. All remaining arguments are passed to the command.
279
+ # This is useful if you have a command that can receive arbitrary additional
280
+ # options, and where those additional options should not be handled by
281
+ # Thor.
282
+ #
283
+ # ==== Example
284
+ #
285
+ # To better understand how this is useful, let's consider a command that calls
286
+ # an external command. A user may want to pass arbitrary options and
287
+ # arguments to that command. The command itself also accepts some options,
288
+ # which should be handled by Thor.
289
+ #
290
+ # class_option "verbose", :type => :boolean
291
+ # stop_on_unknown_option! :exec
292
+ # check_unknown_options! :except => :exec
293
+ #
294
+ # desc "exec", "Run a shell command"
295
+ # def exec(*args)
296
+ # puts "diagnostic output" if options[:verbose]
297
+ # Kernel.exec(*args)
298
+ # end
299
+ #
300
+ # Here +exec+ can be called with +--verbose+ to get diagnostic output,
301
+ # e.g.:
302
+ #
303
+ # $ thor exec --verbose echo foo
304
+ # diagnostic output
305
+ # foo
306
+ #
307
+ # But if +--verbose+ is given after +echo+, it is passed to +echo+ instead:
308
+ #
309
+ # $ thor exec echo --verbose foo
310
+ # --verbose foo
311
+ #
312
+ # ==== Parameters
313
+ # Symbol ...:: A list of commands that should be affected.
314
+ def stop_on_unknown_option!(*command_names)
315
+ stop_on_unknown_option.merge(command_names)
316
+ end
317
+
318
+ def stop_on_unknown_option?(command) #:nodoc:
319
+ command && stop_on_unknown_option.include?(command.name.to_sym)
320
+ end
321
+
322
+ protected
323
+ def stop_on_unknown_option #:nodoc:
324
+ @stop_on_unknown_option ||= Set.new
325
+ end
326
+
327
+ # The method responsible for dispatching given the args.
328
+ def dispatch(meth, given_args, given_opts, config) #:nodoc: # rubocop:disable MethodLength
329
+ meth ||= retrieve_command_name(given_args)
330
+ command = all_commands[normalize_command_name(meth)]
331
+
332
+ if !command && config[:invoked_via_subcommand]
333
+ # We're a subcommand and our first argument didn't match any of our
334
+ # commands. So we put it back and call our default command.
335
+ given_args.unshift(meth)
336
+ command = all_commands[normalize_command_name(default_command)]
337
+ end
338
+
339
+ if command
340
+ args, opts = Thor::Options.split(given_args)
341
+ if stop_on_unknown_option?(command) && !args.empty?
342
+ # given_args starts with a non-option, so we treat everything as
343
+ # ordinary arguments
344
+ args.concat opts
345
+ opts.clear
346
+ end
347
+ else
348
+ args, opts = given_args, nil
349
+ command = dynamic_command_class.new(meth)
350
+ end
351
+
352
+ opts = given_opts || opts || []
353
+ config.merge!(:current_command => command, :command_options => command.options)
354
+
355
+ instance = new(args, opts, config)
356
+ yield instance if block_given?
357
+ args = instance.args
358
+ trailing = args[Range.new(arguments.size, -1)]
359
+ instance.invoke_command(command, trailing || [])
360
+ end
361
+
362
+ # The banner for this class. You can customize it if you are invoking the
363
+ # thor class by another ways which is not the Thor::Runner. It receives
364
+ # the command that is going to be invoked and a boolean which indicates if
365
+ # the namespace should be displayed as arguments.
366
+ #
367
+ def banner(command, namespace = nil, subcommand = false)
368
+ "#{basename} #{command.formatted_usage(self, $thor_runner, subcommand)}"
369
+ end
370
+
371
+ def baseclass #:nodoc:
372
+ Thor
373
+ end
374
+
375
+ def dynamic_command_class #:nodoc:
376
+ Thor::DynamicCommand
377
+ end
378
+
379
+ def create_command(meth) #:nodoc:
380
+ @usage ||= nil
381
+ @desc ||= nil
382
+ @long_desc ||= nil
383
+
384
+ if @usage && @desc
385
+ 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
388
+ true
389
+ elsif all_commands[meth] || meth == "method_missing"
390
+ true
391
+ 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 " <<
394
+ "no_commands{} block. Invoked from #{caller[1].inspect}."
395
+ false
396
+ end
397
+ end
398
+ alias_method :create_task, :create_command
399
+
400
+ def initialize_added #:nodoc:
401
+ class_options.merge!(method_options)
402
+ @method_options = nil
403
+ end
404
+
405
+ # Retrieve the command name from given args.
406
+ def retrieve_command_name(args) #:nodoc:
407
+ meth = args.first.to_s unless args.empty?
408
+ if meth && (map[meth] || meth !~ /^\-/)
409
+ args.shift
410
+ else
411
+ nil
412
+ end
413
+ end
414
+ alias_method :retrieve_task_name, :retrieve_command_name
415
+
416
+ # receives a (possibly nil) command name and returns a name that is in
417
+ # the commands hash. In addition to normalizing aliases, this logic
418
+ # will determine if a shortened command is an unambiguous substring of
419
+ # a command or alias.
420
+ #
421
+ # +normalize_command_name+ also converts names like +animal-prison+
422
+ # into +animal_prison+.
423
+ def normalize_command_name(meth) #:nodoc:
424
+ return default_command.to_s.gsub("-", "_") unless meth
425
+
426
+ 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
431
+ elsif map[meth]
432
+ meth = map[meth]
433
+ else
434
+ meth = possibilities.first
435
+ end
436
+
437
+ meth.to_s.gsub("-", "_") # treat foo-bar as foo_bar
438
+ end
439
+ alias_method :normalize_task_name, :normalize_command_name
440
+
441
+ # this is the logic that takes the command name passed in by the user
442
+ # and determines whether it is an unambiguous substrings of a command or
443
+ # alias name.
444
+ def find_command_possibilities(meth)
445
+ len = meth.to_s.length
446
+ possibilities = all_commands.merge(map).keys.select { |n| meth == n[0, len] }.sort
447
+ unique_possibilities = possibilities.map { |k| map[k] || k }.uniq
448
+
449
+ if possibilities.include?(meth)
450
+ [meth]
451
+ elsif unique_possibilities.size == 1
452
+ unique_possibilities
453
+ else
454
+ possibilities
455
+ end
456
+ end
457
+ alias_method :find_task_possibilities, :find_command_possibilities
458
+
459
+ def subcommand_help(cmd)
460
+ desc "help [COMMAND]", "Describe subcommands or one specific subcommand"
461
+ class_eval "
462
+ def help(command = nil, subcommand = true); super; end
463
+ "
464
+ end
465
+ alias_method :subtask_help, :subcommand_help
466
+ end
467
+
468
+ include Thor::Base
469
+
470
+ map HELP_MAPPINGS => :help
471
+
472
+ desc "help [COMMAND]", "Describe available commands or one specific command"
473
+ def help(command = nil, subcommand = false)
474
+ if command
475
+ if self.class.subcommands.include? command
476
+ self.class.subcommand_classes[command].help(shell, true)
477
+ else
478
+ self.class.command_help(shell, command)
479
+ end
480
+ else
481
+ self.class.help(shell, subcommand)
482
+ end
483
+ end
484
+ end