eac_cli 0.37.0 → 0.38.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (39) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +2 -2
  3. data/lib/eac_cli/config/entry.rb +2 -1
  4. data/lib/eac_cli/config.rb +0 -4
  5. data/lib/eac_cli/core_ext.rb +1 -1
  6. data/lib/eac_cli/definition/alternative.rb +28 -7
  7. data/lib/eac_cli/definition/argument_option.rb +2 -2
  8. data/lib/eac_cli/definition/boolean_option.rb +3 -4
  9. data/lib/eac_cli/definition/{base_option → option}/initialize_args_parser.rb +1 -1
  10. data/lib/eac_cli/definition/option.rb +73 -0
  11. data/lib/eac_cli/definition/option_or_positional.rb +43 -0
  12. data/lib/eac_cli/definition/{positional_argument.rb → positional.rb} +14 -22
  13. data/lib/eac_cli/definition.rb +18 -4
  14. data/lib/eac_cli/old_configs/store_passwords_entry_reader.rb +1 -1
  15. data/lib/eac_cli/parser/alternative/any_options.rb +19 -0
  16. data/lib/eac_cli/parser/alternative/argv.rb +2 -0
  17. data/lib/eac_cli/parser/alternative/long_options.rb +1 -1
  18. data/lib/eac_cli/parser/alternative/short_options.rb +11 -4
  19. data/lib/eac_cli/parser/alternative.rb +20 -9
  20. data/lib/eac_cli/parser/collector.rb +10 -1
  21. data/lib/eac_cli/parser.rb +1 -1
  22. data/lib/eac_cli/patches/object.rb +1 -1
  23. data/lib/eac_cli/patches.rb +1 -1
  24. data/lib/eac_cli/rspec.rb +1 -1
  25. data/lib/eac_cli/runner/context_responders/set.rb +2 -2
  26. data/lib/eac_cli/runner/exit.rb +2 -1
  27. data/lib/eac_cli/runner/instance_methods.rb +1 -1
  28. data/lib/eac_cli/runner_with/help/builder/alternative.rb +1 -1
  29. data/lib/eac_cli/runner_with/help/builder.rb +2 -2
  30. data/lib/eac_cli/runner_with/help.rb +1 -0
  31. data/lib/eac_cli/runner_with/subcommands.rb +1 -1
  32. data/lib/eac_cli/runner_with_set.rb +1 -1
  33. data/lib/eac_cli/speaker/list.rb +4 -4
  34. data/lib/eac_cli/speaker/options.rb +3 -3
  35. data/lib/eac_cli/speaker.rb +2 -1
  36. data/lib/eac_cli/version.rb +1 -1
  37. metadata +18 -11
  38. data/lib/eac_cli/definition/base_option.rb +0 -68
  39. data/lib/eac_cli/definition/default_value.rb +0 -17
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 86b393d29e9db3edc24f1bd34bb4f7ade5935892d8c753b400f7737504d8af21
4
- data.tar.gz: 5f609ff444293079bf8f1d21f292aa72d42012814fbbb6c50acc26b56a8d4613
3
+ metadata.gz: 8a58c5ccac3080dd986b2727ce365a7979a801f059016faa0f7fe8dd8b86e1d3
4
+ data.tar.gz: 06cb591e776e862bfcbe048fb524f05a8bd06b3e85a86a14c28df40654355eba
5
5
  SHA512:
6
- metadata.gz: b2fe55eff4ac6b552cd3d6505eae01415e17dd970977f849b320dd8ceddead841537fdaf27675a7751265dd6f6a1e4810e4fd5450ddefd3d6a8a14d989ea9944
7
- data.tar.gz: a2ae31d75a0a7c1aa75597072acce427ee1c3c9a345795ff85111c72f493767f3362826d4bd941ce0e0f3ff947a3e0e64b8198f61db934904452f06f11b0dbd0
6
+ metadata.gz: 3ebf30f86ad003589e75880af90d75058a55c9e76ed386f0a1972c175ed22c2ea8c135c765ff2cf1d7476591126eac66ea680b6f38c96a95a800069a140060fd
7
+ data.tar.gz: 1d2ea1f751023f5a11e2ef8465bab272429e29088e27123830fae2cb041d7ce4524c931c08a2088597664edc638bf6eb775c7a8e2b6ede1af05e09fe02bc7d7f
data/Gemfile CHANGED
@@ -4,5 +4,5 @@ source 'https://rubygems.org'
4
4
 
5
5
  gemspec
6
6
 
7
- local_gemfile = ::File.join(::File.dirname(__FILE__), 'Gemfile.local')
8
- eval_gemfile local_gemfile if ::File.exist?(local_gemfile)
7
+ local_gemfile = File.join(File.dirname(__FILE__), 'Gemfile.local')
8
+ eval_gemfile local_gemfile if File.exist?(local_gemfile)
@@ -22,8 +22,9 @@ module EacCli
22
22
  root_node
23
23
  end
24
24
 
25
+ # @return [Object, nil]
25
26
  def value
26
- value!
27
+ sub_entry.found? ? sub_value_to_return : nil
27
28
  end
28
29
 
29
30
  def value!
@@ -6,10 +6,6 @@ module EacCli
6
6
  class Config < ::SimpleDelegator
7
7
  require_sub __FILE__
8
8
 
9
- def initialize(sub_node)
10
- super(sub_node)
11
- end
12
-
13
9
  def entry(path, options = {})
14
10
  ::EacCli::Config::Entry.new(self, path, options)
15
11
  end
@@ -3,4 +3,4 @@
3
3
  require 'eac_ruby_utils/core_ext'
4
4
  require 'eac_cli/patches'
5
5
 
6
- ::EacCli::RunnerWithSet.default.add_from_gems_registry
6
+ EacCli::RunnerWithSet.default.add_from_gems_registry
@@ -2,14 +2,35 @@
2
2
 
3
3
  require 'eac_cli/definition/argument_option'
4
4
  require 'eac_cli/definition/boolean_option'
5
- require 'eac_cli/definition/positional_argument'
5
+ require 'eac_cli/definition/positional'
6
6
 
7
7
  module EacCli
8
8
  class Definition
9
9
  class Alternative
10
+ ANY_OPTION_DESCRIPTION = 'ANY_OPTION'
11
+ ANY_OPTION_LONG = '__'
12
+ ANY_OPTION_SHORT = '_'
10
13
  SUBCOMMAND_NAME_ARG = :subcommand
11
14
  SUBCOMMAND_ARGS_ARG = :subcommand_args
12
15
 
16
+ # @return [Boolean]
17
+ def any_opt
18
+ @any_opt = true
19
+ end
20
+
21
+ # @return [Boolean]
22
+ def any_option?
23
+ @any_opt ? true : false
24
+ end
25
+
26
+ # @return [EacCli::Definition::BooleanOption]
27
+ def any_options_option
28
+ @any_options_option ||= ::EacCli::Definition::BooleanOption.new(
29
+ ANY_OPTION_SHORT, ANY_OPTION_LONG, ANY_OPTION_DESCRIPTION,
30
+ optional: true, repeat: true, usage: false
31
+ )
32
+ end
33
+
13
34
  def arg_opt(*args)
14
35
  options_set << ::EacCli::Definition::ArgumentOption.from_args(args)
15
36
  end
@@ -33,7 +54,7 @@ module EacCli
33
54
  end
34
55
 
35
56
  def pos_arg(name, arg_options = {})
36
- new_pos_arg = ::EacCli::Definition::PositionalArgument.new(name, arg_options)
57
+ new_pos_arg = ::EacCli::Definition::Positional.new(name, arg_options)
37
58
  check_positional_blocked(new_pos_arg)
38
59
  pos_set << new_pos_arg
39
60
  end
@@ -48,15 +69,15 @@ module EacCli
48
69
  return 'there are subcommands' if subcommands?
49
70
  return 'last argument repeats' if last.repeat?
50
71
  return 'new argument is required and last is optional' if
51
- last.optional? && new_pos_arg.if_present(&:required?)
72
+ last.optional? && new_pos_arg.if_present(&:required?)
52
73
 
53
74
  nil
54
75
  end
55
76
 
56
77
  def subcommands
57
78
  pos_arg(SUBCOMMAND_NAME_ARG, subcommand: true)
58
- pos_set << ::EacCli::Definition::PositionalArgument.new(SUBCOMMAND_ARGS_ARG,
59
- optional: true, repeat: true)
79
+ pos_set << ::EacCli::Definition::Positional.new(SUBCOMMAND_ARGS_ARG,
80
+ optional: true, repeat: true)
60
81
  end
61
82
 
62
83
  def subcommands?
@@ -67,8 +88,8 @@ module EacCli
67
88
 
68
89
  def check_positional_blocked(new_pos_arg)
69
90
  positional_arguments_blocked_reason(new_pos_arg).if_present do |v|
70
- raise ::EacCli::Definition::Error, "Positional arguments are blocked: #{v}" \
71
- " (New argument: #{new_pos_arg})"
91
+ raise ::EacCli::Definition::Error, "Positional arguments are blocked: #{v} " \
92
+ "(New argument: #{new_pos_arg})"
72
93
  end
73
94
  end
74
95
 
@@ -1,10 +1,10 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'eac_cli/definition/base_option'
3
+ require 'eac_cli/definition/option'
4
4
 
5
5
  module EacCli
6
6
  class Definition
7
- class ArgumentOption < ::EacCli::Definition::BaseOption
7
+ class ArgumentOption < ::EacCli::Definition::Option
8
8
  def argument?
9
9
  true
10
10
  end
@@ -1,10 +1,10 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'eac_cli/definition/base_option'
3
+ require 'eac_cli/definition/option'
4
4
 
5
5
  module EacCli
6
6
  class Definition
7
- class BooleanOption < ::EacCli::Definition::BaseOption
7
+ class BooleanOption < ::EacCli::Definition::Option
8
8
  def argument?
9
9
  false
10
10
  end
@@ -16,8 +16,7 @@ module EacCli
16
16
  def default_value
17
17
  return super unless default_value?
18
18
 
19
- raise(::EacCli::Definition::Error,
20
- "Unallowed default value for boolean options (Option: #{self})")
19
+ raise("Unallowed default value for boolean options (Option: #{self})")
21
20
  end
22
21
 
23
22
  def default_default_value
@@ -2,7 +2,7 @@
2
2
 
3
3
  module EacCli
4
4
  class Definition
5
- class BaseOption
5
+ class Option
6
6
  class InitializeArgsParser
7
7
  PROPERTIES = %i[short long description options].freeze
8
8
  attr_reader(*PROPERTIES)
@@ -0,0 +1,73 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'eac_cli/definition/option_or_positional'
4
+ require 'eac_ruby_utils/core_ext'
5
+
6
+ module EacCli
7
+ class Definition
8
+ # @abstract
9
+ class Option < ::EacCli::Definition::OptionOrPositional
10
+ require_sub __FILE__
11
+
12
+ class << self
13
+ # @param args [Enumerable<String>]
14
+ # @return [EacCli::Definition::Option]
15
+ def from_args(args)
16
+ p = ::EacCli::Definition::Option::InitializeArgsParser.new(args)
17
+ new(p.short, p.long, p.description, p.options)
18
+ end
19
+ end
20
+
21
+ DEFAULT_REQUIRED = false
22
+
23
+ enable_abstract_methods
24
+ lists.add_symbol :option, *OPTION_LIST, :default, :usage
25
+
26
+ # @!method initialize(short, long, description, options = {})
27
+ # @param short [String]
28
+ # @param long [String]
29
+ # @param description [String]
30
+ # @param options [Hash<Symbol, Object>]
31
+ # @raise [EacCli::Definition::Error]
32
+ common_constructor :short, :long, :description, :options, default: [{}] do
33
+ validate
34
+ self.options = ::EacCli::Definition::Option.lists.option.hash_keys_validate!(
35
+ options.symbolize_keys
36
+ )
37
+ end
38
+
39
+ # @return [Object]
40
+ def default_value
41
+ default_value? ? options[OPTION_DEFAULT] : default_default_value
42
+ end
43
+
44
+ # @return [Boolean]
45
+ def default_value?
46
+ options.key?(OPTION_DEFAULT)
47
+ end
48
+
49
+ # @return [Symbol]
50
+ # @raise [EacCli::Definition::Error] If no short or long option is provided.
51
+ def identifier
52
+ [long, short].each do |v|
53
+ v.to_s.if_present { |vv| return vv.variableize.to_sym }
54
+ end
55
+
56
+ raise('No short or long option to build identifier')
57
+ end
58
+
59
+ # @return [Boolean]
60
+ def show_on_usage?
61
+ options[:usage]
62
+ end
63
+
64
+ private
65
+
66
+ # @return [void]
67
+ # @raise [EacCli::Definition::Error]
68
+ def validate
69
+ raise 'Nor short neither long selector was set' if short.blank? && long.blank?
70
+ end
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'eac_ruby_utils/core_ext'
4
+
5
+ module EacCli
6
+ class Definition
7
+ # @abstract
8
+ class OptionOrPositional
9
+ acts_as_abstract :build_value, :default_value, :identifier, :options
10
+ enable_listable
11
+
12
+ OPTION_LIST = %i[optional repeat required].freeze
13
+
14
+ # @return [Boolean]
15
+ def optional?
16
+ !required?
17
+ end
18
+
19
+ # @raise [EacCli::Definition::Error]
20
+ def raise(*args)
21
+ ::Kernel.raise ::EacCli::Definition::Error, *args
22
+ end
23
+
24
+ # @return [Boolean]
25
+ def repeat?
26
+ options[:repeat] ? true : false
27
+ end
28
+
29
+ # @return [Boolean]
30
+ def required?
31
+ return true if options.key?(:required) && options.fetch(:required)
32
+ return false if options.key?(:optional) && options.fetch(:optional)
33
+
34
+ self.class.const_get('DEFAULT_REQUIRED')
35
+ end
36
+
37
+ # @return [String]
38
+ def to_s
39
+ "#{self.class.name.demodulize}[#{identifier}]"
40
+ end
41
+ end
42
+ end
43
+ end
@@ -1,19 +1,26 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'eac_cli/definition/option_or_positional'
3
4
  require 'eac_ruby_utils/core_ext'
4
5
 
5
6
  module EacCli
6
7
  class Definition
7
- class PositionalArgument
8
+ class Positional < ::EacCli::Definition::OptionOrPositional
8
9
  DEFAULT_REQUIRED = true
9
10
  DEFAULT_VISIBLE = true
10
11
 
11
- enable_listable
12
- lists.add_symbol :option, :optional, :repeat, :required, :subcommand, :visible
12
+ lists.add_symbol :option, *OPTION_LIST, :subcommand, :visible
13
+
14
+ # @!method initialize(name, options = {})
15
+ # @param name [String]
16
+ # @param options [Hash<Symbol, Object>]
13
17
  common_constructor :name, :options, default: [{}] do
14
18
  options.assert_valid_keys(self.class.lists.option.values)
15
19
  end
16
20
 
21
+ # @param new_value [Array, Object]
22
+ # @param previous_value [Array, Object]
23
+ # @return [Array]
17
24
  def build_value(new_value, previous_value)
18
25
  if previous_value.is_a?(::Array)
19
26
  previous_value + [new_value]
@@ -22,37 +29,22 @@ module EacCli
22
29
  end
23
30
  end
24
31
 
32
+ # @return [Object]
25
33
  def default_value
26
34
  repeat? ? [] : nil
27
35
  end
28
36
 
37
+ # @return [Symbol]
29
38
  def identifier
30
39
  name.to_s.variableize.to_sym
31
40
  end
32
41
 
33
- def optional?
34
- !required?
35
- end
36
-
37
- def repeat?
38
- options[OPTION_REPEAT]
39
- end
40
-
41
- def required?
42
- return true if options.key?(OPTION_REQUIRED) && options.fetch(OPTION_REQUIRED)
43
- return false if options.key?(OPTION_OPTIONAL) && options.fetch(OPTION_OPTIONAL)
44
-
45
- DEFAULT_REQUIRED
46
- end
47
-
42
+ # @return [Boolean]
48
43
  def subcommand?
49
44
  options[OPTION_SUBCOMMAND]
50
45
  end
51
46
 
52
- def to_s
53
- "#{self.class.name.demodulize}[#{identifier}]"
54
- end
55
-
47
+ # @return [Boolean]
56
48
  def visible?
57
49
  options.key?(OPTION_VISIBLE) ? options.fetch(OPTION_VISIBLE) : DEFAULT_VISIBLE
58
50
  end
@@ -2,7 +2,7 @@
2
2
 
3
3
  require 'eac_cli/definition/argument_option'
4
4
  require 'eac_cli/definition/boolean_option'
5
- require 'eac_cli/definition/positional_argument'
5
+ require 'eac_cli/definition/positional'
6
6
  require 'eac_ruby_utils/core_ext'
7
7
 
8
8
  module EacCli
@@ -13,6 +13,7 @@ module EacCli
13
13
  SUBCOMMAND_NAME_ARG = 'subcommand'
14
14
  SUBCOMMAND_ARGS_ARG = 'subcommand_args'
15
15
 
16
+ # @return [String, nil]
16
17
  attr_accessor :description
17
18
 
18
19
  def initialize
@@ -20,25 +21,35 @@ module EacCli
20
21
  alternatives_set[MAIN_ALTERNATIVE_KEY] = main_alternative
21
22
  end
22
23
 
23
- def alt(&block)
24
+ # @return [EacCli::Definition::Alternative]
25
+ def alt(key = nil, &block)
26
+ key ||= new_alternative_key
27
+ raise(::EacCli::Definition::Error, "A alternative with key=\"#{key}\" already exists") if
28
+ key.present? && alternatives_set.key?(key)
29
+
24
30
  r = ::EacCli::Definition::Alternative.new
25
31
  r.instance_eval(&block)
26
- alternatives_set[new_alternative_key] = r
32
+ alternatives_set[key] = r
27
33
  r
28
34
  end
29
35
 
36
+ # @return [Enumerable<EacCli::Definition::Alternative>]
30
37
  def alternatives
31
38
  alternatives_set.values
32
39
  end
33
40
 
41
+ # @return [EacCli::Definition::Alternative]
42
+ # @raise [KeyError] If there is not a alternative with provided key.
34
43
  def alternative(key)
35
44
  alternatives_set.fetch(key)
36
45
  end
37
46
 
47
+ # Same as {#description=}.
38
48
  def desc(description)
39
49
  self.description = description
40
50
  end
41
51
 
52
+ # @return [EacCli::Definition::Alternative]
42
53
  def main_alternative
43
54
  @main_alternative ||= begin
44
55
  r = ::EacCli::Definition::Alternative.new
@@ -47,10 +58,13 @@ module EacCli
47
58
  end
48
59
  end
49
60
 
61
+ # Same as {#options_argument=}.
62
+ # @param options_argument [Boolean]
50
63
  def options_arg(options_argument)
51
64
  self.options_argument = options_argument
52
65
  end
53
66
 
67
+ # @return [Boolean]
54
68
  def options_argument
55
69
  main_alternative.options_argument?
56
70
  end
@@ -66,7 +80,7 @@ module EacCli
66
80
  alternatives.any?(&:subcommands?)
67
81
  end
68
82
 
69
- def options_first(enable = true)
83
+ def options_first(enable = true) # rubocop:disable Style/OptionalBooleanParameter
70
84
  @options_first = enable
71
85
  end
72
86
 
@@ -17,7 +17,7 @@ module EacCli
17
17
  def banner
18
18
  infom 'Do you wanna to store passwords?'
19
19
  infom 'Warning: the passwords will be store in clear text in ' \
20
- "\"#{console_configs.configs.storage_path}\""
20
+ "\"#{console_configs.configs.storage_path}\""
21
21
  infom 'Enter "yes" or "no"'
22
22
  end
23
23
  end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'eac_ruby_utils/core_ext'
4
+
5
+ module EacCli
6
+ class Parser
7
+ class Alternative
8
+ module AnyOptions
9
+ delegate :any_option?, to: :alternative
10
+
11
+ # @return [EacCli::Definition::BooleanOption] if #any_option? is true.
12
+ # @raise [EacCli::Parser::Error] if #any_option? is false.
13
+ def any_option_collect_option
14
+ any_option? ? alternative.any_options_option : raise_argv_current_invalid_option
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -4,10 +4,12 @@ module EacCli
4
4
  class Parser
5
5
  class Alternative
6
6
  module Argv
7
+ # @return [Enumerator<String>]
7
8
  def argv_enum
8
9
  @argv_enum ||= argv.each
9
10
  end
10
11
 
12
+ # @return [Boolean]
11
13
  def argv_pending?
12
14
  argv_enum.ongoing?
13
15
  end
@@ -24,7 +24,7 @@ module EacCli
24
24
  else
25
25
  option_argument_collect(option, value)
26
26
  end
27
- end || raise_argv_current_invalid_option
27
+ end || any_option_collect_option
28
28
  end
29
29
 
30
30
  def parse_option_current_argv
@@ -5,23 +5,29 @@ module EacCli
5
5
  class Alternative
6
6
  module ShortOptions
7
7
  SHORT_OPTION_PREFIX = '-'
8
+ SHORT_OPTION_CHAR_PATTERN = /\A[0-9a-zA-Z]\z/.freeze
8
9
 
9
10
  private
10
11
 
12
+ # @return [Boolean]
11
13
  def argv_current_short_option?
12
14
  phase == PHASE_ANY && argv_enum.peek.start_with?(SHORT_OPTION_PREFIX) &&
13
15
  !argv_current_long_option?
14
16
  end
15
17
 
18
+ # @para char [String]
19
+ # @return [EacCli::Definition::Option, nil]
16
20
  def find_short_option(char)
17
21
  alternative.options.find do |option|
18
22
  short_without_prefix(option.short).if_present(false) { |v| v == char }
19
23
  end
20
24
  end
21
25
 
26
+ # @return [void]
22
27
  def short_option_collect_argv_value
23
28
  last_option = nil
24
29
  short_without_prefix(argv_enum.peek).each_char do |char|
30
+ raise_error "Invalid option: \"#{char}\"" unless SHORT_OPTION_CHAR_PATTERN.match?(char)
25
31
  raise_error "Option \"#{last_option}\" requires a argument not provided" if
26
32
  last_option.present?
27
33
 
@@ -30,14 +36,15 @@ module EacCli
30
36
  end
31
37
  end
32
38
 
33
- # @return [EacCli::Definition::BaseOption] The option collected.
39
+ # @param char [String]
40
+ # @return [EacCli::Definition::Option] The option collected.
34
41
  def short_option_collect_char(char)
35
42
  option = find_short_option(char)
36
- raise_argv_current_invalid_option unless option
37
-
38
- option_collect_option(option)
43
+ option ? option_collect_option(option) : any_option_collect_option
39
44
  end
40
45
 
46
+ # @param short [String]
47
+ # @return [String]
41
48
  def short_without_prefix(short)
42
49
  short.to_s.gsub(/\A#{::Regexp.quote(SHORT_OPTION_PREFIX)}/, '')
43
50
  end
@@ -10,30 +10,40 @@ module EacCli
10
10
  require_sub __FILE__, include_modules: true
11
11
  enable_listable
12
12
  lists.add_symbol :phase, :any, :option_argument, :positional
13
+
14
+ # @return [EacCli::Parser::Error, nil]
13
15
  attr_reader :error
14
16
 
17
+ # @!method initialize(alternative, argv)
18
+ # @param alternative [EacCli::Definition::Alternative]
19
+ # @param argv [Array<String>]
15
20
  common_constructor :alternative, :argv do
16
21
  alternative.assert_argument(::EacCli::Definition::Alternative, :alternative)
17
22
  self.phase = PHASE_ANY
18
23
  collect
19
24
  end
20
25
 
26
+ # @return [Boolean]
21
27
  def error?
22
28
  error.present?
23
29
  end
24
30
 
31
+ # @return [Boolean]
25
32
  def success?
26
33
  !error?
27
34
  end
28
35
 
36
+ # @return [EacRubyUtils::Struct]
29
37
  def parsed
30
38
  @parsed ||= collector.to_data.freeze
31
39
  end
32
40
 
33
41
  private
34
42
 
43
+ # @return [Symbol]
35
44
  attr_accessor :phase
36
45
 
46
+ # @return [void]
37
47
  def any_collect_argv_value
38
48
  %w[double_dash long_option short_option].each do |arg_type|
39
49
  return send("#{arg_type}_collect_argv_value") if send("argv_current_#{arg_type}?")
@@ -42,10 +52,12 @@ module EacCli
42
52
  positional_collect_argv_value
43
53
  end
44
54
 
55
+ # @return [EacCli::Parser::Collector]
45
56
  def collector
46
57
  @collector ||= ::EacCli::Parser::Collector.new(alternative)
47
58
  end
48
59
 
60
+ # @return [void]
49
61
  def collect
50
62
  loop do
51
63
  break unless argv_pending?
@@ -57,30 +69,29 @@ module EacCli
57
69
  @error = e
58
70
  end
59
71
 
72
+ # @return [void]
60
73
  def collect_argv_value
61
74
  send("#{phase}_collect_argv_value")
62
75
  argv_enum.next
63
76
  end
64
77
 
65
- def collect_option_argv_value
66
- alternative.options.each do |option|
67
- end
68
-
69
- raise ::EacCli::Parser::Error.new(
70
- alternative, argv, "Invalid option: #{argv_enum.current}"
71
- )
72
- end
73
-
78
+ # @param message [String]
79
+ # @raise [EacCli::Parser::Error] Always.
74
80
  def raise_error(message)
75
81
  raise ::EacCli::Parser::Error.new(alternative, argv, message)
76
82
  end
77
83
 
84
+ # @return [void]
85
+ # @raise [EacCli::Parser::Error] If options where not properly supplied.
78
86
  def validate
79
87
  (alternative.options + alternative.positional).each do |option|
80
88
  validate_option(option)
81
89
  end
82
90
  end
83
91
 
92
+ # @param option [EacCli::Definition::Option, EacCli::Definition::Positional]
93
+ # @return [void]
94
+ # @raise [EacCli::Parser::Error] If option was not properly supplied.
84
95
  def validate_option(option)
85
96
  return unless option.required?
86
97
  return if collector.supplied?(option)
@@ -14,29 +14,38 @@ module EacCli
14
14
  end
15
15
  end
16
16
 
17
+ # @!method initialize(definition)
18
+ # @param definition [EacCli::Definition]
17
19
  common_constructor :definition do
18
20
  default_values
19
21
  end
20
22
 
21
- # @return [OpenStruct]
23
+ # @return [EacRubyUtils::Struct]
22
24
  def to_data
23
25
  ::EacRubyUtils::Struct.new(data.transform_keys(&:identifier))
24
26
  end
25
27
 
28
+ # @param option [EacCli::Definition::Option]
29
+ # @param value [String]
30
+ # @return [void]
26
31
  def collect(option, value)
27
32
  data[option] = option.build_value(value, data[option])
28
33
  end
29
34
 
35
+ # @param option [EacCli::Definition::Option]
36
+ # @return [Boolean]
30
37
  def supplied?(option)
31
38
  data[option].present?
32
39
  end
33
40
 
34
41
  private
35
42
 
43
+ # @return [Hash]
36
44
  def data
37
45
  @data ||= {}
38
46
  end
39
47
 
48
+ # @return [void]
40
49
  def default_values
41
50
  definition.options.each { |option| data[option] = option.default_value }
42
51
  definition.positional.each { |positional| data[positional] = positional.default_value }
@@ -12,7 +12,7 @@ module EacCli
12
12
 
13
13
  def parsed_uncached
14
14
  raise 'Definition has no alternatives' if alternatives.empty?
15
- raise first_error unless alternatives.select(&:success?).any?
15
+ raise first_error unless alternatives.any?(&:success?)
16
16
 
17
17
  alternatives_parsed(true).merge(alternatives_parsed(false))
18
18
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- Dir["#{File.dirname(__FILE__)}/#{::File.basename(__FILE__, '.*')}/*.rb"].sort.each do |path|
3
+ Dir["#{File.dirname(__FILE__)}/#{File.basename(__FILE__, '.*')}/*.rb"].sort.each do |path|
4
4
  require path
5
5
  end
@@ -1,4 +1,4 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'eac_ruby_utils/require_sub'
4
- ::EacRubyUtils.require_sub(__FILE__)
4
+ EacRubyUtils.require_sub(__FILE__)
data/lib/eac_cli/rspec.rb CHANGED
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'eac_ruby_utils/core_exts'
3
+ require 'eac_ruby_utils/core_ext'
4
4
 
5
5
  module EacCli
6
6
  module Rspec
@@ -18,9 +18,9 @@ module EacCli
18
18
  responders_instances.any?(&:callable?)
19
19
  end
20
20
 
21
- def call(*args, &block)
21
+ def call(...)
22
22
  caller = responder_to_call
23
- return caller.call(*args, &block) if caller
23
+ return caller.call(...) if caller
24
24
 
25
25
  raise ::NameError, "No method \"#{method_name}\" found in #{runner} or in its ancestors"
26
26
  end
@@ -5,7 +5,8 @@ module EacCli
5
5
  class Exit < ::StandardError
6
6
  attr_reader :status
7
7
 
8
- def initialize(status = true)
8
+ def initialize(status = true) # rubocop:disable Style/OptionalBooleanParameter
9
+ super
9
10
  @status = status
10
11
  end
11
12
  end
@@ -6,7 +6,7 @@ module EacCli
6
6
  def run_run
7
7
  parsed
8
8
  run_callbacks(:run) { run }
9
- rescue ::EacCli::Runner::Exit # rubocop:disable Lint/SuppressedException
9
+ rescue ::EacCli::Runner::Exit
10
10
  # Do nothing
11
11
  end
12
12
 
@@ -35,7 +35,7 @@ module EacCli
35
35
  end
36
36
 
37
37
  def positionals
38
- alternative.positional.map { |p| positional(p) }.reject(&:blank?)
38
+ alternative.positional.map { |p| positional(p) }.compact_blank
39
39
  end
40
40
 
41
41
  def positional(positional)
@@ -26,7 +26,7 @@ module EacCli
26
26
 
27
27
  def option_usage_full(option)
28
28
  if option.long.present?
29
- [option.short, option_long(option)].reject(&:blank?).join(word_separator)
29
+ [option.short, option_long(option)].compact_blank.join(word_separator)
30
30
  else
31
31
  option_short(option)
32
32
  end
@@ -53,7 +53,7 @@ module EacCli
53
53
  def option_definition(option)
54
54
  [self.class.option_usage_full(option), option.description,
55
55
  option.default_value? ? "[Default: \"#{option.default_value}\"]" : nil]
56
- .reject(&:blank?).join(OPTION_DESCRIPTION_SEPARATOR)
56
+ .compact_blank.join(OPTION_DESCRIPTION_SEPARATOR)
57
57
  end
58
58
 
59
59
  # @return [String]
@@ -12,6 +12,7 @@ module EacCli
12
12
 
13
13
  runner_definition.alt do
14
14
  bool_opt '-h', '--help', 'Show help.', usage: true, required: true
15
+ any_opt
15
16
  pos_arg :any_arg_with_help, repeat: true, optional: true, visible: false
16
17
  end
17
18
 
@@ -105,7 +105,7 @@ module EacCli
105
105
  raise(::EacCli::Parser::Error.new(
106
106
  self.class.runner_definition, runner_context.argv,
107
107
  "Subcommand \"#{subcommand_name}\" not found " \
108
- "(Available: #{available_subcommands_to_s})"
108
+ "(Available: #{available_subcommands_to_s})"
109
109
  ))
110
110
  end
111
111
 
@@ -33,7 +33,7 @@ module EacCli
33
33
  private
34
34
 
35
35
  def namespace_set
36
- @namespace_set ||= ::Array.new
36
+ @namespace_set ||= []
37
37
  end
38
38
 
39
39
  def key_to_module(key)
@@ -17,11 +17,11 @@ module EacCli
17
17
  private
18
18
 
19
19
  def hash_to_values(list)
20
- list.map { |key, value| ::OpenStruct.new(key: key, label: key, value: value) }
20
+ list.map { |key, value| ::OpenStruct.new(key: key, label: key, value: value) } # rubocop:disable Style/OpenStructUse
21
21
  end
22
22
 
23
23
  def array_to_values(list)
24
- list.map { |value| ::OpenStruct.new(key: value, label: value, value: value) }
24
+ list.map { |value| ::OpenStruct.new(key: value, label: value, value: value) } # rubocop:disable Style/OpenStructUse
25
25
  end
26
26
  end
27
27
 
@@ -29,7 +29,7 @@ module EacCli
29
29
 
30
30
  def initialize(values)
31
31
  @values = values.map do |v|
32
- ::OpenStruct.new(key: to_key(v.key), label: to_label(v.label), value: v.value)
32
+ ::OpenStruct.new(key: to_key(v.key), label: to_label(v.label), value: v.value) # rubocop:disable Style/OpenStructUse
33
33
  end
34
34
  end
35
35
 
@@ -51,7 +51,7 @@ module EacCli
51
51
 
52
52
  def build_value(value)
53
53
  key = to_key(value)
54
- values.each do |v| # rubocop:disable Style/HashEachMethods
54
+ values.each do |v|
55
55
  return v.value if v.key == key
56
56
  end
57
57
  raise "Value not found: \"#{value}\" (#{values})"
@@ -11,15 +11,15 @@ module EacCli
11
11
  end
12
12
 
13
13
  def err_out
14
- option(OPTION_ERR_OUT, ::EacCli::Speaker::STDERR)
14
+ option(OPTION_ERR_OUT, $stderr)
15
15
  end
16
16
 
17
17
  def out_out
18
- option(OPTION_OUT_OUT, ::EacCli::Speaker::STDOUT)
18
+ option(OPTION_OUT_OUT, $stdout)
19
19
  end
20
20
 
21
21
  def in_in
22
- option(OPTION_IN_IN, ::EacCli::Speaker::STDIN)
22
+ option(OPTION_IN_IN, $stdin)
23
23
  end
24
24
 
25
25
  def err_line_prefix
@@ -83,7 +83,8 @@ module EacCli
83
83
  def list_value(list, input)
84
84
  values = list_values(list)
85
85
  return input, true unless values
86
- return input, false unless values.include?(input)
86
+
87
+ [input, false] unless values.include?(input)
87
88
  end
88
89
 
89
90
  def list_values(list)
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module EacCli
4
- VERSION = '0.37.0'
4
+ VERSION = '0.38.1'
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: eac_cli
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.37.0
4
+ version: 0.38.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Esquilo Azul Company
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-07-22 00:00:00.000000000 Z
11
+ date: 2023-11-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: colorize
@@ -37,6 +37,9 @@ dependencies:
37
37
  - - "~>"
38
38
  - !ruby/object:Gem::Version
39
39
  version: '0.14'
40
+ - - ">="
41
+ - !ruby/object:Gem::Version
42
+ version: 0.14.1
40
43
  type: :runtime
41
44
  prerelease: false
42
45
  version_requirements: !ruby/object:Gem::Requirement
@@ -44,6 +47,9 @@ dependencies:
44
47
  - - "~>"
45
48
  - !ruby/object:Gem::Version
46
49
  version: '0.14'
50
+ - - ">="
51
+ - !ruby/object:Gem::Version
52
+ version: 0.14.1
47
53
  - !ruby/object:Gem::Dependency
48
54
  name: eac_ruby_utils
49
55
  requirement: !ruby/object:Gem::Requirement
@@ -53,7 +59,7 @@ dependencies:
53
59
  version: '0.119'
54
60
  - - ">="
55
61
  - !ruby/object:Gem::Version
56
- version: 0.119.1
62
+ version: 0.119.2
57
63
  type: :runtime
58
64
  prerelease: false
59
65
  version_requirements: !ruby/object:Gem::Requirement
@@ -63,21 +69,21 @@ dependencies:
63
69
  version: '0.119'
64
70
  - - ">="
65
71
  - !ruby/object:Gem::Version
66
- version: 0.119.1
72
+ version: 0.119.2
67
73
  - !ruby/object:Gem::Dependency
68
74
  name: eac_ruby_gem_support
69
75
  requirement: !ruby/object:Gem::Requirement
70
76
  requirements:
71
77
  - - "~>"
72
78
  - !ruby/object:Gem::Version
73
- version: 0.5.1
79
+ version: '0.9'
74
80
  type: :development
75
81
  prerelease: false
76
82
  version_requirements: !ruby/object:Gem::Requirement
77
83
  requirements:
78
84
  - - "~>"
79
85
  - !ruby/object:Gem::Version
80
- version: 0.5.1
86
+ version: '0.9'
81
87
  description:
82
88
  email:
83
89
  executables: []
@@ -95,12 +101,12 @@ files:
95
101
  - lib/eac_cli/definition.rb
96
102
  - lib/eac_cli/definition/alternative.rb
97
103
  - lib/eac_cli/definition/argument_option.rb
98
- - lib/eac_cli/definition/base_option.rb
99
- - lib/eac_cli/definition/base_option/initialize_args_parser.rb
100
104
  - lib/eac_cli/definition/boolean_option.rb
101
- - lib/eac_cli/definition/default_value.rb
102
105
  - lib/eac_cli/definition/error.rb
103
- - lib/eac_cli/definition/positional_argument.rb
106
+ - lib/eac_cli/definition/option.rb
107
+ - lib/eac_cli/definition/option/initialize_args_parser.rb
108
+ - lib/eac_cli/definition/option_or_positional.rb
109
+ - lib/eac_cli/definition/positional.rb
104
110
  - lib/eac_cli/enum.rb
105
111
  - lib/eac_cli/old_configs.rb
106
112
  - lib/eac_cli/old_configs/entry_reader.rb
@@ -109,6 +115,7 @@ files:
109
115
  - lib/eac_cli/old_configs/store_passwords_entry_reader.rb
110
116
  - lib/eac_cli/parser.rb
111
117
  - lib/eac_cli/parser/alternative.rb
118
+ - lib/eac_cli/parser/alternative/any_options.rb
112
119
  - lib/eac_cli/parser/alternative/argv.rb
113
120
  - lib/eac_cli/parser/alternative/double_dash.rb
114
121
  - lib/eac_cli/parser/alternative/long_options.rb
@@ -173,7 +180,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
173
180
  requirements:
174
181
  - - ">="
175
182
  - !ruby/object:Gem::Version
176
- version: '0'
183
+ version: 2.7.0
177
184
  required_rubygems_version: !ruby/object:Gem::Requirement
178
185
  requirements:
179
186
  - - ">="
@@ -1,68 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'eac_cli/definition/default_value'
4
- require 'eac_ruby_utils/core_ext'
5
-
6
- module EacCli
7
- class Definition
8
- class BaseOption
9
- require_sub __FILE__
10
- include ::EacCli::Definition::DefaultValue
11
-
12
- class << self
13
- def from_args(args)
14
- p = ::EacCli::Definition::BaseOption::InitializeArgsParser.new(args)
15
- new(p.short, p.long, p.description, p.options)
16
- end
17
- end
18
-
19
- DEFAULT_REQUIRED = false
20
-
21
- enable_listable
22
- enable_abstract_methods :build_value
23
- lists.add_symbol :option, :default, :optional, :usage, :repeat, :required
24
- common_constructor :short, :long, :description, :options, default: [{}] do
25
- raise 'Nor short neither long selector was set' if short.blank? && long.blank?
26
-
27
- self.options = ::EacCli::Definition::BaseOption.lists.option.hash_keys_validate!(
28
- options.symbolize_keys
29
- )
30
- end
31
-
32
- def default_value
33
- default_value? ? options[OPTION_DEFAULT] : default_default_value
34
- end
35
-
36
- def default_value?
37
- options.key?(OPTION_DEFAULT)
38
- end
39
-
40
- def identifier
41
- [long, short].each do |v|
42
- v.to_s.if_present { |vv| return vv.variableize.to_sym }
43
- end
44
-
45
- raise(::EacCli::Definition::Error, 'No short or long option to build identifier')
46
- end
47
-
48
- def repeat?
49
- options[OPTION_REPEAT]
50
- end
51
-
52
- def required?
53
- return true if options.key?(:required) && options.fetch(:required)
54
- return false if options.key?(:optional) && options.fetch(:optional)
55
-
56
- DEFAULT_REQUIRED
57
- end
58
-
59
- def to_s
60
- "#{self.class.name.demodulize}[#{identifier}]"
61
- end
62
-
63
- def show_on_usage?
64
- options[:usage]
65
- end
66
- end
67
- end
68
- end
@@ -1,17 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'eac_ruby_utils/core_ext'
4
-
5
- module EacCli
6
- class Definition
7
- module DefaultValue
8
- def default_value
9
- default_value? ? options[OPTION_DEFAULT] : default_default_value
10
- end
11
-
12
- def default_value?
13
- options.key?(OPTION_DEFAULT)
14
- end
15
- end
16
- end
17
- end