Module: EY::Serverside::RailsAssetSupport

Included in:
DeployBase
Defined in:
lib/engineyard-serverside/rails_asset_support.rb

Instance Method Summary collapse

Instance Method Details

#app_builds_own_assets?Boolean

Returns:

  • (Boolean)


69
70
71
# File 'lib/engineyard-serverside/rails_asset_support.rb', line 69

def app_builds_own_assets?
  File.directory?(File.join(c.release_path, 'public', 'assets'))
end

#app_disables_assets?(path) ⇒ Boolean

Returns:

  • (Boolean)


49
50
51
52
53
54
55
56
57
# File 'lib/engineyard-serverside/rails_asset_support.rb', line 49

def app_disables_assets?(path)
  disabled = nil
  File.open(path) do |fd|
    pattern = /^[^#].*config\.assets\.enabled\s+=\s+(false|nil)/
    contents = fd.read
    disabled = contents.match(pattern)
  end
  disabled
end

#app_has_asset_task?Boolean

Runs ‘rake -T’ to see if there is an assets:precompile task.

Returns:

  • (Boolean)


60
61
62
63
64
65
66
67
# File 'lib/engineyard-serverside/rails_asset_support.rb', line 60

def app_has_asset_task?
  # We just run this locally on the app master; everybody else should
  # have the same code anyway.
  task_check = "PATH=#{c.binstubs_path}:$PATH #{c.framework_envs} rake -T assets:precompile |grep 'assets:precompile'"
  cmd = "cd #{c.release_path} && #{task_check}"
  logged_system "cd #{c.release_path} && #{task_check}"
  $? == 0
end

#app_needs_assets?Boolean

Returns:

  • (Boolean)


20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
# File 'lib/engineyard-serverside/rails_asset_support.rb', line 20

def app_needs_assets?
  app_rb_path = File.join(c.release_path, 'config', 'application.rb')
  return unless File.readable?(app_rb_path) # Not a Rails app in the first place.

  if File.directory?(File.join(c.release_path, 'app', 'assets'))
    info "~> app/assets/ found. Attempting Rails asset pre-compilation."
  else
    return false
  end

  if app_builds_own_assets?
    info "~> public/assets already exists, skipping pre-compilation."
    return
  end
  if app_disables_assets?(app_rb_path)
    info "~> application.rb has disabled asset compilation. Skipping."
    return
  end
# This check is very expensive, and has been deemed not worth the time.
# Leaving this here in case someone comes up with a faster way.
=begin
  unless app_has_asset_task?
    info "~> No 'assets:precompile' Rake task found. Skipping."
    return
  end
=end
  true
end

#bundled_rails_version(lockfile_path = nil) ⇒ Object



91
92
93
94
95
96
97
98
99
100
101
102
# File 'lib/engineyard-serverside/rails_asset_support.rb', line 91

def bundled_rails_version(lockfile_path = nil)
  lockfile_path ||= File.join(c.release_path, 'Gemfile.lock')
  lockfile = File.open(lockfile_path) {|f| f.read}
  lockfile.each_line do |line|
    # scan for gemname (version) toplevel deps.
    # Likely doesn't handle ancient Bundler versions, but
    # we only call this when something looks like it is Rails 3.
    next unless line =~ /^\s{4}([-\w_.0-9]+)\s*\((.*)\)/
    return $2 if $1 == 'rails'
  end
  nil
end

#compile_assetsObject



4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# File 'lib/engineyard-serverside/rails_asset_support.rb', line 4

def compile_assets
  asset_dir = "#{c.release_path}/app/assets"
  return unless app_needs_assets?
  rails_version = bundled_rails_version
  roles :app_master, :app, :solo do
    keep_existing_assets
    cmd = "cd #{c.release_path} && PATH=#{c.binstubs_path}:$PATH #{c.framework_envs} rake assets:precompile || true"
    if rails_version
      info "~> Precompiling assets for rails v#{rails_version}"
    else
      warning "Precompiling assets even though Rails was not bundled."
    end
    run(cmd)
  end
end

#keep_existing_assetsObject

To support operations like Unicorn’s hot reload, it is useful to have the prior release’s assets as well. Otherwise, while a deploy is running, clients may request stale assets that you just deleted. Making use of this requires a properly-configured front-end HTTP server.



77
78
79
80
81
82
83
84
85
86
87
88
89
# File 'lib/engineyard-serverside/rails_asset_support.rb', line 77

def keep_existing_assets
 current = File.join(c.shared_path, 'assets')
 last_asset_path = File.join(c.shared_path, 'last_assets')
 # If there are current shared assets, move them under a 'last_assets' directory.
 run <<-COMMAND
if [ -d #{current} ]; then
  rm -rf #{last_asset_path} && mkdir #{last_asset_path} && mv #{current} #{last_asset_path} && mkdir -p #{current};
else
  mkdir -p #{current} #{last_asset_path};
fi;
ln -nfs #{current} #{last_asset_path} #{c.release_path}/public
 COMMAND
end