sundawg-sinatra-assetpack-fork 0.0.12.pre1 → 0.1.6
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +1 -1
- data/.travis.yml +17 -0
- data/CONTRIBUTING.md +27 -0
- data/Gemfile +2 -1
- data/Gemfile.lock +72 -0
- data/HISTORY.md +60 -1
- data/README.md +54 -11
- data/examples/basic/app.rb +12 -1
- data/lib/sinatra/assetpack.rb +1 -1
- data/lib/sinatra/assetpack/class_methods.rb +8 -6
- data/lib/sinatra/assetpack/compressor.rb +1 -0
- data/lib/sinatra/assetpack/css.rb +1 -1
- data/lib/sinatra/assetpack/engines/less.rb +11 -0
- data/lib/sinatra/assetpack/helpers.rb +13 -3
- data/lib/sinatra/assetpack/html_helpers.rb +12 -0
- data/lib/sinatra/assetpack/image.rb +2 -2
- data/lib/sinatra/assetpack/options.rb +24 -9
- data/lib/sinatra/assetpack/package.rb +15 -8
- data/lib/sinatra/assetpack/version.rb +1 -1
- data/sinatra-assetpack.gemspec +5 -0
- data/test/app/app.rb +8 -1
- data/test/app/app/fonts/cantarell-regular-webfont.eot +0 -0
- data/test/app/app/fonts/cantarell-regular-webfont.svg +18 -0
- data/test/app/app/fonts/cantarell-regular-webfont.ttf +0 -0
- data/test/app/app/fonts/cantarell-regular-webfont.woff +0 -0
- data/test/app/app/js/jquery-1.8.0.min.js +1 -0
- data/test/app/app/packages/a_package/package.css +1 -0
- data/test/app/app/packages/a_package/package.js +1 -0
- data/test/app/app/packages/a_package/package.png +0 -0
- data/test/app/config.ru +2 -0
- data/test/arity_test.rb +8 -2
- data/test/cache_test.rb +17 -1
- data/test/glob_test.rb +3 -0
- data/test/ignore_test.rb +2 -2
- data/test/img_test.rb +2 -2
- data/test/local_file_test.rb +6 -0
- data/test/mime_type_test.rb +20 -0
- data/test/redundant_test.rb +1 -0
- data/test/sqwish_test.rb +4 -3
- data/test/test_helper.rb +6 -1
- data/test/tilt_test.rb +1 -0
- data/test/unit_test.rb +42 -5
- metadata +207 -189
- data/lib/sinatra/assetpack/hasharray.rb +0 -66
@@ -12,6 +12,18 @@ module Sinatra
|
|
12
12
|
def kv(hash)
|
13
13
|
hash.map { |k, v| " #{e k}='#{e v}'" }.join('')
|
14
14
|
end
|
15
|
+
|
16
|
+
def get_file_uri(file, assets)
|
17
|
+
raise RuntimeError, "You must pass in an asset for a URI to be created for it." if file.nil?
|
18
|
+
|
19
|
+
local = assets.local_file_for file
|
20
|
+
|
21
|
+
if assets.asset_hosts.nil?
|
22
|
+
BusterHelpers.add_cache_buster(file, local)
|
23
|
+
else
|
24
|
+
assets.asset_hosts[Digest::MD5.hexdigest(file).to_i(16) % assets.asset_hosts.length]+BusterHelpers.add_cache_buster(file, local)
|
25
|
+
end
|
26
|
+
end
|
15
27
|
end
|
16
28
|
end
|
17
29
|
end
|
@@ -30,8 +30,8 @@ module Sinatra
|
|
30
30
|
def dimensions
|
31
31
|
return @dimensions unless @dimensions.nil?
|
32
32
|
|
33
|
-
|
34
|
-
|
33
|
+
dim = /(\d+) x (\d+)/.match(`file "#{@file}"`)
|
34
|
+
w, h = dim[1,2]
|
35
35
|
|
36
36
|
if w.to_i != 0 && h.to_i != 0
|
37
37
|
@dimensions = [w.to_i, h.to_i]
|
@@ -153,12 +153,21 @@ module Sinatra
|
|
153
153
|
attrib :js_compression # Symbol, compression method for JS
|
154
154
|
attrib :css_compression # Symbol, compression method for CSS
|
155
155
|
attrib :output_path # '/public'
|
156
|
+
attrib :asset_hosts # [ 'http://cdn0.example.org', 'http://cdn1.example.org' ]
|
156
157
|
|
157
158
|
attrib :js_compression_options # Hash
|
158
159
|
attrib :css_compression_options # Hash
|
159
160
|
|
160
161
|
attrib :prebuild # Bool
|
161
162
|
|
163
|
+
def expires(*args)
|
164
|
+
if args.empty?
|
165
|
+
@expires
|
166
|
+
else
|
167
|
+
@expires = args
|
168
|
+
end
|
169
|
+
end
|
170
|
+
|
162
171
|
def js_compression(name=nil, options=nil)
|
163
172
|
@js_compression = name unless name.nil?
|
164
173
|
@js_compression_options = options if options.is_a?(Hash)
|
@@ -238,16 +247,22 @@ module Sinatra
|
|
238
247
|
# Returns nil if a file is not found.
|
239
248
|
# TODO: consolidate with local_file_for
|
240
249
|
def dyn_local_file_for(requested_file, from)
|
241
|
-
# Remove extension
|
242
250
|
file = requested_file
|
243
|
-
extension =
|
244
|
-
|
245
|
-
file.
|
251
|
+
extension = File.extname(requested_file)
|
252
|
+
# Remove extension
|
253
|
+
file.gsub!(/#{extension}$/, "")
|
254
|
+
# Remove cache-buster (/js/app.28389 => /js/app)
|
255
|
+
file.gsub!(/\.[0-9]+$/, "")
|
256
|
+
matches = Dir[File.join(app.root, from, "#{file}.*")]
|
246
257
|
|
247
|
-
#
|
248
|
-
|
258
|
+
# Fix for filenames with dots (can't do this with glob)
|
259
|
+
matches.select! { |f| f =~ /#{file}\.[^.]+$/ }
|
249
260
|
|
250
|
-
|
261
|
+
# Sort static file match, weighting exact file extension matches
|
262
|
+
matches.sort! do |f, _|
|
263
|
+
(File.basename(f) == "#{file}#{extension}" || File.extname(f) == extension) ? -1 : 1
|
264
|
+
end
|
265
|
+
matches.first
|
251
266
|
end
|
252
267
|
|
253
268
|
# Writes `public/#{path}` based on contents of `output`.
|
@@ -258,7 +273,7 @@ module Sinatra
|
|
258
273
|
yield path if block_given?
|
259
274
|
|
260
275
|
FileUtils.mkdir_p File.dirname(path)
|
261
|
-
File.open(path, '
|
276
|
+
File.open(path, 'wb') { |f| f.write output }
|
262
277
|
|
263
278
|
if mtime
|
264
279
|
File.utime mtime, mtime, path
|
@@ -305,7 +320,7 @@ module Sinatra
|
|
305
320
|
paths = paths.uniq
|
306
321
|
tuples = paths.map { |key| [key, files[key]] }
|
307
322
|
|
308
|
-
|
323
|
+
Hash[*tuples.flatten]
|
309
324
|
end
|
310
325
|
|
311
326
|
private
|
@@ -96,9 +96,12 @@ module Sinatra
|
|
96
96
|
session = Rack::Test::Session.new(@assets.app)
|
97
97
|
paths.map { |path|
|
98
98
|
result = session.get(path)
|
99
|
-
|
100
|
-
|
101
|
-
|
99
|
+
if result.body.respond_to?(:force_encoding)
|
100
|
+
response_encoding = result.content_type.split(/;\s*charset\s*=\s*/).last.upcase rescue 'ASCII-8BIT'
|
101
|
+
result.body.force_encoding(response_encoding).encode(Encoding.default_external || 'ASCII-8BIT') if result.status == 200
|
102
|
+
else
|
103
|
+
result.body if result.status == 200
|
104
|
+
end
|
102
105
|
}.join("\n")
|
103
106
|
end
|
104
107
|
|
@@ -107,18 +110,22 @@ module Sinatra
|
|
107
110
|
|
108
111
|
private
|
109
112
|
def link_tag(file, options={})
|
110
|
-
# allow for building of assets from an application context and CDN host
|
111
113
|
context = options[:context]
|
112
114
|
host = options[:host]
|
113
|
-
|
114
|
-
|
115
|
+
|
116
|
+
file_path = HtmlHelpers.get_file_uri(file, @assets)
|
117
|
+
|
118
|
+
file_path = "#{context}#{file_path}" unless context.nil? || context.empty?
|
119
|
+
file_path = "#{host}#{file_path}" unless host.nil? || host.empty?
|
120
|
+
|
115
121
|
options_copy = options.clone
|
116
122
|
options_copy.delete(:context)
|
117
123
|
options_copy.delete(:host)
|
124
|
+
|
118
125
|
if js?
|
119
|
-
"<script src='#{
|
126
|
+
"<script src='#{file_path}'#{kv options_copy}></script>"
|
120
127
|
elsif css?
|
121
|
-
"<link rel='stylesheet' href='#{
|
128
|
+
"<link rel='stylesheet' href='#{file_path}'#{kv options_copy} />"
|
122
129
|
end
|
123
130
|
end
|
124
131
|
end
|
data/sinatra-assetpack.gemspec
CHANGED
@@ -15,6 +15,9 @@ Gem::Specification.new do |s|
|
|
15
15
|
s.add_dependency "sinatra"
|
16
16
|
s.add_dependency "jsmin"
|
17
17
|
s.add_dependency "rack-test"
|
18
|
+
if RUBY_VERSION < "1.9"
|
19
|
+
s.add_runtime_dependency "backports"
|
20
|
+
end
|
18
21
|
s.add_development_dependency "yui-compressor"
|
19
22
|
s.add_development_dependency "sass"
|
20
23
|
s.add_development_dependency "haml"
|
@@ -23,4 +26,6 @@ Gem::Specification.new do |s|
|
|
23
26
|
s.add_development_dependency "mocha"
|
24
27
|
s.add_development_dependency "stylus"
|
25
28
|
s.add_development_dependency "uglifier"
|
29
|
+
s.add_development_dependency "rake"
|
30
|
+
s.add_development_dependency "less"
|
26
31
|
end
|
data/test/app/app.rb
CHANGED
@@ -14,9 +14,15 @@ class Main < Sinatra::Base
|
|
14
14
|
disable :show_exceptions
|
15
15
|
|
16
16
|
assets {
|
17
|
-
|
17
|
+
serve '/js', :from => 'app/js'
|
18
18
|
serve '/css', :from => 'app/css'
|
19
19
|
serve '/images', :from => 'app/images'
|
20
|
+
serve '/fonts', :from => 'app/fonts'
|
21
|
+
serve '/packages', :from => 'app/packages'
|
22
|
+
|
23
|
+
js :a_package, '/packages/a_package.js', [
|
24
|
+
'/packages/a_package/package.js',
|
25
|
+
]
|
20
26
|
|
21
27
|
js :skitch, '/skitch.js', [
|
22
28
|
'/js/hi.js',
|
@@ -52,6 +58,7 @@ class Main < Sinatra::Base
|
|
52
58
|
'/css/scre*.css',
|
53
59
|
'/css/screen.css'
|
54
60
|
]
|
61
|
+
|
55
62
|
}
|
56
63
|
|
57
64
|
get '/index.html' do
|
Binary file
|
@@ -0,0 +1,18 @@
|
|
1
|
+
<?xml version="1.0" standalone="no"?>
|
2
|
+
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" >
|
3
|
+
<svg xmlns="http://www.w3.org/2000/svg">
|
4
|
+
<metadata></metadata>
|
5
|
+
<defs>
|
6
|
+
<font id="cantarellregular" horiz-adv-x="748" >
|
7
|
+
<font-face units-per-em="2048" ascent="1513" descent="-535" />
|
8
|
+
<missing-glyph horiz-adv-x="559" />
|
9
|
+
<glyph horiz-adv-x="2048" />
|
10
|
+
<glyph horiz-adv-x="2048" />
|
11
|
+
<glyph unicode="
" horiz-adv-x="682" />
|
12
|
+
<glyph unicode=" " horiz-adv-x="559" />
|
13
|
+
<glyph unicode="	" horiz-adv-x="559" />
|
14
|
+
<glyph unicode=" " horiz-adv-x="559" />
|
15
|
+
<glyph unicode="A" horiz-adv-x="1382" d="M129 0l506 1421h192l506 -1421h-172l-143 414h-588l-143 -414h-158zM481 561h484l-240 694z" />
|
16
|
+
<glyph unicode="" horiz-adv-x="985" d="M0 0v985h985v-985h-985z" />
|
17
|
+
</font>
|
18
|
+
</defs></svg>
|
Binary file
|
Binary file
|
@@ -0,0 +1 @@
|
|
1
|
+
$(function() { alert("Hello"); });
|
@@ -0,0 +1 @@
|
|
1
|
+
.hi { color: red; }
|
@@ -0,0 +1 @@
|
|
1
|
+
$(function() { alert("Hello"); });
|
Binary file
|
data/test/app/config.ru
ADDED
data/test/arity_test.rb
CHANGED
@@ -17,8 +17,14 @@ class ArityTest < UnitTest
|
|
17
17
|
|
18
18
|
test "arity in #assets" do
|
19
19
|
paths = App.assets.packages['a.css'].paths
|
20
|
-
|
21
|
-
|
20
|
+
expect = [ "/css/screen.css", "/css/sqwishable.css", "/css/style.css", "/css/stylus.css", "/css/js2c.css" ]
|
21
|
+
if RUBY_VERSION < "1.9"
|
22
|
+
# In 1.8.7 glob returns inconsitent files order so just check array are equivalents
|
23
|
+
assert_equal expect.size, paths.size
|
24
|
+
assert_equal 0, paths.reject{ |p| expect.include?(p) }.size
|
25
|
+
else
|
26
|
+
assert_equal expect, paths
|
27
|
+
end
|
22
28
|
|
23
29
|
assert App.assets.js_compression == :closure
|
24
30
|
assert App.assets.css_compression == :yui
|
data/test/cache_test.rb
CHANGED
@@ -1,8 +1,24 @@
|
|
1
1
|
require File.expand_path('../test_helper', __FILE__)
|
2
2
|
|
3
3
|
class CacheTest < UnitTest
|
4
|
+
class App < UnitTest::App
|
5
|
+
register Sinatra::AssetPack
|
6
|
+
|
7
|
+
set :reload_templates, false
|
8
|
+
assets {
|
9
|
+
js :app, '/js/app.js', [
|
10
|
+
'/js/vendor/**/*.js',
|
11
|
+
'/js/assets/**/*.js',
|
12
|
+
'/js/hi.js',
|
13
|
+
'/js/hell*.js'
|
14
|
+
]
|
15
|
+
js_compression :jsmin
|
16
|
+
}
|
17
|
+
end
|
18
|
+
|
19
|
+
def app() App; end
|
20
|
+
|
4
21
|
test "Compressed js caching" do
|
5
|
-
app.set :reload_templates, false
|
6
22
|
JSMin.expects(:minify).times(1).returns ""
|
7
23
|
3.times { get '/js/app.js' }
|
8
24
|
end
|
data/test/glob_test.rb
CHANGED
@@ -21,6 +21,7 @@ class GlobTest < UnitTest
|
|
21
21
|
end
|
22
22
|
|
23
23
|
should "match double-star globs recursively" do
|
24
|
+
app.stubs(:development?).returns(true)
|
24
25
|
get '/a'
|
25
26
|
assert body.include?("a/b/c1/hello.")
|
26
27
|
assert body.include?("a/b/c2/hi.")
|
@@ -28,12 +29,14 @@ class GlobTest < UnitTest
|
|
28
29
|
end
|
29
30
|
|
30
31
|
should "match single-star globs in filenames" do
|
32
|
+
app.stubs(:development?).returns(true)
|
31
33
|
get '/b'
|
32
34
|
assert body.include?("a/b/c2/hi.")
|
33
35
|
assert body.include?("a/b/c2/hola.")
|
34
36
|
end
|
35
37
|
|
36
38
|
should "match single-star globs in paths" do
|
39
|
+
app.stubs(:development?).returns(true)
|
37
40
|
get '/c'
|
38
41
|
assert body.include?("a/b/c1/hello.")
|
39
42
|
assert body.include?("a/b/c2/hi.")
|
data/test/ignore_test.rb
CHANGED
@@ -20,8 +20,8 @@ class IgnoreTest < UnitTest
|
|
20
20
|
|
21
21
|
test "ignore in package" do
|
22
22
|
get '/main.js'
|
23
|
-
assert body.size > 0
|
24
|
-
assert !body.include?("BUMBLEBEE")
|
23
|
+
assert last_response.body.size > 0
|
24
|
+
assert !last_response.body.include?("BUMBLEBEE")
|
25
25
|
end
|
26
26
|
|
27
27
|
test "package files" do
|
data/test/img_test.rb
CHANGED
@@ -13,14 +13,14 @@ class ImgTest < UnitTest
|
|
13
13
|
assert_equal last_response.headers['Content-Length'], File.size(r("/app/images/email.png")).to_s
|
14
14
|
end
|
15
15
|
|
16
|
-
test "
|
16
|
+
test "compare" do
|
17
17
|
i = Image['/app/images/email.png']
|
18
18
|
j = Image['/app/images/email.png']
|
19
19
|
|
20
20
|
assert j === i
|
21
21
|
end
|
22
22
|
|
23
|
-
test "
|
23
|
+
test "dimensions" do
|
24
24
|
i = Image['/app/images/email.png']
|
25
25
|
j = Image['/app/images/email.png']
|
26
26
|
|
data/test/local_file_test.rb
CHANGED
@@ -6,6 +6,7 @@ class LocalFileTest < UnitTest
|
|
6
6
|
|
7
7
|
assets {
|
8
8
|
css :application, [ '/css/*.css' ]
|
9
|
+
serve '/fonts', :from => 'app/fonts'
|
9
10
|
}
|
10
11
|
end
|
11
12
|
|
@@ -14,6 +15,11 @@ class LocalFileTest < UnitTest
|
|
14
15
|
assert_equal r('app/images/background.jpg'), fn
|
15
16
|
end
|
16
17
|
|
18
|
+
test "local file for (in existing files, custom serve path)" do
|
19
|
+
fn = App.assets.local_file_for '/fonts/cantarell-regular-webfont.ttf'
|
20
|
+
assert_equal r('app/fonts/cantarell-regular-webfont.ttf'), fn
|
21
|
+
end
|
22
|
+
|
17
23
|
test "local file for (in nonexisting files)" do
|
18
24
|
fn = App.assets.local_file_for '/images/404.jpg'
|
19
25
|
assert fn.nil?
|
data/test/mime_type_test.rb
CHANGED
@@ -30,4 +30,24 @@ class AppTest < UnitTest
|
|
30
30
|
get '/skitch.js'
|
31
31
|
assert last_response.content_type =~ %r[^.*?/javascript]
|
32
32
|
end
|
33
|
+
|
34
|
+
test 'eot' do
|
35
|
+
get '/fonts/cantarell-regular-webfont.eot'
|
36
|
+
assert last_response.content_type =~ %r[^application/vnd.ms-fontobject]
|
37
|
+
end
|
38
|
+
|
39
|
+
test 'svg' do
|
40
|
+
get '/fonts/cantarell-regular-webfont.svg'
|
41
|
+
assert last_response.content_type =~ %r[^image/svg\+xml]
|
42
|
+
end
|
43
|
+
|
44
|
+
test 'ttf' do
|
45
|
+
get '/fonts/cantarell-regular-webfont.ttf'
|
46
|
+
assert last_response.content_type =~ %r[^application/octet-stream]
|
47
|
+
end
|
48
|
+
|
49
|
+
test 'woff' do
|
50
|
+
get '/fonts/cantarell-regular-webfont.woff'
|
51
|
+
assert last_response.content_type =~ %r[^application/font-woff]
|
52
|
+
end
|
33
53
|
end
|
data/test/redundant_test.rb
CHANGED
data/test/sqwish_test.rb
CHANGED
@@ -2,6 +2,7 @@ require File.expand_path('../test_helper', __FILE__)
|
|
2
2
|
|
3
3
|
class SqwishTest < UnitTest
|
4
4
|
setup do
|
5
|
+
app.set :reload_templates, true
|
5
6
|
app.assets.css_compression :sqwish, :strict => true
|
6
7
|
end
|
7
8
|
|
@@ -20,10 +21,10 @@ class SqwishTest < UnitTest
|
|
20
21
|
|
21
22
|
if sqwish?
|
22
23
|
test "build" do
|
23
|
-
|
24
|
-
Sinatra::AssetPack::SqwishEngine.any_instance.expects(:css)
|
25
|
-
|
24
|
+
swqished_css = '#bg{background:green;color:red}'
|
25
|
+
Sinatra::AssetPack::SqwishEngine.any_instance.expects(:css).returns swqished_css
|
26
26
|
get '/css/sq.css'
|
27
|
+
assert body == swqished_css
|
27
28
|
end
|
28
29
|
else
|
29
30
|
puts "(No Sqwish found; skipping sqwish tests)"
|
data/test/test_helper.rb
CHANGED
@@ -1,10 +1,15 @@
|
|
1
1
|
require 'contest'
|
2
2
|
require 'jsmin'
|
3
3
|
require 'tilt'
|
4
|
+
require 'haml'
|
5
|
+
require 'sass'
|
4
6
|
require 'stylus'
|
7
|
+
require 'stylus/tilt'
|
5
8
|
require 'rack/test'
|
6
9
|
require 'yaml'
|
7
|
-
require 'mocha'
|
10
|
+
require 'mocha/setup'
|
11
|
+
|
12
|
+
ENV['RACK_ENV'] = 'test'
|
8
13
|
|
9
14
|
require File.expand_path('../app/app.rb', __FILE__)
|
10
15
|
|