sinatra-assetpack 0.0.9 → 0.0.10
Sign up to get free protection for your applications and to get access to all the features.
- data/HISTORY.md +22 -8
- data/README.md +140 -16
- data/examples/basic/app/js/app.js +1 -0
- data/examples/basic/app.rb +6 -1
- data/examples/compass/app.rb +1 -1
- data/lib/sinatra/assetpack/class_methods.rb +7 -0
- data/lib/sinatra/assetpack/compressor.rb +31 -86
- data/lib/sinatra/assetpack/engine.rb +20 -0
- data/lib/sinatra/assetpack/engines/closure.rb +19 -0
- data/lib/sinatra/assetpack/engines/jsmin.rb +10 -0
- data/lib/sinatra/assetpack/engines/sass.rb +11 -0
- data/lib/sinatra/assetpack/engines/simple.rb +11 -0
- data/lib/sinatra/assetpack/engines/sqwish.rb +21 -0
- data/lib/sinatra/assetpack/engines/uglify.rb +12 -0
- data/lib/sinatra/assetpack/engines/yui.rb +22 -0
- data/lib/sinatra/assetpack/hasharray.rb +10 -14
- data/lib/sinatra/assetpack/options.rb +61 -7
- data/lib/sinatra/assetpack/package.rb +3 -1
- data/lib/sinatra/assetpack/version.rb +1 -1
- data/lib/sinatra/assetpack.rb +1 -0
- data/sinatra-assetpack.gemspec +1 -0
- data/test/app/app/js/_ignoreme.js +1 -0
- data/test/app/app/js/ugly.js +7 -0
- data/test/arity_test.rb +1 -2
- data/test/build_test.rb +10 -0
- data/test/cache_test.rb +1 -1
- data/test/ignore_test.rb +30 -0
- data/test/sqwish_test.rb +2 -3
- data/test/uglifier_test.rb +23 -0
- metadata +46 -23
data/HISTORY.md
CHANGED
@@ -1,3 +1,17 @@
|
|
1
|
+
v0.0.10 - Sep 18, 2011
|
2
|
+
----------------------
|
3
|
+
|
4
|
+
### Added:
|
5
|
+
* Support for 'prebuild' to build on startup.
|
6
|
+
* Add UglifyJS support via `js_compression :uglify`. (#18)
|
7
|
+
* Ignore '.*' and '_*' files. (#17)
|
8
|
+
* Allow specifying of files to be ignored. (#17)
|
9
|
+
|
10
|
+
### Changed:
|
11
|
+
* Built files from 'rake assetpack:build' now match the mtimes of their
|
12
|
+
sources. (#12)
|
13
|
+
* Refactor Compressor into separate engine classes.
|
14
|
+
|
1
15
|
v0.0.9 - Sep 18, 2011
|
2
16
|
---------------------
|
3
17
|
|
@@ -6,8 +20,8 @@ v0.0.9 - Sep 18, 2011
|
|
6
20
|
* Fix the Rake task when the main App class is in a module. (#11)
|
7
21
|
|
8
22
|
### Changed:
|
9
|
-
* Use Sinatra's `template_cache`. This makes AssetPack honor Sinatra's
|
10
|
-
`reload_templates` setting. (#15)
|
23
|
+
* Use Sinatra's `template_cache`. This makes AssetPack honor Sinatra's
|
24
|
+
`reload_templates` setting. (#15)
|
11
25
|
|
12
26
|
### Added:
|
13
27
|
* Added .htc (IE behavior files) to the list of file formats to be served.
|
@@ -17,16 +31,16 @@ v0.0.8 - Sep 06, 2011
|
|
17
31
|
---------------------
|
18
32
|
|
19
33
|
### Fixed:
|
20
|
-
* Fixed the CSS preprocessing bug that gives invalid 'url()' properties to
|
21
|
-
|
34
|
+
* Fixed the CSS preprocessing bug that gives invalid 'url()' properties to
|
35
|
+
non-existing images. (#1)
|
22
36
|
|
23
37
|
### Added:
|
24
|
-
* Allow adding CSS/JS files that don't exist.
|
25
|
-
* Support any Tilt-compatible CSS or JS engine.
|
38
|
+
* Allow adding CSS/JS files that don't exist. (#8)
|
39
|
+
* Support any Tilt-compatible CSS or JS engine. (#5)
|
26
40
|
|
27
41
|
### Changed:
|
28
|
-
* Default to '/assets/x.js' then using assets.css without a path. Inspiration
|
29
|
-
|
42
|
+
* Default to '/assets/x.js' then using assets.css without a path. Inspiration
|
43
|
+
from Jammit.
|
30
44
|
* Ask browsers to cache assets for 1 month.
|
31
45
|
|
32
46
|
### Misc:
|
data/README.md
CHANGED
@@ -136,7 +136,7 @@ compressors in the `assets` block:
|
|
136
136
|
|
137
137
|
``` ruby
|
138
138
|
assets {
|
139
|
-
js_compression :jsmin # :jsmin | :yui | :closure
|
139
|
+
js_compression :jsmin # :jsmin | :yui | :closure | :uglify
|
140
140
|
css_compression :simple # :simple | :sass | :yui | :sqwish
|
141
141
|
}
|
142
142
|
```
|
@@ -155,10 +155,19 @@ assets {
|
|
155
155
|
}
|
156
156
|
```
|
157
157
|
|
158
|
+
__Note:__ This depends on the `yui-compressor` gem. You will need to install it.
|
159
|
+
(`gem install yui-compressor`) If you use Bundler, you will need to add it to
|
160
|
+
your Gemfile as well.
|
161
|
+
|
162
|
+
``` ruby
|
163
|
+
# Gemfile
|
164
|
+
gem 'yui-compressor', :require => 'yui/compressor'
|
165
|
+
```
|
166
|
+
|
158
167
|
### SASS compression
|
159
168
|
|
160
169
|
For SASS compression, you need the Sass gem (`gem install sass`). This treats
|
161
|
-
the CSS files as Scss files and uses Sass's
|
170
|
+
the CSS files as Scss files and uses Sass's `:output => :compressed`.
|
162
171
|
|
163
172
|
``` ruby
|
164
173
|
assets {
|
@@ -166,6 +175,15 @@ assets {
|
|
166
175
|
}
|
167
176
|
```
|
168
177
|
|
178
|
+
__Note:__ This depends on the `sass` gem. You will need to install it (`gem
|
179
|
+
install sass`). If you use Bundler, you will need to add it to your Gemfile as
|
180
|
+
well.
|
181
|
+
|
182
|
+
``` ruby
|
183
|
+
# Gemfile
|
184
|
+
gem 'sass'
|
185
|
+
```
|
186
|
+
|
169
187
|
### Sqwish CSS compression
|
170
188
|
|
171
189
|
[Sqwish](http://github.com/ded/sqwish) is a NodeJS-based CSS compressor. To use
|
@@ -196,6 +214,35 @@ assets {
|
|
196
214
|
}
|
197
215
|
```
|
198
216
|
|
217
|
+
### UglifyJS compression
|
218
|
+
|
219
|
+
This uses the [UglifyJS](https://github.com/mishoo/UglifyJS) compressor to
|
220
|
+
compress your JavaScript. You will need to install the
|
221
|
+
[uglifier](http://rubygems.org/gems/uglifier) gem.
|
222
|
+
|
223
|
+
For options, refer to the [Uglifier
|
224
|
+
documentation](https://github.com/lautis/uglifier).
|
225
|
+
|
226
|
+
``` ruby
|
227
|
+
assets {
|
228
|
+
js_compression :uglify
|
229
|
+
js_compression :uglify, [options]
|
230
|
+
}
|
231
|
+
```
|
232
|
+
|
233
|
+
__Note:__ This depends on the `uglifier` gem. In your Gemfile, you will need to
|
234
|
+
add it. For Heroku support, you will need to add the `therubyracer-heroku` gem
|
235
|
+
as well.
|
236
|
+
|
237
|
+
``` ruby
|
238
|
+
# Gemfile
|
239
|
+
gem 'uglifier'
|
240
|
+
|
241
|
+
# If you're on Heroku:
|
242
|
+
gem "therubyracer-heroku", "0.8.1.pre3", :require => false
|
243
|
+
```
|
244
|
+
|
245
|
+
|
199
246
|
Images
|
200
247
|
------
|
201
248
|
|
@@ -378,8 +425,8 @@ from `./app/javascripts/vendor/jquery*.js`.
|
|
378
425
|
|
379
426
|
``` ruby
|
380
427
|
class App < Sinatra::Base
|
381
|
-
serve '/js', from: '/app/javascripts'
|
382
428
|
assets {
|
429
|
+
serve '/js', from: '/app/javascripts'
|
383
430
|
js :application, [
|
384
431
|
'/js/vendor/jquery.*.js',
|
385
432
|
'/js/vendor/jquery.js'
|
@@ -390,6 +437,96 @@ end
|
|
390
437
|
# In views: <%= js :application %>
|
391
438
|
```
|
392
439
|
|
440
|
+
### assets.ignore
|
441
|
+
Excludes any URL paths that match the given spec.
|
442
|
+
|
443
|
+
These files will not show up in packages, and they will not be accessible.
|
444
|
+
|
445
|
+
By default, `.*` and `_*` are ignored. The former protects folders such as
|
446
|
+
`.svn` from being accessed, and the latter protects Sass partial files from
|
447
|
+
being accessed directly.
|
448
|
+
|
449
|
+
Note that this matches against URL paths, not local file paths. This means
|
450
|
+
something like `*.scss` will not work, as all stylesheet files will be compiled
|
451
|
+
to `.css`.
|
452
|
+
|
453
|
+
``` ruby
|
454
|
+
# Usage:
|
455
|
+
assets {
|
456
|
+
ignore FILESPEC
|
457
|
+
}
|
458
|
+
```
|
459
|
+
|
460
|
+
#### Example
|
461
|
+
Here's an example.
|
462
|
+
|
463
|
+
``` ruby
|
464
|
+
class App < Sinatra::Base
|
465
|
+
assets {
|
466
|
+
# Ignores all files matching *.private.js in any folder.
|
467
|
+
ignore '*.private.js'
|
468
|
+
|
469
|
+
# Ignores all files in `/app/js/foo/**/*`
|
470
|
+
ignore '/js/foo'
|
471
|
+
}
|
472
|
+
end
|
473
|
+
```
|
474
|
+
|
475
|
+
#### Advanced usage
|
476
|
+
By default, `.*` and `_*` are ignored. To disable this behavior, you can use
|
477
|
+
`clear_ignores!` before your `ignore` lines.
|
478
|
+
|
479
|
+
``` ruby
|
480
|
+
assets {
|
481
|
+
clear_ignores!
|
482
|
+
ignore '*.private.js'
|
483
|
+
}
|
484
|
+
```
|
485
|
+
|
486
|
+
To check if a certain file is ignored, use `assets.ignore?`
|
487
|
+
|
488
|
+
``` ruby
|
489
|
+
assets.ignored?("/css/_chrome.css") #=> true
|
490
|
+
```
|
491
|
+
|
492
|
+
|
493
|
+
### assets.prebuild
|
494
|
+
Caches the built packages on application startup.
|
495
|
+
|
496
|
+
If this is not used, the packages will be minified when they are first
|
497
|
+
requested. This only has an effect in the production environment (or when
|
498
|
+
Sinatra's `reload_templates` is otherwise set to false).
|
499
|
+
|
500
|
+
``` ruby
|
501
|
+
# Usage:
|
502
|
+
prebuild {true|false}
|
503
|
+
```
|
504
|
+
|
505
|
+
#### Example
|
506
|
+
In this example, the package for `:application` will be built when the
|
507
|
+
application is started in the production environment.
|
508
|
+
|
509
|
+
``` ruby
|
510
|
+
class App < Sinatra::Base
|
511
|
+
assets {
|
512
|
+
js_compression :closure
|
513
|
+
|
514
|
+
js :application, [
|
515
|
+
'/js/vendor/jquery.*.js',
|
516
|
+
'/js/vendor/jquery.js'
|
517
|
+
]
|
518
|
+
prebuild true
|
519
|
+
}
|
520
|
+
end
|
521
|
+
|
522
|
+
# $ RACK_ENV=production ruby app.rb
|
523
|
+
# ** Building /assets/application.js...
|
524
|
+
# == Sinatra/1.2.6 has taken the stage on 4567 for production
|
525
|
+
# >> Thin web server (v1.2.11 codename Bat-Shit Crazy)
|
526
|
+
# >> Maximum connections set to 1024
|
527
|
+
# >> Listening on 0.0.0.0:4567, CTRL+C to stop
|
528
|
+
```
|
529
|
+
|
393
530
|
API reference: helpers
|
394
531
|
----------------------
|
395
532
|
|
@@ -500,19 +637,6 @@ class Main
|
|
500
637
|
end
|
501
638
|
```
|
502
639
|
|
503
|
-
To do
|
504
|
-
-----
|
505
|
-
|
506
|
-
AssetPack will eventually have:
|
507
|
-
|
508
|
-
* Nested packages
|
509
|
-
* Ignored files (to ignore included sass files and such)
|
510
|
-
* `rake assetpack:build` should be able to output to another folder
|
511
|
-
* Cache folder support (best if your app has many workers)
|
512
|
-
* Refactor *Compressor* module
|
513
|
-
* CDN (Cloudfront, S3) support
|
514
|
-
* Better support for Compass sprites
|
515
|
-
|
516
640
|
Acknowledgements
|
517
641
|
----------------
|
518
642
|
|
data/examples/basic/app.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
$:.unshift File.expand_path('
|
1
|
+
$:.unshift File.expand_path('../../../lib', __FILE__)
|
2
2
|
|
3
3
|
require 'sinatra/base'
|
4
4
|
require 'sinatra/assetpack'
|
@@ -8,6 +8,9 @@ class App < Sinatra::Base
|
|
8
8
|
register Sinatra::AssetPack
|
9
9
|
|
10
10
|
assets do
|
11
|
+
#js_compression :closure
|
12
|
+
js_compression :uglify
|
13
|
+
|
11
14
|
js :main, '/js/main.js', [
|
12
15
|
'/js/vendor/*.js',
|
13
16
|
'/js/app.js'
|
@@ -22,6 +25,8 @@ class App < Sinatra::Base
|
|
22
25
|
css :more, '/css/more.css', [
|
23
26
|
'/css/more/*.css'
|
24
27
|
]
|
28
|
+
|
29
|
+
prebuild true
|
25
30
|
end
|
26
31
|
|
27
32
|
get '/' do
|
data/examples/compass/app.rb
CHANGED
@@ -13,6 +13,11 @@ module Sinatra
|
|
13
13
|
def assets_initialize!
|
14
14
|
add_compressed_routes!
|
15
15
|
add_individual_routes!
|
16
|
+
|
17
|
+
# Cache the built files.
|
18
|
+
if assets.prebuild && !reload_templates
|
19
|
+
assets.cache! { |file| $stderr.write "** Building #{file}...\n" }
|
20
|
+
end
|
16
21
|
end
|
17
22
|
|
18
23
|
# Add routes for the compressed versions
|
@@ -40,6 +45,8 @@ module Sinatra
|
|
40
45
|
pass unless AssetPack.supported_formats.include?(fmt)
|
41
46
|
fn = asset_path_for(file, from) or pass
|
42
47
|
|
48
|
+
pass if settings.assets.ignored?("#{path}/#{file}")
|
49
|
+
|
43
50
|
# Send headers
|
44
51
|
content_type fmt.to_sym
|
45
52
|
last_modified File.mtime(fn).to_i
|
@@ -8,102 +8,47 @@ module Sinatra
|
|
8
8
|
# compress File.read('x.js'), :js, :jsmin
|
9
9
|
#
|
10
10
|
def compress(str, type, engine=nil, options={})
|
11
|
-
|
12
|
-
|
11
|
+
# Use defaults if no engine is given.
|
12
|
+
return fallback(str, type, options) if engine.nil?
|
13
13
|
|
14
|
-
|
15
|
-
|
16
|
-
|
14
|
+
# Ensure that the engine exists.
|
15
|
+
klass = compressors[[type, engine]]
|
16
|
+
raise Error, "Engine #{engine} (#{type}) doesn't exist." unless klass
|
17
17
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
def compressors
|
22
|
-
@compressors ||= {
|
23
|
-
:'js/jsmin' => method(:jsmin),
|
24
|
-
:'js/yui' => method(:yui_js),
|
25
|
-
:'js/closure' => method(:closure_js),
|
26
|
-
:'css/sass' => method(:sass),
|
27
|
-
:'css/yui' => method(:yui_css),
|
28
|
-
:'css/simple' => method(:simple_css),
|
29
|
-
:'css/sqwish' => method(:sqwish_css)
|
30
|
-
}
|
31
|
-
end
|
32
|
-
|
33
|
-
# =====================================================================
|
34
|
-
# Compressors
|
35
|
-
|
36
|
-
def jsmin(str, options={})
|
37
|
-
require 'jsmin'
|
38
|
-
JSMin.minify str
|
39
|
-
end
|
40
|
-
|
41
|
-
def sass(str, options={})
|
42
|
-
Tilt.new("scss", {:style => :compressed}) { str }.render
|
43
|
-
rescue LoadError
|
44
|
-
simple_css str
|
45
|
-
end
|
18
|
+
# Ensure that the engine can support that type.
|
19
|
+
engine = klass.new
|
20
|
+
raise Error, "#{klass} does not support #{type.upcase} compression." unless engine.respond_to?(type)
|
46
21
|
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
sass str
|
22
|
+
# Build it using the engine, and fallback to defaults if it fails.
|
23
|
+
output = engine.send type, str, options
|
24
|
+
output ||= fallback(str, type, options) unless options[:no_fallback]
|
25
|
+
output
|
52
26
|
end
|
53
27
|
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
28
|
+
# Compresses a given string using the default engines.
|
29
|
+
def fallback(str, type, options)
|
30
|
+
if type == :js
|
31
|
+
compress str, :js, :jsmin, :no_fallback => true
|
32
|
+
elsif type == :css
|
33
|
+
compress str, :css, :simple, :no_fallback => true
|
34
|
+
end
|
59
35
|
end
|
60
36
|
|
61
|
-
def
|
62
|
-
|
63
|
-
str.gsub! %r{ *([;\{\},:]) *}, '\1'
|
64
|
-
end
|
65
|
-
|
66
|
-
def sqwish_css(str, options={})
|
67
|
-
cmd = "#{sqwish_bin} %f "
|
68
|
-
cmd += "--strict" if options[:strict]
|
69
|
-
|
70
|
-
_, input = sys :css, str, cmd
|
71
|
-
output = input.gsub(/\.css/, '.min.css')
|
72
|
-
|
73
|
-
File.read(output)
|
74
|
-
rescue => e
|
75
|
-
simple_css str
|
76
|
-
end
|
77
|
-
|
78
|
-
def sqwish_bin
|
79
|
-
ENV['SQWISH_PATH'] || "sqwish"
|
80
|
-
end
|
81
|
-
|
82
|
-
def closure_js(str, options={})
|
83
|
-
require 'net/http'
|
84
|
-
require 'uri'
|
85
|
-
|
86
|
-
response = Net::HTTP.post_form(URI.parse('http://closure-compiler.appspot.com/compile'), {
|
87
|
-
'js_code' => str,
|
88
|
-
'compilation_level' => options[:level] || "ADVANCED_OPTIMIZATIONS",
|
89
|
-
'output_format' => 'text',
|
90
|
-
'output_info' => 'compiled_code'
|
91
|
-
})
|
92
|
-
|
93
|
-
response.body
|
37
|
+
def compressors
|
38
|
+
@compressors ||= Hash.new
|
94
39
|
end
|
95
40
|
|
96
|
-
|
97
|
-
|
98
|
-
t = Tempfile.new ['', ".#{type}"]
|
99
|
-
t.write(str)
|
100
|
-
t.close
|
101
|
-
|
102
|
-
output = `#{cmd.gsub('%f', t.path)}`
|
103
|
-
FileUtils.rm t
|
104
|
-
|
105
|
-
[output, t.path]
|
41
|
+
def register(type, engine, meth)
|
42
|
+
compressors[[type, engine]] = meth
|
106
43
|
end
|
107
44
|
end
|
45
|
+
|
46
|
+
require "#{AssetPack::PREFIX}/assetpack/engines/simple"
|
47
|
+
require "#{AssetPack::PREFIX}/assetpack/engines/jsmin"
|
48
|
+
require "#{AssetPack::PREFIX}/assetpack/engines/yui"
|
49
|
+
require "#{AssetPack::PREFIX}/assetpack/engines/sass"
|
50
|
+
require "#{AssetPack::PREFIX}/assetpack/engines/sqwish"
|
51
|
+
require "#{AssetPack::PREFIX}/assetpack/engines/closure"
|
52
|
+
require "#{AssetPack::PREFIX}/assetpack/engines/uglify"
|
108
53
|
end
|
109
54
|
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module Sinatra
|
2
|
+
module AssetPack
|
3
|
+
# The base class for all CSS/JS compression engines.
|
4
|
+
class Engine
|
5
|
+
# Helper for system files.
|
6
|
+
# Usage: sys('css', string, "sqwish %f")
|
7
|
+
# Returns stdout.
|
8
|
+
def sys(type, str, cmd)
|
9
|
+
t = Tempfile.new ['', ".#{type}"]
|
10
|
+
t.write(str)
|
11
|
+
t.close
|
12
|
+
|
13
|
+
output = `#{cmd.gsub('%f', t.path)}`
|
14
|
+
FileUtils.rm t
|
15
|
+
|
16
|
+
[output, t.path]
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Sinatra::AssetPack
|
2
|
+
class ClosureEngine < Engine
|
3
|
+
def js(str, options={})
|
4
|
+
require 'net/http'
|
5
|
+
require 'uri'
|
6
|
+
|
7
|
+
response = Net::HTTP.post_form(URI.parse('http://closure-compiler.appspot.com/compile'), {
|
8
|
+
'js_code' => str,
|
9
|
+
'compilation_level' => options[:level] || "ADVANCED_OPTIMIZATIONS",
|
10
|
+
'output_format' => 'text',
|
11
|
+
'output_info' => 'compiled_code'
|
12
|
+
})
|
13
|
+
|
14
|
+
response.body
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
Compressor.register :js, :closure, ClosureEngine
|
19
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Sinatra::AssetPack
|
2
|
+
class SqwishEngine < Engine
|
3
|
+
def css(str, options={})
|
4
|
+
cmd = "#{sqwish_bin} %f "
|
5
|
+
cmd += "--strict" if options[:strict]
|
6
|
+
|
7
|
+
_, input = sys :css, str, cmd
|
8
|
+
output = input.gsub(/\.css/, '.min.css')
|
9
|
+
|
10
|
+
File.read(output)
|
11
|
+
rescue => e
|
12
|
+
nil
|
13
|
+
end
|
14
|
+
|
15
|
+
def sqwish_bin
|
16
|
+
ENV['SQWISH_PATH'] || "sqwish"
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
Compressor.register :css, :sqwish, SqwishEngine
|
21
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module Sinatra::AssetPack
|
2
|
+
class YuiEngine < Engine
|
3
|
+
def initialize
|
4
|
+
require 'yui/compressor'
|
5
|
+
end
|
6
|
+
|
7
|
+
def js(str, options={})
|
8
|
+
YUI::JavaScriptCompressor.new(options).compress(str)
|
9
|
+
rescue LoadError
|
10
|
+
nil
|
11
|
+
end
|
12
|
+
|
13
|
+
def css(str, options={})
|
14
|
+
YUI::CssCompressor.new.compress(str)
|
15
|
+
rescue Errno::ENOENT
|
16
|
+
nil
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
Compressor.register :js, :yui, YuiEngine
|
21
|
+
Compressor.register :css, :yui, YuiEngine
|
22
|
+
end
|
@@ -38,20 +38,6 @@ module Sinatra
|
|
38
38
|
new arr.each_slice(2).map { |(k, v)| Hash[k, v] }
|
39
39
|
end
|
40
40
|
|
41
|
-
# Works like Hash#each.
|
42
|
-
#
|
43
|
-
# By extension, methods that rely on #each (like #inject) will work
|
44
|
-
# as intended.
|
45
|
-
#
|
46
|
-
def each(&block)
|
47
|
-
super { |hash| yield hash.to_a.flatten }
|
48
|
-
end
|
49
|
-
|
50
|
-
# Works like Hash#map.
|
51
|
-
def map(&block)
|
52
|
-
super { |hash| yield hash.to_a.flatten }
|
53
|
-
end
|
54
|
-
|
55
41
|
# Works like Hash#values.
|
56
42
|
def values
|
57
43
|
inject([]) { |a, (k, v)| a << v; a }
|
@@ -65,6 +51,16 @@ module Sinatra
|
|
65
51
|
def keys
|
66
52
|
inject([]) { |a, (k, v)| a << k; a }
|
67
53
|
end
|
54
|
+
|
55
|
+
[:each, :map, :map!, :reject, :reject!, :select, :select!].each do |meth|
|
56
|
+
send(:define_method, meth) { |*a, &block|
|
57
|
+
if block.respond_to?(:call)
|
58
|
+
super(*a) { |hash| block.call *hash.to_a }
|
59
|
+
else
|
60
|
+
super(*a)
|
61
|
+
end
|
62
|
+
}
|
63
|
+
end
|
68
64
|
end
|
69
65
|
end
|
70
66
|
end
|
@@ -49,6 +49,8 @@ module Sinatra
|
|
49
49
|
@js_compression_options = Hash.new
|
50
50
|
@css_compression_options = Hash.new
|
51
51
|
|
52
|
+
@ignored = Array.new
|
53
|
+
|
52
54
|
reset!
|
53
55
|
|
54
56
|
# Defaults!
|
@@ -56,6 +58,9 @@ module Sinatra
|
|
56
58
|
serve '/js', :from => 'app/js'
|
57
59
|
serve '/images', :from => 'app/images'
|
58
60
|
|
61
|
+
ignore '.*'
|
62
|
+
ignore '_*'
|
63
|
+
|
59
64
|
blk.arity <= 0 ? instance_eval(&blk) : yield(self) if block_given?
|
60
65
|
end
|
61
66
|
|
@@ -75,6 +80,27 @@ module Sinatra
|
|
75
80
|
@packages = Hash.new
|
76
81
|
end
|
77
82
|
|
83
|
+
# Ignores a given path spec.
|
84
|
+
def ignore(spec)
|
85
|
+
if spec[0] == '/'
|
86
|
+
@ignored << "#{spec}"
|
87
|
+
@ignored << "#{spec}/**"
|
88
|
+
else
|
89
|
+
@ignored << "**/#{spec}"
|
90
|
+
@ignored << "**/#{spec}/**"
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
# Makes nothing ignored. Use this if you don't want to ignore dotfiles and underscore files.
|
95
|
+
def clear_ignores!
|
96
|
+
@ignored = Array.new
|
97
|
+
end
|
98
|
+
|
99
|
+
# Checks if a given path is ignored.
|
100
|
+
def ignored?(fn)
|
101
|
+
@ignored.any? { |spec| File.fnmatch spec, fn }
|
102
|
+
end
|
103
|
+
|
78
104
|
# Adds some JS packages.
|
79
105
|
#
|
80
106
|
# js :foo, [ '/js/vendor/jquery.*.js', ... ]
|
@@ -122,6 +148,8 @@ module Sinatra
|
|
122
148
|
attrib :js_compression_options # Hash
|
123
149
|
attrib :css_compression_options # Hash
|
124
150
|
|
151
|
+
attrib :prebuild # Bool
|
152
|
+
|
125
153
|
def js_compression(name=nil, options=nil)
|
126
154
|
@js_compression = name unless name.nil?
|
127
155
|
@js_compression_options = options if options.is_a?(Hash)
|
@@ -142,18 +170,40 @@ module Sinatra
|
|
142
170
|
def build!(&blk)
|
143
171
|
session = Rack::Test::Session.new app
|
144
172
|
|
173
|
+
get = lambda { |path|
|
174
|
+
response = session.get(path)
|
175
|
+
out = response.body
|
176
|
+
mtime = Time.parse(response.headers['Last-Modified']) if response.headers['Last-Modified']
|
177
|
+
|
178
|
+
[ out, mtime ]
|
179
|
+
}
|
180
|
+
|
145
181
|
packages.each { |_, pack|
|
146
|
-
out =
|
182
|
+
out, mtime = get[pack.path]
|
147
183
|
|
148
|
-
write pack.path, out, &blk
|
149
|
-
write pack.production_path, out, &blk
|
184
|
+
write pack.path, out, mtime, &blk
|
185
|
+
write pack.production_path, out, mtime, &blk
|
150
186
|
}
|
151
187
|
|
152
188
|
files.each { |path, local|
|
153
|
-
out =
|
154
|
-
|
155
|
-
write
|
189
|
+
out, mtime = get[path]
|
190
|
+
|
191
|
+
write path, out, mtime, &blk
|
192
|
+
write BusterHelpers.add_cache_buster(path, local), out, mtime, &blk
|
193
|
+
}
|
194
|
+
end
|
195
|
+
|
196
|
+
# Caches the packages.
|
197
|
+
def cache!(&blk)
|
198
|
+
return false if app.reload_templates
|
199
|
+
|
200
|
+
session = Rack::Test::Session.new app
|
201
|
+
packages.each { |_, pack|
|
202
|
+
yield pack.path if block_given?
|
203
|
+
session.get(pack.path)
|
156
204
|
}
|
205
|
+
|
206
|
+
true
|
157
207
|
end
|
158
208
|
|
159
209
|
def served?(path)
|
@@ -189,7 +239,7 @@ module Sinatra
|
|
189
239
|
end
|
190
240
|
|
191
241
|
# Writes `public/#{path}` based on contents of `output`.
|
192
|
-
def write(path, output)
|
242
|
+
def write(path, output, mtime=nil)
|
193
243
|
require 'fileutils'
|
194
244
|
|
195
245
|
path = File.join(@output_path, path)
|
@@ -197,6 +247,10 @@ module Sinatra
|
|
197
247
|
|
198
248
|
FileUtils.mkdir_p File.dirname(path)
|
199
249
|
File.open(path, 'w') { |f| f.write output }
|
250
|
+
|
251
|
+
if mtime
|
252
|
+
File.utime mtime, mtime, path
|
253
|
+
end
|
200
254
|
end
|
201
255
|
|
202
256
|
# Returns the files as a hash.
|
data/lib/sinatra/assetpack.rb
CHANGED
@@ -46,6 +46,7 @@ module Sinatra
|
|
46
46
|
autoload :Helpers, "#{PREFIX}/assetpack/helpers"
|
47
47
|
autoload :HtmlHelpers, "#{PREFIX}/assetpack/html_helpers"
|
48
48
|
autoload :BusterHelpers, "#{PREFIX}/assetpack/buster_helpers"
|
49
|
+
autoload :Engine, "#{PREFIX}/assetpack/engine"
|
49
50
|
autoload :Package, "#{PREFIX}/assetpack/package"
|
50
51
|
autoload :Compressor, "#{PREFIX}/assetpack/compressor"
|
51
52
|
autoload :Image, "#{PREFIX}/assetpack/image"
|
data/sinatra-assetpack.gemspec
CHANGED
@@ -0,0 +1 @@
|
|
1
|
+
alert("HELLO I SHOULD BE IGNORED. BUMBLEBEE.");
|
data/test/arity_test.rb
CHANGED
data/test/build_test.rb
CHANGED
@@ -11,11 +11,21 @@ class BuildTest < UnitTest
|
|
11
11
|
app.assets.build!
|
12
12
|
|
13
13
|
assert File.file? File.join(app.root, 'public/js/app.js')
|
14
|
+
assert File.mtime(File.join(app.root, 'public/js/app.js')).to_i == app.assets.packages['app.js'].mtime.to_i
|
15
|
+
|
14
16
|
assert Dir[File.join(app.root, 'public/js/app.*.js')].first
|
15
17
|
|
16
18
|
assert File.read(File.join(app.root, 'public/js/app.js')).include?('function(){alert("Hello");')
|
17
19
|
|
18
20
|
assert Dir["#{app.root}/public/images/background.*.jpg"].first
|
19
21
|
assert Dir["#{app.root}/public/images/email.*.png"].first
|
22
|
+
|
23
|
+
assert \
|
24
|
+
File.mtime(Dir["#{app.root}/public/images/background.*.jpg"].first).to_i ==
|
25
|
+
File.mtime(Dir["#{app.root}/public/images/background.jpg"].first).to_i
|
26
|
+
|
27
|
+
assert \
|
28
|
+
File.mtime(Dir["#{app.root}/public/images/background.*.jpg"].first).to_i ==
|
29
|
+
File.mtime(Dir["#{app.root}/app/images/background.jpg"].first).to_i
|
20
30
|
end
|
21
31
|
end
|
data/test/cache_test.rb
CHANGED
@@ -3,7 +3,7 @@ require File.expand_path('../test_helper', __FILE__)
|
|
3
3
|
class CacheTest < UnitTest
|
4
4
|
test "Compressed js caching" do
|
5
5
|
app.set :reload_templates, false
|
6
|
-
JSMin.expects(:minify).times(1)
|
6
|
+
JSMin.expects(:minify).times(1).returns ""
|
7
7
|
3.times { get '/js/app.js' }
|
8
8
|
end
|
9
9
|
end
|
data/test/ignore_test.rb
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
require File.expand_path('../test_helper', __FILE__)
|
2
|
+
|
3
|
+
class IgnoreTest < UnitTest
|
4
|
+
class App < UnitTest::App
|
5
|
+
register Sinatra::AssetPack
|
6
|
+
|
7
|
+
assets do
|
8
|
+
js :main, '/main.js', %w[/js/*.js]
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
def app
|
13
|
+
App
|
14
|
+
end
|
15
|
+
|
16
|
+
test "ignore as individual file" do
|
17
|
+
get '/js/_ignoreme.js'
|
18
|
+
assert last_response.status == 404
|
19
|
+
end
|
20
|
+
|
21
|
+
test "ignore in package" do
|
22
|
+
get '/main.js'
|
23
|
+
assert body.size > 0
|
24
|
+
assert !body.include?("BUMBLEBEE")
|
25
|
+
end
|
26
|
+
|
27
|
+
test "package files" do
|
28
|
+
assert !app.assets.packages['main.js'].files.any? { |s| s.include? '_ignoreme.js' }
|
29
|
+
end
|
30
|
+
end
|
data/test/sqwish_test.rb
CHANGED
@@ -20,9 +20,8 @@ class SqwishTest < UnitTest
|
|
20
20
|
|
21
21
|
if sqwish?
|
22
22
|
test "build" do
|
23
|
-
Sinatra::AssetPack::Compressor
|
24
|
-
|
25
|
-
}
|
23
|
+
Sinatra::AssetPack::Compressor
|
24
|
+
Sinatra::AssetPack::SqwishEngine.any_instance.expects(:css)
|
26
25
|
|
27
26
|
get '/css/sq.css'
|
28
27
|
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require File.expand_path('../test_helper', __FILE__)
|
2
|
+
|
3
|
+
class UglifyTest < UnitTest
|
4
|
+
class App < UnitTest::App
|
5
|
+
register Sinatra::AssetPack
|
6
|
+
|
7
|
+
assets do
|
8
|
+
js_compression :uglify, :mangle => true
|
9
|
+
js :main, '/main.js', [
|
10
|
+
'/js/ugly.js'
|
11
|
+
]
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def app
|
16
|
+
App
|
17
|
+
end
|
18
|
+
|
19
|
+
test "build" do
|
20
|
+
get '/main.js'
|
21
|
+
assert !body.include?("noodle")
|
22
|
+
end
|
23
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sinatra-assetpack
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.10
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -13,7 +13,7 @@ date: 2011-09-17 00:00:00.000000000Z
|
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: tilt
|
16
|
-
requirement: &
|
16
|
+
requirement: &2153561760 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ! '>='
|
@@ -21,10 +21,10 @@ dependencies:
|
|
21
21
|
version: 1.3.0
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *2153561760
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: sinatra
|
27
|
-
requirement: &
|
27
|
+
requirement: &2153561340 !ruby/object:Gem::Requirement
|
28
28
|
none: false
|
29
29
|
requirements:
|
30
30
|
- - ! '>='
|
@@ -32,10 +32,10 @@ dependencies:
|
|
32
32
|
version: '0'
|
33
33
|
type: :runtime
|
34
34
|
prerelease: false
|
35
|
-
version_requirements: *
|
35
|
+
version_requirements: *2153561340
|
36
36
|
- !ruby/object:Gem::Dependency
|
37
37
|
name: jsmin
|
38
|
-
requirement: &
|
38
|
+
requirement: &2153560880 !ruby/object:Gem::Requirement
|
39
39
|
none: false
|
40
40
|
requirements:
|
41
41
|
- - ! '>='
|
@@ -43,10 +43,10 @@ dependencies:
|
|
43
43
|
version: '0'
|
44
44
|
type: :runtime
|
45
45
|
prerelease: false
|
46
|
-
version_requirements: *
|
46
|
+
version_requirements: *2153560880
|
47
47
|
- !ruby/object:Gem::Dependency
|
48
48
|
name: rack-test
|
49
|
-
requirement: &
|
49
|
+
requirement: &2153560460 !ruby/object:Gem::Requirement
|
50
50
|
none: false
|
51
51
|
requirements:
|
52
52
|
- - ! '>='
|
@@ -54,10 +54,10 @@ dependencies:
|
|
54
54
|
version: '0'
|
55
55
|
type: :runtime
|
56
56
|
prerelease: false
|
57
|
-
version_requirements: *
|
57
|
+
version_requirements: *2153560460
|
58
58
|
- !ruby/object:Gem::Dependency
|
59
59
|
name: yui-compressor
|
60
|
-
requirement: &
|
60
|
+
requirement: &2153560040 !ruby/object:Gem::Requirement
|
61
61
|
none: false
|
62
62
|
requirements:
|
63
63
|
- - ! '>='
|
@@ -65,10 +65,10 @@ dependencies:
|
|
65
65
|
version: '0'
|
66
66
|
type: :development
|
67
67
|
prerelease: false
|
68
|
-
version_requirements: *
|
68
|
+
version_requirements: *2153560040
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: sass
|
71
|
-
requirement: &
|
71
|
+
requirement: &2153559620 !ruby/object:Gem::Requirement
|
72
72
|
none: false
|
73
73
|
requirements:
|
74
74
|
- - ! '>='
|
@@ -76,10 +76,10 @@ dependencies:
|
|
76
76
|
version: '0'
|
77
77
|
type: :development
|
78
78
|
prerelease: false
|
79
|
-
version_requirements: *
|
79
|
+
version_requirements: *2153559620
|
80
80
|
- !ruby/object:Gem::Dependency
|
81
81
|
name: haml
|
82
|
-
requirement: &
|
82
|
+
requirement: &2153559200 !ruby/object:Gem::Requirement
|
83
83
|
none: false
|
84
84
|
requirements:
|
85
85
|
- - ! '>='
|
@@ -87,10 +87,10 @@ dependencies:
|
|
87
87
|
version: '0'
|
88
88
|
type: :development
|
89
89
|
prerelease: false
|
90
|
-
version_requirements: *
|
90
|
+
version_requirements: *2153559200
|
91
91
|
- !ruby/object:Gem::Dependency
|
92
92
|
name: coffee-script
|
93
|
-
requirement: &
|
93
|
+
requirement: &2153558780 !ruby/object:Gem::Requirement
|
94
94
|
none: false
|
95
95
|
requirements:
|
96
96
|
- - ! '>='
|
@@ -98,10 +98,10 @@ dependencies:
|
|
98
98
|
version: '0'
|
99
99
|
type: :development
|
100
100
|
prerelease: false
|
101
|
-
version_requirements: *
|
101
|
+
version_requirements: *2153558780
|
102
102
|
- !ruby/object:Gem::Dependency
|
103
103
|
name: contest
|
104
|
-
requirement: &
|
104
|
+
requirement: &2153558360 !ruby/object:Gem::Requirement
|
105
105
|
none: false
|
106
106
|
requirements:
|
107
107
|
- - ! '>='
|
@@ -109,10 +109,10 @@ dependencies:
|
|
109
109
|
version: '0'
|
110
110
|
type: :development
|
111
111
|
prerelease: false
|
112
|
-
version_requirements: *
|
112
|
+
version_requirements: *2153558360
|
113
113
|
- !ruby/object:Gem::Dependency
|
114
114
|
name: mocha
|
115
|
-
requirement: &
|
115
|
+
requirement: &2153557940 !ruby/object:Gem::Requirement
|
116
116
|
none: false
|
117
117
|
requirements:
|
118
118
|
- - ! '>='
|
@@ -120,10 +120,10 @@ dependencies:
|
|
120
120
|
version: '0'
|
121
121
|
type: :development
|
122
122
|
prerelease: false
|
123
|
-
version_requirements: *
|
123
|
+
version_requirements: *2153557940
|
124
124
|
- !ruby/object:Gem::Dependency
|
125
125
|
name: stylus
|
126
|
-
requirement: &
|
126
|
+
requirement: &2153557520 !ruby/object:Gem::Requirement
|
127
127
|
none: false
|
128
128
|
requirements:
|
129
129
|
- - ! '>='
|
@@ -131,7 +131,18 @@ dependencies:
|
|
131
131
|
version: '0'
|
132
132
|
type: :development
|
133
133
|
prerelease: false
|
134
|
-
version_requirements: *
|
134
|
+
version_requirements: *2153557520
|
135
|
+
- !ruby/object:Gem::Dependency
|
136
|
+
name: uglifier
|
137
|
+
requirement: &2153557100 !ruby/object:Gem::Requirement
|
138
|
+
none: false
|
139
|
+
requirements:
|
140
|
+
- - ! '>='
|
141
|
+
- !ruby/object:Gem::Version
|
142
|
+
version: '0'
|
143
|
+
type: :development
|
144
|
+
prerelease: false
|
145
|
+
version_requirements: *2153557100
|
135
146
|
description: Package your assets for Sinatra.
|
136
147
|
email:
|
137
148
|
- rico@sinefunc.com
|
@@ -176,6 +187,14 @@ files:
|
|
176
187
|
- lib/sinatra/assetpack/compressor.rb
|
177
188
|
- lib/sinatra/assetpack/configurator.rb
|
178
189
|
- lib/sinatra/assetpack/css.rb
|
190
|
+
- lib/sinatra/assetpack/engine.rb
|
191
|
+
- lib/sinatra/assetpack/engines/closure.rb
|
192
|
+
- lib/sinatra/assetpack/engines/jsmin.rb
|
193
|
+
- lib/sinatra/assetpack/engines/sass.rb
|
194
|
+
- lib/sinatra/assetpack/engines/simple.rb
|
195
|
+
- lib/sinatra/assetpack/engines/sqwish.rb
|
196
|
+
- lib/sinatra/assetpack/engines/uglify.rb
|
197
|
+
- lib/sinatra/assetpack/engines/yui.rb
|
179
198
|
- lib/sinatra/assetpack/hasharray.rb
|
180
199
|
- lib/sinatra/assetpack/helpers.rb
|
181
200
|
- lib/sinatra/assetpack/html_helpers.rb
|
@@ -197,8 +216,10 @@ files:
|
|
197
216
|
- test/app/app/css_stylus/stylus.styl
|
198
217
|
- test/app/app/images/background.jpg
|
199
218
|
- test/app/app/images/email.png
|
219
|
+
- test/app/app/js/_ignoreme.js
|
200
220
|
- test/app/app/js/hello.js
|
201
221
|
- test/app/app/js/hi.coffee
|
222
|
+
- test/app/app/js/ugly.js
|
202
223
|
- test/app/app/js_glob/a/b/c1/hello.js
|
203
224
|
- test/app/app/js_glob/a/b/c2/hi.js
|
204
225
|
- test/app/app/js_glob/a/b/c2/hola.js
|
@@ -209,6 +230,7 @@ files:
|
|
209
230
|
- test/compressed_test.rb
|
210
231
|
- test/glob_test.rb
|
211
232
|
- test/helpers_test.rb
|
233
|
+
- test/ignore_test.rb
|
212
234
|
- test/img_test.rb
|
213
235
|
- test/local_file_test.rb
|
214
236
|
- test/mime_type_test.rb
|
@@ -223,6 +245,7 @@ files:
|
|
223
245
|
- test/template_cache_test.rb
|
224
246
|
- test/test_helper.rb
|
225
247
|
- test/tilt_test.rb
|
248
|
+
- test/uglifier_test.rb
|
226
249
|
- test/unit_test.rb
|
227
250
|
- test/yui_test.rb
|
228
251
|
homepage: http://github.com/rstacruz/sinatra-assetpack
|