lib/eco/cli/config/options_set.rb in eco-helpers-2.0.16 vs lib/eco/cli/config/options_set.rb in eco-helpers-2.0.17
- old
+ new
@@ -3,47 +3,140 @@
class Config
class OptionsSet
include Eco::CLI::Config::Help
attr_reader :core_config
+ class OptConfig < Struct.new(:name, :namespace, :description, :callback)
+ end
+
def initialize(core_config:)
@core_config = core_config
- @options_set = {}
- @description = {}
+ @sets = {}
end
# @return [String] summary of the options.
def help
+ indent = 2
+ spaces = any_non_general_space_active? ? active_namespaces : namespaces
+
["The following are the available options:"].yield_self do |lines|
- max_len = keys_max_len(@options_set.keys)
- @options_set.keys.each do |key|
- lines << help_line(key, @description[key], max_len)
+ max_len = keys_max_len(options_args(spaces)) + indent
+ spaces.each do |namespace|
+ is_general = (namespace == :general)
+ str_indent = is_general ? "" : " " * indent
+ lines << help_line(namespace, "", max_len) unless is_general
+ options_set(namespace).each do |arg, option|
+ lines << help_line(" " * indent + "#{option.name}", option.description, max_len)
+ end
end
lines
end.join("\n")
end
- # @param option [String] the command line option.
+ # @return [Array<String>] all the argument of the options in `namespaces`
+ def options_args(namespaces)
+ namespaces.each_with_object([]) do |space, args|
+ args.concat(options_set(space).keys)
+ end.uniq
+ end
+
+ # @param option [String, Array<String>] the command line option(s).
+ # @param namespace [String] preceding command(s) argument that enables this option.
# @param desc [String] description of the option.
- def add(option, desc = nil)
+ def add(option, desc = nil, namespace: :general)
raise "Missing block to define the options builder" unless block_given?
- callback = Proc.new
- [option].flatten.compact.each do |opt|
- @options_set[opt] = callback
- @description[opt] = desc
+
+ opts = [option].flatten.compact
+ unless opts.empty?
+ callback = Proc.new
+ opts.each do |opt|
+ puts "Overriding option '#{option}' in '#{namespace}' namespace" if option_exists?(opt, namespace)
+ options_set(namespace)[opt] = OptConfig.new(opt, namespace, desc, callback)
+ end
end
self
end
def process(io:)
unless io && io.is_a?(Eco::API::UseCases::BaseIO)
raise "You need to provide Eco::API::UseCases::BaseIO object. Given: #{io.class}"
end
- @options_set.each do |arg, callback|
- callback.call(io.options, io.session) if SCR.get_arg(arg)
+ active_options.each do |option|
+ option.callback.call(io.options, io.session)
end
+
io.options
+ end
+
+ def active_options
+ @active_options ||= sets.select do |namespace, opts_set|
+ active_namespace?(namespace)
+ end.each_with_object([]) do |(namespace, opts_set), options|
+ opts_set.each do |arg, option|
+ options << option if active_option?(arg, namespace)
+ end
+ end
+ end
+
+ def all_options
+ sets.each_with_object([]) do |(namespace, opts_set), options|
+ options << opts_set.values
+ end
+ end
+
+ def namespaces
+ sets.keys.sort_by do |key|
+ key == :general
+ end
+ end
+
+ def any_non_general_space_active?
+ (active_namespaces - [:general]).length > 0
+ end
+
+ def active_namespaces
+ @active_namespaces ||= [].tap do |active|
+ active << :general
+ other = (namespaces - [:general]).select {|nm| SCR.arg?(nm)}
+ active.concat(other)
+ end
+ end
+
+
+ private
+
+ def active_namespace?(namespace)
+ (namespace == :general) || SCR.get_arg(namespace)
+ end
+
+ # Is the option active?
+ # 1. If :general namespace, it does just a direct check
+ # 2. Otherwise, the `namespace` wording should come first in the `cli` or it is considered inactive
+ def active_option?(opt, namespace = :general)
+ if namespace == :general
+ SCR.get_arg(opt)
+ else
+ active_namespace?(namespace) && SCR.arg_order?(namespace, opt) && SCR.get_arg(opt)
+ end
+ end
+
+ def option_exists?(opt, namespace = :general)
+ options_set(namespace).key?(opt)
+ end
+
+ def sets
+ @sets ||= {
+ general: {}
+ }
+ end
+
+ def namespaces
+ @sets.keys
+ end
+
+ def options_set(namespace = :general)
+ @sets[namespace] ||= {}
end
end
end
end