module HasMachineTags class TagList < Array cattr_accessor :delimiter self.delimiter = ',' cattr_accessor :default_predicate self.default_predicate = 'tags' QUICK_MODE_DELIMITER = ';' # ==== Options: # [:quick_mode] # When true enables a quick mode for inputing multiple machine tags under the same namespace. # These machine tags are delimited by QUICK_MODE_DELIMITER. If a predicate is not specified, default_predicate() is used. # Examples: # # Namespace is added to tag 'type=test'. # HasMachineTags::TagList.new("gem:name=flog;type=test, user:name=seattlerb", :quick_mode=>true) # => ["gem:name=flog", "gem:type=test", "user:name=seattlerb"] # # # Namespace and default predicate (tags) are added to tag 'git'. # HasMachineTags::TagList.new("gem:name=grit;git, user:name=mojombo") # => ["gem:name=grit", "gem:tags=git", "user:name=mojombo"] def initialize(string_or_array, options={}) @options = options array = string_or_array.is_a?(Array) ? string_or_array : string_or_array.split(/\s*#{delimiter}\s*/) array = parse_quick_mode(array) if @options[:quick_mode] concat array end def parse_quick_mode(mtag_list) #:nodoc: mtag_list = mtag_list.map {|e| if e.include?(Tag::PREDICATE_DELIMITER) namespace, remainder = e.split(Tag::PREDICATE_DELIMITER) remainder.split(QUICK_MODE_DELIMITER).map {|e| e.include?(Tag::VALUE_DELIMITER) ? "#{namespace}#{Tag::PREDICATE_DELIMITER}#{e}" : Tag.build_machine_tag(namespace, default_predicate, e) } else e end }.flatten end def namespace_hashes #:nodoc: self.inject({}) {|h, e| namespace, *predicate_value = Tag.split_machine_tag(e) (h[namespace] ||= []) << predicate_value unless namespace.nil? h } end def non_machine_tags self.reject {|e| Tag.machine_tag?(e)} end # Converts tag_list to a stringified version of quick_mode. def to_quick_mode_string machine_tags = namespace_hashes.map {|namespace, predicate_values| "#{namespace}:" + predicate_values.map {|pred, value| pred == self.default_predicate ? value : "#{pred}#{Tag::VALUE_DELIMITER}#{value}" }.join(QUICK_MODE_DELIMITER) } (machine_tags + non_machine_tags).join("#{delimiter} ") end def to_s #:nodoc: join("#{delimiter} ") end end end