atli 0.1.4 → 0.1.5

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: f4e7f9477c50ae3c6a9b1b04f219bb54ff71c250
4
- data.tar.gz: 215087b08b4d56af4113b9c1a0d9257501b1e69e
3
+ metadata.gz: 95863e37e95274081f2c343d9df00d0d97d19316
4
+ data.tar.gz: eaf7d27b98f259c3a3b490b41ce57781a2bbe16d
5
5
  SHA512:
6
- metadata.gz: dcfdce63cc6571aa0bb4234275d7fb917b885ee7a2e27d3327f15256f48b694c75bb699bf01a128a30b1ce3240a599f51b11bf32e2b4333449a4e5bcc7686b51
7
- data.tar.gz: e9189beb57073354f93275c82f1176f8e900b75b12a472c7d29cebac03c19e8e9ebcbc5d12a8c7c8dd9ce40c518165a346b53378b0317ad75bec84f29e13e6ef
6
+ metadata.gz: b9acc28c198b5b72f3405d19c43e45a45222092193d012fe5c957cd2218f22261fc15adcb29f92ed90aa2b7f779ce5c4dd5c9635bf08a68956e8a87a354d4faf
7
+ data.tar.gz: 7277fb5f16254c564194803f30a204afd1eeaae0474d569651ecbef3e05796a1ae6430c2820d34a19db750e2318bc25ceb2eea989a9bf75d9cf07d08f9fea0e6
@@ -246,16 +246,36 @@ class Thor
246
246
  end.compact
247
247
  end
248
248
  alias_method :printable_tasks, :printable_commands
249
-
249
+
250
+
251
+ # List of subcommand names, including those inherited from super
252
+ # classes.
253
+ #
254
+ # @return [Array<String>]
255
+ #
250
256
  def subcommands
251
257
  @subcommands ||= from_superclass(:subcommands, [])
252
258
  end
253
259
  alias_method :subtasks, :subcommands
254
-
260
+
261
+
262
+ # Map of subcommand names to Thor classes for *this* Thor class only.
263
+ #
264
+ # @note
265
+ # `.subcommands` is not necessarily equal to `.subcommand_classes.keys`
266
+ # - it won't be when there are subcommands inherited from super classes.
267
+ #
268
+ # @note
269
+ # I'm not really sure how this relates to {Thor::Group}... and I'm not
270
+ # going to take the time to find out now.
271
+ #
272
+ # @return [Hash<String, Class<Thor::Base>]
273
+ #
255
274
  def subcommand_classes
256
275
  @subcommand_classes ||= {}
257
276
  end
258
-
277
+
278
+
259
279
  def subcommand(subcommand, subcommand_class)
260
280
  subcommands << subcommand.to_s
261
281
  subcommand_class.subcommand_help subcommand
@@ -20,7 +20,7 @@ require "thor/shell"
20
20
  require "thor/line_editor"
21
21
  require "thor/util"
22
22
  require 'thor/execution'
23
- require 'thor/base/common_class_options'
23
+ require 'thor/base/class_methods'
24
24
 
25
25
 
26
26
  # Refinements
@@ -68,10 +68,9 @@ class Thor
68
68
  # config<Hash>:: Configuration for this Thor class.
69
69
  #
70
70
  def initialize(args = [], local_options = {}, config = {})
71
- logger.trace "#{ self.class.name }#initialize",
71
+ logger.debug "#{ self.class.name }#initialize",
72
72
  args: args,
73
- local_options: local_options,
74
- config: config
73
+ local_options: local_options
75
74
 
76
75
  parse_options = self.class.class_options
77
76
 
@@ -99,11 +98,20 @@ class Thor
99
98
  self.class.stop_on_unknown_option? config[:current_command]
100
99
  disable_required_check = \
101
100
  self.class.disable_required_check? config[:current_command]
101
+
102
+ logger.debug "Ready to create options",
103
+ array_options: array_options,
104
+ hash_options: hash_options,
105
+ stop_on_unknown: stop_on_unknown,
106
+ disable_required_check: disable_required_check
107
+
102
108
  opts = Thor::Options.new( parse_options,
103
109
  hash_options,
104
110
  stop_on_unknown,
105
111
  disable_required_check )
112
+
106
113
  self.options = opts.parse(array_options)
114
+
107
115
  if config[:class_options]
108
116
  self.options = config[:class_options].merge(options)
109
117
  end
@@ -118,7 +126,9 @@ class Thor
118
126
  # by Thor::Group). Tis will leave us with the remaining
119
127
  # positional arguments.
120
128
  to_parse = args
121
- to_parse += opts.remaining unless self.class.strict_args_position?(config)
129
+ unless self.class.strict_args_position?(config)
130
+ to_parse += opts.remaining
131
+ end
122
132
 
123
133
  thor_args = Thor::Arguments.new(self.class.arguments)
124
134
  thor_args.parse(to_parse).each { |k, v| __send__("#{k}=", v) }
@@ -225,611 +235,5 @@ class Thor
225
235
  file_subclasses = Thor::Base.subclass_files[File.expand_path(file)]
226
236
  file_subclasses << klass unless file_subclasses.include?(klass)
227
237
  end
228
-
229
-
230
- # Methods that are mixed in as module/class/singleton methods to modules
231
- # that include {Thor::Base}.
232
- #
233
- module ClassMethods
234
- include Thor::Base::CommonClassOptions
235
-
236
- def attr_reader(*) #:nodoc:
237
- no_commands { super }
238
- end
239
-
240
- def attr_writer(*) #:nodoc:
241
- no_commands { super }
242
- end
243
-
244
- def attr_accessor(*) #:nodoc:
245
- no_commands { super }
246
- end
247
-
248
- # If you want to raise an error for unknown options, call
249
- # check_unknown_options!
250
- # This is disabled by default to allow dynamic invocations.
251
- def check_unknown_options!
252
- @check_unknown_options = true
253
- end
254
-
255
- def check_unknown_options #:nodoc:
256
- @check_unknown_options ||= from_superclass(:check_unknown_options, false)
257
- end
258
-
259
- def check_unknown_options?(config) #:nodoc:
260
- !!check_unknown_options
261
- end
262
-
263
- # If you want to raise an error when the default value of an option does
264
- # not match the type call check_default_type!
265
- # This is disabled by default for compatibility.
266
- def check_default_type!
267
- @check_default_type = true
268
- end
269
-
270
- def check_default_type #:nodoc:
271
- @check_default_type ||= from_superclass(:check_default_type, false)
272
- end
273
-
274
- def check_default_type? #:nodoc:
275
- !!check_default_type
276
- end
277
-
278
- # If true, option parsing is suspended as soon as an unknown option or a
279
- # regular argument is encountered. All remaining arguments are passed to
280
- # the command as regular arguments.
281
- def stop_on_unknown_option?(command_name) #:nodoc:
282
- false
283
- end
284
-
285
- # If true, option set will not suspend the execution of the command when
286
- # a required option is not provided.
287
- def disable_required_check?(command_name) #:nodoc:
288
- false
289
- end
290
-
291
- # If you want only strict string args (useful when cascading thor classes),
292
- # call strict_args_position! This is disabled by default to allow dynamic
293
- # invocations.
294
- def strict_args_position!
295
- @strict_args_position = true
296
- end
297
-
298
- def strict_args_position #:nodoc:
299
- @strict_args_position ||= from_superclass(:strict_args_position, false)
300
- end
301
-
302
- def strict_args_position?(config) #:nodoc:
303
- !!strict_args_position
304
- end
305
-
306
- # Adds an argument to the class and creates an attr_accessor for it.
307
- #
308
- # Arguments are different from options in several aspects. The first one
309
- # is how they are parsed from the command line, arguments are retrieved
310
- # from position:
311
- #
312
- # thor command NAME
313
- #
314
- # Instead of:
315
- #
316
- # thor command --name=NAME
317
- #
318
- # Besides, arguments are used inside your code as an accessor
319
- # (self.argument), while options are all kept in a hash (self.options).
320
- #
321
- # Finally, arguments cannot have type :default or :boolean but can be
322
- # optional (supplying :optional => :true or :required => false), although
323
- # you cannot have a required argument after a non-required argument. If
324
- # you try it, an error is raised.
325
- #
326
- # ==== Parameters
327
- # name<Symbol>:: The name of the argument.
328
- # options<Hash>:: Described below.
329
- #
330
- # ==== Options
331
- # :desc - Description for the argument.
332
- # :required - If the argument is required or not.
333
- # :optional - If the argument is optional or not.
334
- # :type - The type of the argument, can be :string, :hash, :array,
335
- # :numeric.
336
- # :default - Default value for this argument. It cannot be required and
337
- # have default values.
338
- # :banner - String to show on usage notes.
339
- #
340
- # ==== Errors
341
- # ArgumentError:: Raised if you supply a required argument after a non
342
- # required one.
343
- #
344
- def argument(name, options = {})
345
- is_thor_reserved_word?(name, :argument)
346
- no_commands { attr_accessor name }
347
-
348
- required = if options.key?(:optional)
349
- !options[:optional]
350
- elsif options.key?(:required)
351
- options[:required]
352
- else
353
- options[:default].nil?
354
- end
355
-
356
- remove_argument name
357
-
358
- if required
359
- arguments.each do |argument|
360
- next if argument.required?
361
- raise ArgumentError,
362
- "You cannot have #{name.to_s.inspect} as required argument " \
363
- "after the non-required argument #{argument.human_name.inspect}."
364
- end
365
- end
366
-
367
- options[:required] = required
368
-
369
- arguments << Thor::Argument.new(name, options)
370
- end
371
-
372
- # Returns this class arguments, looking up in the ancestors chain.
373
- #
374
- # ==== Returns
375
- # Array[Thor::Argument]
376
- #
377
- def arguments
378
- @arguments ||= from_superclass(:arguments, [])
379
- end
380
-
381
- # Adds a bunch of options to the set of class options.
382
- #
383
- # class_options :foo => false, :bar => :required, :baz => :string
384
- #
385
- # If you prefer more detailed declaration, check class_option.
386
- #
387
- # ==== Parameters
388
- # Hash[Symbol => Object]
389
- #
390
- def class_options(options = nil)
391
- @class_options ||= from_superclass(:class_options, {})
392
- build_options(options, @class_options) if options
393
- @class_options
394
- end
395
-
396
- # Adds an option to the set of class options
397
- #
398
- # ==== Parameters
399
- # name<Symbol>:: The name of the argument.
400
- # options<Hash>:: Described below.
401
- #
402
- # ==== Options
403
- # :desc:: -- Description for the argument.
404
- # :required:: -- If the argument is required or not.
405
- # :default:: -- Default value for this argument.
406
- # :group:: -- The group for this options. Use by class options to
407
- # output options in different levels.
408
- # :aliases:: -- Aliases for this option. <b>Note:</b> Thor follows a
409
- # convention of one-dash-one-letter options. Thus
410
- # aliases like "-something" wouldn't be parsed; use
411
- # either "\--something" or "-s" instead.
412
- # :type:: -- The type of the argument, can be :string, :hash, :array,
413
- # :numeric or :boolean.
414
- # :banner:: -- String to show on usage notes.
415
- # :hide:: -- If you want to hide this option from the help.
416
- #
417
- def class_option(name, options = {})
418
- build_option(name, options, class_options)
419
- end
420
-
421
- # Removes a previous defined argument. If :undefine is given, undefine
422
- # accessors as well.
423
- #
424
- # ==== Parameters
425
- # names<Array>:: Arguments to be removed
426
- #
427
- # ==== Examples
428
- #
429
- # remove_argument :foo
430
- # remove_argument :foo, :bar, :baz, :undefine => true
431
- #
432
- def remove_argument(*names)
433
- options = names.last.is_a?(Hash) ? names.pop : {}
434
-
435
- names.each do |name|
436
- arguments.delete_if { |a| a.name == name.to_s }
437
- undef_method name, "#{name}=" if options[:undefine]
438
- end
439
- end
440
-
441
- # Removes a previous defined class option.
442
- #
443
- # ==== Parameters
444
- # names<Array>:: Class options to be removed
445
- #
446
- # ==== Examples
447
- #
448
- # remove_class_option :foo
449
- # remove_class_option :foo, :bar, :baz
450
- #
451
- def remove_class_option(*names)
452
- names.each do |name|
453
- class_options.delete(name)
454
- end
455
- end
456
-
457
- # Defines the group. This is used when thor list is invoked so you can
458
- # specify that only commands from a pre-defined group will be shown.
459
- # Defaults to standard.
460
- #
461
- # ==== Parameters
462
- # name<String|Symbol>
463
- #
464
- def group(name = nil)
465
- if name
466
- @group = name.to_s
467
- else
468
- @group ||= from_superclass(:group, "standard")
469
- end
470
- end
471
-
472
- # Returns the commands for this Thor class.
473
- #
474
- # ==== Returns
475
- # OrderedHash:: An ordered hash with commands names as keys and
476
- # Thor::Command objects as values.
477
- #
478
- def commands
479
- @commands ||= Thor::CoreExt::OrderedHash.new
480
- end
481
- alias_method :tasks, :commands
482
-
483
- # Returns the commands for this Thor class and all subclasses.
484
- #
485
- # ==== Returns
486
- # OrderedHash:: An ordered hash with commands names as keys and
487
- # Thor::Command objects as values.
488
- #
489
- def all_commands
490
- @all_commands ||= from_superclass( :all_commands,
491
- Thor::CoreExt::OrderedHash.new )
492
- @all_commands.merge!(commands)
493
- end
494
- alias_method :all_tasks, :all_commands
495
-
496
- # Removes a given command from this Thor class. This is usually done if you
497
- # are inheriting from another class and don't want it to be available
498
- # anymore.
499
- #
500
- # By default it only remove the mapping to the command. But you can supply
501
- # :undefine => true to undefine the method from the class as well.
502
- #
503
- # ==== Parameters
504
- # name<Symbol|String>:: The name of the command to be removed
505
- # options<Hash>:: You can give :undefine => true if you want commands the
506
- # method to be undefined from the class as well.
507
- #
508
- def remove_command(*names)
509
- options = names.last.is_a?(Hash) ? names.pop : {}
510
-
511
- names.each do |name|
512
- commands.delete(name.to_s)
513
- all_commands.delete(name.to_s)
514
- undef_method name if options[:undefine]
515
- end
516
- end
517
- alias_method :remove_task, :remove_command
518
-
519
- # All methods defined inside the given block are not added as commands.
520
- #
521
- # So you can do:
522
- #
523
- # class MyScript < Thor
524
- # no_commands do
525
- # def this_is_not_a_command
526
- # end
527
- # end
528
- # end
529
- #
530
- # You can also add the method and remove it from the command list:
531
- #
532
- # class MyScript < Thor
533
- # def this_is_not_a_command
534
- # end
535
- # remove_command :this_is_not_a_command
536
- # end
537
- #
538
- def no_commands
539
- @no_commands = true
540
- yield
541
- ensure
542
- @no_commands = false
543
- end
544
- alias_method :no_tasks, :no_commands
545
-
546
- # Sets the namespace for the Thor or Thor::Group class. By default the
547
- # namespace is retrieved from the class name. If your Thor class is named
548
- # Scripts::MyScript, the help method, for example, will be called as:
549
- #
550
- # thor scripts:my_script -h
551
- #
552
- # If you change the namespace:
553
- #
554
- # namespace :my_scripts
555
- #
556
- # You change how your commands are invoked:
557
- #
558
- # thor my_scripts -h
559
- #
560
- # Finally, if you change your namespace to default:
561
- #
562
- # namespace :default
563
- #
564
- # Your commands can be invoked with a shortcut. Instead of:
565
- #
566
- # thor :my_command
567
- #
568
- def namespace(name = nil)
569
- if name
570
- @namespace = name.to_s
571
- else
572
- @namespace ||= Thor::Util.namespace_from_thor_class(self)
573
- end
574
- end
575
-
576
- # Parses the command and options from the given args, instantiate the class
577
- # and invoke the command. This method is used when the arguments must be parsed
578
- # from an array. If you are inside Ruby and want to use a Thor class, you
579
- # can simply initialize it:
580
- #
581
- # script = MyScript.new(args, options, config)
582
- # script.invoke(:command, first_arg, second_arg, third_arg)
583
- #
584
- def start(given_args = ARGV, config = {})
585
- config[:shell] ||= Thor::Base.shell.new
586
- dispatch(nil, given_args.dup, nil, config)
587
- rescue Thor::Error => e
588
- if config[:debug] || ENV["THOR_DEBUG"] == "1"
589
- raise e
590
- else
591
- config[:shell].error(e.message)
592
- end
593
- exit(1) if exit_on_failure?
594
- rescue Errno::EPIPE
595
- # This happens if a thor command is piped to something like `head`,
596
- # which closes the pipe when it's done reading. This will also
597
- # mean that if the pipe is closed, further unnecessary
598
- # computation will not occur.
599
- exit(0)
600
- end
601
-
602
-
603
- # Like {#start}, but explicitly for handling over control in an
604
- # executable.
605
- #
606
- # For details on why this is here see
607
- # {file:doc/files/notes/too-broken-to-fail.md Too Broken to Fail}.
608
- #
609
- def exec!(given_args = ARGV, config = {})
610
- execution = Thor::Execution.new thor_class: self,
611
- given_args: given_args,
612
- thor_config: config
613
-
614
- execution.exec!
615
- end # #start
616
-
617
-
618
- # Allows to use private methods from parent in child classes as commands.
619
- #
620
- # ==== Parameters
621
- # names<Array>:: Method names to be used as commands
622
- #
623
- # ==== Examples
624
- #
625
- # public_command :foo
626
- # public_command :foo, :bar, :baz
627
- #
628
- def public_command(*names)
629
- names.each do |name|
630
- class_eval "def #{name}(*); super end"
631
- end
632
- end
633
- alias_method :public_task, :public_command
634
-
635
- def handle_no_command_error(command, has_namespace = $thor_runner) #:nodoc:
636
- if has_namespace
637
- raise UndefinedCommandError,
638
- "Could not find command #{command.inspect} in " \
639
- "#{namespace.inspect} namespace."
640
- end
641
- raise UndefinedCommandError,
642
- "Could not find command #{command.inspect}."
643
- end
644
- alias_method :handle_no_task_error, :handle_no_command_error
645
-
646
- def handle_argument_error(command, error, args, arity) #:nodoc:
647
- name = [command.ancestor_name, command.name].compact.join(" ")
648
- msg = "ERROR: \"#{basename} #{name}\" was called with ".dup
649
- msg << "no arguments" if args.empty?
650
- msg << "arguments " << args.inspect unless args.empty?
651
- msg << "\nUsage: #{banner(command).inspect}"
652
- raise InvocationError, msg
653
- end
654
-
655
- protected
656
- # ============================================================================
657
-
658
- # Prints the class options per group. If an option does not belong to
659
- # any group, it's printed as Class option.
660
- #
661
- def class_options_help(shell, groups = {}) #:nodoc:
662
- # Group options by group
663
- class_options.each do |_, value|
664
- groups[value.group] ||= []
665
- groups[value.group] << value
666
- end
667
-
668
- # Deal with default group
669
- global_options = groups.delete(nil) || []
670
- print_options(shell, global_options)
671
-
672
- # Print all others
673
- groups.each do |group_name, options|
674
- print_options(shell, options, group_name)
675
- end
676
- end
677
-
678
- # Receives a set of options and print them.
679
- def print_options(shell, options, group_name = nil)
680
- return if options.empty?
681
-
682
- list = []
683
- padding = options.map { |o| o.aliases.size }.max.to_i * 4
684
-
685
- options.each do |option|
686
- next if option.hide
687
- item = [option.usage(padding)]
688
- item.push(option.description ? "# #{option.description}" : "")
689
-
690
- list << item
691
- list << ["", "# Default: #{option.default}"] if option.show_default?
692
- if option.enum
693
- list << ["", "# Possible values: #{option.enum.join(', ')}"]
694
- end
695
- end
696
-
697
- shell.say(group_name ? "#{group_name} options:" : "Options:")
698
- shell.print_table(list, :indent => 2)
699
- shell.say ""
700
- end
701
-
702
- # Raises an error if the word given is a Thor reserved word.
703
- def is_thor_reserved_word?(word, type) #:nodoc:
704
- return false unless THOR_RESERVED_WORDS.include?(word.to_s)
705
- raise "#{word.inspect} is a Thor reserved word and cannot be " \
706
- "defined as #{type}"
707
- end
708
-
709
- # Build an option and adds it to the given scope.
710
- #
711
- # ==== Parameters
712
- # name<Symbol>:: The name of the argument.
713
- # options<Hash>:: Described in both class_option and method_option.
714
- # scope<Hash>:: Options hash that is being built up
715
- def build_option(name, options, scope) #:nodoc:
716
- scope[name] = Thor::Option.new(
717
- name,
718
- options.merge(:check_default_type => check_default_type?)
719
- )
720
- end
721
-
722
- # Receives a hash of options, parse them and add to the scope. This is a
723
- # fast way to set a bunch of options:
724
- #
725
- # build_options :foo => true, :bar => :required, :baz => :string
726
- #
727
- # ==== Parameters
728
- # Hash[Symbol => Object]
729
- def build_options(options, scope) #:nodoc:
730
- options.each do |key, value|
731
- scope[key] = Thor::Option.parse(key, value)
732
- end
733
- end
734
-
735
- # Finds a command with the given name. If the command belongs to the current
736
- # class, just return it, otherwise dup it and add the fresh copy to the
737
- # current command hash.
738
- def find_and_refresh_command(name) #:nodoc:
739
- if commands[name.to_s]
740
- commands[name.to_s]
741
- elsif command = all_commands[name.to_s] # rubocop:disable AssignmentInCondition
742
- commands[name.to_s] = command.clone
743
- else
744
- raise ArgumentError,
745
- "You supplied :for => #{name.inspect}, but the command " \
746
- "#{name.inspect} could not be found."
747
- end
748
- end
749
- alias_method :find_and_refresh_task, :find_and_refresh_command
750
-
751
- # Everytime someone inherits from a Thor class, register the klass
752
- # and file into baseclass.
753
- def inherited(klass)
754
- Thor::Base.register_klass_file(klass)
755
- klass.instance_variable_set(:@no_commands, false)
756
- end
757
-
758
- # Fire this callback whenever a method is added. Added methods are
759
- # tracked as commands by invoking the create_command method.
760
- def method_added(meth)
761
- meth = meth.to_s
762
-
763
- if meth == "initialize"
764
- initialize_added
765
- return
766
- end
767
-
768
- # Return if it's not a public instance method
769
- return unless public_method_defined?(meth.to_sym)
770
-
771
- @no_commands ||= false
772
- return if @no_commands || !create_command(meth)
773
-
774
- is_thor_reserved_word?(meth, :command)
775
- Thor::Base.register_klass_file(self)
776
- end
777
-
778
- # Retrieves a value from superclass. If it reaches the baseclass,
779
- # returns default.
780
- def from_superclass(method, default = nil)
781
- if self == baseclass || !superclass.respond_to?(method, true)
782
- default
783
- else
784
- value = superclass.send(method)
785
-
786
- # Ruby implements `dup` on Object, but raises a `TypeError`
787
- # if the method is called on immediates. As a result, we
788
- # don't have a good way to check whether dup will succeed
789
- # without calling it and rescuing the TypeError.
790
- begin
791
- value.dup
792
- rescue TypeError
793
- value
794
- end
795
-
796
- end
797
- end
798
-
799
- # A flag that makes the process exit with status 1 if any error happens.
800
- def exit_on_failure?
801
- false
802
- end
803
-
804
- #
805
- # The basename of the program invoking the thor class.
806
- #
807
- def basename
808
- File.basename($PROGRAM_NAME).split(" ").first
809
- end
810
-
811
- # SIGNATURE: Sets the baseclass. This is where the superclass lookup
812
- # finishes.
813
- def baseclass #:nodoc:
814
- end
815
-
816
- # SIGNATURE: Creates a new command if valid_command? is true. This method
817
- # is called when a new method is added to the class.
818
- def create_command(meth) #:nodoc:
819
- end
820
- alias_method :create_task, :create_command
821
-
822
- # SIGNATURE: Defines behavior when the initialize method is added to the
823
- # class.
824
- def initialize_added #:nodoc:
825
- end
826
-
827
- # SIGNATURE: The hook invoked by start.
828
- def dispatch(command, given_args, given_opts, config) #:nodoc:
829
- raise NotImplementedError
830
- end
831
-
832
- # end protected
833
- end # ClassMethods
834
238
  end # module Base
835
239
  end # class Thor