lib/ass_launcher/enterprise/cli/parameters.rb in ass_launcher-0.1.1.alpha vs lib/ass_launcher/enterprise/cli/parameters.rb in ass_launcher-0.2.0

- old
+ new

@@ -11,16 +11,17 @@ # # For implement binding parameters and subparameters, parameter have # +parent+ propery. If +parent+ property is +nil+ it is root parameter # and subpurameter if else module Parameters + # Options for parameter DEFAULT_OPTIONS = { required: false, - value_validator: proc { |value| value }, + value_validator: nil, switch_list: nil, chose_list: nil, - switch_value: proc { |value| value } + switch_value: nil }.freeze # Parameter name like it define in 1C cli api # Name may start with '/' or '-' key. Example: /Parameter or # -subpurameter @@ -41,65 +42,102 @@ # @return [Array<Symbol>] attr_reader :modes # Parent parameter for subpurameter # @return kinde of [String] attr_reader :parent - # Options + # Options see {DEFAULT_OPTIONS} # @return [Hash] attr_reader :options + # Return +true+ if parameter defined for +binary_wrapper+ and +run_mode+ + # @param binary_wrapper [BinaryWrapper::ThickClient + # BinaryWrapper::ThinClient WebClient] + # @param run_mode [Symbol] see {Parameters#modes} def match?(binary_wrapper, run_mode) binary_matcher.match?(binary_wrapper) && modes.include?(run_mode) end + # Return +true+ if parameter defined for +version+ + # @param version [Gem::Version] + def match_version?(version) + binary_matcher.requirement.satisfied_by? version + end + + # :nodoc: def to_sym name.downcase.to_sym end + # Returns parameter full name. Full name + # composed from +full_name+ of all + # {#parents} parameters + # @return [String] def full_name return name if root? "#{parent.full_name}#{name}" end + # Array of parent parameters + # @return [Array] def parents return [] if root? parent.parents << parent end + # Returns deep parameter in hierarchy tree + # @return [Fixnum] def deep parents.size end + # Returns +true+ if haven't {#parent} parameter def root? parent.nil? end + # Returns +true+ if it's child of +expected_parent+ parameter + # @param expected_parent kinde of [StringParam] def child?(expected_parent) return false if root? parent == expected_parent end + # :nodoc: def to_s name.to_s end + # Returns self with +value+ as 1C:Enterprise CLI argumets array + # @example + # param.name #=> "/Parm" + # param.to_args 'value' #=> ["/Param", "value"] + # @return [Array<String>] def to_args(value) - [key(value), value(value)] + [key(value).to_s, value(value).to_s] end + # Wrapper for {#options} def switch_list options[:switch_list] end + # (see #switch_list) def chose_list options[:chose_list] end + # (see #switch_list) def value_validator - options[:value_validator] + options[:value_validator] || proc { |value| value } end + # (see #switch_list) + def switch_value + options[:switch_value] || proc { |value| value } + end + + # (see #switch_list) def required? options[:required] end def key(_value) @@ -121,131 +159,262 @@ def def_options DEFAULT_OPTIONS end private :def_options + # Builds usage message def usage fail NotImplementedError end def auto_binary_matcher(arg) return arg if arg.is_a? BinaryMatcher - return BinaryMatcher.new(auto_client, arg) if arg.is_a? String - BinaryMatcher.new auto_client + return BinaryMatcher.auto(modes, arg) if arg.is_a? String + BinaryMatcher.auto modes end private :auto_binary_matcher - def auto_client - #return :thick if modes.include?(:createinfobase) || - # modes.include?(:designer) - return :thick unless modes.include?(:enterprise) - :all + # Array of subparameters + # @return [Array] + def childs + @childs ||= [] end - private :auto_client + # Add subparameter into {#childs} array + # @param param kinde of {StringParam} + def add_child(param) + childs << param + end + + # Restricts parameter from +version+ + # and do it recursively for all subparameters from {#childs} array + # @param (see #match_version?) + def restrict_from(version) + restrict_childs(version) + binary_matcher.requirement = + restrict_v(binary_matcher.requirement, + version) if match_version? version + end + + def restrict_childs(version) + childs.each do |p| + p.restrict_from version + end + end + private :restrict_childs + + def restrict_v(r, v) + Gem::Version::Requirement.new r.to_s.split(','), "< #{v}" + end + private :restrict_v + # Parameter expects string value class StringParam include Parameters # @api private # @param name [String] name of parameter like defined 1C cli api # @param desc [String] help description # @param binary_matcher [BinaryMatcher, String, nil] for which # parameter defined # - If nil will be build default matcher. - # - If string. String value mast be suitable for Gem::Requirement. + # - If string. String value must be suitable for Gem::Requirement. # In this case, will be build matcher for version defined in # string and suitable bynary type detected on run_modes # @param group [Symbol] parameter group # @param modes [Array] run modes for which parameter defined - # @param parent kinde of [StringParam] parent for subpurameter + # @param parent kinde of {StringParam} parent for subpurameter # @param options [Hash] see {Parameters::DEFAULT_OPTIONS} def initialize(name, desc, binary_matcher, group, modes, parent = nil, **options) @name = name @desc = desc @modes = modes || Cli::DEFINED_MODES @binary_matcher = auto_binary_matcher(binary_matcher) @group = group @options = def_options.merge options @parent = parent + @parent.add_child(self) unless parent.nil? end + + # Parameter require argumet + def argument_require + arguments_count > 0 + end + + # Count of parameter argumets + def arguments_count + 1 + end end # Parameter expects filesystem path # Path string cam came from diferent sources # and have windows, unix or unix-cygwin format # It class instance make path string platform independet use # {AssLauncher::Support::Platforms::PathExtension} class class Path < StringParam + # Extends for {Parameters::DEFAULT_OPTIONS}. + # + # Option: +:must_be+ expects +:exist+ or +:not_exist+ values. + # + # If +:exist+ given verified for path must be exists and + # if +:not_exist+ given verified for pat must be not exists + DEFAULT_OPTIONS = Parameters::DEFAULT_OPTIONS.merge(must_be: nil) include AssLauncher::Support::Platforms + + def default_options + DEFAULT_OPTIONS + end + private :default_options + + # (see #switch_list) + def must_be + options[:must_be] + end + def value(value) - platform.path(value).to_s + validate(value) + path = platform.path(value).realdirpath + verify(path) + path.to_s end private :value + + def verify(path) + case must_be + when :exist then must_exists(path) + when :not_exist then must_not_exists(path) + end + end + private :verify + + def must_exists(path) + fail ArgumentError, "Wrong value for #{name}."\ + " Path #{path} not exists" unless path.exist? + end + private :must_exists + + def must_not_exists(path) + fail ArgumentError, "Wrong value for #{name}."\ + " Path #{path} exists" if path.exist? + end + private :must_not_exists end - # Chose parameter expects argunment value from chose_list - class Chose < StringParam - def validate(value) - fail ArgumentError, "Wrong value `#{value}' for #{name} parameter"\ - unless chose_list.key? value.to_sym + # In 8.3.8 platform add CLI parameters like as + # +/DumpExternalDataProcessorOrReportToFiles+ expects 2 argumetns + class PathTwice < StringParam + include AssLauncher::Support::Platforms + def to_args(p1, p2) + [key('').to_s, rdp_(p1).to_s, rdp_(p2).to_s] end - private :validate + + def rdp_(p) + platform.path(p).realdirpath + end + private :rdp_ end # Flag parameter not expects argument class Flag < StringParam - def to_args + # Returns self as 1C:Enterprise CLI argumets array like + # +["/Flag", ""]+ + # @param _ [nil] {Flag} not expects argument + # @return (see StringParam#to_args) + def to_args(_ = nil) super '' end + + # Count of parameter argumets + def arguments_count + 0 + end end - # Switch parameter is most stupid cli parameter of 1C:Enterprise. - # Switch parameter expects argument value from +:switch_list* or + class SkippedError < StandardError; end + + # Stub for define stupid or not importand parameters + # {#to_args} raises of {SkippedError} + class Skip < StringParam + def to_args(*values) + fail SkippedError, "Parameter #{full_name} skipped and restricted for use" + end + + def skip? + true + end + end + + # Chose parameter expects argunment value from chose_list + class Chose < StringParam + def validate(value) + fail ArgumentError, + "Wrong value `#{value}' for #{name} parameter" unless\ + valid?(value) + end + private :validate + + def valid?(value) + chose_list.keys.map(&:to_s).map(&:downcase).include?\ + value.to_s.downcase + end + end + + + # Switch parameter is most stupid CLI parameter of 1C:Enterprise. + # Switch parameter expects argument value from +:switch_list+ or # block +:switch_value+ which return modified value argument. # Switch parameter modifyed self name when uses parameter value # @example - # # /UseHwLicenses have {:"+"=>'',:"-"=>''} switch_list and: - # to_args(:"+") # => ['/UseHwLicenses+',''] - # to_args(:"-") # => ['/UseHwLicenses-',''] - # to_args(:"bad value") # => ArgumentError + # # /UseHwLicenses have {:+=>'',:-=>''} switch_list and: + # to_args(:+) # => ['/UseHwLicenses+',''] + # to_args(:-) # => ['/UseHwLicenses-',''] + # to_args(:bad_value) # => ArgumentError # # # -TimeLimit have block: - # switch_value: =>{|value|; ":#{value}"} + # {switch_value: ->(value) { ":#{value}"}} # # and - # to_args("12:00") #=> ['-TimeLimit:12:00',''] + # to_args("12:00") # => ['-TimeLimit:12:00',''] class Switch < StringParam def value(_value) '' end private :value def key(value) - "#{name}#{switch_value(value)}" + "#{name}#{switch_value_get(value)}" end private :key - def switch_value(value) + def switch_value_get(value) if switch_list - fail ArgumentError, "Wrong value #{value} for parameter #{name}"\ - unless switch_list.key? value.to_sym + fail ArgumentError, + "Wrong value #{value} for parameter #{name}" unless\ + valid?(value) end validate(value) - options[:switch_value].call(value) + switch_value.call(value) end - private :switch_value + private :switch_value_get + + def valid?(value) + switch_list.keys.map(&:to_s).map(&:downcase).include?\ + value.to_s.downcase + end end - # List of parameters + # List of parameters defined for one version + # @raise (see #<<) class ParametersList - def initialize - @parameters = [] + # Array of parameters. + # For add parameter into array use {#<<} + def parameters + @parameters ||= [] end - attr_reader :parameters - private :parameters - + # Returns +true+ if parameter +p+ presents in list + # @param p kinde of {StringParam} def param_defined?(p) !find(p.name, p.parent).nil? end # Add parameter in to tail of list @@ -253,11 +422,11 @@ # @raise [ArgumentError] if parameter alrady present in list def <<(p) fail ArgumentError, "Parameter #{p.full_name} alrady defined" if\ param_defined?(p) - @parameters << p + parameters << p end alias_method :"+", :"<<" alias_method :add, :"<<" # Find parameter in list @@ -273,15 +442,99 @@ end end nil end + # :nodoc: def each(&block) parameters.each(&block) end + # (see Parameters#usage) def usage fail NotImplementedError + end + end + + # List of parameters defined for all versions + # @raise (see #add) + class AllParameters + # Array of parameters. + # For add parameter into array use {#add} + def parameters + @parameters ||= [] + end + + # Add parameter into list + # @param (see #param_defined?) + # @raise [ArgumentError] if parameter +p.name+ alrady defined for + # +version+ + def add(p, version) + fail_if_difined(p, version) + parameters << p + end + + def fail_if_difined(p, version) + fail ArgumentError, + "Parameter #{p.full_name} alrady defined for version"\ + " #{version}" if param_defined? p, version + end + private :fail_if_difined + + # Returns +true+ if parameter +p+ for +version+ presents in list + # @param p kinde of {StringParam} + # @param version (see Parameters#match_version?) + def param_defined?(p, version) + find(p.name, p.parent).each do |p_| + return true if p_.match_version? version + end + false + end + + # Return parameters list for given +binary_wrapper+ and +run_mode+ + # @return [ParametersList] for given +binary_wrapper+ and +run_mode+ + # @param (see Parameters#match?) + def to_parameters_list(binary_wrapper, run_mode) + r = new_list + parameters.each do |p| + r << p if p.match? binary_wrapper, run_mode + end + r + end + + def new_list + ParametersList.new + end + private :new_list + + # Find actual parameter for +version+ + # @return kinde of {StringParam} + # @param name (see #find) + # @param parent (see #find) + # @param version [Gem::Version] + def find_for_version(name, parent, version) + r = nil + find(name, parent).each do |p| + r = oops!(r, p, version) if p.match_version? version + end + r + end + + def oops!(r, p, v) + fail "Too many params #{p.full_name} spec for #{v}" unless r.nil? + p + end + private :oops! + + # Find all parameter versions + # @param name (see StringParam#initialize) + # @param parent (see StringParam#initialize) + # @return [Array] of parameters + def find(name, parent) + parameters.select do |p| + p.to_sym == name.downcase.to_sym && + p.parent == parent + end end end end end end