Skip to content

Commit 39d8ec3

Browse files
committed
Cache asset paths by methods
1 parent 59406ab commit 39d8ec3

File tree

3 files changed

+41
-20
lines changed

3 files changed

+41
-20
lines changed

lib/propshaft/helper.rb

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,20 +6,24 @@ def compute_asset_path(path, options = {})
66

77
# Add an option to call `stylesheet_link_tag` with `:all` to include every css file found on the load path.
88
def stylesheet_link_tag(*sources, **options)
9-
if sources.first == :all
10-
super(*all_stylesheets_paths, **options)
9+
case sources.first
10+
when :all
11+
super(*all_stylesheets_paths , **options)
12+
when :app
13+
super(*app_stylesheets_paths , **options)
1114
else
1215
super
1316
end
1417
end
1518

1619
# Returns a sorted and unique array of logical paths for all stylesheets in the load path.
1720
def all_stylesheets_paths
18-
Rails.application.assets.load_path
19-
.assets(content_types: [ Mime::EXTENSION_LOOKUP["css"] ])
20-
.collect { |css| css.logical_path.to_s }
21-
.sort
22-
.uniq
21+
Rails.application.assets.load_path.asset_paths_by_type("css")
22+
end
23+
24+
# Returns a sorted and unique array of logical paths for all stylesheets in app/assets/stylesheets.
25+
def app_stylesheets_path
26+
Rails.application.assets.load_path.assets_path_by_glob("**/app/assets/stylesheets/**/*.css")
2327
end
2428
end
2529
end

lib/propshaft/load_path.rb

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,18 @@ def find_referenced_by(asset)
1515
compilers.referenced_by(asset).delete(self)
1616
end
1717

18-
def assets(content_types: nil)
19-
if content_types
20-
assets_by_path.values.select { |asset| asset.content_type.in?(content_types) }
21-
else
22-
assets_by_path.values
23-
end
18+
def assets
19+
assets_by_path.values
20+
end
21+
22+
def asset_paths_by_type(content_type)
23+
(@cached_asset_paths_by_type ||= Hash.new)[content_type] ||=
24+
extract_logical_paths_from(assets.select { |a| a.content_type == Mime::EXTENSION_LOOKUP[content_type] })
25+
end
26+
27+
def asset_paths_by_glob(glob)
28+
(@cached_asset_paths_by_glob ||= Hash.new)[glob] ||=
29+
extract_logical_paths_from(assets.select { |a| a.path.fnmatch?(glob) })
2430
end
2531

2632
def manifest
@@ -61,12 +67,18 @@ def all_files_from_tree(path)
6167
path.children.flat_map { |child| child.directory? ? all_files_from_tree(child) : child }
6268
end
6369

70+
def extract_logical_paths_from(assets)
71+
assets.collect { |asset| asset.logical_path.to_s }.sort
72+
end
73+
6474
def without_dotfiles(files)
6575
files.reject { |file| file.basename.to_s.starts_with?(".") }
6676
end
6777

6878
def clear_cache
6979
@cached_assets_by_path = nil
80+
@cached_asset_paths_by_type = nil
81+
@cached_asset_paths_by_glob = nil
7082
end
7183

7284
def dedup(paths)

test/propshaft/load_path_test.rb

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -29,13 +29,6 @@ class Propshaft::LoadPathTest < ActiveSupport::TestCase
2929
assert_not_includes @load_path.assets, find_asset(".stuff")
3030
end
3131

32-
test "assets by given content types" do
33-
assert_not_includes @load_path.assets(content_types: [ Mime[:js] ]), find_asset("one.txt")
34-
assert_includes @load_path.assets(content_types: [ Mime[:js] ]), find_asset("again.js")
35-
assert_includes @load_path.assets(content_types: [ Mime[:js], Mime[:css] ]), find_asset("again.js")
36-
assert_includes @load_path.assets(content_types: [ Mime[:js], Mime[:css] ]), find_asset("another.css")
37-
end
38-
3932
test "manifest" do
4033
@load_path.manifest.tap do |manifest|
4134
assert_equal "one-f2e1ec14.txt", manifest["one.txt"]
@@ -70,6 +63,18 @@ class Propshaft::LoadPathTest < ActiveSupport::TestCase
7063
assert_equal Pathname.new("app/assets"), paths.last
7164
end
7265

66+
test "asset paths by type" do
67+
assert_equal \
68+
["another.css", "dependent/a.css", "dependent/b.css", "dependent/c.css", "file-already-abcdefVWXYZ0123456789_-.digested.css", "file-already-abcdefVWXYZ0123456789_-.digested.debug.css", "file-not.digested.css"],
69+
@load_path.asset_paths_by_type("css")
70+
end
71+
72+
test "asset paths by glob" do
73+
assert_equal \
74+
["dependent/a.css", "dependent/b.css", "dependent/c.css"],
75+
@load_path.asset_paths_by_glob("**/dependent/*.css")
76+
end
77+
7378
private
7479
def find_asset(logical_path)
7580
root_path = Pathname.new("#{__dir__}/../fixtures/assets/first_path")

0 commit comments

Comments
 (0)