Skip to content

Commit

Permalink
Make assets precompile symlink task compatible with Rails 3 (#566)
Browse files Browse the repository at this point in the history
  • Loading branch information
etripier authored and justin808 committed Oct 25, 2016
1 parent bfa238a commit 337561c
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 25 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@ All notable changes to this project will be documented in this file. Items under

Contributors: please follow the recommendations outlined at [keepachangelog.com](http://keepachangelog.com/). Please use the existing headings and styling as a guide, and add a link for the version diff at the bottom of the file. Also, please update the `Unreleased` link to compare to the latest release version.

## [Unreleased]
##### Fixed
- Added compatibility with older manifest.yml files produced by Rails 3 Sprockets when symlinking digested assets during precompilation [#566](https://github.com/shakacode/react_on_rails/pull/566) by [etripier](https://github.com/etripier).

## [6.1.1] 2016-09-09
##### Fixed
- React on Rails was incorrectly failing to create symlinks when a file existed in the location for the new symlink. [#491](https://github.com/shakacode/react_on_rails/pull/541) by [robwise ](https://github.com/robwise) and [justin808](https://github.com/justin808).
Expand Down
53 changes: 29 additions & 24 deletions lib/react_on_rails/assets_precompile.rb
Original file line number Diff line number Diff line change
Expand Up @@ -57,30 +57,35 @@ def symlink_non_digested_assets
# directory with a digest, then the files are essentially "double-digested" and the CSS
# references from webpack's CSS would be invalid. The fix is to symlink the double-digested
# file back to the original digested name, and make a similar symlink for the gz version.
if @symlink_non_digested_assets_regex
manifest_glob = Dir.glob(@assets_path.join(".sprockets-manifest-*.json")) +
Dir.glob(@assets_path.join("manifest-*.json"))
if manifest_glob.empty?
puts "Warning: React On Rails: expected to find .sprockets-manifest-*.json or manifest-*.json "\
"at #{@assets_path}, but found none. Canceling symlinking tasks."
return -1
end
manifest_path = manifest_glob.first
manifest_data = JSON.load(File.new(manifest_path))

# We realize that we're copying other Rails assets that match the regexp, but this just
# means that we'd be exposing the original, undigested names.
manifest_data["assets"].each do |original_filename, rails_digested_filename|
# TODO: we should remove any original_filename that is NOT in the webpack deploy folder.
next unless original_filename =~ @symlink_non_digested_assets_regex
# We're symlinking from the digested filename back to the original filename which has
# already been symlinked by Webpack
symlink_file(rails_digested_filename, original_filename)

# We want the gz ones as well if they exist
if File.exist?(@assets_path.join("#{rails_digested_filename}.gz"))
symlink_file("#{rails_digested_filename}.gz", "#{original_filename}.gz")
end
return unless @symlink_non_digested_assets_regex
manifest_glob = Dir.glob(@assets_path.join(".sprockets-manifest-*.json")) +
Dir.glob(@assets_path.join("manifest-*.json")) +
Dir.glob(@assets_path.join("manifest.yml"))
if manifest_glob.empty?
puts "Warning: React On Rails: expected to find .sprockets-manifest-*.json, manifest-*.json "\
"or manifest.yml at #{@assets_path}, but found none. Canceling symlinking tasks."
return -1
end
manifest_path = manifest_glob.first
manifest_file = File.new(manifest_path)
manifest_data = if File.extname(manifest_file) == ".json"
JSON.load(manifest_file)["assets"]
else
YAML.load(manifest_file)
end

# We realize that we're copying other Rails assets that match the regexp, but this just
# means that we'd be exposing the original, undigested names.
manifest_data.each do |original_filename, rails_digested_filename|
# TODO: we should remove any original_filename that is NOT in the webpack deploy folder.
next unless original_filename =~ @symlink_non_digested_assets_regex
# We're symlinking from the digested filename back to the original filename which has
# already been symlinked by Webpack
symlink_file(rails_digested_filename, original_filename)

# We want the gz ones as well if they exist
if File.exist?(@assets_path.join("#{rails_digested_filename}.gz"))
symlink_file("#{rails_digested_filename}.gz", "#{original_filename}.gz")
end
end
end
Expand Down
22 changes: 21 additions & 1 deletion spec/react_on_rails/assets_precompile_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -112,17 +112,36 @@ module ReactOnRails
let(:digest_filename) { "alfa.12345.js" }
let(:nondigest_filename) { "alfa.js" }

let(:checker) do
let(:create_json_manifest) do
File.open(assets_path.join("manifest-alfa.json"), "w") do |f|
f.write("{\"assets\":{\"#{nondigest_filename}\": \"#{digest_filename}\"}}")
end
end

let(:create_yaml_manifest) do
File.open(assets_path.join("manifest.yml"), "w") do |f|
f.write("---\n#{nondigest_filename}: #{digest_filename}")
end
end

let(:checker) do
AssetsPrecompile.new(assets_path: assets_path,
symlink_non_digested_assets_regex: Regexp.new('.*\.js$'))
end

it "creates a symlink with the original filename that points to the digested filename" do
FileUtils.touch assets_path.join(digest_filename)
create_json_manifest
checker.symlink_non_digested_assets

expect(assets_path.join(nondigest_filename).lstat.symlink?).to be true
expect(File.identical?(assets_path.join(nondigest_filename),
assets_path.join(digest_filename))).to be true
end

it "creates a symlink that points to the digested filename for the original filename found in the manifest.yml" do
FileUtils.touch assets_path.join(digest_filename)
create_yaml_manifest
checker.symlink_non_digested_assets

expect(assets_path.join(nondigest_filename).lstat.symlink?).to be true
Expand All @@ -133,6 +152,7 @@ module ReactOnRails
it "creates a symlink with the original filename plus .gz that points to the gzipped digested filename" do
FileUtils.touch assets_path.join(digest_filename)
FileUtils.touch assets_path.join("#{digest_filename}.gz")
create_json_manifest
checker.symlink_non_digested_assets

expect(assets_path.join("#{nondigest_filename}.gz").lstat.symlink?).to be true
Expand Down

0 comments on commit 337561c

Please sign in to comment.