lib/eco/cli/config/use_cases.rb in eco-helpers-1.5.1 vs lib/eco/cli/config/use_cases.rb in eco-helpers-1.5.2

- old
+ new

@@ -1,102 +1,128 @@ module Eco class CLI class Config class UseCases - + include Eco::CLI::Config::Help attr_reader :core_config def initialize(core_config:) @core_config = core_config - @linked_opt_cases = {} + @linked_cases = {} + @description = {} end - # Integrates a usecase to the command line - # @param option_case [String] the command line option to invoke the usecase - # @param type [Symbol] the type of usecase - # @param case_name [String, nil] the name of the usecase as defined - def add(option_case, type, case_name: nil) + # @return [String] summary of the use cases. + def help + ["The following are the available use cases:"].yield_self do |lines| + max_len = keys_max_len(@linked_cases.keys) + @linked_cases.keys.sort.each do |key| + lines << help_line(key, @description[key], max_len) + end + lines + end.join("\n") + end + + # Integrates a usecase to the command line. + # @param option_case [String] the command line option to invoke the usecase. + # @param type [Symbol] the type of usecase. + # @param desc [String] description of the case. + # @param case_name [String, nil] the name of the usecase as defined. + def add(option_case, type, desc = nil, case_name: nil) Eco::API::UseCases::UseCase.validate_type(type) unless callback = block_given?? Proc.new : nil raise "You must specify a valid 'case_name' when no block is provided" unless case_name raise "'case_name' expected to be a String. Given: #{case_name.class}" unless case_name.is_a?(String) end - @linked_opt_cases[option_case] = { + @linked_cases[option_case] = { type => { + option: option_case, + type: type, casename: case_name, callback: callback } } + @description[option_case] = desc self end # Scopes/identifies which usecases are being invoked from the command line + # @note + # - this method will sort the active usecases by the position they hold in the command line # @param io [Eco::API::UseCases::BaseIO] the input/output object # @return [Hash] where keys are cases and values a `Hash` with `option` String and `callback` def active(io:) + validate_io!(io) return @active_cases unless !@active_cases - @active_cases = {}.tap do |opt_cases| - @linked_opt_cases.each do |option_case, types| - types.each do |type, data| - if SCR.get_arg(option_case) - usecase = nil - if case_name = data[:casename] - usecase = io.session.usecases.case(case_name, type: type) - end - - if callback = data[:callback] - unless usecase - # identify usecase - params = io.params(keyed: true).merge(type: type) - io = io.new(**params, validate: false) - - usecase = callback.call(*io.params) - unless usecase.is_a?(Eco::API::UseCases::UseCase) - msg = "When adding a usecase, without specifying 'case_name:', " - msg += "the block that integrates usecase for cli option '#{option_case}'" - msg += " must return an Eco::API::UseCases::UseCase object. It returns #{usecase.class}" - raise msg - end - end - end - - if usecase - opt_cases[usecase] = { - option: option_case, - callback: data[:callback] - } - end - - end + active_cases = {} + @linked_cases.each do |option_case, types| + next nil unless SCR.get_arg(option_case) + types.each do |type, data| + if usecase = get_usecase(io: io, data: data) + active_cases[usecase] = { + index: SCR.get_arg_index(option_case), + option: option_case, + callback: data[:callback] + } end end - end + @active_cases = active_cases.sort_by {|c, d| d[:index]}.to_h 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 - + validate_io!(io) processed = false active(io: io).each do |usecase, data| raise "Something went wrong when scoping active cases" unless data - processed = true + io = case_io(io: io, usecase: usecase) + # some usecases have a callback to collect the parameters + data[:callback]&.call(*io.params) + io = usecase.launch(io: io) + end + processed + end - params = io.params(keyed: true).merge(type: usecase.type) - io = io.new(**params) + private - if callback = data[:callback] - callback.call(*io.params) + # Gets a `UseCaseIO` + def case_io(io:, usecase:) + validate_io!(io) + case io + when Eco::API::UseCases::UseCaseIO + io.chain(usecase: usecase) + when Eco::API::UseCases::BaseIO + params = io.params(keyed: true).merge(usecase: usecase) + Eco::API::UseCases::UseCaseIO.new(**params) + end + end + + def get_usecase(io:, data:) + usecase = if case_name = data[:casename] + io.session.usecases.case(case_name, type: data[:type]) + end + usecase ||= if callback = data[:callback] + # identify/retrieve usecase via callback + params = io.params(keyed: true).merge(type: data[:type]) + io = io.new(**params, validate: false) + callback.call(*io.params).tap do |usecase| + unless usecase.is_a?(Eco::API::UseCases::UseCase) + msg = "When adding a usecase, without specifying 'case_name:', " + msg += "the block that integrates usecase for cli option '#{data[:option]}'" + msg += " must return an Eco::API::UseCases::UseCase object. It returns #{usecase.class}" + raise msg + end end + end + end - usecase.launch(io: io) + def validate_io!(io) + unless io && io.is_a?(Eco::API::UseCases::BaseIO) + raise "You need to provide Eco::API::UseCases::BaseIO object. Given: #{io.class}" end - processed end end end end