# Copyright (c) 2013-2016 SUSE LLC # # This program is free software; you can redistribute it and/or # modify it under the terms of version 3 of the GNU General Public License as # published by the Free Software Foundation. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, contact SUSE LLC. # # To contact SUSE about this file by physical or electronic mail, # you may find current contact information at www.suse.com # The Filter class is used to hold the information about the filter conditions # that should be applied during certain Machinery commands. # # Filters are usually created by passing a filter definition string to the # constructor, e.g. # # filter = Filter.new("/unmanaged_files/name=/opt") # # Existing filters can be extended by amending the definition: # # filter.add_element_filter_from_definition("/unmanaged_files/name=/srv") # # or by adding ElementFilters directly: # # element_filter = ElementFilter.new("/unmanaged_files/name", ["/opt", "/srv"]) # filter.add_element_filter(element_filter) # # # The actual filtering can be done by passing values to Filter#matches? # # filter = Filter.new("/unmanaged_files/name=/opt*") # filter.matches?("/unmanaged_files/name", "/opt/foo") # => true # filter.matches?("/unmanaged_files/name", "/srv/bar") # => false # # More details about how the filter work can be found at # https://github.com/SUSE/machinery/blob/master/docs/Filtering-Design.md module Machinery class Filter attr_accessor :element_filters OPERATOR_EQUALS = "=".freeze OPERATOR_EQUALS_NOT = "!=".freeze def self.parse_filter_definitions(filter_definitions) element_filters = {} Array(filter_definitions).each do |definition| path, operator, matcher_definition = definition.scan(/([a-zA-Z_\/]+)(.*=)(.*)/)[0] raise Machinery::Errors::InvalidFilter.new( "Invalid filter: '#{definition}'" ) unless operator element_filters[path] ||= ElementFilter.new(path) if matcher_definition.index(",") matchers = matcher_definition.split(/(? e Machinery::Ui.warn("Warning: Filter '#{e.failed_matcher}' tries to match an array, " \ "but the according element is not an array.") end end end def empty? element_filters.empty? end end end