wied03/karma-opal-rspec

View on GitHub
lib/sprockets_metadata.rb

Summary

Maintainability
A
50 mins
Test Coverage
require 'uri'

module SprocketsMetadata
  def self.get_dependency_graph(sprockets_env, files, result = nil, current_dependency_chain = [])
    unless result
      result = {
        file_mapping: {},
        dependencies: Hash.new([])
      }
    end
    file_mapping = result[:file_mapping]
    dependencies = result[:dependencies]

    files.each do |file_asset|
      asset = file_asset.is_a?(Sprockets::Asset) ? file_asset : sprockets_env.find_asset(file_asset)
      our_logical_path = asset.logical_path
      dependency_assets = get_dependent_assets(asset, current_dependency_chain, sprockets_env)
      dependent_logical_paths = dependency_assets.map(&:logical_path)
      dependencies[our_logical_path] = (dependencies[our_logical_path] + dependent_logical_paths).uniq
      new_dependencies = dependency_assets.reject { |dependency| dependencies.include?(dependency.logical_path) }
      dependency_chain = current_dependency_chain.clone << asset
      get_dependency_graph sprockets_env, new_dependencies, result, dependency_chain
      file_mapping[our_logical_path] = asset.filename
    end
    result
  end

  def self.get_dependent_assets(asset, original_dependency_chain, sprockets_env)
    our_logical_path = asset.logical_path
    if original_dependency_chain.any? { |dependency| dependency.logical_path == our_logical_path }
      referring_paths = original_dependency_chain.map(&:logical_path)
      raise "Circular dependency, one of #{referring_paths} refers to #{our_logical_path} and #{our_logical_path} refers to one of those files."
    end
    all_assets = (asset.metadata[:included] || []).map do |dep|
      asset_uri = URI dep
      # Fetching with path to avoid the self/pipeline that sprockets puts on here
      sprockets_env.find_asset(asset_uri.path)
    end
    # Don't want to include ourselves
    all_assets.reject { |other_asset| other_asset.filename == asset.filename }
  end

  def self.default_roll_up_list
    # use find all to catch pre-release
    opal_spec = Gem::Specification.find_all_by_name('opal').first
    gems_dir = File.expand_path('..', opal_spec.gem_dir)
    [Regexp.new(Regexp.escape(gems_dir))]
  end

  def self.get_metadata(dependency_graph, roll_up_list, watch)
    dep_hash = {}
    file_mapping = dependency_graph[:file_mapping]
    file_mapping.each do |logical_path, filename|
      roll_up = roll_up_list.any? do |roll_up_item|
        if roll_up_item.is_a?(Regexp)
          roll_up_item.match filename
        else
          base_asset_name = File.basename(filename)
          base_asset_name == roll_up_item
        end
      end
      if roll_up
        dependency_graph[:dependencies][logical_path].each do |dep|
          dep_hash.delete file_mapping[dep]
        end
      end
      dep_hash[filename] = {
        logical_path: logical_path,
        watch: watch,
        roll_up: roll_up
      }
    end
    dep_hash
  end
end