asset_hat 0.1.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.
- data/.gitignore +1 -0
- data/HISTORY +12 -0
- data/LICENSE +20 -0
- data/README.markdown +153 -0
- data/Rakefile +22 -0
- data/VERSION.yml +5 -0
- data/app/helpers/asset_hat_helper.rb +171 -0
- data/asset_hat.gemspec +98 -0
- data/config/assets.yml +59 -0
- data/lib/asset_hat.rb +85 -0
- data/lib/asset_hat/css.rb +76 -0
- data/lib/asset_hat/js.rb +86 -0
- data/lib/asset_hat/tasks.rb +296 -0
- data/lib/asset_hat/vcs.rb +65 -0
- data/lib/asset_hat/version.rb +11 -0
- data/public/javascripts/bundles/js-bundle-1.min.js +6 -0
- data/public/javascripts/bundles/js-bundle-2.min.js +6 -0
- data/public/javascripts/bundles/js-bundle-3.min.js +6 -0
- data/public/javascripts/js-file-1-1.js +1 -0
- data/public/javascripts/js-file-1-2.js +1 -0
- data/public/javascripts/js-file-1-3.js +1 -0
- data/public/javascripts/js-file-2-1.js +1 -0
- data/public/javascripts/js-file-2-2.js +1 -0
- data/public/javascripts/js-file-2-3.js +1 -0
- data/public/javascripts/js-file-3-1.js +1 -0
- data/public/javascripts/js-file-3-2.js +1 -0
- data/public/javascripts/js-file-3-3.js +1 -0
- data/public/stylesheets/bundles/css-bundle-1.min.css +3 -0
- data/public/stylesheets/bundles/css-bundle-2.min.css +3 -0
- data/public/stylesheets/bundles/css-bundle-3.min.css +3 -0
- data/public/stylesheets/css-file-1-1.css +1 -0
- data/public/stylesheets/css-file-1-2.css +1 -0
- data/public/stylesheets/css-file-1-3.css +1 -0
- data/public/stylesheets/css-file-2-1.css +1 -0
- data/public/stylesheets/css-file-2-2.css +1 -0
- data/public/stylesheets/css-file-2-3.css +1 -0
- data/public/stylesheets/css-file-3-1.css +1 -0
- data/public/stylesheets/css-file-3-2.css +1 -0
- data/public/stylesheets/css-file-3-3.css +1 -0
- data/rails/init.rb +17 -0
- data/tasks/asset_hat.rake +1 -0
- data/test/asset_hat_helper_test.rb +237 -0
- data/test/asset_hat_test.rb +46 -0
- data/test/test_helper.rb +23 -0
- metadata +141 -0
data/config/assets.yml
ADDED
@@ -0,0 +1,59 @@
|
|
1
|
+
# This belongs in your app's `config` directory. Configure your bundles
|
2
|
+
# below; no `.css` or `.js` suffixes needed. Example:
|
3
|
+
#
|
4
|
+
# css:
|
5
|
+
# engine: cssmin
|
6
|
+
# bundles:
|
7
|
+
# application:
|
8
|
+
# - reset
|
9
|
+
# - application
|
10
|
+
# - clearfix
|
11
|
+
# admin:
|
12
|
+
# - reset
|
13
|
+
# - admin
|
14
|
+
# - clearfix
|
15
|
+
# js:
|
16
|
+
# engine: jsmin
|
17
|
+
# vendors:
|
18
|
+
# jquery:
|
19
|
+
# version: 1.4
|
20
|
+
# bundles:
|
21
|
+
# plugins:
|
22
|
+
# - init
|
23
|
+
# - third-party-plugin.min
|
24
|
+
# # Here, the suffix `.min` indicates that the code has already
|
25
|
+
# # been minified, and should not be re-minified.
|
26
|
+
# common:
|
27
|
+
# - utilities
|
28
|
+
# - application
|
29
|
+
|
30
|
+
css:
|
31
|
+
engine: cssmin
|
32
|
+
bundles:
|
33
|
+
css-bundle-1:
|
34
|
+
- css-file-1-1
|
35
|
+
- css-file-1-2
|
36
|
+
- css-file-1-3
|
37
|
+
css-bundle-2:
|
38
|
+
- css-file-2-1
|
39
|
+
- css-file-2-2
|
40
|
+
- css-file-2-3
|
41
|
+
css-bundle-3:
|
42
|
+
- css-file-3-1
|
43
|
+
- css-file-3-2
|
44
|
+
- css-file-3-3
|
45
|
+
js:
|
46
|
+
engine: jsmin
|
47
|
+
bundles:
|
48
|
+
js-bundle-1:
|
49
|
+
- js-file-1-1
|
50
|
+
- js-file-1-2
|
51
|
+
- js-file-1-3
|
52
|
+
js-bundle-2:
|
53
|
+
- js-file-2-1
|
54
|
+
- js-file-2-2
|
55
|
+
- js-file-2-3
|
56
|
+
js-bundle-3:
|
57
|
+
- js-file-3-1
|
58
|
+
- js-file-3-2
|
59
|
+
- js-file-3-3
|
data/lib/asset_hat.rb
ADDED
@@ -0,0 +1,85 @@
|
|
1
|
+
%w[css js vcs].each do |x|
|
2
|
+
require File.join(File.dirname(__FILE__), 'asset_hat', x)
|
3
|
+
end
|
4
|
+
|
5
|
+
module AssetHat
|
6
|
+
RAILS_ROOT = File.join(File.dirname(__FILE__), '..') unless defined?(RAILS_ROOT)
|
7
|
+
TYPES = [:css, :js]
|
8
|
+
ASSETS_DIR = defined?(Rails.public_path) ? Rails.public_path : 'public'
|
9
|
+
JAVASCRIPTS_DIR = "#{ASSETS_DIR}/javascripts"
|
10
|
+
STYLESHEETS_DIR = "#{ASSETS_DIR}/stylesheets"
|
11
|
+
CONFIG_FILEPATH = File.join(RAILS_ROOT, 'config', 'assets.yml')
|
12
|
+
|
13
|
+
def self.config
|
14
|
+
@@config ||= YAML.load(File.open(CONFIG_FILEPATH, 'r'))
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.assets_dir(type)
|
18
|
+
case type.to_sym
|
19
|
+
when :css ; STYLESHEETS_DIR
|
20
|
+
when :js ; JAVASCRIPTS_DIR
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.asset_exists?(filename, type)
|
25
|
+
# Process arguments
|
26
|
+
type = type.to_sym
|
27
|
+
unless TYPES.include?(type)
|
28
|
+
raise "Unknown type \"#{type}\"; should be one of: #{TYPES.join(', ')}."
|
29
|
+
return
|
30
|
+
end
|
31
|
+
|
32
|
+
@@asset_exists ||= TYPES.inject({}) do |hsh, known_type|
|
33
|
+
hsh.merge!(known_type => {})
|
34
|
+
end
|
35
|
+
if @@asset_exists[type][filename].nil?
|
36
|
+
@@asset_exists[type][filename] =
|
37
|
+
File.exist?(File.join(self.assets_dir(type), filename))
|
38
|
+
end
|
39
|
+
@@asset_exists[type][filename]
|
40
|
+
end
|
41
|
+
|
42
|
+
def self.cache? ; ActionController::Base.perform_caching ; end
|
43
|
+
|
44
|
+
def self.min_filepath(filepath, extension)
|
45
|
+
filepath.sub(/([^\.]*).#{extension}$/, "\\1.min.#{extension}")
|
46
|
+
end
|
47
|
+
|
48
|
+
def self.bundle_filenames(bundle, type)
|
49
|
+
# Usage:
|
50
|
+
#
|
51
|
+
# AssetHat.bundle_filenames('application', :css)
|
52
|
+
# # => ['reset', 'application', 'clearfix']
|
53
|
+
# AssetHat.bundle_filenames('non-existent-file', :css)
|
54
|
+
# # => nil
|
55
|
+
|
56
|
+
# Process arguments
|
57
|
+
unless TYPES.include?(type.to_sym)
|
58
|
+
raise "Unknown type \"#{type}\"; should be one of: #{TYPES.join(', ')}."
|
59
|
+
return
|
60
|
+
end
|
61
|
+
|
62
|
+
self.config[type.to_s]['bundles'][bundle] rescue nil
|
63
|
+
end
|
64
|
+
|
65
|
+
def self.bundle_filepaths(bundle, type)
|
66
|
+
# Usage:
|
67
|
+
#
|
68
|
+
# AssetHat.bundle_filenames('application', :css)
|
69
|
+
# # => ['reset', 'application', 'clearfix']
|
70
|
+
# AssetHat.bundle_filenames('non-existent-file', :css)
|
71
|
+
# # => nil
|
72
|
+
|
73
|
+
# Process arguments
|
74
|
+
unless TYPES.include?(type.to_sym)
|
75
|
+
raise "Unknown type \"#{type}\"; should be one of: #{TYPES.join(', ')}."
|
76
|
+
return
|
77
|
+
end
|
78
|
+
|
79
|
+
dir = self.assets_dir(type)
|
80
|
+
filenames = self.bundle_filenames(bundle, type)
|
81
|
+
filepaths = filenames.present? ?
|
82
|
+
filenames.map { |fn| File.join(dir, "#{fn}.#{type}") } : nil
|
83
|
+
end
|
84
|
+
|
85
|
+
end
|
@@ -0,0 +1,76 @@
|
|
1
|
+
require 'cssmin'
|
2
|
+
# - http://github.com/rgrove/cssmin
|
3
|
+
# - http://gemcutter.org/gems/cssmin
|
4
|
+
|
5
|
+
module AssetHat
|
6
|
+
module CSS
|
7
|
+
ENGINES = [:weak, :cssmin]
|
8
|
+
|
9
|
+
def self.min_filepath(filepath)
|
10
|
+
AssetHat.min_filepath(filepath, 'css')
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.minify(input_string, options={})
|
14
|
+
options.reverse_merge!(:engine => :cssmin)
|
15
|
+
|
16
|
+
options[:engine] = options[:engine].to_sym
|
17
|
+
unless ENGINES.include?(options[:engine])
|
18
|
+
raise %Q{
|
19
|
+
Unknown CSS minification engine '#{options[:engine]}'.
|
20
|
+
Allowed: #{ENGINES.map{ |e| "'#{e}'" }.join(', ')}
|
21
|
+
}.strip.gsub(/\s+/, ' ') and return
|
22
|
+
end
|
23
|
+
|
24
|
+
AssetHat::CSS::Engines.send(options[:engine], input_string)
|
25
|
+
end
|
26
|
+
|
27
|
+
# def self.add_asset_mtimes(css)
|
28
|
+
# css.gsub(/url[\s]*\((\/images\/[^)]+)\)/) do |match|
|
29
|
+
# src = $1
|
30
|
+
# mtime = File.mtime(File.join(Rails.public_path, src))
|
31
|
+
# "url(#{src}?#{mtime.to_i})"
|
32
|
+
# end
|
33
|
+
# end
|
34
|
+
|
35
|
+
def self.add_asset_commit_ids(css)
|
36
|
+
css.gsub(/url[\s]*\((\/images\/[^)]+)\)/) do |match|
|
37
|
+
src = $1
|
38
|
+
filepath = File.join(Rails.public_path, src)
|
39
|
+
commit_id = AssetHat.last_commit_id(filepath)
|
40
|
+
commit_id.present? ? "url(#{src}?#{commit_id})" : "url(#{src})"
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def self.add_asset_hosts(css, asset_host)
|
45
|
+
return if asset_host.blank?
|
46
|
+
css.gsub(/url[\s]*\((\/images\/[^)]+)\)/) do |match|
|
47
|
+
src = $1
|
48
|
+
"url(#{(asset_host =~ /%d/) ? asset_host % (src.hash % 4) : asset_host}#{src})"
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
module Engines
|
53
|
+
def self.weak(input_string)
|
54
|
+
input = StringIO.new(input_string)
|
55
|
+
output = StringIO.new
|
56
|
+
|
57
|
+
input.each do |line|
|
58
|
+
# Remove indentation and trailing whitespace (including line breaks)
|
59
|
+
line.strip!
|
60
|
+
next if line.blank?
|
61
|
+
|
62
|
+
output.write line
|
63
|
+
end
|
64
|
+
|
65
|
+
output.rewind
|
66
|
+
output.read
|
67
|
+
end
|
68
|
+
|
69
|
+
def self.cssmin(input_string)
|
70
|
+
CSSMin.minify(input_string)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
end
|
75
|
+
|
76
|
+
end
|
data/lib/asset_hat/js.rb
ADDED
@@ -0,0 +1,86 @@
|
|
1
|
+
require 'jsmin'
|
2
|
+
# - http://github.com/rgrove/jsmin
|
3
|
+
# - http://gemcutter.org/gems/jsmin
|
4
|
+
|
5
|
+
module AssetHat
|
6
|
+
module JS
|
7
|
+
ENGINES = [:weak, :jsmin]
|
8
|
+
VENDORS = [:jquery]
|
9
|
+
# TODO: Support jQuery UI, Prototype, MooTools, etc.
|
10
|
+
|
11
|
+
def self.min_filepath(filepath)
|
12
|
+
AssetHat.min_filepath(filepath, 'js')
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.minify(input_string, options={})
|
16
|
+
options.reverse_merge!(:engine => :jsmin)
|
17
|
+
|
18
|
+
options[:engine] = options[:engine].to_sym
|
19
|
+
unless ENGINES.include?(options[:engine])
|
20
|
+
raise %Q{
|
21
|
+
Unknown JS minification engine '#{options[:engine]}'.
|
22
|
+
Allowed: #{ENGINES.map{ |e| "'#{e}'" }.join(', ')}
|
23
|
+
}.strip.gsub(/\s+/, ' ') and return
|
24
|
+
end
|
25
|
+
|
26
|
+
AssetHat::JS::Engines.send(options[:engine], input_string)
|
27
|
+
end
|
28
|
+
|
29
|
+
module Engines
|
30
|
+
def self.weak(input_string)
|
31
|
+
input = StringIO.new(input_string)
|
32
|
+
output = StringIO.new
|
33
|
+
|
34
|
+
input.each do |line|
|
35
|
+
# Remove indentation and trailing whitespace
|
36
|
+
line.strip!
|
37
|
+
next if line.blank?
|
38
|
+
|
39
|
+
# Skip single-line comments
|
40
|
+
next if !(line =~ /^\/\//).nil?
|
41
|
+
# TODO: Also skip single-line comments that began mid-line, but not
|
42
|
+
# inside a string or regex
|
43
|
+
|
44
|
+
# TODO: Skip multi-line comments
|
45
|
+
# - Should not strip from within a string or regex
|
46
|
+
# - Should not strip comments that begin with `/*!` (e.g., licenses)
|
47
|
+
|
48
|
+
output.write(line + "\n")
|
49
|
+
end
|
50
|
+
|
51
|
+
output.rewind
|
52
|
+
output.read
|
53
|
+
end
|
54
|
+
|
55
|
+
def self.jsmin(input_string)
|
56
|
+
JSMin.minify(input_string)
|
57
|
+
end
|
58
|
+
end # module Engines
|
59
|
+
|
60
|
+
module Vendors
|
61
|
+
JQUERY_DEFAULT_VERSION = '1.4'
|
62
|
+
|
63
|
+
def self.source_for(vendor, options={})
|
64
|
+
version = options[:version]
|
65
|
+
if version.blank?
|
66
|
+
version = begin
|
67
|
+
AssetHat.config['js']['vendors'][vendor.to_s]['version']
|
68
|
+
rescue
|
69
|
+
AssetHat::JS::Vendors.const_get(
|
70
|
+
:"#{vendor.to_s.upcase}_DEFAULT_VERSION")
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
case vendor
|
75
|
+
when :jquery
|
76
|
+
src = ActionController::Base.consider_all_requests_local ?
|
77
|
+
"jquery-#{version}.min.js" :
|
78
|
+
"http://ajax.googleapis.com/ajax/libs/jquery/#{version}/jquery.min.js"
|
79
|
+
end
|
80
|
+
src
|
81
|
+
end
|
82
|
+
end # module Vendors
|
83
|
+
|
84
|
+
end
|
85
|
+
|
86
|
+
end
|
@@ -0,0 +1,296 @@
|
|
1
|
+
require 'rake/testtask'
|
2
|
+
require 'active_support'
|
3
|
+
require 'action_controller'
|
4
|
+
require 'action_view'
|
5
|
+
require File.join(File.dirname(__FILE__), %w[.. asset_hat])
|
6
|
+
|
7
|
+
|
8
|
+
|
9
|
+
unless defined?(RAILS_ROOT)
|
10
|
+
RAILS_ROOT = File.join(File.dirname(__FILE__), '..', '..')
|
11
|
+
end
|
12
|
+
|
13
|
+
task :default => :test
|
14
|
+
|
15
|
+
desc 'Run tests'
|
16
|
+
Rake::TestTask.new(:test) do |t|
|
17
|
+
t.libs << 'lib' << 'test'
|
18
|
+
t.pattern = 'test/**/*_test.rb'
|
19
|
+
t.verbose = false
|
20
|
+
end
|
21
|
+
|
22
|
+
|
23
|
+
|
24
|
+
namespace :asset_hat do
|
25
|
+
desc 'Minifies all CSS and JS bundles'
|
26
|
+
task :minify do
|
27
|
+
Rake::Task['asset_hat:css:minify'].invoke # Generate all CSS bundles
|
28
|
+
Rake::Task['asset_hat:js:minify'].invoke # Generate all JS bundles
|
29
|
+
end
|
30
|
+
|
31
|
+
desc 'Prepare configuration file'
|
32
|
+
task :config do
|
33
|
+
template_filepath =
|
34
|
+
File.join(File.dirname(__FILE__), '..', '..', AssetHat::CONFIG_FILEPATH)
|
35
|
+
target_filepath = File.join(RAILS_ROOT, AssetHat::CONFIG_FILEPATH)
|
36
|
+
|
37
|
+
if File.exists?(target_filepath)
|
38
|
+
print "Replace #{target_filepath}? (y/n) "
|
39
|
+
response = STDIN.gets.chomp
|
40
|
+
unless response.downcase == 'y'
|
41
|
+
puts 'Aborted.' ; exit
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
FileUtils.cp(template_filepath, target_filepath)
|
46
|
+
puts "Wrote to #{target_filepath}"
|
47
|
+
end
|
48
|
+
|
49
|
+
namespace :css do
|
50
|
+
# desc 'Adds mtimes to asset URLs in CSS'
|
51
|
+
# task :add_asset_mtimes, :filename, :verbose do |t, args|
|
52
|
+
# if args.filename.blank?
|
53
|
+
# raise 'Usage: rake asset_hat:css:add_asset_mtimes[filename.css]' and return
|
54
|
+
# end
|
55
|
+
#
|
56
|
+
# args.with_defaults :verbose => true
|
57
|
+
#
|
58
|
+
# css = File.open(args.filename, 'r') { |f| f.read }
|
59
|
+
# css = AssetHat::CSS.add_asset_mtimes(css)
|
60
|
+
# File.open(args.filename, 'w') { |f| f.write css }
|
61
|
+
#
|
62
|
+
# puts "- Added asset mtimes to #{args.filename}" if args.verbose
|
63
|
+
# end
|
64
|
+
|
65
|
+
desc 'Adds commit IDs to asset URLs in CSS for cache busting'
|
66
|
+
task :add_asset_commit_ids, :filename, :verbose do |t, args|
|
67
|
+
if args.filename.blank?
|
68
|
+
raise 'Usage: rake asset_hat:css:add_asset_commit_ids[filename.css]' and return
|
69
|
+
end
|
70
|
+
|
71
|
+
args.with_defaults :verbose => true
|
72
|
+
|
73
|
+
css = File.open(args.filename, 'r') { |f| f.read }
|
74
|
+
css = AssetHat::CSS.add_asset_commit_ids(css)
|
75
|
+
File.open(args.filename, 'w') { |f| f.write css }
|
76
|
+
|
77
|
+
puts "- Added asset commit IDs to #{args.filename}" if args.verbose
|
78
|
+
end
|
79
|
+
|
80
|
+
desc 'Adds hosts to asset URLs in CSS'
|
81
|
+
task :add_asset_hosts, :filename, :verbose, :needs => :environment do |t, args|
|
82
|
+
if args.filename.blank?
|
83
|
+
raise 'Usage: rake asset_hat:css:add_asset_hosts[filename.css]' and return
|
84
|
+
end
|
85
|
+
|
86
|
+
args.with_defaults :verbose => true
|
87
|
+
|
88
|
+
asset_host = ActionController::Base.asset_host
|
89
|
+
if asset_host.blank?
|
90
|
+
raise "This environment (#{ENV['RAILS_ENV']}) doesn't have an `asset_host` configured."
|
91
|
+
return
|
92
|
+
end
|
93
|
+
|
94
|
+
css = File.open(args.filename, 'r') { |f| f.read }
|
95
|
+
css = AssetHat::CSS.add_asset_hosts(css, asset_host)
|
96
|
+
File.open(args.filename, 'w') { |f| f.write css }
|
97
|
+
|
98
|
+
puts "- Added asset hosts to #{args.filename}" if args.verbose
|
99
|
+
end
|
100
|
+
|
101
|
+
desc 'Minifies one CSS file'
|
102
|
+
task :minify_file, :filepath, :verbose do |t, args|
|
103
|
+
if args.filepath.blank?
|
104
|
+
raise 'Usage: rake asset_hat:css:minify_file[path/to/filename.css]' and return
|
105
|
+
end
|
106
|
+
|
107
|
+
args.with_defaults :verbose => false
|
108
|
+
min_options = {
|
109
|
+
:engine => AssetHat.config['css']['engine']
|
110
|
+
}.reject { |k,v| v.blank? }
|
111
|
+
|
112
|
+
input = File.open(args.filepath, 'r').read
|
113
|
+
output = AssetHat::CSS.minify(input, min_options)
|
114
|
+
|
115
|
+
# Write minified content to file
|
116
|
+
target_filepath = AssetHat::CSS.min_filepath(args.filepath)
|
117
|
+
File.open(target_filepath, 'w') { |f| f.write output }
|
118
|
+
|
119
|
+
# Print results
|
120
|
+
puts "- Minified to #{target_filepath}" if args.verbose
|
121
|
+
end
|
122
|
+
|
123
|
+
desc 'Minifies one CSS bundle'
|
124
|
+
task :minify_bundle, :bundle, :needs => :environment do |t, args|
|
125
|
+
if args.bundle.blank?
|
126
|
+
raise 'Usage: rake asset_hat:css:minify_bundle[application]' and return
|
127
|
+
end
|
128
|
+
|
129
|
+
config = AssetHat.config
|
130
|
+
old_bundle_size = 0.0
|
131
|
+
new_bundle_size = 0.0
|
132
|
+
min_options = {
|
133
|
+
:engine => config['css']['engine']
|
134
|
+
}.reject { |k,v| v.blank? }
|
135
|
+
|
136
|
+
# Get bundle filenames
|
137
|
+
filenames = config['css']['bundles'][args.bundle]
|
138
|
+
if filenames.empty?
|
139
|
+
raise "No CSS files are specified for the #{args.bundle} bundle in #{AssetHat::CONFIG_FILEPATH}."
|
140
|
+
return
|
141
|
+
end
|
142
|
+
filepaths = filenames.map do |filename|
|
143
|
+
File.join('public', 'stylesheets', "#{filename}.css")
|
144
|
+
end
|
145
|
+
bundle_filepath = AssetHat::CSS.min_filepath(File.join(
|
146
|
+
'public', 'stylesheets', 'bundles', "#{args.bundle}.css"))
|
147
|
+
|
148
|
+
# Concatenate and process output
|
149
|
+
output = ''
|
150
|
+
asset_host = ActionController::Base.asset_host
|
151
|
+
filepaths.each do |filepath|
|
152
|
+
file_output = File.open(filepath, 'r').read
|
153
|
+
old_bundle_size += file_output.size
|
154
|
+
|
155
|
+
file_output = AssetHat::CSS.minify(file_output, min_options)
|
156
|
+
file_output = AssetHat::CSS.add_asset_commit_ids(file_output)
|
157
|
+
if asset_host.present?
|
158
|
+
file_output = AssetHat::CSS.add_asset_hosts(file_output, asset_host)
|
159
|
+
end
|
160
|
+
|
161
|
+
new_bundle_size += file_output.size
|
162
|
+
output << file_output + "\n"
|
163
|
+
end
|
164
|
+
FileUtils.makedirs(File.dirname(bundle_filepath))
|
165
|
+
File.open(bundle_filepath, 'w') { |f| f.write output }
|
166
|
+
|
167
|
+
# Print results
|
168
|
+
percent_saved = 1 - (new_bundle_size / old_bundle_size)
|
169
|
+
puts "\nWrote CSS bundle: #{bundle_filepath}"
|
170
|
+
filepaths.each do |filepath|
|
171
|
+
puts " contains: #{filepath}"
|
172
|
+
end
|
173
|
+
if old_bundle_size > 0
|
174
|
+
engine = "(Engine: #{min_options[:engine]})"
|
175
|
+
puts " MINIFIED: #{'%.1f' % (percent_saved * 100)}% #{engine}"
|
176
|
+
end
|
177
|
+
end
|
178
|
+
|
179
|
+
desc 'Concatenates and minifies all CSS bundles'
|
180
|
+
task :minify do
|
181
|
+
# Get input bundles
|
182
|
+
config = AssetHat.config
|
183
|
+
if config['css'].blank? || config['css']['bundles'].blank?
|
184
|
+
puts "You need to set up CSS bundles in #{AssetHat::CONFIG_FILEPATH}."
|
185
|
+
exit
|
186
|
+
end
|
187
|
+
bundles = config['css']['bundles'].keys
|
188
|
+
|
189
|
+
# Minify bundles
|
190
|
+
bundles.each do |bundle|
|
191
|
+
Rake::Task['asset_hat:css:minify_bundle'].reenable
|
192
|
+
Rake::Task['asset_hat:css:minify_bundle'].invoke(bundle)
|
193
|
+
end
|
194
|
+
end
|
195
|
+
|
196
|
+
end # namespace :css
|
197
|
+
|
198
|
+
namespace :js do
|
199
|
+
desc 'Minifies one JS file'
|
200
|
+
task :minify_file, :filepath, :verbose do |t, args|
|
201
|
+
if args.filepath.blank?
|
202
|
+
raise 'Usage: rake asset_hat:js:minify_file[filepath.js]' and return
|
203
|
+
end
|
204
|
+
|
205
|
+
args.with_defaults :verbose => false
|
206
|
+
min_options = {
|
207
|
+
:engine => AssetHat.config['js']['engine']
|
208
|
+
}.reject { |k,v| v.blank? }
|
209
|
+
|
210
|
+
if args.verbose && args.filepath.match(/\.min\.js$/)
|
211
|
+
puts "#{args.filepath} is already minified."
|
212
|
+
exit 1
|
213
|
+
end
|
214
|
+
|
215
|
+
input = File.open(args.filepath, 'r').read
|
216
|
+
output = AssetHat::JS.minify(input, min_options)
|
217
|
+
|
218
|
+
# Write minified content to file
|
219
|
+
target_filepath = AssetHat::JS.min_filepath(args.filepath)
|
220
|
+
File.open(target_filepath, 'w') { |f| f.write output }
|
221
|
+
|
222
|
+
# Print results
|
223
|
+
puts "- Minified to #{target_filepath}" if args.verbose
|
224
|
+
end
|
225
|
+
|
226
|
+
desc 'Minifies one JS bundle'
|
227
|
+
task :minify_bundle, :bundle do |t, args|
|
228
|
+
if args.bundle.blank?
|
229
|
+
raise 'Usage: rake asset_hat:js:minify_bundle[application]' and return
|
230
|
+
end
|
231
|
+
|
232
|
+
config = AssetHat.config
|
233
|
+
old_bundle_size = 0.0
|
234
|
+
new_bundle_size = 0.0
|
235
|
+
min_options = {
|
236
|
+
:engine => config['js']['engine']
|
237
|
+
}.reject { |k,v| v.blank? }
|
238
|
+
|
239
|
+
# Get bundle filenames
|
240
|
+
filenames = config['js']['bundles'][args.bundle]
|
241
|
+
if filenames.empty?
|
242
|
+
raise "No JS files are specified for the #{args.bundle} bundle in #{AssetHat::CONFIG_FILEPATH}."
|
243
|
+
return
|
244
|
+
end
|
245
|
+
filepaths = filenames.map do |filename|
|
246
|
+
File.join('public', 'javascripts', "#{filename}.js")
|
247
|
+
end
|
248
|
+
bundle_filepath = AssetHat::JS.min_filepath(File.join(
|
249
|
+
'public', 'javascripts', 'bundles', "#{args.bundle}.js"))
|
250
|
+
|
251
|
+
# Concatenate and process output
|
252
|
+
output = ''
|
253
|
+
filepaths.each do |filepath|
|
254
|
+
file_output = File.open(filepath, 'r').read
|
255
|
+
old_bundle_size += file_output.size
|
256
|
+
unless filepath =~ /\.min\.js$/ # Already minified
|
257
|
+
file_output = AssetHat::JS.minify(file_output, min_options)
|
258
|
+
end
|
259
|
+
new_bundle_size += file_output.size
|
260
|
+
output << file_output + "\n"
|
261
|
+
end
|
262
|
+
FileUtils.makedirs(File.dirname(bundle_filepath))
|
263
|
+
File.open(bundle_filepath, 'w') { |f| f.write output }
|
264
|
+
|
265
|
+
# Print results
|
266
|
+
percent_saved = 1 - (new_bundle_size / old_bundle_size)
|
267
|
+
puts "\n Wrote JS bundle: #{bundle_filepath}"
|
268
|
+
filepaths.each do |filepath|
|
269
|
+
puts " contains: #{filepath}"
|
270
|
+
end
|
271
|
+
if old_bundle_size > 0
|
272
|
+
engine = "(Engine: #{min_options[:engine]})"
|
273
|
+
puts " MINIFIED: #{'%.1f' % (percent_saved * 100)}% #{engine}"
|
274
|
+
end
|
275
|
+
end
|
276
|
+
|
277
|
+
desc 'Concatenates and minifies all JS bundles'
|
278
|
+
task :minify do
|
279
|
+
# Get input bundles
|
280
|
+
config = AssetHat.config
|
281
|
+
if config['js'].blank? || config['js']['bundles'].blank?
|
282
|
+
puts "You need to set up JS bundles in #{AssetHat::CONFIG_FILEPATH}."
|
283
|
+
exit
|
284
|
+
end
|
285
|
+
bundles = config['js']['bundles'].keys
|
286
|
+
|
287
|
+
# Minify bundles
|
288
|
+
bundles.each do |bundle|
|
289
|
+
Rake::Task['asset_hat:js:minify_bundle'].reenable
|
290
|
+
Rake::Task['asset_hat:js:minify_bundle'].invoke(bundle)
|
291
|
+
end
|
292
|
+
end
|
293
|
+
|
294
|
+
end # namespace :js
|
295
|
+
|
296
|
+
end # namespace :asset_hat
|