front-end-blender 0.8.3 → 0.14

Sign up to get free protection for your applications and to get access to all the features.
data/README.rdoc ADDED
@@ -0,0 +1,81 @@
1
+ = Front-End Blender
2
+
3
+ == What is Blender?
4
+
5
+ Blender is like ant or make for the front-end. It aggregates and compresses
6
+ CSS and/or JavaScript assets for a site into efficient, production-ready files.
7
+
8
+ == The Blendfile
9
+
10
+ The Blendfile, named Blendfile.yaml by default, is the configuration file
11
+ that tells Blender which source files are combined into which output files.
12
+ The file uses the YAML format. The output file is listed as hash key and
13
+ source files are the hash values as an array. Here is a sample Blendfile:
14
+
15
+ # Blendfile.yaml for www.boldpx.com
16
+ _behavior:
17
+ _global-min.js:
18
+ - ../_vendor/jquery/jquery.js
19
+ - ../_vendor/shadowbox/src/js/adapter/shadowbox-jquery.js
20
+ - ../_vendor/shadowbox/src/js/shadowbox.js
21
+ - _global.js
22
+ - _analytics.js
23
+ - ../vendor/google-analytics/ga.js
24
+ _style:
25
+ _global:
26
+ min.css:
27
+ - ../../_vendor/shadowbox/src/css/shadowbox.css
28
+ - typography.css
29
+ - typography-print.css
30
+ - colors.css
31
+ - colors-print.css
32
+ - layout-screen.css
33
+ - layout-print.css
34
+
35
+ == Usage
36
+
37
+ Usage: blend [options]
38
+ -h, --help Show this message
39
+ -V, --version Prints Blender's version number
40
+ -g, --generate Generate a stub Blendfile
41
+ -f, --file FILE Use given Blendfile
42
+ -r, --root ROOT Specify the path to the web root directory
43
+ -t, --type TYPE Select file type to blend (css, js)
44
+ -c, --cache-buster [BUSTER] Append cache busters to URLs in CSS, defaults to timestamps
45
+ --force Force blending when source files aren't newer than output files
46
+ --yui=YUIOPTS Pass arguments to YUI Compressor
47
+ -d, --data EXPERIMENTAL Convert url(file.ext) to url(data:) in CSS files
48
+ -z, --gzip EXPERIMENTAL Also create gzip output files
49
+
50
+ == Examples
51
+
52
+ In your site directory run 'blend' to minify CSS and JavaScript.
53
+ blend
54
+
55
+ Other examples:
56
+ blend --generate
57
+ blend --yui='--preserve-semi'
58
+ blend -t css
59
+ blend -t css -d
60
+ blend -f public/Blendfile.yaml
61
+
62
+ == Installation
63
+
64
+ To install the RubyGem, run the following at the command line:
65
+ sudo gem sources --add http://gems.github.com
66
+ sudo gem install front-end-blender
67
+
68
+ * Java, v1.4 or greater is required
69
+ * RubyGems, v1.2 or greater is recommended
70
+
71
+ Ruby installation instructions for your platform can be found here: http://www.ruby-lang.org/en/downloads/
72
+ Instructions for downloading & installing RubyGems can be found here: http://rubygems.org/read/chapter/3
73
+ Download and install Java here: http://java.com/en/
74
+
75
+ == License
76
+
77
+ Copyright (c) 2008 Chris Griego
78
+ (c) 2008 Blake Elshire
79
+
80
+ Blender is freely distributable under the terms of an MIT-style license.
81
+ For details, see http://www.opensource.org/licenses/mit-license.php
data/bin/blend CHANGED
@@ -13,17 +13,30 @@ require 'front_end_architect/blender'
13
13
  options = {}
14
14
 
15
15
  opts = OptionParser.new do |opts|
16
- opts.on('-h', '--help', "Show this message") { puts opts; exit 0 }
17
- opts.on('-V', '--version', "Show the version number") { puts "Front-End Blender v#{Blender::VERSION}"; exit 0 }
18
- opts.on('-f FILE', '--file FILE', String, "Use given Blendfile") {|f| options[:blendfile] = f }
19
- opts.on('-t TYPE', '--type TYPE', [:css, :js], "Select file type to blend (css, js)") {|t| options[:file_type] = t }
20
- opts.on('-d', '--data', String, "Convert url(image.ext) to url(data:) in CSS files EXPERIMENTAL") { options[:data] = true }
21
- opts.on( '--force', String, "Force blending when source files aren't newer than output files") { options[:force] = true }
22
- opts.on( '--yui=YUIOPTS', String, "Pass arguments to YUI Compressor") {|o| options[:yuiopts] = o }
23
- opts.on('-g', '--generate', String, "Generate a stub Blendfile") { options[:generate] = true }
16
+ opts.on('-h', '--help', "Show this message") { puts opts; exit 0 }
17
+ opts.on('-V', '--version', "Show the version number") { puts "Front-End Blender v#{Blender::VERSION}"; exit 0 }
18
+ opts.on('-g', '--generate', String, "Generate a stub Blendfile") { options[:generate] = true }
19
+ opts.on('-f FILE', '--file FILE', String, "Use given Blendfile") {|f| options[:blendfile] = f }
20
+ opts.on('-r ROOT', '--root ROOT', String, "Set the path to the web root directory") {|r| options[:root] = r }
21
+ opts.on('-t TYPE', '--type TYPE', [:css, :js], "Select file type to blend (css, js)") {|t| options[:file_type] = t }
22
+ opts.on('-c [BUSTER]', '--cache-buster [BUSTER]', String, "Append cache busters to URLs in CSS, defaults to timestamps") {|b| options[:cache_buster] = b.nil? ? :mtime : b }
23
+ opts.on( '--force', String, "Force blending when source files aren't newer than output files") { options[:force] = true }
24
+ opts.on( '--yui=YUIOPTS', String, "Pass arguments to YUI Compressor") {|o| options[:yuiopts] = o }
25
+ opts.on('-d', '--data', String, "EXPERIMENTAL Convert url(file.ext) to url(data:) in CSS files") { options[:data] = true }
26
+ opts.on('-z', '--gzip', String, "EXPERIMENTAL Also create gzip output files") { options[:gzip] = true }
24
27
 
25
28
  opts.parse!(ARGV) rescue return false
26
29
  end
27
30
 
28
- blender = FrontEndArchitect::Blender.new(options)
29
- blender.blend
31
+ begin
32
+ blender = FrontEndArchitect::Blender.new(options)
33
+
34
+ if (options[:generate])
35
+ blender.generate
36
+ else
37
+ blender.blend
38
+ end
39
+ rescue Exception => e
40
+ puts e
41
+ exit 1
42
+ end
@@ -0,0 +1,379 @@
1
+ # Copyright (c) 2008 Chris Griego
2
+ # (c) 2008 Blake Elshire
3
+ #
4
+ # Blender is freely distributable under the terms of an MIT-style license.
5
+ # For details, see http://www.opensource.org/licenses/mit-license.php
6
+
7
+ # TODO Nearly all file name comparisons should be case-insensitive
8
+
9
+ $:.unshift File.join(File.dirname(File.symlink?(__FILE__) ? File.readlink(__FILE__) : __FILE__), *%w[..])
10
+
11
+ require 'rubygems'
12
+ require 'yaml'
13
+ require 'base64'
14
+ require 'benchmark'
15
+ require 'mime/types'
16
+ require 'find'
17
+ require 'pathname'
18
+ require 'zlib'
19
+ require 'front_end_architect/hash'
20
+
21
+ module FrontEndArchitect
22
+ class Blender
23
+ VERSION = '0.14'
24
+
25
+ FILTER_REGEX = /filter: ?[^?]+\(src=(['"])([^\?'"]+)(\?(?:[^'"]+)?)?\1,[^?]+\1\);/im
26
+ IMPORT_REGEX = /@import(?: url\(| )(['"]?)([^\?'"\)\s]+)(\?(?:[^'"\)]+)?)?\1\)?(?:[^?;]+)?;/im
27
+ URL_REGEX = /url\((['"]?)([^\?'"\)]+)(\?(?:[^'"\)]+)?)?\1?\)/im
28
+
29
+ DEFAULT_OPTIONS = {
30
+ :blendfile => 'Blendfile.yaml',
31
+ :data => false,
32
+ :force => false,
33
+ :root => File.dirname(:blendfile.to_s),
34
+ }
35
+
36
+ def initialize(opts)
37
+ @options = DEFAULT_OPTIONS.merge(opts)
38
+ end
39
+
40
+ def blend
41
+ elapsed = Benchmark.realtime do
42
+ unless File.exists? @options[:blendfile]
43
+ raise "Couldn't find '#{@options[:blendfile]}'"
44
+ end
45
+
46
+ blender = YAML::load_file @options[:blendfile]
47
+
48
+ Dir.chdir(File.dirname(@options[:blendfile]))
49
+
50
+ blender = flatten_blendfile(blender)
51
+
52
+ blender.each do |output_name, sources|
53
+ output_name = Pathname.new(output_name).cleanpath.to_s
54
+
55
+ output_new = false
56
+ gzip_output_name = output_name + '.gz'
57
+
58
+ # Checks the type flag and if the current file meets the type requirements continues
59
+ if output_name.match '.' + @options[:file_type].to_s
60
+ file_type = output_name.match(/\.css/) ? 'css' : 'js'
61
+
62
+ # Checks if output file exists and checks the mtimes of the source files to the output file if new creates a new file
63
+ if File.exists?(output_name) && (!@options[:gzip] || File.exists?(gzip_output_name))
64
+ output_files = []
65
+ output_files << File.mtime(output_name)
66
+ output_files << File.mtime(gzip_output_name) if @options[:gzip] && File.exists?(gzip_output_name)
67
+
68
+ oldest_output = output_files.sort.first
69
+
70
+ sources.each do |i|
71
+ if File.mtime(i) > oldest_output
72
+ output_new = true
73
+ break
74
+ end
75
+ end
76
+
77
+ if output_new || @options[:force]
78
+ create_output(output_name, sources, file_type)
79
+ else
80
+ puts "Skipping: #{output_name}"
81
+ puts "Skipping: #{gzip_output_name}" if @options[:gzip]
82
+ end
83
+ else
84
+ create_output(output_name, sources, file_type)
85
+ end
86
+ end
87
+ end
88
+ end
89
+
90
+ puts sprintf('%.5f', elapsed) + ' seconds'
91
+ end
92
+
93
+ def generate
94
+ if File.exists?(@options[:blendfile]) && !@options[:force]
95
+ raise "'#{@options[:blendfile]}' already exists"
96
+ end
97
+
98
+ blend_files = Hash.new
99
+
100
+ Find.find(Dir.getwd) do |f|
101
+ basename = File.basename(f)
102
+
103
+ if FileTest.directory?(f) && (basename[0] == ?. || basename.match(/^(yui|tinymce|dojo|wp-includes|wp-admin|mint)$/) || (File.basename(f) == 'rails' && File.basename(File.dirname(f)) == 'vendor'))
104
+ Find.prune
105
+ elsif !(basename.match(/[-.](pack|min)\.(css|js)$/) || basename.match(/^(sifr\.js|ext\.js|mootools.*\.js)$/))
106
+ # TODO Test for 'pack.js' and 'min.css' where the folder name serves as the identifier
107
+ # TODO Check file contents instead of name for minification (port YSlow's isMinified)
108
+ f.gsub!(Dir.getwd.to_s + '/', '')
109
+
110
+ if File.extname(f) == '.css' || File.extname(f) == '.js'
111
+ min_file = basename.sub(/\.(css|js)$/, '-min.\1')
112
+ path = File.dirname(f).split('/') # File#dirname depends on /
113
+
114
+ path.push min_file
115
+ path.push [basename]
116
+
117
+ h = path.reverse.inject { |m,v| { v => m } }
118
+
119
+ blend_files.deep_merge!(h).inspect
120
+ end
121
+ end
122
+ end
123
+
124
+ File.open(@options[:blendfile], 'w') do |blendfile|
125
+ blendfile << blend_files.to_yaml
126
+ end
127
+ end
128
+
129
+ protected
130
+
131
+ def flatten_blendfile(value, key=nil, context=[])
132
+ if value.is_a? Hash
133
+ context << key unless key.nil?
134
+
135
+ new_hash = {}
136
+
137
+ value.each do |k, v|
138
+ new_hash.merge! flatten_blendfile(v, k, context.dup)
139
+ end
140
+
141
+ new_hash
142
+ else
143
+ prefix = context.join(File::SEPARATOR)
144
+ prefix += File::SEPARATOR unless context.empty?
145
+
146
+ value.each_index do |i|
147
+ value[i] = prefix + value[i]
148
+ end
149
+
150
+ return { (prefix + key) => value }
151
+ end
152
+ end
153
+
154
+ def create_output(output_name, sources, type)
155
+ output = ''
156
+
157
+ File.open(output_name, 'w') do |output_file|
158
+ # Determine full path of the output file
159
+ output_path = Pathname.new(File.expand_path(File.dirname(output_name)))
160
+ imports = ''
161
+
162
+ sources.each do |i|
163
+ if File.extname(i) == '.css'
164
+ processed_output, processed_imports = process_css(i, output_path)
165
+
166
+ output << processed_output
167
+ imports << processed_imports
168
+ else
169
+ output << IO.read(i)
170
+ end
171
+ end
172
+
173
+ if File.extname(output_name) == '.css' && !imports.empty?
174
+ output.insert(0, imports)
175
+ end
176
+
177
+ # Compress
178
+ libdir = File.join(File.dirname(File.symlink?(__FILE__) ? File.readlink(__FILE__) : __FILE__), *%w[.. .. lib])
179
+
180
+ IO.popen("java -jar #{libdir}/yui/yuicompressor.jar #{@options[:yuiopts]} --type #{type}", 'r+') do |io|
181
+ io.write output
182
+ io.close_write
183
+
184
+ output = io.read
185
+
186
+ if File.extname(output_name) == '.css'
187
+ output.gsub! ' and(', ' and (' # Workaround for YUI Compressor Bug #1938329
188
+ output.gsub! '*/;}', '*/}' # Workaround for YUI Compressor Bug #1961175
189
+
190
+ if @options[:data]
191
+ output = output.gsub(URL_REGEX) do
192
+ unless $2.include?('.css')
193
+ mime_type = MIME::Types.type_for($2)
194
+ url_contents = make_data_uri(IO.read($2), mime_type[0])
195
+ else
196
+ url_contents = $2
197
+ end
198
+ %Q!url(#{url_contents})!
199
+ end
200
+ end
201
+ end
202
+
203
+ output_file << output
204
+ end
205
+
206
+ if $? == 32512 # command not found
207
+ raise "\nBlender requires Java, v1.4 or greater, to be installed for YUI Compressor"
208
+ end
209
+ end
210
+
211
+ puts output_name
212
+
213
+ if @options[:gzip]
214
+ output_gzip = output_name + '.gz'
215
+
216
+ Zlib::GzipWriter.open(output_gzip) do |gz|
217
+ gz.write(output)
218
+ end
219
+
220
+ puts output_gzip
221
+ end
222
+ end
223
+
224
+ # TODO Move this to a seperate class and clean it up A LOT. For 1.1
225
+ def process_css(input_file, output_path)
226
+ # Determine full path of input file
227
+ input_path = Pathname.new(File.dirname(input_file))
228
+ input = IO.read(input_file)
229
+ found_imports = ''
230
+
231
+ # Find filter statements and append cache busters to URLs
232
+ if @options[:cache_buster]
233
+ input = input.gsub(FILTER_REGEX) do |filter|
234
+ uri = $2
235
+ unless uri.match(/^(https:\/\/|http:\/\/|\/\/)/)
236
+ full_path = File.expand_path($2, File.dirname(input_file))
237
+ buster = make_cache_buster(full_path, $3)
238
+ new_path = uri.to_s + buster
239
+
240
+ %Q!filter='#{new_path}'!
241
+ else
242
+ %Q!filter='#{$2}#{$3}'!
243
+ end
244
+ end
245
+ end
246
+
247
+ # Handle @import statements URL rewrite and adding cache busters
248
+ input = input.gsub(IMPORT_REGEX) do |import|
249
+ uri = $2
250
+ asset_path = Pathname.new(File.expand_path(uri, input_path))
251
+
252
+ if uri.match(/^(\/[^\/]+.+)$/)
253
+ asset_path = Pathname.new(File.join(File.expand_path(@options[:root]), uri))
254
+ end
255
+
256
+ unless uri.match(/^(https:\/\/|http:\/\/|\/\/)/)
257
+ if (output_path != input_path)
258
+
259
+ new_path = asset_path.relative_path_from(output_path)
260
+
261
+ if @options[:cache_buster]
262
+ buster = make_cache_buster(asset_path, $3)
263
+ import.gsub!(uri, new_path.to_s+buster)
264
+ else
265
+ import.gsub!(uri, new_path)
266
+ end
267
+ else
268
+ if @options[:cache_buster]
269
+ buster = make_cache_buster(asset_path, $3)
270
+ import.gsub!(uri, asset_path.to_s+buster)
271
+ end
272
+ end
273
+ end
274
+
275
+ found_imports << import
276
+
277
+ %Q!!
278
+ end
279
+
280
+ if output_path == input_path
281
+ if @options[:data]
282
+ input = input.gsub(URL_REGEX) do
283
+ uri = $2
284
+
285
+ unless uri.match(/^(https:\/\/|http:\/\/|\/\/)/)
286
+ new_path = File.expand_path($2, File.dirname(input_file))
287
+ if uri.match(/^(\/[^\/]+.+)$/)
288
+ new_path = Pathname.new(File.join(File.expand_path(@options[:root]), uri))
289
+ end
290
+
291
+ %Q!url(#{new_path})!
292
+ else
293
+ %Q!url(#{$2}#{$3})!
294
+ end
295
+ end
296
+ elsif @options[:cache_buster]
297
+ input = input.gsub(URL_REGEX) do
298
+ unless uri.match(/^(https:\/\/|http:\/\/|\/\/)/)
299
+ uri = $2
300
+
301
+ if uri.match(/^(\/[^\/]+.+)$/)
302
+ uri = Pathname.new(File.join(File.expand_path(@options[:root]), uri))
303
+ end
304
+
305
+ if @options[:cache_buster]
306
+ buster = make_cache_buster(uri, $3)
307
+ new_path = uri.to_s+buster
308
+ end
309
+
310
+ %Q!url(#{new_path})!
311
+ else
312
+ %Q!url(#{$2}#{$3})!
313
+ end
314
+ end
315
+ end
316
+
317
+ return input, found_imports
318
+ else
319
+ # Find all url(.ext) in file and rewrite relative url from output directory.
320
+ input = input.gsub(URL_REGEX) do
321
+ uri = $2
322
+
323
+ unless uri.match(/^(https:\/\/|http:\/\/|\/\/)/)
324
+ if @options[:data]
325
+ # if doing data conversion rewrite url as an absolute path.
326
+ new_path = File.expand_path(uri, File.dirname(input_file))
327
+
328
+ if uri.match(/^(\/[^\/]+.+)$/)
329
+ new_path = Pathname.new(File.join(File.expand_path(@options[:root]), uri))
330
+ end
331
+ else
332
+ asset_path = Pathname.new(File.expand_path(uri, File.dirname(input_file)))
333
+
334
+ if uri.match(/^(\/[^\/]+.+)$/)
335
+ asset_path = Pathname.new(File.join(File.expand_path(@options[:root]), uri))
336
+ end
337
+
338
+ new_path = asset_path.relative_path_from(output_path)
339
+
340
+ if @options[:cache_buster]
341
+ buster = make_cache_buster(asset_path, $3)
342
+ new_path = new_path.to_s+buster
343
+ else
344
+ new_path = new_path.to_s+$3 unless $3.nil?
345
+ end
346
+ end
347
+
348
+ %Q!url(#{new_path})!
349
+ else
350
+ %Q!url(#{$2}#{$3})!
351
+ end
352
+ end
353
+
354
+ return input, found_imports
355
+ end
356
+ end
357
+
358
+ def make_cache_buster(asset_path, query_string)
359
+ unless query_string.nil?
360
+ query_string += '&'
361
+ else
362
+ query_string = '?'
363
+ end
364
+
365
+ if @options[:cache_buster] == :mtime
366
+ file_mtime = File.mtime(asset_path).to_i
367
+ buster = query_string + file_mtime.to_s
368
+ else
369
+ buster = query_string + @options[:cache_buster]
370
+ end
371
+
372
+ return buster
373
+ end
374
+
375
+ def make_data_uri(content, content_type)
376
+ "data:#{content_type};base64,#{Base64.encode64(content)}".gsub("\n", '')
377
+ end
378
+ end
379
+ end
@@ -0,0 +1,26 @@
1
+ class Hash
2
+ def deep_merge(hash)
3
+ target = dup
4
+
5
+ hash.keys.each do |key|
6
+ if hash[key].is_a? Hash and self[key].is_a? Hash
7
+ target[key] = target[key].deep_merge(hash[key])
8
+ next
9
+ end
10
+
11
+ target[key] = hash[key]
12
+ end
13
+
14
+ target
15
+ end
16
+
17
+ def deep_merge!(second)
18
+ second.each_pair do |k,v|
19
+ if self[k].is_a?(Hash) and second[k].is_a? Hash
20
+ self[k].deep_merge!(second[k])
21
+ else
22
+ self[k] = second[k]
23
+ end
24
+ end
25
+ end
26
+ end
data/lib/yui/LICENSE ADDED
@@ -0,0 +1,30 @@
1
+ Software License Agreement (BSD License)
2
+
3
+ Copyright (c) 2008, Yahoo! Inc.
4
+ All rights reserved.
5
+
6
+ Redistribution and use of this software in source and binary forms, with or without modification, are
7
+ permitted provided that the following conditions are met:
8
+
9
+ * Redistributions of source code must retain the above
10
+ copyright notice, this list of conditions and the
11
+ following disclaimer.
12
+
13
+ * Redistributions in binary form must reproduce the above
14
+ copyright notice, this list of conditions and the
15
+ following disclaimer in the documentation and/or other
16
+ materials provided with the distribution.
17
+
18
+ * Neither the name of Yahoo! Inc. nor the names of its
19
+ contributors may be used to endorse or promote products
20
+ derived from this software without specific prior
21
+ written permission of Yahoo! Inc.
22
+
23
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
24
+ WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
25
+ PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
26
+ ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
29
+ TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
30
+ ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Binary file
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: front-end-blender
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.8.3
4
+ version: "0.14"
5
5
  platform: ruby
6
6
  authors:
7
7
  - Blake Elshire & Chris Griego
@@ -9,7 +9,7 @@ autorequire: front_end_architect/blend
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2008-05-22 00:00:00 -07:00
12
+ date: 2008-06-23 00:00:00 -07:00
13
13
  default_executable: blend
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -30,10 +30,13 @@ extensions: []
30
30
  extra_rdoc_files: []
31
31
 
32
32
  files:
33
- - README
33
+ - README.rdoc
34
34
  - MIT-LICENSE
35
- - bin/*
36
- - lib/**/*
35
+ - bin/blend
36
+ - lib/front_end_architect/blender.rb
37
+ - lib/front_end_architect/hash.rb
38
+ - lib/yui/LICENSE
39
+ - lib/yui/yuicompressor.jar
37
40
  has_rdoc: false
38
41
  homepage: http://github.com/front-end/front-end-blender/tree/master
39
42
  post_install_message:
@@ -55,7 +58,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
55
58
  version:
56
59
  requirements:
57
60
  - Java, v1.4 or greater
58
- rubyforge_project:
61
+ rubyforge_project: frontendblender
59
62
  rubygems_version: 1.0.1
60
63
  signing_key:
61
64
  specification_version: 2
data/README DELETED
@@ -1,65 +0,0 @@
1
- == What is Blender?
2
-
3
- Blender is like ant or make for the front-end. It aggregates and compresses
4
- CSS and/or JavaScript assets for a site into efficient, production-ready files.
5
-
6
- == Blendfile
7
-
8
- The Blendfile, named blender.yaml by default, is the configuration file that
9
- tells Blender which source files are combined into which output files. The
10
- file uses the YAML format. The output file is listed as hash key and source
11
- files are the hash values as an array. Here is a sample Blendfile:
12
-
13
- # blender.yaml for boldpx.com
14
- _behavior/_global-min.js:
15
- - _vendor/jquery/jquery.js
16
- - _vendor/shadowbox/src/js/adapter/shadowbox-jquery.js
17
- - _vendor/shadowbox/src/js/shadowbox.js
18
- - _behavior/_global.js
19
-
20
- _style/_global-min.css:
21
- - _vendor/shadowbox/src/css/shadowbox.css
22
- - _style/_global/typography.css
23
- - _style/_global/typography-print.css
24
- - _style/_global/colors.css
25
- - _style/_global/colors-print.css
26
- - _style/_global/layout-screen.css
27
- - _style/_global/layout-print.css
28
-
29
- == Usage
30
-
31
- Usage: blend [options]
32
- -h, --help Show this message
33
- -V, --version Prints Blender's version number
34
- -f, --file FILE Use given Blendfile
35
- -t, --type TYPE Select file type to blend (css, js)
36
- -d, --data Convert url(image.ext) to url(data:) in CSS files EXPERIMENTAL
37
- --force Force blending when source files aren't newer than output files
38
- --yui=YUIOPTS Pass arguments to YUI Compressor
39
- -g, --generate Generate a stub Blendfile
40
-
41
- == Examples
42
-
43
- In your site directory run 'blend' to minify CSS and JavaScript.
44
- blend
45
-
46
- Other examples:
47
- blend -f site/blender.yaml
48
- blend -t css
49
- blend -t css -d
50
- blend --yui='--preserve-semi'
51
-
52
- == Installation
53
-
54
- To install the rubygem, run the following at the command line:
55
- sudo gem install blender
56
-
57
- Java, v1.4 or greater is required
58
-
59
- == License
60
-
61
- Copyright (c) 2008 Chris Griego
62
- (c) 2008 Blake Elshire
63
-
64
- Blender is freely distributable under the terms of an MIT-style license.
65
- For details, see http://www.opensource.org/licenses/mit-license.php