sinatra-assetpack 0.0.9 → 0.0.10
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/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
|