front-end-blender 0.14 → 0.16

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 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.