class JekyllAssetPipeline::Pipeline
The pipeline itself, the run method is where it all happens rubocop:disable Metrics/ClassLength
Attributes
Public Class Methods
Cache processed pipelines
# File lib/jekyll_asset_pipeline/pipeline.rb, line 49 def cache @cache ||= {} end
Empty cache
# File lib/jekyll_asset_pipeline/pipeline.rb, line 54 def clear_cache @cache = {} end
Generate hash based on manifest
# File lib/jekyll_asset_pipeline/pipeline.rb, line 10 def hash(source, manifest, options = {}) options = DEFAULTS.merge(options) begin Digest::MD5.hexdigest(YAML.safe_load(manifest).map! do |path| "#{path}#{File.mtime(File.join(source, path)).to_i}" end.join.concat(options.to_s)) rescue StandardError => e puts "Failed to generate hash from provided manifest: #{e.message}" raise e end end
Initialize new pipeline rubocop:disable Metrics/ParameterLists
# File lib/jekyll_asset_pipeline/pipeline.rb, line 88 def initialize(manifest, prefix, source, destination, type, options = {}) # rubocop:enable Metrics/ParameterLists @manifest = manifest @prefix = prefix @source = source @destination = destination @type = type @options = ::JekyllAssetPipeline::DEFAULTS.merge(options) process end
Add prefix to output
# File lib/jekyll_asset_pipeline/pipeline.rb, line 66 def puts(message) $stdout.puts("Asset Pipeline: #{message}") end
Remove staged assets
# File lib/jekyll_asset_pipeline/pipeline.rb, line 59 def remove_staged_assets(source, config) config = DEFAULTS.merge(config) staging_path = File.join(source, config['staging_path']) FileUtils.rm_rf(staging_path) end
Run the pipeline This is called from JekyllAssetPipeline::LiquidBlockExtensions.render
or, to be more precise, from JekyllAssetPipeline::CssAssetTag.render
and JekyllAssetPipeline::JavaScriptAssetTag.render
rubocop:disable Metrics/ParameterLists
# File lib/jekyll_asset_pipeline/pipeline.rb, line 27 def run(manifest, prefix, source, destination, tag, type, config) # rubocop:enable Metrics/ParameterLists # Get hash for pipeline hash = hash(source, manifest, config) # Check if pipeline has been cached return cache[hash], true if cache.key?(hash) begin puts "Processing '#{tag}' manifest '#{prefix}'" pipeline = new(manifest, prefix, source, destination, type, config) process_pipeline(hash, pipeline) rescue StandardError => e # Add exception to cache cache[hash] = e # Re-raise the exception raise e end end
Private Class Methods
# File lib/jekyll_asset_pipeline/pipeline.rb, line 72 def process_pipeline(hash, pipeline) pipeline.assets.each do |asset| puts "Saved '#{asset.filename}' to " \ "'#{pipeline.destination}/#{asset.output_path}'" end # Add processed pipeline to cache cache[hash] = pipeline # Return newly processed pipeline and cached status [pipeline, false] end
Private Instance Methods
Bundle multiple assets into a single asset
# File lib/jekyll_asset_pipeline/pipeline.rb, line 169 def bundle content = @assets.map(&:content).join("\n") hash = ::JekyllAssetPipeline::Pipeline.hash(@source, @manifest, @options) @assets = [ ::JekyllAssetPipeline::Asset.new(content, "#{@prefix}-#{hash}#{@type}") ] end
Collect assets based on manifest
# File lib/jekyll_asset_pipeline/pipeline.rb, line 116 def collect @assets = YAML.safe_load(@manifest).map! do |path| full_path = File.join(@source, path) File.open(File.join(@source, path)) do |file| ::JekyllAssetPipeline::Asset.new(file.read, File.basename(path), File.dirname(full_path)) end end rescue StandardError => e puts 'Asset Pipeline: Failed to load assets from provided ' \ "manifest: #{e.message}" raise e end
Compress assets if compressor is defined
# File lib/jekyll_asset_pipeline/pipeline.rb, line 179 def compress @assets.each do |asset| # Find a compressor to use klass = ::JekyllAssetPipeline::Compressor.subclasses.select do |c| c.filetype == @type end.last break unless klass begin asset.content = klass.new(asset.content).compressed rescue StandardError => e puts "Asset Pipeline: Failed to compress '#{asset.filename}' " \ "with '#{klass}': #{e.message}" raise e end end end
Convert assets based on the file extension if converter is defined
# File lib/jekyll_asset_pipeline/pipeline.rb, line 131 def convert @assets.each do |asset| # Convert asset multiple times if more than one converter is found finished = false while finished == false # Find a converter to use klass = ::JekyllAssetPipeline::Converter.klass(asset.filename) # Convert asset if converter is found if klass.nil? finished = true else convert_asset(klass, asset) end end end end
Convert an asset with a given converter class
# File lib/jekyll_asset_pipeline/pipeline.rb, line 150 def convert_asset(klass, asset) # Convert asset content converter = klass.new(asset) # Replace asset content and filename asset.content = converter.converted asset.filename = File.basename(asset.filename, '.*') # Add back the output extension if no extension left if File.extname(asset.filename) == '' asset.filename = "#{asset.filename}#{@type}" end rescue StandardError => e puts "Asset Pipeline: Failed to convert '#{asset.filename}' " \ "with '#{klass}': #{e.message}" raise e end
Create Gzip versions of assets
# File lib/jekyll_asset_pipeline/pipeline.rb, line 199 def gzip @assets.map! do |asset| gzip_content = Zlib::Deflate.deflate(asset.content) [ asset, ::JekyllAssetPipeline::Asset .new(gzip_content, "#{asset.filename}.gz", asset.dirname) ] end.flatten! end
Generate html markup pointing to assets
# File lib/jekyll_asset_pipeline/pipeline.rb, line 240 def markup # Use display_path if defined, otherwise use output_path in url display_path = @options['display_path'] || @options['output_path'] @html = @assets.map do |asset| klass = ::JekyllAssetPipeline::Template.klass(asset.filename) html = klass.new(display_path, asset.filename).html unless klass.nil? html end.join end
Process the pipeline
# File lib/jekyll_asset_pipeline/pipeline.rb, line 105 def process collect convert bundle if @options['bundle'] compress if @options['compress'] gzip if @options['gzip'] save markup end
Save assets to file
# File lib/jekyll_asset_pipeline/pipeline.rb, line 211 def save output_path = @options['output_path'] staging_path = @options['staging_path'] @assets.each do |asset| directory = File.join(@source, staging_path, output_path) write_asset_file(directory, asset) # Store output path of saved file asset.output_path = output_path end end
Write asset file to disk
# File lib/jekyll_asset_pipeline/pipeline.rb, line 225 def write_asset_file(directory, asset) FileUtils.mkpath(directory) unless File.directory?(directory) begin # Save file to disk File.open(File.join(directory, asset.filename), 'w') do |file| file.write(asset.content) end rescue StandardError => e puts "Asset Pipeline: Failed to save '#{asset.filename}' to " \ "disk: #{e.message}" raise e end end