module Grably::Core::ProductFilter

Set of predefined product filters, used by ProductExpand

Constants

FILTER_STRING_GROUPS

FILTER_STRING_REGEXP groups in fixed order.

FILTER_STRING_REGEXP

Matches filter string

Public Instance Methods

filter_products(products, new_base, old_base, &dst_filter) click to toggle source
# File lib/grably/core/product.rb, line 53
def filter_products(products, new_base, old_base, &dst_filter)
  products
    .map { |p| [p.src, p.dst, p.meta] }
    .select { |_, dst, _| !old_base || dst.start_with?(old_base) }
    .map { |src, dst, meta| [src, dst.gsub(%r{^#{old_base.to_s}[/\\]}, ''), meta] }
    .select(&dst_filter)
    .map { |src, dst, meta| [src, new_base.nil? ? dst : File.join(new_base, dst), meta] }
end
generate_glob_filter(glob) click to toggle source

Generates lambda filter out of `String` with glob pattern description

# File lib/grably/core/product.rb, line 16
def generate_glob_filter(glob)
  # Negative glob starts with '!'
  negative = glob.start_with?('!')
  # Strip leading '!' then
  glob.remove_prefix!('!') if negative
  lambda do |path|
    # TODO: I'm pretty sure that someone would like to have set_no_extglob, set_no_dotmatch, set_no_pathname
    # TODO: as global methods for ProductFilter module
    matches = File.fnmatch(glob, path, File::FNM_EXTGLOB | File::FNM_DOTMATCH | File::FNM_PATHNAME)
    # inverse match if glob is negative
    matches = !matches if negative
    matches
  end
end
generate_string_filter(filter_string) click to toggle source
# File lib/grably/core/product.rb, line 36
def generate_string_filter(filter_string)
  new_base, old_base, glob = parse_string_filter(filter_string)
  glob_filter = generate_glob_filter(glob)
  lambda do |products, _expand|
    filtered = filter_products(products, new_base, old_base) { |_src, dst, _meta| glob_filter.call(dst) }
    filtered.map { |src, dst, meta| Product.new(src, dst, meta) }
  end
end
parse_string_filter(filter_string) click to toggle source
# File lib/grably/core/product.rb, line 45
def parse_string_filter(filter_string)
  # Here we need generate lambda for string filter
  parsed_filter = FILTER_STRING_REGEXP.match(filter_string) do |m|
    FILTER_STRING_GROUPS.map { |g| m[g] }
  end
  parsed_filter || raise('Filter \'%s\' doesn\'t match format'.format(filter_string))
end