/sprites contains many directories. Each directory represents one sprite.
How can we do this? Here's one possible solution:
Dir['/sprites/*'].each do "sprite_name"
match "/sprites/#{sprite_name}/*.png" do
sprite
end
end
Problems with this use case: all sprites have to be known as pipeline load time.
Load time is not the same as build time (using the preview server).
Here's another solution: use a directory matcher to iterate over directories
and provide their contents as inputs to a filter.
directory "images/sprites" do
sprite
end
I think this is a valid use case. The use case itself is abstract and useful in other scenarios.
I've included my rough implementation of this in the issue to see if there is interest in this
functionality.
I'd change this so that the DirectoryFilter can also be used in other pipelines. If the parent
pipeline is a DirectoryMatcher then do the custom behavior. Else call super.
module Rake::Pipeline::Web::Filters
class DirectoryMatcher < Rake::Pipeline::Matcher
# Take files matching the directory glob from the set of all files.
# Return an array of array where each element in the array is
# the contents of an input directory
def eligible_input_files
directory_files = input_files.select do |file|
file.path.include? @glob
end
directory_files.inject({}) do |memo, input|
directory_name = File.dirname(input.path)
memo[directory_name] ||= []
memo[directory_name] << input
memo
end.values
end
end
class DirectoryFilter < Rake::Pipeline::Filter
def initialize(*args, &block)
block ||= proc { |input| File.basename input }
super &block
end
# We are working with an array of arrays to act accordingly
def input_files=(files)
@input_files = files.map do |directory|
directory.map { |f| f.with_encoding(encoding) }
end
end
# Outputs look like this:
#
# {
# generated_output_name => directory_contents,
# generated_output_name => directory_contents.
# }
#
# This ensures the filter's `generate_output` method is called
# once for each directory
def outputs
hash = {}
input_files.each do |directory|
directory_name = File.dirname directory.first.path
path = output_name_generator.call(*directory_name)
output_file = file_wrapper_class.new(output_root, path, encoding)
hash[output_file] = directory
end
hash
end
def output_files
outputs.keys
end
# Just like normal
def generate_output(inputs, output)
end
end
module PipelineHelpers
def directory(pattern, &block)
matcher = pipeline.copy(DirectoryMatcher, &block)
matcher.glob = pattern
pipeline.add_filter matcher
matcher
end
def directory_filter(*args, &block)
filter Rake::Pipeline::Web::Filters::DirectoryFilter, *args, &block
end
end
end
Here's a use case:
/sprites contains many directories. Each directory represents one sprite.
How can we do this? Here's one possible solution:
Problems with this use case: all sprites have to be known as pipeline load time. Load time is not the same as build time (using the preview server).
Here's another solution: use a directory matcher to iterate over directories and provide their contents as inputs to a filter.
I think this is a valid use case. The use case itself is abstract and useful in other scenarios.
I've included my rough implementation of this in the issue to see if there is interest in this functionality.
I'd change this so that the DirectoryFilter can also be used in other pipelines. If the parent pipeline is a
DirectoryMatcher
then do the custom behavior. Else callsuper
.