From af8073736b0b5ea5abcbcfa11ad885fc9b6128c0 Mon Sep 17 00:00:00 2001 From: Breno Gazzola Date: Fri, 18 Feb 2022 16:34:50 -0300 Subject: [PATCH] Deduplicate paths --- lib/propshaft/load_path.rb | 14 +++++++++++--- test/propshaft/load_path_test.rb | 15 +++++++++++++++ 2 files changed, 26 insertions(+), 3 deletions(-) diff --git a/lib/propshaft/load_path.rb b/lib/propshaft/load_path.rb index 944d8aa..cb67cd9 100644 --- a/lib/propshaft/load_path.rb +++ b/lib/propshaft/load_path.rb @@ -4,7 +4,7 @@ class Propshaft::LoadPath attr_reader :paths, :version def initialize(paths = [], version: nil) - @paths = Array(paths).collect { |path| Pathname.new(path) } + @paths = dedup(paths) @version = version end @@ -33,8 +33,8 @@ def manifest # and test to ensure the map caches are reset when javascript files are changed. def cache_sweeper @cache_sweeper ||= begin - exts_to_watch = Mime::EXTENSION_LOOKUP.map(&:first) - files_to_watch = Array(paths).collect { |dir| [ dir.to_s, exts_to_watch ] }.to_h + exts_to_watch = Mime::EXTENSION_LOOKUP.map(&:first) + files_to_watch = Array(paths).collect { |dir| [dir.to_s, exts_to_watch] }.to_h Rails.application.config.file_watcher.new([], files_to_watch) do clear_cache @@ -65,4 +65,12 @@ def without_dotfiles(files) def clear_cache @cached_assets_by_path = nil end + + def dedup(paths) + [].tap do |deduped| + Array(paths).sort.each do |path| + deduped << Pathname.new(path) if deduped.blank? || !path.to_s.start_with?(deduped.last.to_s) + end + end + end end diff --git a/test/propshaft/load_path_test.rb b/test/propshaft/load_path_test.rb index 1985f07..1d4f06a 100644 --- a/test/propshaft/load_path_test.rb +++ b/test/propshaft/load_path_test.rb @@ -55,6 +55,21 @@ class Propshaft::LoadPathTest < ActiveSupport::TestCase assert_nil Propshaft::LoadPath.new(Pathname.new("#{__dir__}/../fixtures/assets/nowhere")).find("missing") end + test "deduplicate paths" do + load_path = Propshaft::LoadPath.new [ + "app/assets/stylesheets", + "app/assets/images", + "app/assets", + "app/javascript", + "app/javascript/packs" + ] + + paths = load_path.paths + assert_equal 2, paths.count + assert_equal Pathname.new("app/assets"), paths.first + assert_equal Pathname.new("app/javascript"), paths.last + end + private def find_asset(logical_path) Propshaft::Asset.new(