asset_library 0.4.0 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README.rdoc +103 -55
- data/lib/asset_library/asset_module.rb +14 -27
- data/lib/asset_library/compiler/base.rb +32 -0
- data/lib/asset_library/compiler/closure.rb +39 -0
- data/lib/asset_library/compiler/default.rb +15 -0
- data/lib/asset_library/compiler.rb +37 -0
- data/lib/asset_library/helpers.rb +2 -0
- data/lib/asset_library/rake_tasks.rb +4 -7
- data/lib/asset_library/util.rb +20 -5
- data/lib/asset_library.rb +62 -12
- data/rails/init.rb +3 -2
- data/spec/asset_library/asset_module_spec.rb +2 -48
- data/spec/asset_library/asset_spec.rb +1 -1
- data/spec/asset_library/compiler/base_spec.rb +11 -0
- data/spec/asset_library/compiler/closure_spec.rb +104 -0
- data/spec/asset_library/compiler/default_spec.rb +27 -0
- data/spec/asset_library/compiler_spec.rb +35 -0
- data/spec/asset_library/helpers_spec.rb +1 -1
- data/spec/asset_library_spec.rb +49 -26
- data/spec/integration_spec.rb +88 -0
- data/spec/spec_helper.rb +69 -0
- metadata +12 -2
data/README.rdoc
CHANGED
|
@@ -58,63 +58,66 @@ A cached module is simply the concatenation of its constituent files.
|
|
|
58
58
|
A typical configuration (Yaml) file might look like this. In Rails, this
|
|
59
59
|
should be in <tt>config/asset_library.yml</tt>.
|
|
60
60
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
61
|
+
modules:
|
|
62
|
+
javascripts:
|
|
63
|
+
cache: library
|
|
64
|
+
optional_suffix: compressed
|
|
65
|
+
base: javascripts
|
|
66
|
+
suffix: js
|
|
67
|
+
files:
|
|
68
|
+
- vendor/jquery
|
|
69
|
+
|
|
70
|
+
# jQuery UI parts we need
|
|
71
|
+
- vendor/jquery-ui/ui.core
|
|
72
|
+
- vendor/jquery-ui/ui.draggable
|
|
73
|
+
- vendor/jquery-ui/ui.droppable
|
|
74
|
+
- vendor/jquery-ui/ui.sortable
|
|
75
|
+
- vendor/jquery-ui/effects.core
|
|
76
|
+
|
|
77
|
+
- lib
|
|
78
|
+
- plugins/*
|
|
79
|
+
- application
|
|
80
|
+
- initializers/*
|
|
81
|
+
|
|
82
|
+
tiny_mce_javascripts:
|
|
83
|
+
# TinyMCE doesn't give us a choice on cache name
|
|
84
|
+
cache: vendor/tiny_mce/tiny_mce_gzip
|
|
85
|
+
optional_suffix: compressed
|
|
86
|
+
base: javascripts
|
|
87
|
+
suffix: js
|
|
88
|
+
files:
|
|
89
|
+
- vendor/tiny_mce/tiny_mce
|
|
90
|
+
# ... it's possible to bundle all of TinyMCE together with a bit of magic
|
|
91
|
+
|
|
92
|
+
stylesheets:
|
|
93
|
+
cache: library
|
|
94
|
+
base: stylesheets
|
|
95
|
+
suffix: css
|
|
96
|
+
formats:
|
|
97
|
+
- ie6: [null, ie8, ie7, ie6]
|
|
98
|
+
- ie7: [null, ie8, ie7]
|
|
99
|
+
- ie8: [null, ie8]
|
|
100
|
+
files:
|
|
101
|
+
- reset
|
|
102
|
+
- application
|
|
103
|
+
- layout
|
|
104
|
+
- views/**/*
|
|
104
105
|
|
|
105
106
|
# in general...
|
|
106
|
-
#
|
|
107
|
-
#
|
|
108
|
-
#
|
|
109
|
-
#
|
|
110
|
-
#
|
|
111
|
-
#
|
|
112
|
-
#
|
|
113
|
-
#
|
|
114
|
-
#
|
|
115
|
-
#
|
|
116
|
-
#
|
|
117
|
-
#
|
|
107
|
+
# modules:
|
|
108
|
+
# module_name:
|
|
109
|
+
# cache: cache_file
|
|
110
|
+
# base: base_path_of_assets_in_web_root
|
|
111
|
+
# suffix: suffix ("css" or "js")
|
|
112
|
+
# formats:
|
|
113
|
+
# format1: ["extra_suffix_1", "extra_suffix_2"]
|
|
114
|
+
# format2: [null, "extra_suffix3"]
|
|
115
|
+
# optional_suffix: optional_suffix
|
|
116
|
+
# files:
|
|
117
|
+
# - file1_relative_to_base
|
|
118
|
+
# - file2_relative_to_base
|
|
119
|
+
# - ...
|
|
120
|
+
# ...
|
|
118
121
|
|
|
119
122
|
Here are what the various configuration elements mean:
|
|
120
123
|
|
|
@@ -160,6 +163,51 @@ not exist will be excluded; globbing will include/exclude files with
|
|
|
160
163
|
<tt>formats</tt> as appropriate; and files without <tt>optional_suffix</tt>
|
|
161
164
|
will not be output alongside files with the same name endowed with the suffix.
|
|
162
165
|
|
|
166
|
+
== Compilers
|
|
167
|
+
|
|
168
|
+
If you would like asset library to do more than just concatenate the
|
|
169
|
+
files to produce your modules, then you need to specify a compiler.
|
|
170
|
+
Asset Library currently ships with support for one compiler: Closure
|
|
171
|
+
Compiler, and has an extendable framework to add more.
|
|
172
|
+
|
|
173
|
+
To specify that a module is to be compiled with the Closure Compiler,
|
|
174
|
+
use the <tt>compiler</tt> key for that module. You may pass
|
|
175
|
+
additional flags with the <tt>compiler_flags</tt> option:
|
|
176
|
+
|
|
177
|
+
modules:
|
|
178
|
+
javascripts:
|
|
179
|
+
cache: library
|
|
180
|
+
compiler: closure
|
|
181
|
+
compiler_flags: --warning_level QUIET
|
|
182
|
+
base: javascripts
|
|
183
|
+
suffix: js
|
|
184
|
+
files:
|
|
185
|
+
- javascripts/**/*
|
|
186
|
+
|
|
187
|
+
You also need to configure the compiler by using a
|
|
188
|
+
<tt>compilers.closure</tt> key:
|
|
189
|
+
|
|
190
|
+
compilers:
|
|
191
|
+
closure:
|
|
192
|
+
path: /path/to/closure.jar
|
|
193
|
+
flags: --warning_level QUIET
|
|
194
|
+
|
|
195
|
+
The full list of Closure Compiler settings are:
|
|
196
|
+
|
|
197
|
+
<tt>path</tt>: The path to the Closure Compiler jar. This is
|
|
198
|
+
mandatory.
|
|
199
|
+
|
|
200
|
+
<tt>flags</tt>: Flags to pass to Closure Compiler. These are combined
|
|
201
|
+
with any per-module flags given via the <tt>compiler_flags</tt> option
|
|
202
|
+
in the individual modules. Default: no flags.
|
|
203
|
+
|
|
204
|
+
<tt>java</tt>: The java command to use. This will be searched for in
|
|
205
|
+
the <tt>PATH</tt> unless it is an absolute filename. Default:
|
|
206
|
+
<tt>java</tt>.
|
|
207
|
+
|
|
208
|
+
<tt>java_flags</tt>: Flags to pass to the java interpreter. Default:
|
|
209
|
+
no flags.
|
|
210
|
+
|
|
163
211
|
== Copyright
|
|
164
212
|
|
|
165
213
|
I believe in software freedom, not any abomination thereof. This project is
|
|
@@ -4,10 +4,23 @@ class AssetLibrary
|
|
|
4
4
|
class AssetModule
|
|
5
5
|
attr_reader(:config)
|
|
6
6
|
|
|
7
|
-
def initialize(config)
|
|
7
|
+
def initialize(name, config)
|
|
8
|
+
@name = name.to_s
|
|
8
9
|
@config = config
|
|
9
10
|
end
|
|
10
11
|
|
|
12
|
+
attr_reader :name
|
|
13
|
+
|
|
14
|
+
# Returns the type of compiler to use for this asset module.
|
|
15
|
+
def compiler_type
|
|
16
|
+
(config[:compiler] || :default).to_sym
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
# Returns the Array of compiler flags to use.
|
|
20
|
+
def compiler_flags
|
|
21
|
+
Util.normalize_flags(config[:compiler_flags])
|
|
22
|
+
end
|
|
23
|
+
|
|
11
24
|
# Returns an Array of Assets to include.
|
|
12
25
|
#
|
|
13
26
|
# Arguments:
|
|
@@ -49,36 +62,10 @@ class AssetLibrary
|
|
|
49
62
|
extra_suffixes.inject([]) { |r, s| r.concat(assets_with_extra_suffix(s)) }
|
|
50
63
|
end
|
|
51
64
|
|
|
52
|
-
def contents(format = nil)
|
|
53
|
-
s = StringIO.new
|
|
54
|
-
|
|
55
|
-
assets(format).each do |asset|
|
|
56
|
-
File.open(asset.absolute_path, 'r') do |infile|
|
|
57
|
-
s.write(infile.read)
|
|
58
|
-
end
|
|
59
|
-
end
|
|
60
|
-
s.rewind
|
|
61
|
-
|
|
62
|
-
s
|
|
63
|
-
end
|
|
64
|
-
|
|
65
65
|
# Returns an Asset representing the cache file
|
|
66
66
|
def cache_asset(format = nil)
|
|
67
67
|
extra = format ? ".#{format}" : ''
|
|
68
68
|
Asset.new(File.join(AssetLibrary.root, config[:base], "#{config[:cache]}#{extra}.#{config[:suffix]}"))
|
|
69
69
|
end
|
|
70
|
-
|
|
71
|
-
def write_cache(format = nil)
|
|
72
|
-
File.open(cache_asset(format).absolute_path, 'w') do |outfile|
|
|
73
|
-
outfile.write(contents(format).read)
|
|
74
|
-
end
|
|
75
|
-
end
|
|
76
|
-
|
|
77
|
-
def write_all_caches
|
|
78
|
-
write_cache
|
|
79
|
-
(config[:formats] || {}).keys.each do |format|
|
|
80
|
-
write_cache(format)
|
|
81
|
-
end
|
|
82
|
-
end
|
|
83
70
|
end
|
|
84
71
|
end
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
class AssetLibrary
|
|
2
|
+
module Compiler
|
|
3
|
+
class Base
|
|
4
|
+
def initialize(config)
|
|
5
|
+
@config = config || {}
|
|
6
|
+
@asset_modules = []
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
attr_reader :config, :asset_modules
|
|
10
|
+
|
|
11
|
+
def add_asset_module(asset_module)
|
|
12
|
+
@asset_modules << asset_module
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def write_all_caches(format = nil)
|
|
16
|
+
raise NotImplementedError, "abstract method"
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
protected
|
|
20
|
+
|
|
21
|
+
# Return the absolute output path for the given asset module.
|
|
22
|
+
def output_path(asset_module, format)
|
|
23
|
+
asset_module.cache_asset(format).absolute_path
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
# Return the absolute input paths for the given asset module.
|
|
27
|
+
def input_paths(asset_module, format)
|
|
28
|
+
asset_module.assets(format).map{|asset| asset.absolute_path}
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
require 'tmpdir'
|
|
2
|
+
|
|
3
|
+
class AssetLibrary
|
|
4
|
+
module Compiler
|
|
5
|
+
class Closure < Base
|
|
6
|
+
def initialize(config)
|
|
7
|
+
super
|
|
8
|
+
config[:path] or
|
|
9
|
+
raise ConfigurationError, "Please set path of closure jar with compilers.closure.path configuration setting"
|
|
10
|
+
config[:java] ||= 'java'
|
|
11
|
+
config[:java_flags] = Util.normalize_flags(config[:java_flags])
|
|
12
|
+
config[:path] = normalize_path(config[:path])
|
|
13
|
+
config[:flags] = Util.normalize_flags(config[:flags])
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def write_all_caches(format = nil)
|
|
17
|
+
asset_modules.each do |asset_module|
|
|
18
|
+
command = [config[:java]]
|
|
19
|
+
command.concat(config[:java_flags])
|
|
20
|
+
command << '-jar' << config[:path]
|
|
21
|
+
command.concat(config[:flags])
|
|
22
|
+
command.concat(asset_module.compiler_flags)
|
|
23
|
+
command << '--js_output_file' << "#{output_path(asset_module, format)}"
|
|
24
|
+
input_paths(asset_module, format).each do |input|
|
|
25
|
+
command << '--js' << input
|
|
26
|
+
end
|
|
27
|
+
system *command or
|
|
28
|
+
raise Error, "closure compiler failed"
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
private
|
|
33
|
+
|
|
34
|
+
def normalize_path(path)
|
|
35
|
+
(Pathname(AssetLibrary.app_root) + path).to_s
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
class AssetLibrary
|
|
2
|
+
module Compiler
|
|
3
|
+
class Default < Base
|
|
4
|
+
def write_all_caches(format = nil)
|
|
5
|
+
asset_modules.each do |asset_module|
|
|
6
|
+
open(output_path(asset_module, format), 'w') do |file|
|
|
7
|
+
input_paths(asset_module, format).each do |path|
|
|
8
|
+
file << File.read(path)
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
require File.dirname(__FILE__) + '/compiler/base'
|
|
2
|
+
require File.dirname(__FILE__) + '/compiler/default'
|
|
3
|
+
require File.dirname(__FILE__) + '/compiler/closure'
|
|
4
|
+
|
|
5
|
+
class AssetLibrary
|
|
6
|
+
module Compiler
|
|
7
|
+
Error = Class.new(RuntimeError)
|
|
8
|
+
|
|
9
|
+
class << self
|
|
10
|
+
# Create an instance of a compiler for the given compiler type.
|
|
11
|
+
def create(type, config={})
|
|
12
|
+
klass = compiler_classes[type] ||= built_in_class_for(type)
|
|
13
|
+
klass.new(config)
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
# Register a custom compiler class.
|
|
17
|
+
def register(type, klass)
|
|
18
|
+
compiler_classes[type] = klass
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def reset!
|
|
22
|
+
compiler_classes.clear
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
private
|
|
26
|
+
|
|
27
|
+
def compiler_classes
|
|
28
|
+
@compiler_classes ||= {}
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def built_in_class_for(type)
|
|
32
|
+
class_name = type.to_s.gsub(/(?:\A|_)(.)/){$1.upcase}
|
|
33
|
+
const_get(class_name)
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
@@ -2,8 +2,9 @@ def init_asset_library
|
|
|
2
2
|
require 'asset_library'
|
|
3
3
|
|
|
4
4
|
# TODO: Find a way to not-hard-code these paths?
|
|
5
|
-
AssetLibrary.config_path =
|
|
6
|
-
AssetLibrary.root =
|
|
5
|
+
AssetLibrary.config_path = Rails.root + 'config/asset_library.yml'
|
|
6
|
+
AssetLibrary.root = Rails.public_path
|
|
7
|
+
AssetLibrary.app_root = Rails.root
|
|
7
8
|
end
|
|
8
9
|
|
|
9
10
|
namespace(:asset_library) do
|
|
@@ -16,10 +17,6 @@ namespace(:asset_library) do
|
|
|
16
17
|
desc "Deletes all asset caches specified in config/asset.yml"
|
|
17
18
|
task(:clean) do
|
|
18
19
|
init_asset_library
|
|
19
|
-
|
|
20
|
-
asset_modules = keys.collect{|k| AssetLibrary.asset_module(k)}
|
|
21
|
-
asset_modules.each do |m|
|
|
22
|
-
FileUtils.rm_f(m.cache_asset.absolute_path)
|
|
23
|
-
end
|
|
20
|
+
AssetLibrary.delete_all_caches
|
|
24
21
|
end
|
|
25
22
|
end
|
data/lib/asset_library/util.rb
CHANGED
|
@@ -1,10 +1,25 @@
|
|
|
1
|
+
require 'shellwords'
|
|
2
|
+
|
|
1
3
|
class AssetLibrary
|
|
2
4
|
module Util
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
5
|
+
class << self
|
|
6
|
+
def symbolize_hash_keys(hash)
|
|
7
|
+
return hash unless Hash === hash # because we recurse
|
|
8
|
+
hash.inject({}) do |ret, (key, value)|
|
|
9
|
+
ret[(key.to_sym rescue key) || key] = symbolize_hash_keys(value)
|
|
10
|
+
ret
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def normalize_flags(flags)
|
|
15
|
+
case flags
|
|
16
|
+
when String
|
|
17
|
+
Shellwords.shellwords(flags)
|
|
18
|
+
when nil
|
|
19
|
+
[]
|
|
20
|
+
else
|
|
21
|
+
flags
|
|
22
|
+
end
|
|
8
23
|
end
|
|
9
24
|
end
|
|
10
25
|
end
|
data/lib/asset_library.rb
CHANGED
|
@@ -5,10 +5,14 @@ rescue LoadError
|
|
|
5
5
|
require 'glob_fu'
|
|
6
6
|
end
|
|
7
7
|
|
|
8
|
+
require 'yaml'
|
|
9
|
+
require File.dirname(__FILE__) + '/asset_library/compiler'
|
|
8
10
|
require File.dirname(__FILE__) + '/asset_library/asset_module'
|
|
9
11
|
require File.dirname(__FILE__) + '/asset_library/util'
|
|
10
12
|
|
|
11
13
|
class AssetLibrary
|
|
14
|
+
ConfigurationError = Class.new(RuntimeError)
|
|
15
|
+
|
|
12
16
|
class << self
|
|
13
17
|
def config_path
|
|
14
18
|
@config_path
|
|
@@ -18,13 +22,20 @@ class AssetLibrary
|
|
|
18
22
|
@config_path = config_path
|
|
19
23
|
end
|
|
20
24
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
25
|
+
#
|
|
26
|
+
# Root of your application.
|
|
27
|
+
#
|
|
28
|
+
# Paths of external programs (if required) are resolved relative
|
|
29
|
+
# to this path.
|
|
30
|
+
#
|
|
31
|
+
attr_accessor :app_root
|
|
24
32
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
33
|
+
#
|
|
34
|
+
# Root directory of your output files.
|
|
35
|
+
#
|
|
36
|
+
# Output files are resolved relative to this path.
|
|
37
|
+
#
|
|
38
|
+
attr_accessor :root
|
|
28
39
|
|
|
29
40
|
def cache
|
|
30
41
|
return true if @cache.nil?
|
|
@@ -32,8 +43,7 @@ class AssetLibrary
|
|
|
32
43
|
end
|
|
33
44
|
|
|
34
45
|
def cache=(cache)
|
|
35
|
-
|
|
36
|
-
@cache_vars = nil
|
|
46
|
+
reset!
|
|
37
47
|
@cache = cache
|
|
38
48
|
end
|
|
39
49
|
|
|
@@ -50,22 +60,62 @@ class AssetLibrary
|
|
|
50
60
|
else
|
|
51
61
|
{}
|
|
52
62
|
end
|
|
63
|
+
if !ret[:modules] && ret.values.any?{|value| value.is_a?(Hash) && value[:files]}
|
|
64
|
+
warn <<-EOS.gsub(/^ *\|/, '')
|
|
65
|
+
| WARNING: Your asset library configuration follows a
|
|
66
|
+
| deprecated format. Please move all your asset modules
|
|
67
|
+
| under a "modules:" key, as described in the
|
|
68
|
+
| documentation.
|
|
69
|
+
EOS
|
|
70
|
+
ret = { :modules => ret }
|
|
71
|
+
end
|
|
72
|
+
ret[:modules] ||= {}
|
|
73
|
+
ret[:compilers] ||= {}
|
|
53
74
|
@config = cache ? ret : nil
|
|
54
75
|
ret
|
|
55
76
|
end
|
|
56
77
|
|
|
78
|
+
def compilers
|
|
79
|
+
@compilers ||= {}
|
|
80
|
+
end
|
|
81
|
+
|
|
57
82
|
def asset_module(key)
|
|
58
|
-
module_config = config[key.to_sym]
|
|
83
|
+
module_config = config[:modules][key.to_sym]
|
|
59
84
|
if module_config
|
|
60
|
-
AssetModule.new(module_config)
|
|
85
|
+
AssetModule.new(key, module_config)
|
|
61
86
|
end
|
|
62
87
|
end
|
|
63
88
|
|
|
89
|
+
def compiler(asset_module)
|
|
90
|
+
type = asset_module.compiler_type
|
|
91
|
+
config = self.config[:compilers][type] || {}
|
|
92
|
+
compilers[type] ||= Compiler.create(type, config)
|
|
93
|
+
end
|
|
94
|
+
|
|
64
95
|
def write_all_caches
|
|
65
|
-
config.keys.each do |key|
|
|
96
|
+
config[:modules].keys.each do |key|
|
|
66
97
|
m = asset_module(key)
|
|
67
|
-
m
|
|
98
|
+
c = compiler(m)
|
|
99
|
+
c.add_asset_module(m)
|
|
68
100
|
end
|
|
101
|
+
|
|
102
|
+
compilers.values.each do |compiler|
|
|
103
|
+
compiler.write_all_caches
|
|
104
|
+
end
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
def delete_all_caches
|
|
108
|
+
asset_modules = config[:modules].keys.collect{|k| AssetLibrary.asset_module(k)}
|
|
109
|
+
asset_modules.each do |m|
|
|
110
|
+
FileUtils.rm_f(m.cache_asset.absolute_path)
|
|
111
|
+
end
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
def reset!
|
|
115
|
+
@config = nil
|
|
116
|
+
@cache_vars = nil
|
|
117
|
+
@compilers = nil
|
|
118
|
+
Compiler.reset!
|
|
69
119
|
end
|
|
70
120
|
end
|
|
71
121
|
end
|
data/rails/init.rb
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
1
|
AssetLibrary.cache = ActionController::Base.perform_caching
|
|
2
|
-
AssetLibrary.config_path =
|
|
3
|
-
AssetLibrary.root =
|
|
2
|
+
AssetLibrary.config_path = Rails.root + 'config/asset_library.yml'
|
|
3
|
+
AssetLibrary.root = Rails.public_path
|
|
4
|
+
AssetLibrary.app_root = Rails.root
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
require File.dirname(__FILE__) + '/../spec_helper'
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
|
2
2
|
|
|
3
3
|
require 'set'
|
|
4
4
|
|
|
@@ -110,18 +110,6 @@ describe(AssetLibrary::AssetModule) do
|
|
|
110
110
|
end
|
|
111
111
|
end
|
|
112
112
|
|
|
113
|
-
describe('#contents') do
|
|
114
|
-
it('should return an IO object') do
|
|
115
|
-
stub_fs([ '/c/file1.css', '/c/file2.css' ])
|
|
116
|
-
m(css_config(:files => ['file*'])).contents.should(respond_to(:read))
|
|
117
|
-
end
|
|
118
|
-
|
|
119
|
-
it('should concatenate individual file contents') do
|
|
120
|
-
stub_fs([ '/c/file1.css', '/c/file2.css' ])
|
|
121
|
-
m(css_config(:files => ['file*'])).contents.read.should == "/c/file1.css\n/c/file2.css\n"
|
|
122
|
-
end
|
|
123
|
-
end
|
|
124
|
-
|
|
125
113
|
describe('#cache_asset') do
|
|
126
114
|
it('should use options[:cache]') do
|
|
127
115
|
m(css_config).cache_asset.absolute_path.should == "#{prefix}/c/cache.css"
|
|
@@ -132,44 +120,10 @@ describe(AssetLibrary::AssetModule) do
|
|
|
132
120
|
end
|
|
133
121
|
end
|
|
134
122
|
|
|
135
|
-
describe('#write_cache') do
|
|
136
|
-
it('should write to cache.css') do
|
|
137
|
-
File.should_receive(:open).with("#{prefix}/c/cache.css", 'w')
|
|
138
|
-
m(css_config).write_cache
|
|
139
|
-
end
|
|
140
|
-
|
|
141
|
-
it('should write cache contents to cache') do
|
|
142
|
-
stub_fs([ '/c/file1.css', '/c/file2.css' ])
|
|
143
|
-
m(css_config(:files => ['file*'])).write_cache
|
|
144
|
-
File.open("#{prefix}/c/cache.css") { |f| f.read.should == "/c/file1.css\n/c/file2.css\n" }
|
|
145
|
-
end
|
|
146
|
-
|
|
147
|
-
it('should use :format to determine CSS output file') do
|
|
148
|
-
File.should_receive(:open).with("#{prefix}/c/cache.e.css", 'w')
|
|
149
|
-
m(css_config).write_cache(:e)
|
|
150
|
-
end
|
|
151
|
-
end
|
|
152
|
-
|
|
153
|
-
describe('#write_all_caches') do
|
|
154
|
-
it('should write cache.css (no :format)') do
|
|
155
|
-
File.should_receive(:open).with("#{prefix}/c/cache.css", 'w')
|
|
156
|
-
m(css_config).write_all_caches
|
|
157
|
-
end
|
|
158
|
-
|
|
159
|
-
it('should write no-format and all format files') do
|
|
160
|
-
formats = { :e1 => [], :e2 => [] }
|
|
161
|
-
File.should_receive(:open).with("#{prefix}/c/cache.css", 'w')
|
|
162
|
-
formats.keys.each do |format|
|
|
163
|
-
File.should_receive(:open).with("#{prefix}/c/cache.#{format}.css", 'w')
|
|
164
|
-
end
|
|
165
|
-
m(css_config(:formats => formats)).write_all_caches
|
|
166
|
-
end
|
|
167
|
-
end
|
|
168
|
-
|
|
169
123
|
private
|
|
170
124
|
|
|
171
125
|
def m(config)
|
|
172
|
-
AssetLibrary::AssetModule.new(config)
|
|
126
|
+
AssetLibrary::AssetModule.new(:name, config)
|
|
173
127
|
end
|
|
174
128
|
|
|
175
129
|
def js_config(options = {})
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
|
|
2
|
+
|
|
3
|
+
describe(AssetLibrary::Compiler::Base) do
|
|
4
|
+
describe('#write_all_caches') do
|
|
5
|
+
it('should raise NotImplementedError') do
|
|
6
|
+
lambda do
|
|
7
|
+
AssetLibrary::Compiler::Base.new({}).write_all_caches
|
|
8
|
+
end.should raise_error(NotImplementedError)
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
end
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
|
|
2
|
+
|
|
3
|
+
describe(AssetLibrary::Compiler::Closure) do
|
|
4
|
+
include TemporaryDirectory
|
|
5
|
+
include CompilerHelpers
|
|
6
|
+
|
|
7
|
+
before do
|
|
8
|
+
AssetLibrary.app_root = "#{tmp}/app_root"
|
|
9
|
+
AssetLibrary.root = "#{tmp}/root"
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def compiler(configuration = {})
|
|
13
|
+
configuration[:path] = '/PATH/TO/CLOSURE.jar' unless configuration.key?(:path)
|
|
14
|
+
compiler = AssetLibrary::Compiler::Closure.new(configuration)
|
|
15
|
+
compiler.stub!(:system)
|
|
16
|
+
compiler
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def add_one_compilation(compiler)
|
|
20
|
+
compiler.add_asset_module mock_asset_module('lib', :format, 'out.js', 'in.js')
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
describe('#initialize') do
|
|
24
|
+
it('should cry if the path to the compiler is not set') do
|
|
25
|
+
lambda{compiler(:path => nil)}.should raise_error(AssetLibrary::ConfigurationError)
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
describe('#write_all_caches') do
|
|
30
|
+
before do
|
|
31
|
+
@tmpdir = "#{tmp}/tmpdir"
|
|
32
|
+
FileUtils.mkdir_p @tmpdir
|
|
33
|
+
AssetLibrary::Util.stub!(:mktmpdir).and_yield(@tmpdir)
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
it("should run each module's files through closure compiler") do
|
|
37
|
+
compiler = self.compiler
|
|
38
|
+
compiler.add_asset_module mock_asset_module('lib1', :format, 'LIB1.js', 'lib1-file1.js')
|
|
39
|
+
compiler.add_asset_module mock_asset_module('lib2', :format, 'LIB2.js', 'lib2-file1.js', 'lib2-file2.js')
|
|
40
|
+
compiler.should_receive(:system).with(*%W"java -jar /PATH/TO/CLOSURE.jar --js_output_file LIB1.js --js lib1-file1.js").and_return(true)
|
|
41
|
+
compiler.should_receive(:system).with(*%W"java -jar /PATH/TO/CLOSURE.jar --js_output_file LIB2.js --js lib2-file1.js --js lib2-file2.js").and_return(true)
|
|
42
|
+
compiler.write_all_caches(:format)
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
it('should take the java executable name from the :java configuration option') do
|
|
46
|
+
compiler = compiler(:java => '/PATH/TO/JAVA')
|
|
47
|
+
add_one_compilation(compiler)
|
|
48
|
+
compiler.should_receive(:system).with{ |*args| args.first == '/PATH/TO/JAVA' }.and_return(true)
|
|
49
|
+
compiler.write_all_caches(:format)
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
it('should take the path to closure compiler from the :path configuration option') do
|
|
53
|
+
compiler = compiler(:path => '/CLOSURE.jar')
|
|
54
|
+
add_one_compilation(compiler)
|
|
55
|
+
compiler.should_receive(:system).with{ |*args| args[1..2] == ['-jar', '/CLOSURE.jar'] }.and_return(true)
|
|
56
|
+
compiler.write_all_caches(:format)
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
it('should interpret the path as relative to the application root') do
|
|
60
|
+
AssetLibrary.app_root = "#{tmp}/app_root"
|
|
61
|
+
compiler = compiler(:path => 'CLOSURE')
|
|
62
|
+
add_one_compilation(compiler)
|
|
63
|
+
compiler.should_receive(:system).with{ |*args| args[1..2] == ['-jar', "#{tmp}/app_root/CLOSURE"] }.and_return(true)
|
|
64
|
+
compiler.write_all_caches(:format)
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
it('should pass any configured java_flags to java') do
|
|
68
|
+
compiler = compiler(:java_flags => "-foo -bar")
|
|
69
|
+
add_one_compilation(compiler)
|
|
70
|
+
compiler.should_receive(:system).with{ |*args| args[1..2] == ['-foo', '-bar'] }.and_return(true)
|
|
71
|
+
compiler.write_all_caches(:format)
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
it('should accept an Array for java_flags') do
|
|
75
|
+
compiler = compiler(:java_flags => %w"-foo -bar")
|
|
76
|
+
add_one_compilation(compiler)
|
|
77
|
+
compiler.should_receive(:system).with{ |*args| args[1..2] == ['-foo', '-bar'] }.and_return(true)
|
|
78
|
+
compiler.write_all_caches(:format)
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
it('should pass any configured flags to the compiler') do
|
|
82
|
+
compiler = compiler(:flags => "--foo --bar")
|
|
83
|
+
add_one_compilation(compiler)
|
|
84
|
+
compiler.should_receive(:system).with{ |*args| args[3..4] == ['--foo', '--bar'] }.and_return(true)
|
|
85
|
+
compiler.write_all_caches(:format)
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
it('should add module compiler flags to the compiler command') do
|
|
89
|
+
compiler = self.compiler
|
|
90
|
+
compiler.add_asset_module mock_asset_module('lib1', :format, 'LIB1.js', 'lib1-file1.js', :compiler_flags => ['--foo'])
|
|
91
|
+
compiler.add_asset_module mock_asset_module('lib2', :format, 'LIB2.js', 'lib2-file1.js', :compiler_flags => ['--bar'])
|
|
92
|
+
compiler.should_receive(:system).with(*%W"java -jar /PATH/TO/CLOSURE.jar --foo --js_output_file LIB1.js --js lib1-file1.js").and_return(true)
|
|
93
|
+
compiler.should_receive(:system).with(*%W"java -jar /PATH/TO/CLOSURE.jar --bar --js_output_file LIB2.js --js lib2-file1.js").and_return(true)
|
|
94
|
+
compiler.write_all_caches(:format)
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
it('should raise a Compiler::Error if the compiler fails') do
|
|
98
|
+
compiler = self.compiler
|
|
99
|
+
compiler.add_asset_module mock_asset_module('lib1', :format, "lib1.js", "file1.js")
|
|
100
|
+
compiler.stub!(:system).and_return(false)
|
|
101
|
+
lambda{compiler.write_all_caches(:format)}.should raise_error(AssetLibrary::Compiler::Error)
|
|
102
|
+
end
|
|
103
|
+
end
|
|
104
|
+
end
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
|
|
2
|
+
|
|
3
|
+
describe(AssetLibrary::Compiler::Default) do
|
|
4
|
+
include TemporaryDirectory
|
|
5
|
+
include CompilerHelpers
|
|
6
|
+
|
|
7
|
+
before do
|
|
8
|
+
@compiler = AssetLibrary::Compiler::Default.new(nil)
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
describe('#write_all_caches') do
|
|
12
|
+
it('should concatenate each set of input files to produce the respective output files') do
|
|
13
|
+
write_file "lib1-file1.txt", "lib1-file1\n"
|
|
14
|
+
write_file "lib2-file1.txt", "lib2-file1\n"
|
|
15
|
+
write_file "lib2-file2.txt", "lib2-file2\n"
|
|
16
|
+
@compiler.add_asset_module mock_asset_module('lib1', :format, "#{tmp}/lib1.txt", "#{tmp}/lib1-file1.txt")
|
|
17
|
+
@compiler.add_asset_module mock_asset_module('lib2', :format, "#{tmp}/lib2.txt", "#{tmp}/lib2-file1.txt", "#{tmp}/lib2-file2.txt")
|
|
18
|
+
@compiler.write_all_caches(:format)
|
|
19
|
+
File.read("#{tmp}/lib1.txt").should == "lib1-file1\n"
|
|
20
|
+
File.read("#{tmp}/lib2.txt").should == "lib2-file1\nlib2-file2\n"
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def write_file(path, content)
|
|
24
|
+
open("#{tmp}/#{path}", 'w'){|f| f.print content}
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
|
2
|
+
|
|
3
|
+
describe(AssetLibrary::Compiler) do
|
|
4
|
+
Compiler = AssetLibrary::Compiler
|
|
5
|
+
include TemporaryDirectory
|
|
6
|
+
|
|
7
|
+
before do
|
|
8
|
+
AssetLibrary.app_root = "#{tmp}/app_root"
|
|
9
|
+
AssetLibrary.root = "#{tmp}/root"
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
describe('.create') do
|
|
13
|
+
it('should return a Default compiler for :default') do
|
|
14
|
+
Compiler.create(:default).should be_a(Compiler::Default)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
it('should return a Closure compiler for :closure') do
|
|
18
|
+
Compiler.create(:closure, :path => '').should be_a(Compiler::Closure)
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
it('should pass the configuration to the compiler') do
|
|
22
|
+
Compiler.create(:default, {:param => 2}).config[:param].should == 2
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
describe('.register') do
|
|
27
|
+
TestCompiler = Class.new(Compiler::Base)
|
|
28
|
+
|
|
29
|
+
it('should register a custom compiler type') do
|
|
30
|
+
Compiler.register(:test, TestCompiler)
|
|
31
|
+
compiler = Compiler.create(:test)
|
|
32
|
+
compiler.should be_a(TestCompiler)
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
data/spec/asset_library_spec.rb
CHANGED
|
@@ -1,16 +1,8 @@
|
|
|
1
|
-
require File.dirname(__FILE__) + '/spec_helper'
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
|
2
2
|
|
|
3
3
|
describe(AssetLibrary) do
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
@old_config_path = AssetLibrary.config_path
|
|
7
|
-
@old_cache = AssetLibrary.cache
|
|
8
|
-
end
|
|
9
|
-
|
|
10
|
-
after(:each) do
|
|
11
|
-
AssetLibrary.root = @old_root
|
|
12
|
-
AssetLibrary.config_path = @old_config_path
|
|
13
|
-
AssetLibrary.cache = @old_cache
|
|
4
|
+
def config_skeleton
|
|
5
|
+
{:modules => {}, :compilers => {}}
|
|
14
6
|
end
|
|
15
7
|
|
|
16
8
|
describe('#config') do
|
|
@@ -21,10 +13,10 @@ describe(AssetLibrary) do
|
|
|
21
13
|
AssetLibrary.config
|
|
22
14
|
end
|
|
23
15
|
|
|
24
|
-
it('should return
|
|
16
|
+
it('should return a skeletal configuration if config_path does not exist') do
|
|
25
17
|
AssetLibrary.config_path = '/config.yml'
|
|
26
18
|
File.stub!(:exist?).with('/config.yml').and_return(false)
|
|
27
|
-
AssetLibrary.config.should ==
|
|
19
|
+
AssetLibrary.config.should == config_skeleton
|
|
28
20
|
end
|
|
29
21
|
|
|
30
22
|
it('should cache config if cache is set') do
|
|
@@ -58,13 +50,26 @@ describe(AssetLibrary) do
|
|
|
58
50
|
{ 'a' => { 'b' => 'c' } }
|
|
59
51
|
)
|
|
60
52
|
|
|
61
|
-
AssetLibrary.config.should ==
|
|
53
|
+
AssetLibrary.config.should == config_skeleton.merge(:a => {:b => 'c'})
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
it('should accept a v0.4 config file with a deprecation warning') do
|
|
57
|
+
AssetLibrary.cache = false
|
|
58
|
+
AssetLibrary.config_path = '/config.yml'
|
|
59
|
+
|
|
60
|
+
File.stub!(:exist?).with('/config.yml').and_return(true)
|
|
61
|
+
YAML.should_receive(:load_file).with('/config.yml').and_return(
|
|
62
|
+
{ 'a' => { 'files' => ['a.js'] } }
|
|
63
|
+
)
|
|
64
|
+
AssetLibrary.should_receive(:warn)
|
|
65
|
+
|
|
66
|
+
AssetLibrary.config.should == { :compilers => {}, :modules => { :a => { :files => ['a.js'] } } }
|
|
62
67
|
end
|
|
63
68
|
end
|
|
64
69
|
|
|
65
70
|
describe('#asset_module') do
|
|
66
71
|
before(:each) do
|
|
67
|
-
@config =
|
|
72
|
+
@config = config_skeleton
|
|
68
73
|
AssetLibrary.stub!(:config).and_return(@config)
|
|
69
74
|
end
|
|
70
75
|
|
|
@@ -73,25 +78,43 @@ describe(AssetLibrary) do
|
|
|
73
78
|
end
|
|
74
79
|
|
|
75
80
|
it('should return an AssetModule when given a valid key') do
|
|
76
|
-
@config[:foo] = {}
|
|
81
|
+
@config[:modules][:foo] = {}
|
|
77
82
|
AssetLibrary.asset_module(:foo).should(be_a(AssetLibrary::AssetModule))
|
|
78
83
|
end
|
|
79
84
|
end
|
|
80
85
|
|
|
81
|
-
describe('#
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
86
|
+
describe('#compiler') do
|
|
87
|
+
include TemporaryDirectory
|
|
88
|
+
|
|
89
|
+
before do
|
|
90
|
+
AssetLibrary.app_root = "#{tmp}/root"
|
|
91
|
+
end
|
|
85
92
|
|
|
86
|
-
|
|
87
|
-
|
|
93
|
+
it('should return a Default compiler if no compiler type has been configured for the given asset module') do
|
|
94
|
+
configure_compilers
|
|
95
|
+
asset_module = mock(:compiler_type => :default)
|
|
96
|
+
AssetLibrary.compiler(asset_module).should be_a(AssetLibrary::Compiler::Default)
|
|
97
|
+
end
|
|
88
98
|
|
|
89
|
-
|
|
90
|
-
|
|
99
|
+
it('should return a compiler of the configured type for the given asset module, if one is given') do
|
|
100
|
+
configure_compilers
|
|
101
|
+
asset_module = mock(:compiler_type => :closure)
|
|
102
|
+
AssetLibrary.compiler(asset_module).should be_a(AssetLibrary::Compiler::Closure)
|
|
103
|
+
end
|
|
91
104
|
|
|
92
|
-
|
|
105
|
+
it('should pass the right compiler configuration to the compiler') do
|
|
106
|
+
config = {:default => {:foo => 2}}
|
|
107
|
+
configure_compilers(config)
|
|
108
|
+
asset_module = mock(:compiler_type => :default)
|
|
109
|
+
AssetLibrary.compiler(asset_module).config[:foo].should == 2
|
|
110
|
+
end
|
|
93
111
|
|
|
94
|
-
|
|
112
|
+
def configure_compilers(config=nil)
|
|
113
|
+
config = {:compilers => config || {:closure => {:path => 'closure.jar'}}}
|
|
114
|
+
config_path = "#{tmp}/config.yml"
|
|
115
|
+
open(config_path, 'w'){|f| YAML.dump(config, f)}
|
|
116
|
+
AssetLibrary.config_path = config_path
|
|
117
|
+
AssetLibrary.config
|
|
95
118
|
end
|
|
96
119
|
end
|
|
97
120
|
end
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
|
2
|
+
|
|
3
|
+
describe(AssetLibrary) do
|
|
4
|
+
include TemporaryDirectory
|
|
5
|
+
|
|
6
|
+
class ReverseCompiler < AssetLibrary::Compiler::Base
|
|
7
|
+
def write_all_caches(format = nil)
|
|
8
|
+
asset_modules.each do |asset_module|
|
|
9
|
+
open(output_path(asset_module, format), 'w') do |file|
|
|
10
|
+
file.print config[:header]
|
|
11
|
+
input_paths(asset_module, format).reverse_each do |input|
|
|
12
|
+
file << File.read(input)
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
before do
|
|
20
|
+
AssetLibrary::Compiler.register(:reverse, ReverseCompiler)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
describe "AssetLibrary.write_all_caches" do
|
|
24
|
+
it "should generate cached asset libraries for each asset module, with the configured compiler" do
|
|
25
|
+
write_file "#{tmp}/root/cssbase/stylesheet-1.css", "style1 { background: #000 }"
|
|
26
|
+
write_file "#{tmp}/root/cssbase/stylesheet-2.css.opt", "style2 { background: #fff }"
|
|
27
|
+
write_file "#{tmp}/root/jsbase/javascript-1.js", "function f1(){alert('1');}"
|
|
28
|
+
write_file "#{tmp}/root/jsbase/javascript-2.js.opt", "function f2(){alert('2');}"
|
|
29
|
+
config_path = "#{tmp}/config.yml"
|
|
30
|
+
open(config_path, 'w'){|f| f.puts <<-EOS}
|
|
31
|
+
compilers:
|
|
32
|
+
reverse:
|
|
33
|
+
header: HEADER
|
|
34
|
+
|
|
35
|
+
modules:
|
|
36
|
+
stylsheets:
|
|
37
|
+
cache: lib
|
|
38
|
+
optional_suffix: opt
|
|
39
|
+
base: cssbase
|
|
40
|
+
suffix: css
|
|
41
|
+
files:
|
|
42
|
+
- stylesheet-1
|
|
43
|
+
- stylesheet-2
|
|
44
|
+
|
|
45
|
+
javascripts:
|
|
46
|
+
cache: lib
|
|
47
|
+
optional_suffix: opt
|
|
48
|
+
base: jsbase
|
|
49
|
+
suffix: js
|
|
50
|
+
compiler: reverse
|
|
51
|
+
files:
|
|
52
|
+
- javascript-1
|
|
53
|
+
- javascript-2
|
|
54
|
+
EOS
|
|
55
|
+
AssetLibrary.root = "#{tmp}/root"
|
|
56
|
+
AssetLibrary.config_path = config_path
|
|
57
|
+
AssetLibrary.write_all_caches
|
|
58
|
+
File.read("#{tmp}/root/cssbase/lib.css").should == "style1 { background: #000 }style2 { background: #fff }"
|
|
59
|
+
File.read("#{tmp}/root/jsbase/lib.js").should == "HEADERfunction f2(){alert('2');}function f1(){alert('1');}"
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
describe "AssetLibrary.delete_all_caches" do
|
|
64
|
+
it "should delete all caches" do
|
|
65
|
+
write_file "#{tmp}/root/cssbase/lib.css"
|
|
66
|
+
config_path = "#{tmp}/config.yml"
|
|
67
|
+
open(config_path, 'w'){|f| f.puts <<-EOS}
|
|
68
|
+
modules:
|
|
69
|
+
stylesheets:
|
|
70
|
+
cache: lib
|
|
71
|
+
base: cssbase
|
|
72
|
+
suffix: css
|
|
73
|
+
files:
|
|
74
|
+
- stylesheet-1
|
|
75
|
+
- stylesheet-2
|
|
76
|
+
EOS
|
|
77
|
+
AssetLibrary.root = "#{tmp}/root"
|
|
78
|
+
AssetLibrary.config_path = config_path
|
|
79
|
+
AssetLibrary.delete_all_caches
|
|
80
|
+
File.should_not exist("#{tmp}/root/cssbase/lib.css")
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
def write_file(path, content='...')
|
|
85
|
+
FileUtils.mkdir_p File.dirname(path)
|
|
86
|
+
open(path, 'w'){|f| f.print content}
|
|
87
|
+
end
|
|
88
|
+
end
|
data/spec/spec_helper.rb
CHANGED
|
@@ -2,3 +2,72 @@ require 'rubygems'
|
|
|
2
2
|
require 'spec'
|
|
3
3
|
|
|
4
4
|
require File.dirname(__FILE__) + '/../lib/asset_library'
|
|
5
|
+
|
|
6
|
+
module TemporaryDirectory
|
|
7
|
+
TMP = File.expand_path(File.dirname(__FILE__) + '/tmp')
|
|
8
|
+
|
|
9
|
+
def self.included(base)
|
|
10
|
+
base.before do
|
|
11
|
+
remove_tmp
|
|
12
|
+
make_tmp
|
|
13
|
+
enter_tmp
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
base.after do
|
|
17
|
+
leave_tmp
|
|
18
|
+
remove_tmp
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def make_tmp
|
|
23
|
+
FileUtils.mkdir_p tmp
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def remove_tmp
|
|
27
|
+
FileUtils.rm_rf tmp
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def enter_tmp
|
|
31
|
+
@original_pwd = Dir.pwd
|
|
32
|
+
Dir.chdir tmp
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def leave_tmp
|
|
36
|
+
Dir.chdir @original_pwd
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def tmp
|
|
40
|
+
TMP
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
module CompilerHelpers
|
|
45
|
+
def mock_asset_module(name, format, output_path, *input_paths)
|
|
46
|
+
config = input_paths.last.is_a?(Hash) ? input_paths.pop : {}
|
|
47
|
+
output_asset = mock(:absolute_path => output_path)
|
|
48
|
+
input_assets = input_paths.map{|path| mock(:absolute_path => path)}
|
|
49
|
+
asset_module = mock(:name => name)
|
|
50
|
+
asset_module.stub!(:cache_asset).with(format).and_return(output_asset)
|
|
51
|
+
asset_module.stub!(:assets).with(format).and_return(input_assets)
|
|
52
|
+
asset_module.stub!(:compiler_flags).and_return(config[:compiler_flags] || [])
|
|
53
|
+
asset_module.stub!(:config).and_return(config)
|
|
54
|
+
asset_module
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
Spec::Runner.configure do |config|
|
|
59
|
+
config.before do
|
|
60
|
+
@old_app_root = AssetLibrary.app_root
|
|
61
|
+
@old_root = AssetLibrary.root
|
|
62
|
+
@old_config_path = AssetLibrary.config_path
|
|
63
|
+
@old_cache = AssetLibrary.cache
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
config.after do
|
|
67
|
+
AssetLibrary.app_root = @app_root
|
|
68
|
+
AssetLibrary.root = @old_root
|
|
69
|
+
AssetLibrary.config_path = @old_config_path
|
|
70
|
+
AssetLibrary.cache = @old_cache
|
|
71
|
+
AssetLibrary.reset!
|
|
72
|
+
end
|
|
73
|
+
end
|
metadata
CHANGED
|
@@ -1,16 +1,17 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: asset_library
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.5.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- adamh
|
|
8
8
|
- alegscogs
|
|
9
|
+
- oggy
|
|
9
10
|
autorequire:
|
|
10
11
|
bindir: bin
|
|
11
12
|
cert_chain: []
|
|
12
13
|
|
|
13
|
-
date: 2010-02-
|
|
14
|
+
date: 2010-02-24 00:00:00 -05:00
|
|
14
15
|
default_executable:
|
|
15
16
|
dependencies:
|
|
16
17
|
- !ruby/object:Gem::Dependency
|
|
@@ -35,6 +36,10 @@ files:
|
|
|
35
36
|
- lib/asset_library.rb
|
|
36
37
|
- lib/asset_library/asset.rb
|
|
37
38
|
- lib/asset_library/asset_module.rb
|
|
39
|
+
- lib/asset_library/compiler.rb
|
|
40
|
+
- lib/asset_library/compiler/base.rb
|
|
41
|
+
- lib/asset_library/compiler/closure.rb
|
|
42
|
+
- lib/asset_library/compiler/default.rb
|
|
38
43
|
- lib/asset_library/helpers.rb
|
|
39
44
|
- lib/asset_library/rake_tasks.rb
|
|
40
45
|
- lib/asset_library/util.rb
|
|
@@ -71,6 +76,11 @@ summary: Manage and bundle CSS and JavaScript files
|
|
|
71
76
|
test_files:
|
|
72
77
|
- spec/asset_library_spec.rb
|
|
73
78
|
- spec/asset_library/asset_module_spec.rb
|
|
79
|
+
- spec/asset_library/compiler/default_spec.rb
|
|
80
|
+
- spec/asset_library/compiler/base_spec.rb
|
|
81
|
+
- spec/asset_library/compiler/closure_spec.rb
|
|
82
|
+
- spec/asset_library/compiler_spec.rb
|
|
74
83
|
- spec/asset_library/asset_spec.rb
|
|
75
84
|
- spec/asset_library/helpers_spec.rb
|
|
76
85
|
- spec/spec_helper.rb
|
|
86
|
+
- spec/integration_spec.rb
|