thor 0.19.4 → 1.2.1

Sign up to get free protection for your applications and to get access to all the features.
data/lib/thor/base.rb CHANGED
@@ -1,17 +1,17 @@
1
- require "thor/command"
2
- require "thor/core_ext/hash_with_indifferent_access"
3
- require "thor/core_ext/ordered_hash"
4
- require "thor/error"
5
- require "thor/invocation"
6
- require "thor/parser"
7
- require "thor/shell"
8
- require "thor/line_editor"
9
- require "thor/util"
1
+ require_relative "command"
2
+ require_relative "core_ext/hash_with_indifferent_access"
3
+ require_relative "error"
4
+ require_relative "invocation"
5
+ require_relative "nested_context"
6
+ require_relative "parser"
7
+ require_relative "shell"
8
+ require_relative "line_editor"
9
+ require_relative "util"
10
10
 
11
11
  class Thor
12
- autoload :Actions, "thor/actions"
13
- autoload :RakeCompat, "thor/rake_compat"
14
- autoload :Group, "thor/group"
12
+ autoload :Actions, File.expand_path("actions", __dir__)
13
+ autoload :RakeCompat, File.expand_path("rake_compat", __dir__)
14
+ autoload :Group, File.expand_path("group", __dir__)
15
15
 
16
16
  # Shortcuts for help.
17
17
  HELP_MAPPINGS = %w(-h -? --help -D)
@@ -22,6 +22,15 @@ class Thor
22
22
 
23
23
  TEMPLATE_EXTNAME = ".tt"
24
24
 
25
+ class << self
26
+ def deprecation_warning(message) #:nodoc:
27
+ unless ENV['THOR_SILENCE_DEPRECATION']
28
+ warn "Deprecation warning: #{message}\n" +
29
+ 'You can silence deprecations warning by setting the environment variable THOR_SILENCE_DEPRECATION.'
30
+ end
31
+ end
32
+ end
33
+
25
34
  module Base
26
35
  attr_accessor :options, :parent_options, :args
27
36
 
@@ -42,7 +51,7 @@ class Thor
42
51
  # config<Hash>:: Configuration for this Thor class.
43
52
  #
44
53
  def initialize(args = [], local_options = {}, config = {})
45
- parse_options = config[:current_command] && config[:current_command].disable_class_options ? {} : self.class.class_options
54
+ parse_options = self.class.class_options
46
55
 
47
56
  # The start method splits inbound arguments at the first argument
48
57
  # that looks like an option (starts with - or --). It then calls
@@ -65,7 +74,8 @@ class Thor
65
74
  # declared options from the array. This will leave us with
66
75
  # a list of arguments that weren't declared.
67
76
  stop_on_unknown = self.class.stop_on_unknown_option? config[:current_command]
68
- opts = Thor::Options.new(parse_options, hash_options, stop_on_unknown)
77
+ disable_required_check = self.class.disable_required_check? config[:current_command]
78
+ opts = Thor::Options.new(parse_options, hash_options, stop_on_unknown, disable_required_check)
69
79
  self.options = opts.parse(array_options)
70
80
  self.options = config[:class_options].merge(options) if config[:class_options]
71
81
 
@@ -88,6 +98,7 @@ class Thor
88
98
 
89
99
  class << self
90
100
  def included(base) #:nodoc:
101
+ super(base)
91
102
  base.extend ClassMethods
92
103
  base.send :include, Invocation
93
104
  base.send :include, Shell
@@ -112,7 +123,7 @@ class Thor
112
123
  end
113
124
 
114
125
  # Whenever a class inherits from Thor or Thor::Group, we should track the
115
- # class and the file on Thor::Base. This is the method responsable for it.
126
+ # class and the file on Thor::Base. This is the method responsible for it.
116
127
  #
117
128
  def register_klass_file(klass) #:nodoc:
118
129
  file = caller[1].match(/(.*):\d+/)[1]
@@ -150,6 +161,24 @@ class Thor
150
161
  !!check_unknown_options
151
162
  end
152
163
 
164
+ # If you want to raise an error when the default value of an option does not match
165
+ # the type call check_default_type!
166
+ # This will be the default; for compatibility a deprecation warning is issued if necessary.
167
+ def check_default_type!
168
+ @check_default_type = true
169
+ end
170
+
171
+ # If you want to use defaults that don't match the type of an option,
172
+ # either specify `check_default_type: false` or call `allow_incompatible_default_type!`
173
+ def allow_incompatible_default_type!
174
+ @check_default_type = false
175
+ end
176
+
177
+ def check_default_type #:nodoc:
178
+ @check_default_type = from_superclass(:check_default_type, nil) unless defined?(@check_default_type)
179
+ @check_default_type
180
+ end
181
+
153
182
  # If true, option parsing is suspended as soon as an unknown option or a
154
183
  # regular argument is encountered. All remaining arguments are passed to
155
184
  # the command as regular arguments.
@@ -157,6 +186,12 @@ class Thor
157
186
  false
158
187
  end
159
188
 
189
+ # If true, option set will not suspend the execution of the command when
190
+ # a required option is not provided.
191
+ def disable_required_check?(command_name) #:nodoc:
192
+ false
193
+ end
194
+
160
195
  # If you want only strict string args (useful when cascading thor classes),
161
196
  # call strict_args_position! This is disabled by default to allow dynamic
162
197
  # invocations.
@@ -331,22 +366,22 @@ class Thor
331
366
  # Returns the commands for this Thor class.
332
367
  #
333
368
  # ==== Returns
334
- # OrderedHash:: An ordered hash with commands names as keys and Thor::Command
335
- # objects as values.
369
+ # Hash:: An ordered hash with commands names as keys and Thor::Command
370
+ # objects as values.
336
371
  #
337
372
  def commands
338
- @commands ||= Thor::CoreExt::OrderedHash.new
373
+ @commands ||= Hash.new
339
374
  end
340
375
  alias_method :tasks, :commands
341
376
 
342
377
  # Returns the commands for this Thor class and all subclasses.
343
378
  #
344
379
  # ==== Returns
345
- # OrderedHash:: An ordered hash with commands names as keys and Thor::Command
346
- # objects as values.
380
+ # Hash:: An ordered hash with commands names as keys and Thor::Command
381
+ # objects as values.
347
382
  #
348
383
  def all_commands
349
- @all_commands ||= from_superclass(:all_commands, Thor::CoreExt::OrderedHash.new)
384
+ @all_commands ||= from_superclass(:all_commands, Hash.new)
350
385
  @all_commands.merge!(commands)
351
386
  end
352
387
  alias_method :all_tasks, :all_commands
@@ -393,14 +428,20 @@ class Thor
393
428
  # remove_command :this_is_not_a_command
394
429
  # end
395
430
  #
396
- def no_commands
397
- @no_commands = true
398
- yield
399
- ensure
400
- @no_commands = false
431
+ def no_commands(&block)
432
+ no_commands_context.enter(&block)
401
433
  end
434
+
402
435
  alias_method :no_tasks, :no_commands
403
436
 
437
+ def no_commands_context
438
+ @no_commands_context ||= NestedContext.new
439
+ end
440
+
441
+ def no_commands?
442
+ no_commands_context.entered?
443
+ end
444
+
404
445
  # Sets the namespace for the Thor or Thor::Group class. By default the
405
446
  # namespace is retrieved from the class name. If your Thor class is named
406
447
  # Scripts::MyScript, the help method, for example, will be called as:
@@ -444,13 +485,13 @@ class Thor
444
485
  dispatch(nil, given_args.dup, nil, config)
445
486
  rescue Thor::Error => e
446
487
  config[:debug] || ENV["THOR_DEBUG"] == "1" ? (raise e) : config[:shell].error(e.message)
447
- exit(1) if exit_on_failure?
488
+ exit(false) if exit_on_failure?
448
489
  rescue Errno::EPIPE
449
490
  # This happens if a thor command is piped to something like `head`,
450
491
  # which closes the pipe when it's done reading. This will also
451
492
  # mean that if the pipe is closed, further unnecessary
452
493
  # computation will not occur.
453
- exit(0)
494
+ exit(true)
454
495
  end
455
496
 
456
497
  # Allows to use private methods from parent in child classes as commands.
@@ -471,19 +512,25 @@ class Thor
471
512
  alias_method :public_task, :public_command
472
513
 
473
514
  def handle_no_command_error(command, has_namespace = $thor_runner) #:nodoc:
474
- raise UndefinedCommandError, "Could not find command #{command.inspect} in #{namespace.inspect} namespace." if has_namespace
475
- raise UndefinedCommandError, "Could not find command #{command.inspect}."
515
+ raise UndefinedCommandError.new(command, all_commands.keys, (namespace if has_namespace))
476
516
  end
477
517
  alias_method :handle_no_task_error, :handle_no_command_error
478
518
 
479
519
  def handle_argument_error(command, error, args, arity) #:nodoc:
480
- msg = "ERROR: \"#{basename} #{command.name}\" was called with "
520
+ name = [command.ancestor_name, command.name].compact.join(" ")
521
+ msg = "ERROR: \"#{basename} #{name}\" was called with ".dup
481
522
  msg << "no arguments" if args.empty?
482
523
  msg << "arguments " << args.inspect unless args.empty?
483
- msg << "\nUsage: #{banner(command).inspect}"
524
+ msg << "\nUsage: \"#{banner(command).split("\n").join("\"\n \"")}\""
484
525
  raise InvocationError, msg
485
526
  end
486
527
 
528
+ # A flag that makes the process exit with status 1 if any error happens.
529
+ def exit_on_failure?
530
+ Thor.deprecation_warning "Thor exit with status 0 on errors. To keep this behavior, you must define `exit_on_failure?` in `#{self.name}`"
531
+ false
532
+ end
533
+
487
534
  protected
488
535
 
489
536
  # Prints the class options per group. If an option does not belong to
@@ -541,7 +588,7 @@ class Thor
541
588
  # options<Hash>:: Described in both class_option and method_option.
542
589
  # scope<Hash>:: Options hash that is being built up
543
590
  def build_option(name, options, scope) #:nodoc:
544
- scope[name] = Thor::Option.new(name, options)
591
+ scope[name] = Thor::Option.new(name, {:check_default_type => check_default_type}.merge!(options))
545
592
  end
546
593
 
547
594
  # Receives a hash of options, parse them and add to the scope. This is a
@@ -574,13 +621,15 @@ class Thor
574
621
  # Everytime someone inherits from a Thor class, register the klass
575
622
  # and file into baseclass.
576
623
  def inherited(klass)
624
+ super(klass)
577
625
  Thor::Base.register_klass_file(klass)
578
- klass.instance_variable_set(:@no_commands, false)
626
+ klass.instance_variable_set(:@no_commands, 0)
579
627
  end
580
628
 
581
629
  # Fire this callback whenever a method is added. Added methods are
582
630
  # tracked as commands by invoking the create_command method.
583
631
  def method_added(meth)
632
+ super(meth)
584
633
  meth = meth.to_s
585
634
 
586
635
  if meth == "initialize"
@@ -591,8 +640,7 @@ class Thor
591
640
  # Return if it's not a public instance method
592
641
  return unless public_method_defined?(meth.to_sym)
593
642
 
594
- @no_commands ||= false
595
- return if @no_commands || !create_command(meth)
643
+ return if no_commands? || !create_command(meth)
596
644
 
597
645
  is_thor_reserved_word?(meth, :command)
598
646
  Thor::Base.register_klass_file(self)
@@ -619,11 +667,6 @@ class Thor
619
667
  end
620
668
  end
621
669
 
622
- # A flag that makes the process exit with status 1 if any error happens.
623
- def exit_on_failure?
624
- false
625
- end
626
-
627
670
  #
628
671
  # The basename of the program invoking the thor class.
629
672
  #
data/lib/thor/command.rb CHANGED
@@ -1,9 +1,9 @@
1
1
  class Thor
2
- class Command < Struct.new(:name, :description, :long_description, :usage, :options, :disable_class_options)
2
+ class Command < Struct.new(:name, :description, :long_description, :usage, :options, :ancestor_name)
3
3
  FILE_REGEXP = /^#{Regexp.escape(File.dirname(__FILE__))}/
4
4
 
5
- def initialize(name, description, long_description, usage, options = nil, disable_class_options = false)
6
- super(name.to_s, description, long_description, usage, options || {}, disable_class_options)
5
+ def initialize(name, description, long_description, usage, options = nil)
6
+ super(name.to_s, description, long_description, usage, options || {})
7
7
  end
8
8
 
9
9
  def initialize_copy(other) #:nodoc:
@@ -39,32 +39,42 @@ class Thor
39
39
  # Returns the formatted usage by injecting given required arguments
40
40
  # and required options into the given usage.
41
41
  def formatted_usage(klass, namespace = true, subcommand = false)
42
- if namespace
42
+ if ancestor_name
43
+ formatted = "#{ancestor_name} ".dup # add space
44
+ elsif namespace
43
45
  namespace = klass.namespace
44
- formatted = "#{namespace.gsub(/^(default)/, '')}:"
46
+ formatted = "#{namespace.gsub(/^(default)/, '')}:".dup
45
47
  end
46
- formatted = "#{klass.namespace.split(':').last} " if subcommand
48
+ formatted ||= "#{klass.namespace.split(':').last} ".dup if subcommand
47
49
 
48
- formatted ||= ""
50
+ formatted ||= "".dup
49
51
 
50
- # Add usage with required arguments
51
- formatted << if klass && !klass.arguments.empty?
52
- usage.to_s.gsub(/^#{name}/) do |match|
53
- match << " " << klass.arguments.map(&:usage).compact.join(" ")
54
- end
55
- else
56
- usage.to_s
57
- end
52
+ Array(usage).map do |specific_usage|
53
+ formatted_specific_usage = formatted
58
54
 
59
- # Add required options
60
- formatted << " #{required_options}"
55
+ formatted_specific_usage += required_arguments_for(klass, specific_usage)
61
56
 
62
- # Strip and go!
63
- formatted.strip
57
+ # Add required options
58
+ formatted_specific_usage += " #{required_options}"
59
+
60
+ # Strip and go!
61
+ formatted_specific_usage.strip
62
+ end.join("\n")
64
63
  end
65
64
 
66
65
  protected
67
66
 
67
+ # Add usage with required arguments
68
+ def required_arguments_for(klass, usage)
69
+ if klass && !klass.arguments.empty?
70
+ usage.to_s.gsub(/^#{name}/) do |match|
71
+ match << " " << klass.arguments.map(&:usage).compact.join(" ")
72
+ end
73
+ else
74
+ usage.to_s
75
+ end
76
+ end
77
+
68
78
  def not_debugging?(instance)
69
79
  !(instance.class.respond_to?(:debugging) && instance.class.debugging)
70
80
  end
@@ -95,8 +105,7 @@ class Thor
95
105
  def handle_argument_error?(instance, error, caller)
96
106
  not_debugging?(instance) && (error.message =~ /wrong number of arguments/ || error.message =~ /given \d*, expected \d*/) && begin
97
107
  saned = sans_backtrace(error.backtrace, caller)
98
- # Ruby 1.9 always include the called method in the backtrace
99
- saned.empty? || (saned.size == 1 && RUBY_VERSION >= "1.9")
108
+ saned.empty? || saned.size == 1
100
109
  end
101
110
  end
102
111
 
@@ -28,6 +28,12 @@ class Thor
28
28
  super(convert_key(key))
29
29
  end
30
30
 
31
+ def except(*keys)
32
+ dup.tap do |hash|
33
+ keys.each { |key| hash.delete(convert_key(key)) }
34
+ end
35
+ end
36
+
31
37
  def fetch(key, *args)
32
38
  super(convert_key(key), *args)
33
39
  end
@@ -51,6 +57,18 @@ class Thor
51
57
  self
52
58
  end
53
59
 
60
+ def reverse_merge(other)
61
+ self.class.new(other).merge(self)
62
+ end
63
+
64
+ def reverse_merge!(other_hash)
65
+ replace(reverse_merge(other_hash))
66
+ end
67
+
68
+ def replace(other_hash)
69
+ super(other_hash)
70
+ end
71
+
54
72
  # Convert to a Hash with String keys.
55
73
  def to_hash
56
74
  Hash.new(default).merge!(self)
data/lib/thor/error.rb CHANGED
@@ -1,4 +1,19 @@
1
1
  class Thor
2
+ Correctable = if defined?(DidYouMean::SpellChecker) && defined?(DidYouMean::Correctable) # rubocop:disable Naming/ConstantName
3
+ # In order to support versions of Ruby that don't have keyword
4
+ # arguments, we need our own spell checker class that doesn't take key
5
+ # words. Even though this code wouldn't be hit because of the check
6
+ # above, it's still necessary because the interpreter would otherwise be
7
+ # unable to parse the file.
8
+ class NoKwargSpellChecker < DidYouMean::SpellChecker # :nodoc:
9
+ def initialize(dictionary)
10
+ @dictionary = dictionary
11
+ end
12
+ end
13
+
14
+ DidYouMean::Correctable
15
+ end
16
+
2
17
  # Thor::Error is raised when it's caused by wrong usage of thor classes. Those
3
18
  # errors have their backtrace suppressed and are nicely shown to the user.
4
19
  #
@@ -10,6 +25,35 @@ class Thor
10
25
 
11
26
  # Raised when a command was not found.
12
27
  class UndefinedCommandError < Error
28
+ class SpellChecker
29
+ attr_reader :error
30
+
31
+ def initialize(error)
32
+ @error = error
33
+ end
34
+
35
+ def corrections
36
+ @corrections ||= spell_checker.correct(error.command).map(&:inspect)
37
+ end
38
+
39
+ def spell_checker
40
+ NoKwargSpellChecker.new(error.all_commands)
41
+ end
42
+ end
43
+
44
+ attr_reader :command, :all_commands
45
+
46
+ def initialize(command, all_commands, namespace)
47
+ @command = command
48
+ @all_commands = all_commands
49
+
50
+ message = "Could not find command #{command.inspect}"
51
+ message = namespace ? "#{message} in #{namespace.inspect} namespace." : "#{message}."
52
+
53
+ super(message)
54
+ end
55
+
56
+ prepend Correctable if Correctable
13
57
  end
14
58
  UndefinedTaskError = UndefinedCommandError
15
59
 
@@ -22,6 +66,33 @@ class Thor
22
66
  end
23
67
 
24
68
  class UnknownArgumentError < Error
69
+ class SpellChecker
70
+ attr_reader :error
71
+
72
+ def initialize(error)
73
+ @error = error
74
+ end
75
+
76
+ def corrections
77
+ @corrections ||=
78
+ error.unknown.flat_map { |unknown| spell_checker.correct(unknown) }.uniq.map(&:inspect)
79
+ end
80
+
81
+ def spell_checker
82
+ @spell_checker ||= NoKwargSpellChecker.new(error.switches)
83
+ end
84
+ end
85
+
86
+ attr_reader :switches, :unknown
87
+
88
+ def initialize(switches, unknown)
89
+ @switches = switches
90
+ @unknown = unknown
91
+
92
+ super("Unknown switches #{unknown.map(&:inspect).join(', ')}")
93
+ end
94
+
95
+ prepend Correctable if Correctable
25
96
  end
26
97
 
27
98
  class RequiredArgumentMissingError < InvocationError
@@ -29,4 +100,16 @@ class Thor
29
100
 
30
101
  class MalformattedArgumentError < InvocationError
31
102
  end
103
+
104
+ if Correctable
105
+ if DidYouMean.respond_to?(:correct_error)
106
+ DidYouMean.correct_error(Thor::UndefinedCommandError, UndefinedCommandError::SpellChecker)
107
+ DidYouMean.correct_error(Thor::UnknownArgumentError, UnknownArgumentError::SpellChecker)
108
+ else
109
+ DidYouMean::SPELL_CHECKERS.merge!(
110
+ 'Thor::UndefinedCommandError' => UndefinedCommandError::SpellChecker,
111
+ 'Thor::UnknownArgumentError' => UnknownArgumentError::SpellChecker
112
+ )
113
+ end
114
+ end
32
115
  end
data/lib/thor/group.rb CHANGED
@@ -1,4 +1,4 @@
1
- require "thor/base"
1
+ require_relative "base"
2
2
 
3
3
  # Thor has a special class called Thor::Group. The main difference to Thor class
4
4
  # is that it invokes all commands at once. It also include some methods that allows
@@ -61,7 +61,7 @@ class Thor::Group
61
61
  invocations[name] = false
62
62
  invocation_blocks[name] = block if block_given?
63
63
 
64
- class_eval <<-METHOD, __FILE__, __LINE__
64
+ class_eval <<-METHOD, __FILE__, __LINE__ + 1
65
65
  def _invoke_#{name.to_s.gsub(/\W/, '_')}
66
66
  klass, command = self.class.prepare_for_invocation(nil, #{name.inspect})
67
67
 
@@ -120,7 +120,7 @@ class Thor::Group
120
120
  invocations[name] = true
121
121
  invocation_blocks[name] = block if block_given?
122
122
 
123
- class_eval <<-METHOD, __FILE__, __LINE__
123
+ class_eval <<-METHOD, __FILE__, __LINE__ + 1
124
124
  def _invoke_from_option_#{name.to_s.gsub(/\W/, '_')}
125
125
  return unless options[#{name.inspect}]
126
126
 
@@ -205,7 +205,7 @@ class Thor::Group
205
205
  alias_method :printable_tasks, :printable_commands
206
206
 
207
207
  def handle_argument_error(command, error, _args, arity) #:nodoc:
208
- msg = "#{basename} #{command.name} takes #{arity} argument"
208
+ msg = "#{basename} #{command.name} takes #{arity} argument".dup
209
209
  msg << "s" if arity > 1
210
210
  msg << ", but it should not."
211
211
  raise error, msg
@@ -1,6 +1,7 @@
1
1
  class Thor
2
2
  module Invocation
3
3
  def self.included(base) #:nodoc:
4
+ super(base)
4
5
  base.extend ClassMethods
5
6
  end
6
7
 
@@ -23,6 +23,8 @@ class Thor
23
23
  if echo?
24
24
  $stdin.gets
25
25
  else
26
+ # Lazy-load io/console since it is gem-ified as of 2.3
27
+ require "io/console"
26
28
  $stdin.noecho(&:gets)
27
29
  end
28
30
  end
@@ -1,19 +1,19 @@
1
- begin
2
- require "readline"
3
- rescue LoadError
4
- end
5
-
6
1
  class Thor
7
2
  module LineEditor
8
3
  class Readline < Basic
9
4
  def self.available?
5
+ begin
6
+ require "readline"
7
+ rescue LoadError
8
+ end
9
+
10
10
  Object.const_defined?(:Readline)
11
11
  end
12
12
 
13
13
  def readline
14
14
  if echo?
15
15
  ::Readline.completion_append_character = nil
16
- # Ruby 1.8.7 does not allow Readline.completion_proc= to receive nil.
16
+ # rb-readline does not allow Readline.completion_proc= to receive nil.
17
17
  if complete = completion_proc
18
18
  ::Readline.completion_proc = complete
19
19
  end
@@ -1,5 +1,5 @@
1
- require "thor/line_editor/basic"
2
- require "thor/line_editor/readline"
1
+ require_relative "line_editor/basic"
2
+ require_relative "line_editor/readline"
3
3
 
4
4
  class Thor
5
5
  module LineEditor
@@ -0,0 +1,29 @@
1
+ class Thor
2
+ class NestedContext
3
+ def initialize
4
+ @depth = 0
5
+ end
6
+
7
+ def enter
8
+ push
9
+
10
+ yield
11
+ ensure
12
+ pop
13
+ end
14
+
15
+ def entered?
16
+ @depth > 0
17
+ end
18
+
19
+ private
20
+
21
+ def push
22
+ @depth += 1
23
+ end
24
+
25
+ def pop
26
+ @depth -= 1
27
+ end
28
+ end
29
+ end
@@ -9,7 +9,7 @@ class Thor
9
9
  arguments = []
10
10
 
11
11
  args.each do |item|
12
- break if item =~ /^-/
12
+ break if item.is_a?(String) && item =~ /^-/
13
13
  arguments << item
14
14
  end
15
15
 
@@ -30,7 +30,11 @@ class Thor
30
30
 
31
31
  arguments.each do |argument|
32
32
  if !argument.default.nil?
33
- @assigns[argument.human_name] = argument.default
33
+ begin
34
+ @assigns[argument.human_name] = argument.default.dup
35
+ rescue TypeError # Compatibility shim for un-dup-able Fixnum in Ruby < 2.4
36
+ @assigns[argument.human_name] = argument.default
37
+ end
34
38
  elsif argument.required?
35
39
  @non_assigned_required << argument
36
40
  end
@@ -82,7 +86,7 @@ class Thor
82
86
  end
83
87
 
84
88
  def current_is_value?
85
- peek && peek.to_s !~ /^-/
89
+ peek && peek.to_s !~ /^-{1,2}\S+/
86
90
  end
87
91
 
88
92
  # Runs through the argument array getting strings that contains ":" and