atli 0.1.4 → 0.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.
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