sinatra-minify 0.1.1 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
data/Rakefile CHANGED
@@ -50,3 +50,17 @@ Rake::RDocTask.new do |rdoc|
50
50
  rdoc.rdoc_files.include('README*')
51
51
  rdoc.rdoc_files.include('lib/**/*.rb')
52
52
  end
53
+
54
+ namespace :minify do
55
+ desc "Builds the example files in test/fixtures/exampleapp"
56
+ task :build_example do
57
+ $:.unshift File.dirname(__FILE__) + '/lib'
58
+
59
+ require 'test/fixtures/exampleapp/app'
60
+ puts "Building..."
61
+
62
+ files = Sinatra::Minify::Package.build(App)
63
+ files.each { |f| puts " * #{File.basename f}" }
64
+ puts "Construction complete!"
65
+ end
66
+ end
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.1
1
+ 0.2.0
@@ -1,4 +1,6 @@
1
1
  require 'sinatra/base'
2
+ require 'yaml'
3
+ require 'forwardable'
2
4
 
3
5
  begin
4
6
  require 'jsmin'
@@ -8,8 +10,10 @@ end
8
10
 
9
11
  module Sinatra
10
12
  module Minify
11
- autoload :Builder, 'sinatra/minify/builder'
12
- autoload :Helpers, 'sinatra/minify/helpers'
13
+ autoload :Config, 'sinatra/minify/config'
14
+ autoload :Package, 'sinatra/minify/package'
15
+ autoload :Compressor, 'sinatra/minify/compressor'
16
+ autoload :Helpers, 'sinatra/minify/helpers'
13
17
 
14
18
  def self.registered( app )
15
19
  app.helpers Helpers
@@ -0,0 +1,54 @@
1
+ module Sinatra
2
+ module Minify
3
+ class Compressor
4
+ attr :type, :package, :file
5
+
6
+ def initialize(type, file, package)
7
+ @type = type.to_s
8
+ @file = file
9
+ @package = package
10
+ @command = :"minify_#{@type}"
11
+
12
+ raise ArgumentError if not ['js', 'css'].include?(type)
13
+ end
14
+
15
+ # Rebuilds the minified .min.* files.
16
+ def build
17
+ File.open(file, 'w') { |f| f.write minify(concatenated) }
18
+ file
19
+ end
20
+
21
+ # Deletes all minified files.
22
+ def clean
23
+ File.unlink(file) if File.exists?(file)
24
+ end
25
+
26
+ private
27
+ # TODO: decouple this further?
28
+ def concatenated
29
+ package.files.map { |f| File.read(f) }.join("\n").strip
30
+ end
31
+
32
+ def minify(src)
33
+ send @command, src
34
+ end
35
+
36
+ def minify_css(src)
37
+ src.gsub!(/\s+/, " ")
38
+ src.gsub!(/\/\*(.*?)\*\//, "")
39
+ src.gsub!(/\} /, "}\n")
40
+ src.gsub!(/\n$/, "")
41
+ src.gsub!(/[ \t]*\{[ \t]*/, "{")
42
+ src.gsub!(/;[ \t]*\}/, "}")
43
+
44
+ src.gsub!(/[ \t]*([,|{|}|>|:|;])[ \t]*/,"\\1") # Tersify
45
+ src.gsub!(/[ \t]*\n[ \t]*/, "") # Hardcore mode (no NLs)
46
+ src.strip
47
+ end
48
+
49
+ def minify_js(src)
50
+ JSMin.minify(src).strip
51
+ end
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,34 @@
1
+ module Sinatra
2
+ module Minify
3
+ class Config
4
+ def initialize(type, app_class = ::Main)
5
+ @settings = app_class
6
+ @type = type.to_s
7
+ end
8
+
9
+ def js_url
10
+ @settings.js_url
11
+ end
12
+
13
+ def css_url
14
+ @settings.css_url
15
+ end
16
+
17
+ def public_dir(*args)
18
+ root_path(@settings.send("#{@type}_path"), *args)
19
+ end
20
+
21
+ def public_url(path)
22
+ File.join(@settings.send("#{@type}_url"), path).squeeze('/')
23
+ end
24
+
25
+ def root_path(*args)
26
+ File.join(File.dirname(@settings.app_file), *args)
27
+ end
28
+
29
+ def sets
30
+ YAML.load_file(root_path("config/assets.yml"))[@type]
31
+ end
32
+ end
33
+ end
34
+ end
@@ -1,14 +1,13 @@
1
1
  module Sinatra
2
2
  module Minify
3
3
  module Helpers
4
- def js_assets( set )
5
- Builder.new(self.class).js_assets set
4
+ def js_assets(set)
5
+ Package.new(:js, set, self.class).html
6
6
  end
7
7
 
8
- def css_assets( set )
9
- Builder.new(self.class).css_assets set
8
+ def css_assets(set)
9
+ Package.new(:css, set, self.class).html
10
10
  end
11
11
  end
12
12
  end
13
13
  end
14
-
@@ -0,0 +1,107 @@
1
+ module Sinatra
2
+ module Minify
3
+ class Package
4
+ GlobNoMatchError = Class.new(StandardError)
5
+
6
+ attr :type, :set, :compressor, :filename
7
+
8
+ class << self
9
+ # Deletes all the different packaged and minified files
10
+ # You may pass in a different application object
11
+ # e.g.
12
+ #
13
+ # Sinatra::Minify::Package.clean(HelloWorld)
14
+ #
15
+ # as long as the appication has registered Sinatra::Minify
16
+ #
17
+ # The files will be based on config/assets.yml
18
+ #
19
+ # See test/fixtures/exampleapp/config/assets.yml for an example
20
+ def clean(app_class = ::Main)
21
+ all(:js, app_class).each { |p| p.compressor.clean }
22
+ all(:css, app_class).each { |p| p.compressor.clean }
23
+ end
24
+
25
+ # Packages and minifies all of the files declared on config/assets.yml
26
+ #
27
+ # Returns all of the minified files
28
+ def build(app_class = ::Main)
29
+ ret = []
30
+ ret << all(:js, app_class).map { |p| p.compressor.build }
31
+ ret << all(:css, app_class).map { |p| p.compressor.build }
32
+ ret.flatten
33
+ end
34
+
35
+ private
36
+ def all(type, app_class = ::Main)
37
+ config = Config.new(type, app_class)
38
+ config.sets.keys.map do |set|
39
+ Package.new(type, set, app_class)
40
+ end
41
+ end
42
+ end
43
+
44
+ extend Forwardable
45
+ def_delegators :@config, :public_url, :public_dir, :sets, :js_url, :css_url
46
+
47
+ def initialize(type, set, app_class = ::Main)
48
+ @type = type.to_s
49
+ @app_class = app_class
50
+ @set = set
51
+ @config = Config.new(@type, app_class)
52
+ @filename = "#{set}.min.#{type}"
53
+ @compressor = Compressor.new(@type, public_dir(@filename), self)
54
+
55
+ end
56
+
57
+ def html
58
+ if @app_class.minify?
59
+ file = public_dir(filename)
60
+ @compressor.build unless File.exists?(file)
61
+ mtime = File.mtime(file).to_i
62
+
63
+ asset_include_tag public_url(filename), mtime
64
+ else
65
+ enumerate_all_assets
66
+ end
67
+ end
68
+
69
+ def files
70
+ specs = sets[set]
71
+ globs = Array(specs).map { |s| public_dir(s) }
72
+
73
+ globs.map { |glob|
74
+ list = Dir[glob]
75
+
76
+ if list.empty? and glob.include?('*')
77
+ raise GlobNoMatchError, "The spec `#{glob}` does not match any files."
78
+ end
79
+
80
+ list.empty? ? glob : list
81
+ }.flatten.uniq
82
+ end
83
+
84
+ private
85
+ def enumerate_all_assets
86
+ files.map { |file|
87
+ mtime = File.mtime(file).to_i if File.exist?(file)
88
+
89
+ asset_include_tag(
90
+ public_url(file.gsub(/^#{Regexp.escape(public_dir)}/, '')), mtime
91
+ )
92
+ }.join("\n")
93
+ end
94
+
95
+ def asset_include_tag(path, mtime)
96
+ case type
97
+ when 'js'
98
+ "<script src='#{js_url}/#{path}?#{mtime}' type='text/javascript'></script>"
99
+ when 'css'
100
+ "<link rel='stylesheet' href='#{css_url}/#{path}?#{mtime}' media='screen' />"
101
+ else
102
+ raise ArgumentError, "only js/css are supported"
103
+ end
104
+ end
105
+ end
106
+ end
107
+ end
data/lib/tasks.rake CHANGED
@@ -3,7 +3,8 @@ namespace :minify do
3
3
  task :build do
4
4
  require 'init'
5
5
  puts "Building..."
6
- files = Sinatra::Minify::Builder.new.build
6
+
7
+ files = Sinatra::Minify::Package.build
7
8
  files.each { |f| puts " * #{File.basename f}" }
8
9
  puts "Construction complete!"
9
10
  end
@@ -5,7 +5,7 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{sinatra-minify}
8
- s.version = "0.1.1"
8
+ s.version = "0.2.0"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["sinefunc"]
@@ -22,10 +22,13 @@ Gem::Specification.new do |s|
22
22
  "Rakefile",
23
23
  "VERSION",
24
24
  "lib/sinatra/minify.rb",
25
- "lib/sinatra/minify/builder.rb",
25
+ "lib/sinatra/minify/compressor.rb",
26
+ "lib/sinatra/minify/config.rb",
26
27
  "lib/sinatra/minify/helpers.rb",
28
+ "lib/sinatra/minify/package.rb",
27
29
  "lib/tasks.rake",
28
30
  "sinatra-minify.gemspec",
31
+ "test/fixtures/control/style-default-compressed.css",
29
32
  "test/fixtures/exampleapp/app.rb",
30
33
  "test/fixtures/exampleapp/config/assets.yml",
31
34
  "test/fixtures/exampleapp/public/css/style-default.css",
@@ -0,0 +1 @@
1
+ div,dl,dt,dd,ul,ol,li,form,fieldset,input,th,td{margin:0;padding:0}pre,p,blockquote,h1,h2,h3,h4,h5,h6{margin:1em 0 1em 0}blockquote{border-left:solid 2px #ccc;padding:0 1em;margin-left:0.2em;color:#888}h1{font-size:1.4em}h2{font-size:1.3em}h3{font-size:1.2em}h4{font-size:1.1em}h5{font-size:0.9em}h6{font-size:0.9em}ol,ul{margin-left:2em}html,body{margin:0;padding:0}body,td,input,textarea{font-family:arial,helvetica,sans-serif;font-size:1em}body{font-size:0.85em;line-height:1.6em;background:#6ba241;color:#333}#all{margin:0 auto;width:auto;position:relative}a{color:#393;text-decoration:none;font-weight:bold;padding:1px}a:visited{color:#393}a:hover{color:#393;text-decoration:underline}a img{border:0}#what-we-do,#who-we-are,#content{overflow:hidden}#header>.c,#what-we-do>.c,#who-we-are>.c,#footer>.c{width:940px;margin:0 auto;overflow:hidden}#header{background:#f8fbf4 url(bg-header.png) center bottom repeat-x;padding:10px 0 130px 0}#what-we-do{background:#f0f6e9;padding:30px 0 0 0}#who-we-are{background:#6ba241 url(bg-stripe.png) center top repeat-x;padding:90px 0 30px 0;color:#d3e3c6;text-shadow:1px 1px #5c843d}#footer{background:#444;padding:50px 0 50px 0;color:#bbb}#header{overflow:hidden}#header #logo{float:left;margin-right:75px;margin-left:75px}#header h1{background:url(text.png) 0 0 no-repeat;width:511px;height:95px;text-indent:-9999px;margin:0;padding:0;display:block;float:left}#contact-header{border-bottom:solid 1px #ccc;margin-bottom:90px;padding:0 0 4px 0;text-align:right;color:#aaa;font-size:0.9em}#contact-header em{margin:0 12px 0 10px;color:#ccc}#contact-header a{color:#888;text-decoration:underline}#contact-header a:hover{color:#6b6}#content h2{float:left;width:240px}#content ul,#content li{margin:0;padding:0;display:block}#what-we-do>.c ul{float:left;width:700px;overflow:hidden}#what-we-do li{float:left;width:340px}#what-we-do li.left{margin-right:20px}#what-we-do li h3{font-size:1.4em}#what-we-do li h4{font-family:georgia,times,serif;font-style:italic;color:#777;font-weight:normal;font-size:1.2em;line-height:1.4em;margin:0.8em 0 0 0}#what-we-do li p{margin:3px 0 2em 0}#what-we-do #do-build,#what-we-do #do-scale{padding-bottom:1.5em}#what-we-do h2{background:url(text.png) 0 -400px no-repeat;height:18px;text-indent:-9999px;margin:0;padding:0;display:block}#what-we-do h3{background:url(text.png) 0 0 no-repeat;height:21px;text-indent:-9999px;margin:0;padding:0;display:block}#do-build h3{background-position:0 -200px}#do-scale h3{background-position:0 -250px}#do-craft h3{background-position:0 -300px}#do-train h3{background-position:0 -350px}#who-we-are>.c div{float:left;width:560px;overflow:hidden}#who-we-are h3{font-size:1.4em;line-height:1.5em;color:white;background:url(text.png) 0 -550px no-repeat;width:521px;height:73px;text-indent:-9999px;margin:0;padding:0;display:block;padding-bottom:7px}#who-we-are h2{background:url(text.png) 0 -450px no-repeat;height:18px;text-indent:-9999px;margin:0;padding:0;display:block}#footer{text-align:center}#footer a{font-size:1.3em;color:white;font-weight:normal}#footer span{display:block;font-size:1.2em;color:#888;margin-bottom:3px;font-family:georgia;font-style:italic}
@@ -11,7 +11,7 @@ class App < Sinatra::Base
11
11
  set :app_file, __FILE__
12
12
 
13
13
  register Sinatra::Minify
14
-
14
+ enable :raise_errors
15
15
  get '/' do
16
16
  "Hello"
17
17
  end
@@ -1 +1 @@
1
- aoeu = 234 /* Test */;
1
+ aoeu = 456 /* Test */;
data/test/test_minify.rb CHANGED
@@ -9,10 +9,6 @@ class TestMinify < Test::Unit::TestCase
9
9
  last_response.body
10
10
  end
11
11
 
12
- def builder
13
- Sinatra::Minify::Builder.new app
14
- end
15
-
16
12
  should "rock pants off" do
17
13
  get '/'
18
14
  assert_match "Hello", output
@@ -23,6 +19,34 @@ class TestMinify < Test::Unit::TestCase
23
19
  assert_match /\/js\/script-1.js\?/, output
24
20
  assert_match /\/js\/script-2.js\?/, output
25
21
  end
22
+
23
+ describe "Package.all(:js)" do
24
+ setup do
25
+ @packages = Sinatra::Minify::Package.send(:all, :js, App)
26
+ end
27
+
28
+ should "have only one package" do
29
+ assert_equal 1, @packages.size
30
+ end
31
+
32
+ should "return base as the only package" do
33
+ assert_equal 'base', @packages.first.set
34
+ end
35
+ end
36
+
37
+ describe "Package.all(:css)" do
38
+ setup do
39
+ @packages = Sinatra::Minify::Package.send(:all, :css, App)
40
+ end
41
+
42
+ should "have only one package" do
43
+ assert_equal 1, @packages.size
44
+ end
45
+
46
+ should "return base as the only package" do
47
+ assert_equal 'base', @packages.first.set
48
+ end
49
+ end
26
50
 
27
51
  describe "In a production environment" do
28
52
  def setup
@@ -41,12 +65,31 @@ class TestMinify < Test::Unit::TestCase
41
65
 
42
66
  describe "Building files" do
43
67
  def setup
44
- builder.clean
45
- builder.build
68
+ Sinatra::Minify::Package.clean(App)
69
+ Sinatra::Minify::Package.build(App)
70
+ end
71
+
72
+ should "at least create the files" do
73
+ assert File.exist?(File.dirname(App.app_file) + '/public/js/base.min.js')
74
+ assert File.exist?(File.dirname(App.app_file) + '/public/css/base.min.css')
75
+ end
76
+
77
+ should "include the css file in base.min.css" do
78
+ control = File.read('test/fixtures/control/style-default-compressed.css')
79
+ unknown = File.read(File.dirname(App.app_file) + '/public/css/base.min.css')
80
+
81
+ assert unknown.include?(control)
46
82
  end
47
83
 
48
- should "Build properly" do
49
- assert true
84
+ should "include the script-1 file first in base.min.js" do
85
+ unknown = File.read(File.dirname(App.app_file) + '/public/js/base.min.js')
86
+ assert_equal 0, unknown.index('aoeu=234;')
87
+ end
88
+
89
+ should "include the script-2 file second in base.min.js" do
90
+ unknown = File.read(File.dirname(App.app_file) + '/public/js/base.min.js')
91
+
92
+ assert_equal 9, unknown.index('aoeu=456;')
50
93
  end
51
94
  end
52
95
  end
metadata CHANGED
@@ -4,9 +4,9 @@ version: !ruby/object:Gem::Version
4
4
  prerelease: false
5
5
  segments:
6
6
  - 0
7
- - 1
8
- - 1
9
- version: 0.1.1
7
+ - 2
8
+ - 0
9
+ version: 0.2.0
10
10
  platform: ruby
11
11
  authors:
12
12
  - sinefunc
@@ -44,10 +44,13 @@ files:
44
44
  - Rakefile
45
45
  - VERSION
46
46
  - lib/sinatra/minify.rb
47
- - lib/sinatra/minify/builder.rb
47
+ - lib/sinatra/minify/compressor.rb
48
+ - lib/sinatra/minify/config.rb
48
49
  - lib/sinatra/minify/helpers.rb
50
+ - lib/sinatra/minify/package.rb
49
51
  - lib/tasks.rake
50
52
  - sinatra-minify.gemspec
53
+ - test/fixtures/control/style-default-compressed.css
51
54
  - test/fixtures/exampleapp/app.rb
52
55
  - test/fixtures/exampleapp/config/assets.yml
53
56
  - test/fixtures/exampleapp/public/css/style-default.css
@@ -1,224 +0,0 @@
1
- require 'yaml'
2
-
3
- module Sinatra
4
- module Minify
5
- class Builder
6
- # Returns the root path of the main Sinatra application.
7
- # Mimins the root_path functionality of Monk.`
8
- def root_path(*args)
9
- File.join(File.dirname(settings.app_file), *args)
10
- end
11
-
12
- # Deletes all minified files.
13
- def clean
14
- [:js, :css].each do |type|
15
- assets_config(type).keys.each do |set|
16
- prefix = type == :js ? settings.js_path : settings.css_path
17
- path = root_path File.join(prefix, "#{set}.min.#{type}")
18
- File.unlink path if File.exists? path
19
- end
20
- end
21
- end
22
-
23
- # Rebuilds the minified .min.js and .min.css files.
24
- def build
25
- out = []
26
- [:js, :css].each do |type|
27
- assets_config(type).keys.each do |set|
28
- prefix = type == :js ? settings.js_path : settings.css_path
29
- path = root_path(prefix, "#{set}.min.#{type}")
30
- File.open(path, 'w') { |f| f.write compress(type, set) }
31
- out << path
32
- end
33
- end
34
- out
35
- end
36
-
37
- def initialize(app_class = ::Main)
38
- @app_class = app_class
39
- end
40
-
41
- def settings
42
- @app_class
43
- end
44
-
45
- # Returns the file sets for a given type as defined in the `assets.yml` config file.
46
- #
47
- # Params:
48
- # - `type` (Symbol/string) - Can be either `:js` or `:css`
49
- #
50
- def assets_config(type)
51
- YAML.load_file(root_path("config/assets.yml"))[type.to_s]
52
- end
53
-
54
- # Returns HTML code with `<script>` tags to include the scripts in a given `set`.
55
- # In a production environment, this tries to include the minified version of the
56
- # files. If it doesn't exist, it falls back to the original files.
57
- #
58
- # Params:
59
- # - `set` (String) - The set name, as defined in `config/assets.yml`.
60
- #
61
- # Example:
62
- #
63
- # <%= js_assets 'base' %>
64
- #
65
- def js_assets( set )
66
- min_file = root_path(settings.js_path, "#{set}.min.js")
67
- min_path = "/#{settings.js_url}/#{set}.min.js".squeeze("/")
68
- if settings.minify? and File.exists? min_file
69
- mtime = File.mtime(min_file).to_i
70
- "<script src='#{min_path}?#{mtime}' type='text/javascript'></script>\n"
71
- else
72
- js_assets_all set
73
- end
74
- end
75
-
76
- def js_assets_all(set)
77
- assets(:js, set).map { |script|
78
- "<script src='#{script[:url]}' type='text/javascript'></script>"
79
- }.join("\n")
80
- end
81
-
82
- # Returns HTML code with `<link>` tags to include the stylesheets in a given `set`.
83
- # In a production environment, this tries to include the minified version of the
84
- # files. If it doesn't exist, it falls back to the original files.
85
- #
86
- # Params:
87
- # - `set` (String) - The set name, as defined in `config/assets.yml`.
88
- #
89
- # Example:
90
- #
91
- # <%= css_assets 'base' %>
92
- #
93
- def css_assets( set )
94
- min_file = root_path settings.css_path, "#{set}.min.css"
95
- min_path = "/#{settings.css_url}/#{set}.min.css".squeeze("/")
96
- if settings.minify? and File.exists? min_file
97
- mtime = File.mtime(file).to_i
98
- "<link rel='stylesheet' href='#{min_path}?#{mtime}' media='screen' />\n"
99
- else
100
- css_assets_all set
101
- end
102
- end
103
-
104
- def css_assets_all(set)
105
- assets(:css, set).map { |sheet|
106
- "<link rel='stylesheet' href='#{sheet[:url]}' media='screen' />"
107
- }.join("\n")
108
- end
109
-
110
- # Returns the raw consolidated CSS/JS contents of a given type/set
111
- def combine(type, set)
112
- assets(type, set).map { |asset| File.open(asset[:path]).read }.join("\n").strip
113
- end
114
-
115
- # Returns compressed code
116
- def compress(type, set)
117
- code = combine(type, set)
118
- if type == :js
119
- minify_js code
120
- elsif type == :css
121
- minify_css code
122
- else
123
- raise ArgumentError, "type should be one of :js or :css"
124
- end
125
- end
126
-
127
- def minify_css( src )
128
- src.gsub! /\s+/, " "
129
- src.gsub! /\/\*(.*?)\*\//, ""
130
- src.gsub! /\} /, "}\n"
131
- src.gsub! /\n$/, ""
132
- src.gsub! /[ \t]*\{[ \t]*/, "{"
133
- src.gsub! /;[ \t]*\}/, "}"
134
- src.gsub! /[ \t]*([,|{|}|>|:|;])[ \t]*/,"\\1" # Tersify
135
- src.gsub! /[ \t]*\n[ \t]*/, "" # Hardcore mode (no NLs)
136
- src.strip
137
- end
138
-
139
- def minify_js(src)
140
- JSMin.minify src
141
- end
142
-
143
-
144
- # Returns the file path of where assets of a certain type are stored.
145
- #
146
- # Params:
147
- # - `type` (Symbol) - Either `:js` or `:css`.
148
- #
149
- # Example:
150
- # get_path :js
151
- # # Possible value: "/home/rsc/myproject/public/js"
152
- #
153
- def get_path(type)
154
- path = (type == :js) ? settings.js_path : settings.css_path
155
- root_path path.squeeze('/')
156
- end
157
-
158
- # Returns the URL for a given filename and a type.
159
- #
160
- # Params:
161
- # - `type` (Symbol) - Either `:js` or `:css`.
162
- #
163
- # Example:
164
- # get_url :js, '/path/to/file.js'
165
- #
166
- def get_url(type, filename)
167
- prefix = (type == :js) ? settings.js_url : settings.css_url
168
- path = filename.gsub(/^#{Regexp.escape(get_path(type))}/, '')
169
- File.join(prefix, path).squeeze('/')
170
- end
171
-
172
- # Returns a list of assets of a given type for a given set.
173
- #
174
- # Params:
175
- # - `type` (Symbol) - Either `:js` or `:css`.
176
- # - `set` (String) - The set name, as defined in `config/assets.yml`.
177
- #
178
- # Returns:
179
- # An array of objects.
180
- #
181
- # Example:
182
- #
183
- # puts assets(:js, 'base').to_json
184
- # # Possible output:
185
- # # [ { 'url': '/js/app.js', 'path': '/home/rsc/projects/assets/public/js/app.js' },
186
- # # { 'url': '/js/main.js', 'path': '/home/rsc/projects/assets/public/js/main.js' },
187
- # # ...
188
- # # ]
189
- #
190
- # See also:
191
- # - js_assets
192
- #
193
- def assets(type, set)
194
- # type is either :js or :css
195
- specs = assets_config(type)[set]
196
- path = get_path(type)
197
- done = []
198
- # `specs` will be a list of filespecs. Find all files that
199
- # match all specs.
200
- [specs].flatten.inject([]) do |ret, spec|
201
- filepath = "#{path}/#{spec}"
202
- files = Dir[filepath]
203
-
204
- # Add it anyway if it doesn't match anything
205
- unless files.any? || done.include?(filepath) || filepath.include?('*')
206
- ret << { :url => get_url(type, filepath), :path => filepath }
207
- done << filepath
208
- end
209
-
210
- files.each do |filename|
211
- unless done.include? filename
212
- ret << {
213
- :url => [get_url(type, filename), File.mtime(filename).to_i].join('?'),
214
- :path => filename
215
- }
216
- done << filename
217
- end
218
- end
219
- ret
220
- end
221
- end
222
- end
223
- end
224
- end