front-end-blender 0.14 → 0.16

Sign up to get free protection for your applications and to get access to all the features.
data/README.rdoc CHANGED
@@ -41,6 +41,7 @@ source files are the hash values as an array. Here is a sample Blendfile:
41
41
  -f, --file FILE Use given Blendfile
42
42
  -r, --root ROOT Specify the path to the web root directory
43
43
  -t, --type TYPE Select file type to blend (css, js)
44
+ -m, --min [MINIFIER] Select minifier to use (yui, none)
44
45
  -c, --cache-buster [BUSTER] Append cache busters to URLs in CSS, defaults to timestamps
45
46
  --force Force blending when source files aren't newer than output files
46
47
  --yui=YUIOPTS Pass arguments to YUI Compressor
data/bin/blend CHANGED
@@ -13,17 +13,18 @@ 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('-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 }
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('-m [MINIFIER]', '--min [MINIFIER]', [:yui, :none], "Select minifier to use (yui, none)") {|m| options[:min] = m.nil? ? :none : m.to_sym }
23
+ 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 }
24
+ opts.on( '--force', String, "Force blending when source files aren't newer than output files") { options[:force] = true }
25
+ opts.on( '--yui=YUIOPTS', String, "Pass arguments to YUI Compressor") {|o| options[:yuiopts] = o }
26
+ opts.on('-d', '--data', String, "EXPERIMENTAL Convert url(file.ext) to url(data:) in CSS files") { options[:data] = true }
27
+ opts.on('-z', '--gzip', String, "EXPERIMENTAL Also create gzip output files") { options[:gzip] = true }
27
28
 
28
29
  opts.parse!(ARGV) rescue return false
29
30
  end
@@ -12,6 +12,7 @@ require 'rubygems'
12
12
  require 'yaml'
13
13
  require 'base64'
14
14
  require 'benchmark'
15
+ require 'colored'
15
16
  require 'mime/types'
16
17
  require 'find'
17
18
  require 'pathname'
@@ -20,7 +21,7 @@ require 'front_end_architect/hash'
20
21
 
21
22
  module FrontEndArchitect
22
23
  class Blender
23
- VERSION = '0.14'
24
+ VERSION = '0.16'
24
25
 
25
26
  FILTER_REGEX = /filter: ?[^?]+\(src=(['"])([^\?'"]+)(\?(?:[^'"]+)?)?\1,[^?]+\1\);/im
26
27
  IMPORT_REGEX = /@import(?: url\(| )(['"]?)([^\?'"\)\s]+)(\?(?:[^'"\)]+)?)?\1\)?(?:[^?;]+)?;/im
@@ -31,6 +32,7 @@ module FrontEndArchitect
31
32
  :data => false,
32
33
  :force => false,
33
34
  :root => File.dirname(:blendfile.to_s),
35
+ :min => :yui,
34
36
  }
35
37
 
36
38
  def initialize(opts)
@@ -75,10 +77,15 @@ module FrontEndArchitect
75
77
  end
76
78
 
77
79
  if output_new || @options[:force]
78
- create_output(output_name, sources, file_type)
80
+ if File.writable?(output_name) && !(@options[:gzip] && !File.writable?(gzip_output_name))
81
+ create_output(output_name, sources, file_type)
82
+ else
83
+ puts "Permission Denied:".white_on_red + " " + output_name.red
84
+ puts "Permission Denied:".white_on_red + " " + gzip_output_name.red if @options[:gzip]
85
+ end
79
86
  else
80
- puts "Skipping: #{output_name}"
81
- puts "Skipping: #{gzip_output_name}" if @options[:gzip]
87
+ puts "Skipping: ".yellow + output_name.yellow
88
+ puts "Skipping: ".yellow + gzip_output_name.yellow if @options[:gzip]
82
89
  end
83
90
  else
84
91
  create_output(output_name, sources, file_type)
@@ -144,7 +151,11 @@ module FrontEndArchitect
144
151
  prefix += File::SEPARATOR unless context.empty?
145
152
 
146
153
  value.each_index do |i|
147
- value[i] = prefix + value[i]
154
+ unless value[i].match(/^(\/[^\/]+.+)$/)
155
+ value[i] = prefix + value[i]
156
+ else
157
+ value[i] = @options[:root] + value[i]
158
+ end
148
159
  end
149
160
 
150
161
  return { (prefix + key) => value }
@@ -175,40 +186,45 @@ module FrontEndArchitect
175
186
  end
176
187
 
177
188
  # 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
189
+ if @options[:min] == :yui
190
+ libdir = File.join(File.dirname(File.symlink?(__FILE__) ? File.readlink(__FILE__) : __FILE__), *%w[.. .. lib])
185
191
 
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
192
+ IO.popen("java -jar #{libdir}/yui/yuicompressor.jar #{@options[:yuiopts]} --type #{type}", 'r+') do |io|
193
+ io.write output
194
+ io.close_write
189
195
 
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
196
+ output = io.read
197
+
198
+ if File.extname(output_name) == '.css'
199
+ output.gsub! ' and(', ' and (' # Workaround for YUI Compressor Bug #1938329
200
+ output.gsub! '*/;}', '*/}' # Workaround for YUI Compressor Bug #1961175
200
201
  end
201
202
  end
202
203
 
203
- output_file << output
204
+ if $? == 32512 # command not found
205
+ raise "\nBlender requires Java, v1.4 or greater, to be installed for YUI Compressor"
206
+ end
204
207
  end
205
208
 
206
- if $? == 32512 # command not found
207
- raise "\nBlender requires Java, v1.4 or greater, to be installed for YUI Compressor"
209
+ # Data
210
+ if @options[:data]
211
+ if File.extname(output_name) == '.css'
212
+ output = output.gsub(URL_REGEX) do
213
+ unless $2.include?('.css')
214
+ mime_type = MIME::Types.type_for($2)
215
+ url_contents = make_data_uri(IO.read($2), mime_type[0])
216
+ else
217
+ url_contents = $2
218
+ end
219
+ %Q!url(#{url_contents})!
220
+ end
221
+ end
208
222
  end
223
+
224
+ output_file << output
209
225
  end
210
226
 
211
- puts output_name
227
+ puts output_name.green
212
228
 
213
229
  if @options[:gzip]
214
230
  output_gzip = output_name + '.gz'
@@ -217,7 +233,7 @@ module FrontEndArchitect
217
233
  gz.write(output)
218
234
  end
219
235
 
220
- puts output_gzip
236
+ puts output_gzip.green
221
237
  end
222
238
  end
223
239
 
@@ -232,6 +248,7 @@ module FrontEndArchitect
232
248
  if @options[:cache_buster]
233
249
  input = input.gsub(FILTER_REGEX) do |filter|
234
250
  uri = $2
251
+ cbuster = $3
235
252
  unless uri.match(/^(https:\/\/|http:\/\/|\/\/)/)
236
253
  full_path = File.expand_path($2, File.dirname(input_file))
237
254
  buster = make_cache_buster(full_path, $3)
@@ -239,7 +256,7 @@ module FrontEndArchitect
239
256
 
240
257
  %Q!filter='#{new_path}'!
241
258
  else
242
- %Q!filter='#{$2}#{$3}'!
259
+ %Q!filter='#{uri}#{cbuster}'!
243
260
  end
244
261
  end
245
262
  end
@@ -281,6 +298,7 @@ module FrontEndArchitect
281
298
  if @options[:data]
282
299
  input = input.gsub(URL_REGEX) do
283
300
  uri = $2
301
+ cbuster = $3
284
302
 
285
303
  unless uri.match(/^(https:\/\/|http:\/\/|\/\/)/)
286
304
  new_path = File.expand_path($2, File.dirname(input_file))
@@ -290,13 +308,14 @@ module FrontEndArchitect
290
308
 
291
309
  %Q!url(#{new_path})!
292
310
  else
293
- %Q!url(#{$2}#{$3})!
311
+ %Q!url(#{uri}#{cbuster})!
294
312
  end
295
313
  end
296
314
  elsif @options[:cache_buster]
297
315
  input = input.gsub(URL_REGEX) do
298
316
  unless uri.match(/^(https:\/\/|http:\/\/|\/\/)/)
299
317
  uri = $2
318
+ cbuster = $3
300
319
 
301
320
  if uri.match(/^(\/[^\/]+.+)$/)
302
321
  uri = Pathname.new(File.join(File.expand_path(@options[:root]), uri))
@@ -309,7 +328,7 @@ module FrontEndArchitect
309
328
 
310
329
  %Q!url(#{new_path})!
311
330
  else
312
- %Q!url(#{$2}#{$3})!
331
+ %Q!url(#{uri}#{cbuster})!
313
332
  end
314
333
  end
315
334
  end
@@ -319,7 +338,7 @@ module FrontEndArchitect
319
338
  # Find all url(.ext) in file and rewrite relative url from output directory.
320
339
  input = input.gsub(URL_REGEX) do
321
340
  uri = $2
322
-
341
+ cbuster = $3
323
342
  unless uri.match(/^(https:\/\/|http:\/\/|\/\/)/)
324
343
  if @options[:data]
325
344
  # if doing data conversion rewrite url as an absolute path.
@@ -347,7 +366,7 @@ module FrontEndArchitect
347
366
 
348
367
  %Q!url(#{new_path})!
349
368
  else
350
- %Q!url(#{$2}#{$3})!
369
+ %Q!url(#{uri}#{cbuster})!
351
370
  end
352
371
  end
353
372
 
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.14"
4
+ version: "0.16"
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-06-23 00:00:00 -07:00
12
+ date: 2008-09-17 00:00:00 -07:00
13
13
  default_executable: blend
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -21,6 +21,15 @@ dependencies:
21
21
  - !ruby/object:Gem::Version
22
22
  version: "1.15"
23
23
  version:
24
+ - !ruby/object:Gem::Dependency
25
+ name: colored
26
+ version_requirement:
27
+ version_requirements: !ruby/object:Gem::Requirement
28
+ requirements:
29
+ - - ">="
30
+ - !ruby/object:Gem::Version
31
+ version: "1.1"
32
+ version:
24
33
  description: Blender is like ant or make for the front-end. It aggregates and compresses CSS and/or JavaScript assets for a site into efficient, production-ready files.
25
34
  email: belshire@gmail.com
26
35
  executables:
@@ -59,7 +68,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
59
68
  requirements:
60
69
  - Java, v1.4 or greater
61
70
  rubyforge_project: frontendblender
62
- rubygems_version: 1.0.1
71
+ rubygems_version: 1.2.0
63
72
  signing_key:
64
73
  specification_version: 2
65
74
  summary: Blender gives you efficient, production-ready CSS and/or JavaScript assets.