sq-asset_sync 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +15 -0
- data/.ruby-version +1 -0
- data/.travis.yml +42 -0
- data/Appraisals +15 -0
- data/CHANGELOG.md +738 -0
- data/Gemfile +7 -0
- data/README.md +466 -0
- data/Rakefile +44 -0
- data/asset_sync.gemspec +38 -0
- data/docs/heroku.md +36 -0
- data/gemfiles/rails_3.1.gemfile +10 -0
- data/gemfiles/rails_3.2.gemfile +10 -0
- data/gemfiles/rails_4.0.gemfile +10 -0
- data/gemfiles/rails_4.1.gemfile +10 -0
- data/kochiku.yml +7 -0
- data/lib/asset_sync.rb +15 -0
- data/lib/asset_sync/asset_sync.rb +73 -0
- data/lib/asset_sync/config.rb +226 -0
- data/lib/asset_sync/engine.rb +53 -0
- data/lib/asset_sync/multi_mime.rb +16 -0
- data/lib/asset_sync/railtie.rb +5 -0
- data/lib/asset_sync/storage.rb +291 -0
- data/lib/asset_sync/version.rb +3 -0
- data/lib/generators/asset_sync/install_generator.rb +67 -0
- data/lib/generators/asset_sync/templates/asset_sync.rb +41 -0
- data/lib/generators/asset_sync/templates/asset_sync.yml +43 -0
- data/lib/tasks/asset_sync.rake +30 -0
- data/script/ci +31 -0
- data/spec/dummy_app/Rakefile +30 -0
- data/spec/dummy_app/app/assets/javascripts/application.js +1 -0
- data/spec/fixtures/aws_with_yml/config/asset_sync.yml +25 -0
- data/spec/fixtures/google_with_yml/config/asset_sync.yml +19 -0
- data/spec/fixtures/rackspace_with_yml/config/asset_sync.yml +20 -0
- data/spec/fixtures/with_invalid_yml/config/asset_sync.yml +24 -0
- data/spec/integration/aws_integration_spec.rb +77 -0
- data/spec/spec_helper.rb +64 -0
- data/spec/unit/asset_sync_spec.rb +257 -0
- data/spec/unit/google_spec.rb +142 -0
- data/spec/unit/multi_mime_spec.rb +48 -0
- data/spec/unit/rackspace_spec.rb +90 -0
- data/spec/unit/railsless_spec.rb +72 -0
- data/spec/unit/storage_spec.rb +244 -0
- metadata +248 -0
@@ -0,0 +1,53 @@
|
|
1
|
+
module AssetSync
|
2
|
+
class Engine < Rails::Engine
|
3
|
+
|
4
|
+
engine_name "asset_sync"
|
5
|
+
|
6
|
+
initializer "asset_sync config", :group => :all do |app|
|
7
|
+
app_initializer = Rails.root.join('config', 'initializers', 'asset_sync.rb').to_s
|
8
|
+
app_yaml = Rails.root.join('config', 'asset_sync.yml').to_s
|
9
|
+
|
10
|
+
if File.exist?( app_initializer )
|
11
|
+
AssetSync.log "AssetSync: using #{app_initializer}"
|
12
|
+
load app_initializer
|
13
|
+
elsif !File.exist?( app_initializer ) && !File.exist?( app_yaml )
|
14
|
+
AssetSync.log "AssetSync: using default configuration from built-in initializer"
|
15
|
+
AssetSync.configure do |config|
|
16
|
+
config.fog_provider = ENV['FOG_PROVIDER'] if ENV.has_key?('FOG_PROVIDER')
|
17
|
+
config.fog_directory = ENV['FOG_DIRECTORY'] if ENV.has_key?('FOG_DIRECTORY')
|
18
|
+
config.fog_region = ENV['FOG_REGION'] if ENV.has_key?('FOG_REGION')
|
19
|
+
|
20
|
+
config.aws_access_key_id = ENV['AWS_ACCESS_KEY_ID'] if ENV.has_key?('AWS_ACCESS_KEY_ID')
|
21
|
+
config.aws_secret_access_key = ENV['AWS_SECRET_ACCESS_KEY'] if ENV.has_key?('AWS_SECRET_ACCESS_KEY')
|
22
|
+
config.aws_reduced_redundancy = ENV['AWS_REDUCED_REDUNDANCY'] == true if ENV.has_key?('AWS_REDUCED_REDUNDANCY')
|
23
|
+
|
24
|
+
config.rackspace_username = ENV['RACKSPACE_USERNAME'] if ENV.has_key?('RACKSPACE_USERNAME')
|
25
|
+
config.rackspace_api_key = ENV['RACKSPACE_API_KEY'] if ENV.has_key?('RACKSPACE_API_KEY')
|
26
|
+
|
27
|
+
config.google_storage_access_key_id = ENV['GOOGLE_STORAGE_ACCESS_KEY_ID'] if ENV.has_key?('GOOGLE_STORAGE_ACCESS_KEY_ID')
|
28
|
+
config.google_storage_secret_access_key = ENV['GOOGLE_STORAGE_SECRET_ACCESS_KEY'] if ENV.has_key?('GOOGLE_STORAGE_SECRET_ACCESS_KEY')
|
29
|
+
|
30
|
+
config.enabled = (ENV['ASSET_SYNC_ENABLED'] == 'true') if ENV.has_key?('ASSET_SYNC_ENABLED')
|
31
|
+
|
32
|
+
config.existing_remote_files = ENV['ASSET_SYNC_EXISTING_REMOTE_FILES'] || "keep"
|
33
|
+
|
34
|
+
config.gzip_compression = (ENV['ASSET_SYNC_GZIP_COMPRESSION'] == 'true') if ENV.has_key?('ASSET_SYNC_GZIP_COMPRESSION')
|
35
|
+
config.manifest = (ENV['ASSET_SYNC_MANIFEST'] == 'true') if ENV.has_key?('ASSET_SYNC_MANIFEST')
|
36
|
+
end
|
37
|
+
|
38
|
+
config.prefix = ENV['ASSET_SYNC_PREFIX'] if ENV.has_key?('ASSET_SYNC_PREFIX')
|
39
|
+
|
40
|
+
config.existing_remote_files = ENV['ASSET_SYNC_EXISTING_REMOTE_FILES'] || "keep"
|
41
|
+
|
42
|
+
config.gzip_compression = (ENV['ASSET_SYNC_GZIP_COMPRESSION'] == 'true') if ENV.has_key?('ASSET_SYNC_GZIP_COMPRESSION')
|
43
|
+
config.manifest = (ENV['ASSET_SYNC_MANIFEST'] == 'true') if ENV.has_key?('ASSET_SYNC_MANIFEST')
|
44
|
+
|
45
|
+
end
|
46
|
+
|
47
|
+
if File.exist?( app_yaml )
|
48
|
+
AssetSync.log "AssetSync: YAML file found #{app_yaml} settings will be merged into the configuration"
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'mime/types'
|
2
|
+
|
3
|
+
module AssetSync
|
4
|
+
class MultiMime
|
5
|
+
|
6
|
+
def self.lookup(ext)
|
7
|
+
if defined?(Mime::Type)
|
8
|
+
Mime::Type.lookup_by_extension(ext)
|
9
|
+
elsif defined?(Rack::Mime)
|
10
|
+
ext_with_dot = ".#{ext}"
|
11
|
+
Rack::Mime.mime_type(ext_with_dot)
|
12
|
+
end || ::MIME::Types.type_for(ext).first
|
13
|
+
end
|
14
|
+
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,291 @@
|
|
1
|
+
module AssetSync
|
2
|
+
class Storage
|
3
|
+
REGEXP_FINGERPRINTED_FILES = /^(.*)\/([^-]+)-[^\.]+\.([^\.]+)$/
|
4
|
+
|
5
|
+
class BucketNotFound < StandardError;
|
6
|
+
end
|
7
|
+
|
8
|
+
attr_accessor :config
|
9
|
+
|
10
|
+
def initialize(cfg)
|
11
|
+
@config = cfg
|
12
|
+
end
|
13
|
+
|
14
|
+
def connection
|
15
|
+
@connection ||= Fog::Storage.new(self.config.fog_options)
|
16
|
+
end
|
17
|
+
|
18
|
+
def bucket
|
19
|
+
# fixes: https://github.com/rumblelabs/asset_sync/issues/18
|
20
|
+
@bucket ||= connection.directories.get(self.config.fog_directory, :prefix => self.config.assets_prefix)
|
21
|
+
end
|
22
|
+
|
23
|
+
def log(msg)
|
24
|
+
AssetSync.log(msg)
|
25
|
+
end
|
26
|
+
|
27
|
+
def keep_existing_remote_files?
|
28
|
+
self.config.existing_remote_files?
|
29
|
+
end
|
30
|
+
|
31
|
+
def path
|
32
|
+
self.config.public_path
|
33
|
+
end
|
34
|
+
|
35
|
+
def ignored_files
|
36
|
+
files = []
|
37
|
+
Array(self.config.ignored_files).each do |ignore|
|
38
|
+
case ignore
|
39
|
+
when Regexp
|
40
|
+
files += self.local_files.select do |file|
|
41
|
+
file =~ ignore
|
42
|
+
end
|
43
|
+
when String
|
44
|
+
files += self.local_files.select do |file|
|
45
|
+
file.split('/').last == ignore
|
46
|
+
end
|
47
|
+
else
|
48
|
+
log "Error: please define ignored_files as string or regular expression. #{ignore} (#{ignore.class}) ignored."
|
49
|
+
end
|
50
|
+
end
|
51
|
+
files.uniq
|
52
|
+
end
|
53
|
+
|
54
|
+
def local_files
|
55
|
+
@local_files ||= get_local_files.uniq
|
56
|
+
end
|
57
|
+
|
58
|
+
def always_upload_files
|
59
|
+
self.config.always_upload.map { |f| File.join(self.config.assets_prefix, f) }
|
60
|
+
end
|
61
|
+
|
62
|
+
def files_with_custom_headers
|
63
|
+
self.config.custom_headers.inject({}) { |h,(k, v)| h[File.join(self.config.assets_prefix, k)] = v; h; }
|
64
|
+
end
|
65
|
+
|
66
|
+
def files_to_invalidate
|
67
|
+
self.config.invalidate.map { |filename| File.join("/", self.config.assets_prefix, filename) }
|
68
|
+
end
|
69
|
+
|
70
|
+
def get_local_files
|
71
|
+
if self.config.manifest
|
72
|
+
if ActionView::Base.respond_to?(:assets_manifest)
|
73
|
+
log "Using: Rails 4.0 manifest access"
|
74
|
+
manifest = Sprockets::Manifest.new(ActionView::Base.assets_manifest.environment, ActionView::Base.assets_manifest.dir)
|
75
|
+
return manifest.assets.values.map { |f| File.join(self.config.assets_prefix, f) }
|
76
|
+
elsif File.exist?(self.config.manifest_path)
|
77
|
+
log "Using: Manifest #{self.config.manifest_path}"
|
78
|
+
yml = YAML.load(IO.read(self.config.manifest_path))
|
79
|
+
|
80
|
+
return yml.map do |original, compiled|
|
81
|
+
# Upload font originals and compiled
|
82
|
+
if original =~ /^.+(eot|svg|ttf|woff)$/
|
83
|
+
[original, compiled]
|
84
|
+
else
|
85
|
+
compiled
|
86
|
+
end
|
87
|
+
end.flatten.map { |f| File.join(self.config.assets_prefix, f) }.uniq!
|
88
|
+
else
|
89
|
+
log "Warning: Manifest could not be found"
|
90
|
+
end
|
91
|
+
end
|
92
|
+
log "Using: Directory Search of #{path}/#{self.config.assets_prefix}"
|
93
|
+
Dir.chdir(path) do
|
94
|
+
to_load = self.config.assets_prefix.present? ? "#{self.config.assets_prefix}/**/**" : '**/**'
|
95
|
+
Dir[to_load]
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
def get_remote_files
|
100
|
+
raise BucketNotFound.new("#{self.config.fog_provider} Bucket: #{self.config.fog_directory} not found.") unless bucket
|
101
|
+
# fixes: https://github.com/rumblelabs/asset_sync/issues/16
|
102
|
+
# (work-around for https://github.com/fog/fog/issues/596)
|
103
|
+
files = []
|
104
|
+
bucket.files.each { |f| files << f.key }
|
105
|
+
return files
|
106
|
+
end
|
107
|
+
|
108
|
+
def delete_file(f, remote_files_to_delete)
|
109
|
+
if remote_files_to_delete.include?(f.key)
|
110
|
+
log "Deleting: #{f.key}"
|
111
|
+
f.destroy
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
def delete_extra_remote_files
|
116
|
+
log "Fetching files to flag for delete"
|
117
|
+
remote_files = get_remote_files
|
118
|
+
# fixes: https://github.com/rumblelabs/asset_sync/issues/19
|
119
|
+
from_remote_files_to_delete = remote_files - local_files - ignored_files - always_upload_files
|
120
|
+
|
121
|
+
log "Flagging #{from_remote_files_to_delete.size} file(s) for deletion"
|
122
|
+
# Delete unneeded remote files
|
123
|
+
bucket.files.each do |f|
|
124
|
+
delete_file(f, from_remote_files_to_delete)
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
def upload_file(f)
|
129
|
+
# TODO output files in debug logs as asset filename only.
|
130
|
+
one_year = 31557600
|
131
|
+
ext = File.extname(f)[1..-1]
|
132
|
+
mime = MultiMime.lookup(ext)
|
133
|
+
file = {
|
134
|
+
:key => f,
|
135
|
+
:body => File.open("#{path}/#{f}"),
|
136
|
+
:public => true,
|
137
|
+
:content_type => mime
|
138
|
+
}
|
139
|
+
|
140
|
+
uncompressed_filename = f.sub(/\.gz\z/, '')
|
141
|
+
basename = File.basename(uncompressed_filename, File.extname(uncompressed_filename))
|
142
|
+
if /-[0-9a-fA-F]{32,}$/.match(basename)
|
143
|
+
file.merge!({
|
144
|
+
:cache_control => "public, max-age=#{one_year}",
|
145
|
+
:expires => CGI.rfc1123_date(Time.now + one_year)
|
146
|
+
})
|
147
|
+
end
|
148
|
+
|
149
|
+
# overwrite headers if applicable, you probably shouldn't specific key/body, but cache-control headers etc.
|
150
|
+
|
151
|
+
if files_with_custom_headers.has_key? f
|
152
|
+
file.merge! files_with_custom_headers[f]
|
153
|
+
log "Overwriting #{f} with custom headers #{files_with_custom_headers[f].to_s}"
|
154
|
+
elsif key = self.config.custom_headers.keys.detect {|k| f.match(Regexp.new(k))}
|
155
|
+
headers = {}
|
156
|
+
self.config.custom_headers[key].each do |k, value|
|
157
|
+
headers[k.to_sym] = value
|
158
|
+
end
|
159
|
+
file.merge! headers
|
160
|
+
log "Overwriting matching file #{f} with custom headers #{headers.to_s}"
|
161
|
+
end
|
162
|
+
|
163
|
+
|
164
|
+
gzipped = "#{path}/#{f}.gz"
|
165
|
+
ignore = false
|
166
|
+
|
167
|
+
if config.gzip? && File.extname(f) == ".gz"
|
168
|
+
# Don't bother uploading gzipped assets if we are in gzip_compression mode
|
169
|
+
# as we will overwrite file.css with file.css.gz if it exists.
|
170
|
+
log "Ignoring: #{f}"
|
171
|
+
ignore = true
|
172
|
+
elsif config.gzip? && File.exist?(gzipped)
|
173
|
+
original_size = File.size("#{path}/#{f}")
|
174
|
+
gzipped_size = File.size(gzipped)
|
175
|
+
|
176
|
+
if gzipped_size < original_size
|
177
|
+
percentage = ((gzipped_size.to_f/original_size.to_f)*100).round(2)
|
178
|
+
file.merge!({
|
179
|
+
:key => f,
|
180
|
+
:body => File.open(gzipped),
|
181
|
+
:content_encoding => 'gzip'
|
182
|
+
})
|
183
|
+
log "Uploading: #{gzipped} in place of #{f} saving #{percentage}%"
|
184
|
+
else
|
185
|
+
percentage = ((original_size.to_f/gzipped_size.to_f)*100).round(2)
|
186
|
+
log "Uploading: #{f} instead of #{gzipped} (compression increases this file by #{percentage}%)"
|
187
|
+
end
|
188
|
+
else
|
189
|
+
if !config.gzip? && File.extname(f) == ".gz"
|
190
|
+
# set content encoding for gzipped files this allows cloudfront to properly handle requests with Accept-Encoding
|
191
|
+
# http://docs.amazonwebservices.com/AmazonCloudFront/latest/DeveloperGuide/ServingCompressedFiles.html
|
192
|
+
uncompressed_filename = f[0..-4]
|
193
|
+
ext = File.extname(uncompressed_filename)[1..-1]
|
194
|
+
mime = MultiMime.lookup(ext)
|
195
|
+
file.merge!({
|
196
|
+
:content_type => mime,
|
197
|
+
:content_encoding => 'gzip'
|
198
|
+
})
|
199
|
+
end
|
200
|
+
log "Uploading: #{f}"
|
201
|
+
end
|
202
|
+
|
203
|
+
if config.aws? && config.aws_rrs?
|
204
|
+
file.merge!({
|
205
|
+
:storage_class => 'REDUCED_REDUNDANCY'
|
206
|
+
})
|
207
|
+
end
|
208
|
+
|
209
|
+
file = bucket.files.create( file ) unless ignore
|
210
|
+
end
|
211
|
+
|
212
|
+
def skip_uploading?(manifest_file)
|
213
|
+
unless manifest_file
|
214
|
+
log "Failed to find manifest file"
|
215
|
+
return false
|
216
|
+
end
|
217
|
+
|
218
|
+
log "Found manifest file #{manifest_file}"
|
219
|
+
|
220
|
+
begin
|
221
|
+
s3_manifest = connection.head_object(self.config.fog_directory, manifest_file)
|
222
|
+
|
223
|
+
# If the manifest is within 24 hours old and exists on the server, we're going to assume
|
224
|
+
# we can skip uploading the assets.
|
225
|
+
created_at = Time.parse(s3_manifest.headers['Last-Modified']).utc
|
226
|
+
log "S3 Manifest was created on #{created_at} (#{Time.now.utc})"
|
227
|
+
return true if (Time.now.utc - created_at) <= 86400
|
228
|
+
|
229
|
+
rescue => ex
|
230
|
+
log "Got #{ex.class}, #{ex.message} while trying to HEAD the manifest from S3"
|
231
|
+
return false
|
232
|
+
end
|
233
|
+
|
234
|
+
false
|
235
|
+
end
|
236
|
+
|
237
|
+
def upload_files
|
238
|
+
manifest_file = self.config.manifest_digest_path
|
239
|
+
if skip_uploading?(manifest_file)
|
240
|
+
log "Skipping file upload"
|
241
|
+
return
|
242
|
+
end
|
243
|
+
|
244
|
+
# get a fresh list of remote files
|
245
|
+
remote_files = ignore_existing_remote_files? ? [] : get_remote_files
|
246
|
+
# fixes: https://github.com/rumblelabs/asset_sync/issues/19
|
247
|
+
local_files_to_upload = local_files - ignored_files - remote_files + always_upload_files
|
248
|
+
local_files_to_upload = (local_files_to_upload + get_non_fingerprinted(local_files_to_upload)).uniq
|
249
|
+
|
250
|
+
local_files_to_upload.delete manifest_file if manifest_file
|
251
|
+
|
252
|
+
# Upload new files
|
253
|
+
local_files_to_upload.each do |f|
|
254
|
+
next unless File.file? "#{path}/#{f}" # Only files.
|
255
|
+
upload_file f
|
256
|
+
end
|
257
|
+
|
258
|
+
# At the very end, upload the manifest indicating we're done
|
259
|
+
upload_file manifest_file if manifest_file
|
260
|
+
|
261
|
+
if self.config.cdn_distribution_id && files_to_invalidate.any?
|
262
|
+
log "Invalidating Files"
|
263
|
+
cdn ||= Fog::CDN.new(self.config.fog_options.except(:region))
|
264
|
+
data = cdn.post_invalidation(self.config.cdn_distribution_id, files_to_invalidate)
|
265
|
+
log "Invalidation id: #{data.body["Id"]}"
|
266
|
+
end
|
267
|
+
end
|
268
|
+
|
269
|
+
def sync
|
270
|
+
# fixes: https://github.com/rumblelabs/asset_sync/issues/19
|
271
|
+
log "AssetSync: Syncing."
|
272
|
+
upload_files
|
273
|
+
delete_extra_remote_files unless keep_existing_remote_files?
|
274
|
+
log "AssetSync: Done."
|
275
|
+
end
|
276
|
+
|
277
|
+
private
|
278
|
+
|
279
|
+
def ignore_existing_remote_files?
|
280
|
+
self.config.existing_remote_files == 'ignore'
|
281
|
+
end
|
282
|
+
|
283
|
+
def get_non_fingerprinted(files)
|
284
|
+
files.map do |file|
|
285
|
+
match_data = file.match(REGEXP_FINGERPRINTED_FILES)
|
286
|
+
match_data && "#{match_data[1]}/#{match_data[2]}.#{match_data[3]}"
|
287
|
+
end.compact
|
288
|
+
end
|
289
|
+
|
290
|
+
end
|
291
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
require 'rails/generators'
|
2
|
+
module AssetSync
|
3
|
+
class InstallGenerator < Rails::Generators::Base
|
4
|
+
desc "Install a config/asset_sync.yml and the asset:precompile rake task enhancer"
|
5
|
+
|
6
|
+
# Commandline options can be defined here using Thor-like options:
|
7
|
+
class_option :use_yml, :type => :boolean, :default => false, :desc => "Use YML file instead of Rails Initializer"
|
8
|
+
class_option :provider, :type => :string, :default => "AWS", :desc => "Generate with support for 'AWS', 'Rackspace', or 'Google'"
|
9
|
+
|
10
|
+
def self.source_root
|
11
|
+
@source_root ||= File.join(File.dirname(__FILE__), 'templates')
|
12
|
+
end
|
13
|
+
|
14
|
+
def aws?
|
15
|
+
options[:provider] == 'AWS'
|
16
|
+
end
|
17
|
+
|
18
|
+
def google?
|
19
|
+
options[:provider] == 'Google'
|
20
|
+
end
|
21
|
+
|
22
|
+
def rackspace?
|
23
|
+
options[:provider] == 'Rackspace'
|
24
|
+
end
|
25
|
+
|
26
|
+
def aws_access_key_id
|
27
|
+
"<%= ENV['AWS_ACCESS_KEY_ID'] %>"
|
28
|
+
end
|
29
|
+
|
30
|
+
def aws_secret_access_key
|
31
|
+
"<%= ENV['AWS_SECRET_ACCESS_KEY'] %>"
|
32
|
+
end
|
33
|
+
|
34
|
+
def google_storage_access_key_id
|
35
|
+
"<%= ENV['GOOGLE_STORAGE_ACCESS_KEY_ID'] %>"
|
36
|
+
end
|
37
|
+
|
38
|
+
def google_storage_secret_access_key
|
39
|
+
"<%= ENV['GOOGLE_STORAGE_SECRET_ACCESS_KEY'] %>"
|
40
|
+
end
|
41
|
+
|
42
|
+
def rackspace_username
|
43
|
+
"<%= ENV['RACKSPACE_USERNAME'] %>"
|
44
|
+
end
|
45
|
+
|
46
|
+
def rackspace_api_key
|
47
|
+
"<%= ENV['RACKSPACE_API_KEY'] %>"
|
48
|
+
end
|
49
|
+
|
50
|
+
def app_name
|
51
|
+
@app_name ||= Rails.application.is_a?(Rails::Application) && Rails.application.class.name.sub(/::Application$/, "").downcase
|
52
|
+
end
|
53
|
+
|
54
|
+
def generate_config
|
55
|
+
if options[:use_yml]
|
56
|
+
template "asset_sync.yml", "config/asset_sync.yml"
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def generate_initializer
|
61
|
+
unless options[:use_yml]
|
62
|
+
template "asset_sync.rb", "config/initializers/asset_sync.rb"
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
end
|
67
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
AssetSync.configure do |config|
|
2
|
+
<%- if aws? -%>
|
3
|
+
config.fog_provider = 'AWS'
|
4
|
+
config.aws_access_key_id = ENV['AWS_ACCESS_KEY_ID']
|
5
|
+
config.aws_secret_access_key = ENV['AWS_SECRET_ACCESS_KEY']
|
6
|
+
# To use AWS reduced redundancy storage.
|
7
|
+
# config.aws_reduced_redundancy = true
|
8
|
+
<%- elsif google? -%>
|
9
|
+
config.fog_provider = 'Google'
|
10
|
+
config.google_storage_access_key_id = ENV['GOOGLE_STORAGE_ACCESS_KEY_ID']
|
11
|
+
config.google_storage_secret_access_key = ENV['GOOGLE_STORAGE_SECRET_ACCESS_KEY']
|
12
|
+
<%- elsif rackspace? -%>
|
13
|
+
config.fog_provider = 'Rackspace'
|
14
|
+
config.rackspace_username = ENV['RACKSPACE_USERNAME']
|
15
|
+
config.rackspace_api_key = ENV['RACKSPACE_API_KEY']
|
16
|
+
|
17
|
+
# if you need to change rackspace_auth_url (e.g. if you need to use Rackspace London)
|
18
|
+
# config.rackspace_auth_url = "lon.auth.api.rackspacecloud.com"
|
19
|
+
<%- end -%>
|
20
|
+
config.fog_directory = ENV['FOG_DIRECTORY']
|
21
|
+
|
22
|
+
# Invalidate a file on a cdn after uploading files
|
23
|
+
# config.cdn_distribution_id = "12345"
|
24
|
+
# config.invalidate = ['file1.js']
|
25
|
+
|
26
|
+
# Increase upload performance by configuring your region
|
27
|
+
# config.fog_region = 'eu-west-1'
|
28
|
+
#
|
29
|
+
# Don't delete files from the store
|
30
|
+
# config.existing_remote_files = "keep"
|
31
|
+
#
|
32
|
+
# Automatically replace files with their equivalent gzip compressed version
|
33
|
+
# config.gzip_compression = true
|
34
|
+
#
|
35
|
+
# Use the Rails generated 'manifest.yml' file to produce the list of files to
|
36
|
+
# upload instead of searching the assets directory.
|
37
|
+
# config.manifest = true
|
38
|
+
#
|
39
|
+
# Fail silently. Useful for environments such as Heroku
|
40
|
+
# config.fail_silently = true
|
41
|
+
end
|