Skip to content

Commit 87c65e3

Browse files
committed
Use latest EmberCLI-generated asset files
Closes [#298] Use Sprockets-generated manifest to detect which files are the most up to date versions of EmberCLI-generated assets. No longer support Sprockets-based helpers for Rails 3.2, given the difference in how the Asset Pipeline works post-4.0. [#298]: #298
1 parent abd8901 commit 87c65e3

File tree

8 files changed

+269
-11
lines changed

8 files changed

+269
-11
lines changed

CHANGELOG.md

+2
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
master
22
------
33

4+
* Use latest EmberCLI-generated asset files. [#316]
45
* Delete previous build output on application boot instead of on process exit.
56
[#308]
67

8+
[#316]: https://github.com/thoughtbot/ember-cli-rails/pull/316
79
[#308]: https://github.com/thoughtbot/ember-cli-rails/pull/308
810

911
0.5.6

README.md

+9-1
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,10 @@ In addition to rendering the EmberCLI generated `index.html`, you can inject the
198198
<%= include_ember_stylesheet_tags :frontend %>
199199
```
200200

201+
**NOTE**
202+
203+
These helpers are only available for Rails versions `>= 4.0`.
204+
201205
### Multiple Ember CLI apps
202206

203207
In the initializer you may specify multiple Ember CLI apps, each of which can be
@@ -519,10 +523,14 @@ jQuery and Handlebars are the main use cases for this flag.
519523
This project supports:
520524

521525
* Ruby versions `>= 2.1.0`
522-
* Rails `3.2.x` and `>=4.1.x`.
526+
* Rails versions `3.2.x` and `>=4.1.x`.
527+
528+
[Rendering EmberCLI-generated assets through Sprockets](asset-helpers) is
529+
**NOT** supported for Rails `3.2.x`.
523530

524531
To learn more about supported versions and upgrades, read the [upgrading guide].
525532

533+
[asset-helpers]: #rendering-the-embercli-generated-js-and-css
526534
[upgrading guide]: /UPGRADING.md
527535

528536
## Contributing

app/helpers/ember_rails_helper.rb

+37-7
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,7 @@
22

33
module EmberRailsHelper
44
def include_ember_index_html(name, &block)
5-
warn <<-MSG.strip_heredoc
6-
The `include_ember_index_html` helper has been deprecated.
7-
8-
Rename all invocations to `render_ember_app`
9-
MSG
5+
Warnings.warn_include_index_html
106

117
render_ember_app(name, &block)
128
end
@@ -20,10 +16,44 @@ def render_ember_app(name, &block)
2016
end
2117

2218
def include_ember_script_tags(name, **options)
23-
javascript_include_tag(*EmberCli[name].sprockets.assets, options)
19+
Warnings.warn_asset_helper
20+
21+
javascript_include_tag(*EmberCli[name].sprockets.javascript_assets, options)
2422
end
2523

2624
def include_ember_stylesheet_tags(name, **options)
27-
stylesheet_link_tag(*EmberCli[name].sprockets.assets, options)
25+
Warnings.warn_asset_helper
26+
27+
stylesheet_link_tag(*EmberCli[name].sprockets.stylesheet_assets, options)
28+
end
29+
30+
module Warnings
31+
def self.warn_include_index_html
32+
warn <<-MSG.strip_heredoc
33+
The `include_ember_index_html` helper has been deprecated.
34+
35+
Rename all invocations to `render_ember_app`
36+
MSG
37+
end
38+
39+
def self.warn_asset_helper
40+
if Rails::VERSION::MAJOR < 4
41+
warn <<-MSG.strip_heredoc
42+
`ember-cli-rails` no longer supports Sprockets-based helpers for Rails
43+
versions below 4.0.
44+
45+
Replace usage of
46+
* `include_ember_script_tags`
47+
* `include_ember_stylesheet_tags`
48+
49+
with `render_ember_app` invocations.
50+
51+
To learn more, please read:
52+
53+
* https://github.com/thoughtbot/ember-cli-rails#configuring-the-ember-controller
54+
* https://github.com/thoughtbot/ember-cli-rails/pull/316
55+
MSG
56+
end
57+
end
2858
end
2959
end

lib/ember_cli/assets.rb

+66
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
module EmberCli
2+
class Assets
3+
def initialize(app_name:, ember_app_name:, manifest:)
4+
@app_name = app_name
5+
@ember_app_name = ember_app_name
6+
@manifest = manifest
7+
end
8+
9+
def javascripts
10+
if empty_manifest?
11+
fallback_assets
12+
else
13+
[
14+
latest_matching(%r{#{app_name}/assets/vendor(.*)\.js\z}),
15+
latest_matching(%r{#{app_name}/assets/#{ember_app_name}(.*)\.js\z}),
16+
]
17+
end
18+
end
19+
20+
def stylesheets
21+
if empty_manifest?
22+
fallback_assets
23+
else
24+
[
25+
latest_matching(%r{#{app_name}/assets/vendor(.*)\.css\z}),
26+
latest_matching(%r{#{app_name}/assets/#{ember_app_name}(.*)\.css\z}),
27+
]
28+
end
29+
end
30+
31+
private
32+
33+
attr_reader :app_name, :ember_app_name, :manifest
34+
35+
def fallback_assets
36+
["#{app_name}/assets/vendor", "#{app_name}/assets/#{ember_app_name}"]
37+
end
38+
39+
def empty_manifest?
40+
files.empty?
41+
end
42+
43+
def latest_matching(regex)
44+
asset, = assets.detect { |(_, digest)| digest == latest_file_for(regex) }
45+
46+
asset
47+
end
48+
49+
def latest_file_for(regex)
50+
file, = files.
51+
select { |key, _| key =~ regex }.
52+
sort_by { |_, data| data["mtime"] }.
53+
last
54+
55+
file
56+
end
57+
58+
def assets
59+
manifest.assets
60+
end
61+
62+
def files
63+
manifest.files
64+
end
65+
end
66+
end

lib/ember_cli/missing_manifest.rb

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
module EmberCli
2+
class MissingManifest
3+
def files
4+
{}
5+
end
6+
7+
def assets
8+
{}
9+
end
10+
end
11+
end

lib/ember_cli/sprockets.rb

+26-2
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,14 @@
1+
require "sprockets"
12
require "ember_cli/errors"
23
require "non-stupid-digest-assets"
34
require "ember_cli/html_page"
5+
require "ember_cli/missing_manifest"
6+
require "ember_cli/assets"
47

58
module EmberCli
69
class Sprockets
710
class AssetPipelineError < BuildError; end
11+
812
def initialize(app)
913
@app = app
1014
end
@@ -24,14 +28,26 @@ def index_html(head:, body:)
2428
html_page.render
2529
end
2630

27-
def assets
28-
["#{app.name}/assets/vendor", "#{app.name}/assets/#{ember_app_name}"]
31+
def javascript_assets
32+
assets.javascripts
33+
end
34+
35+
def stylesheet_assets
36+
assets.stylesheets
2937
end
3038

3139
private
3240

3341
attr_reader :app
3442

43+
def assets
44+
Assets.new(
45+
app_name: app.name,
46+
ember_app_name: ember_app_name,
47+
manifest: rails_manifest,
48+
)
49+
end
50+
3551
def ember_app_name
3652
@ember_app_name ||= app.options.fetch(:name) { package_json.fetch(:name) }
3753
end
@@ -41,6 +57,14 @@ def package_json
4157
JSON.parse(app.paths.package_json_file.read).with_indifferent_access
4258
end
4359

60+
def rails_manifest
61+
if Rails.application.respond_to?(:assets_manifest)
62+
Rails.application.assets_manifest
63+
else
64+
MissingManifest.new
65+
end
66+
end
67+
4468
def asset_matcher
4569
%r{\A#{app.name}/}
4670
end

spec/lib/ember_cli/app_spec.rb

+9-1
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,17 @@
11
require "ember-cli-rails"
22

33
describe EmberCli::App do
4+
describe "#compile" do
5+
it "exits with exit status of 0" do
6+
passed = EmberCli["my-app"].compile
7+
8+
expect(passed).to be true
9+
end
10+
end
11+
412
describe "#test" do
513
it "exits with exit status of 0" do
6-
passed = silence_stream(STDOUT) { EmberCli["my-app"].test }
14+
passed = EmberCli["my-app"].test
715

816
expect(passed).to be true
917
end

spec/lib/ember_cli/assets_spec.rb

+109
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
require "ember_cli/assets"
2+
3+
describe EmberCli::Assets do
4+
describe "#javascripts" do
5+
it "includes the most recent javascript build artifacts" do
6+
manifest = build_manifest(
7+
assets: {
8+
"foo/assets/bar.js" => "foo/assets/bar-abc123.js",
9+
"foo/assets/vendor.js" => "foo/assets/vendor-abc123.js",
10+
},
11+
files: {
12+
"not-a-match" => {},
13+
"foo/assets/bar-abc123.js" => { "mtime" => 1.day.ago.iso8601 },
14+
"foo/assets/bar-def456.js" => { "mtime" => 2.days.ago.iso8601 },
15+
"foo/assets/vendor-def456.js" => { "mtime" => 2.days.ago.iso8601 },
16+
"foo/assets/vendor-abc123.js" => { "mtime" => 1.day.ago.iso8601 },
17+
},
18+
)
19+
assets = build_assets(
20+
app_name: "foo",
21+
ember_app_name: "bar",
22+
manifest: manifest,
23+
)
24+
25+
javascripts = assets.javascripts
26+
27+
expect(javascripts).to match_array([
28+
"foo/assets/bar.js",
29+
"foo/assets/vendor.js",
30+
])
31+
end
32+
33+
context "when the manifest is empty" do
34+
it "falls back to the default assets" do
35+
assets = build_assets(
36+
manifest: build_empty_manifest,
37+
app_name: "foo",
38+
ember_app_name: "bar",
39+
)
40+
41+
javascripts = assets.javascripts
42+
43+
expect(javascripts).to match_array([
44+
"foo/assets/vendor",
45+
"foo/assets/bar",
46+
])
47+
end
48+
end
49+
end
50+
51+
describe "#stylesheets" do
52+
it "includes the most recent stylesheet build artifacts" do
53+
manifest = build_manifest(
54+
assets: {
55+
"foo/assets/bar.css" => "foo/assets/bar-abc123.css",
56+
"foo/assets/vendor.css" => "foo/assets/vendor-abc123.css",
57+
},
58+
files: {
59+
"not-a-match" => {},
60+
"foo/assets/bar-def456.css" => { "mtime" => 2.days.ago.iso8601 },
61+
"foo/assets/bar-abc123.css" => { "mtime" => 1.day.ago.iso8601 },
62+
"foo/assets/vendor-abc123.css" => { "mtime" => 1.day.ago.iso8601 },
63+
"foo/assets/vendor-def456.css" => { "mtime" => 2.days.ago.iso8601 },
64+
},
65+
)
66+
assets = build_assets(
67+
app_name: "foo",
68+
ember_app_name: "bar",
69+
manifest: manifest,
70+
)
71+
72+
stylesheets = assets.stylesheets
73+
74+
expect(stylesheets).to match_array([
75+
"foo/assets/bar.css",
76+
"foo/assets/vendor.css",
77+
])
78+
end
79+
80+
context "when the manifest is empty" do
81+
it "falls back to the default assets" do
82+
assets = build_assets(
83+
manifest: build_empty_manifest,
84+
app_name: "foo",
85+
ember_app_name: "bar",
86+
)
87+
88+
stylesheets = assets.stylesheets
89+
90+
expect(stylesheets).to match_array([
91+
"foo/assets/vendor",
92+
"foo/assets/bar",
93+
])
94+
end
95+
end
96+
end
97+
end
98+
99+
def build_assets(manifest: build_manifest, **options)
100+
EmberCli::Assets.new(options.merge(manifest: manifest))
101+
end
102+
103+
def build_manifest(assets: {}, files: {})
104+
double(files: files, assets: assets)
105+
end
106+
107+
def build_empty_manifest
108+
build_manifest
109+
end

0 commit comments

Comments
 (0)