front-end-blender 0.8.1 → 0.8.2

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.
Files changed (4) hide show
  1. data/README +16 -21
  2. data/bin/blend +16 -186
  3. data/lib/front_end_architect/blender.rb +159 -0
  4. metadata +2 -1
data/README CHANGED
@@ -6,8 +6,8 @@ CSS and/or JavaScript assets for a site into efficient, production-ready files.
6
6
  == Blendfile
7
7
 
8
8
  The Blendfile, named blender.yaml by default, is the configuration file that
9
- tells Blender which input files are combined into which output files. The
10
- file uses the YAML format. The output file is listed as hash key and input
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
11
  files are the hash values as an array. Here is a sample Blendfile:
12
12
 
13
13
  # blender.yaml for boldpx.com
@@ -26,6 +26,18 @@ _style/_global-min.css:
26
26
  - _style/_global/layout-screen.css
27
27
  - _style/_global/layout-print.css
28
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
+
29
41
  == Examples
30
42
 
31
43
  In your site directory run 'blend' to minify CSS and JavaScript.
@@ -37,27 +49,10 @@ Other examples:
37
49
  blend -t css -d
38
50
  blend --yui='--preserve-semi'
39
51
 
40
- == Usage
41
-
42
- blend [options] [-- yui-compressor-options]
43
-
44
- For help use: blend -h
45
-
46
- == Options
47
-
48
- -h, --help Displays help message
49
- -v, --version Display the version
50
- -f <file>, --file <file> Use given Blendfile
51
- -t <css|js>, --type <css|js> Select file type to blend (css, js)
52
- -d, --data Convert url(image.ext) to url(data:) in CSS files EXPERIMENTAL
53
- --force Force blending when source files aren't newer than output files
54
- --yui= Pass arguments to YUI Compressor
55
- -g, --generate Generate a stub Blendfile
56
-
57
52
  == Installation
58
53
 
59
- To install the beta gem, run the following at the command line:
60
- sudo gem install frontendblender
54
+ To install the rubygem, run the following at the command line:
55
+ sudo gem install blender
61
56
 
62
57
  Java, v1.4 or greater is required
63
58
 
data/bin/blend CHANGED
@@ -6,194 +6,24 @@
6
6
  # Blender is freely distributable under the terms of an MIT-style license.
7
7
  # For details, see http://www.opensource.org/licenses/mit-license.php
8
8
 
9
- require 'yaml'
9
+ $:.unshift File.join(File.dirname(File.symlink?(__FILE__) ? File.readlink(__FILE__) : __FILE__), *%w[.. lib])
10
10
  require 'optparse'
11
- require 'rdoc/usage'
12
- require 'ostruct'
13
- require 'base64'
14
- require 'benchmark'
15
- require 'mime/types'
16
- require 'find'
11
+ require 'front_end_architect/blender'
17
12
 
18
- # TODO Move class to lib so other tools could potentially reuse it
19
- class Blender
20
- VERSION = '0.8.1'
21
-
22
- attr_reader :options
23
-
24
- def initialize(arguments, stdin)
25
- @arguments = arguments
26
-
27
- # Set defaults
28
- @options = OpenStruct.new
29
- @options.blendfile = 'blender.yaml'
30
- @options.data = false
31
- @options.force = false
32
- @options.generate = false
33
- end
34
-
35
- def blend
36
- if parsed_options?
37
- if @options.generate
38
- create_blendfile
39
- end
40
-
41
- elapsed = Benchmark.realtime do
42
- unless File.exists? @options.blendfile
43
- puts "Couldn't find '#{@options.blendfile}'"
44
- exit 1
45
- end
46
-
47
- blender = YAML::load_file @options.blendfile
48
-
49
- Dir.chdir(File.dirname(@options.blendfile))
50
-
51
- blender.each do |output_name, inputs|
52
- output_new = false
53
-
54
- # Checks the type flag and if the current file meets the type requirements continues
55
- if output_name.match "." + @options.file_type.to_s
56
- file_type = output_name.match(/\.css/) ? "css" : "js"
57
-
58
- # Checks if output file exists and checks the mtimes of the source files to the output file if new creates a new file
59
- if File.exists? output_name
60
- inputs.each do |i|
61
- if File.mtime(i) > File.mtime(output_name)
62
- output_new = true
63
- break
64
- end
65
- end
66
-
67
- if output_new || @options.force
68
- create_output(output_name, inputs, file_type)
69
- else
70
- puts "Skipping: #{output_name}"
71
- end
72
- else
73
- create_output(output_name, inputs, file_type)
74
- end
75
- end
76
- end
77
- end
78
-
79
- puts sprintf("%.5f", elapsed) + " seconds"
80
- end
81
- end
82
-
83
- protected
84
-
85
- def parsed_options?
86
- opts = OptionParser.new
87
-
88
- opts.on('-h', '--help') { output_help }
89
- opts.on('-v', '--version') { output_version; exit 0 }
90
- opts.on('-f FILE', '--file FILE', String, "Use given Blendfile") {|f| @options.blendfile = f }
91
- opts.on('-t TYPE', '--type TYPE', [:css, :js], "Select file type to blend (css, js)") {|t| @options.file_type = t }
92
- opts.on('-d', '--data', String, "Convert url(image.ext) to url(data:) in CSS files EXPERIMENTAL") { @options.data = true }
93
- opts.on( '--force', String, "Force blending when source files aren't newer than output files") { @options.force = true }
94
- opts.on( '--yui=YUIOPTS', String, "Pass arguments to YUI Compressor") {|o| @options.yuiopts = o }
95
- opts.on('-g', '--generate', String, "Generate a stub Blendfile") { @options.generate = true }
96
-
97
- opts.parse!(@arguments) rescue return false
98
-
99
- true
100
- end
101
-
102
- def create_blendfile
103
- if File.exists?(@options.blendfile) && !@options.force
104
- puts "'#{@options.blendfile}' already exists"
105
- exit 1
106
- end
107
-
108
- blend_files = Hash.new
109
-
110
- Find.find(Dir.getwd) do |f|
111
- f.gsub!(Dir.getwd.to_s+"/", "")
112
- if File.extname(f) == ".css"
113
- file = f.split(".css")
114
- min_file = file[0] + "-min.css"
115
- blend_files[f] = [min_file]
116
- end
117
-
118
- if File.extname(f) == ".js"
119
- file = f.split(".js")
120
- min_file = file[0] + "-min.js"
121
- blend_files[f] = [min_file]
122
- end
123
-
124
- Find.prune if File.basename(f).index('.') == 0
125
- end
126
-
127
- File.open(@options.blendfile, 'w') { |f| YAML.dump(blend_files, f) }
128
-
129
- exit 0
130
- end
131
-
132
- # TODO Change to work with directory hashes (css/: [ colors.css, layout.css ])
133
- def create_output(output_name, inputs, type)
134
- File.open(output_name, 'w') do |output_file|
135
- output = ''
136
-
137
- inputs.each do |i|
138
- output << IO.read(i)
139
- end
140
-
141
- # Compress
142
- real_file = File.symlink?(__FILE__) ? File.readlink(__FILE__) : __FILE__
143
-
144
- IO.popen("java -jar #{File.dirname(real_file)}/../lib/yui/yuicompressor.jar #{@options.yuiopts} --type #{type}", mode="r+") do |io|
145
- io.write output
146
- io.close_write
147
-
148
- output = io.read
149
-
150
- if File.extname(output_name) == ".css"
151
- output.gsub! ' and(', ' and (' # Workaround for YUI Compressor Bug #1938329
152
- output.gsub! '/**/;}', '/**/}' # Workaround for YUI Compressor Bug #1961175
153
-
154
- if @options.data
155
- output = output.gsub(/url\(['"]?([^?']+)['"]+\)/im) do
156
- uri = $1
157
- mime_type = ''
158
-
159
- # Make the URI absolute instead of relative. TODO Seems kinda hacky is there a better way?
160
- uri.gsub! "../", ""
161
-
162
- # Figure out the mime type.
163
- mime_type = MIME::Types.type_for(uri)
164
-
165
- url_contents = make_data_uri(IO.read(uri), mime_type[0])
166
-
167
- %Q!url("#{url_contents}")!
168
- end
169
- end
170
- end
171
-
172
- output_file << output
173
- end
174
- end
175
-
176
- puts output_name
177
- end
178
-
179
- def make_data_uri(content, content_type)
180
- outuri = 'data:' + content_type + ';base64'
181
- content = Base64.encode64(content)
182
- outuri += ",#{content}"
183
-
184
- outuri.gsub("\n", '')
185
- end
186
-
187
- def output_version
188
- puts "Blender v#{VERSION}"
189
- end
190
-
191
- def output_help
192
- output_version
193
- RDoc::usage() #exits app
194
- end
13
+ options = {}
14
+
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 }
24
+
25
+ opts.parse!(ARGV) rescue return false
195
26
  end
196
27
 
197
- # Create and run the application
198
- blender = Blender.new(ARGV, STDIN)
28
+ blender = Blender.new(options)
199
29
  blender.blend
@@ -0,0 +1,159 @@
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
+ require 'rubygems'
8
+ require 'yaml'
9
+ require 'base64'
10
+ require 'benchmark'
11
+ require 'mime/types'
12
+ require 'find'
13
+
14
+ class Blender
15
+ VERSION = '0.8.2'
16
+
17
+ DEFAULT_OPTIONS = {
18
+ :blendfile => 'blender.yaml',
19
+ :data => false,
20
+ :force => false,
21
+ }
22
+
23
+ attr_reader :options
24
+
25
+ def initialize(opts)
26
+ @options = DEFAULT_OPTIONS.merge(opts)
27
+ end
28
+
29
+ def blend
30
+ if @options[:generate]
31
+ create_blendfile
32
+ end
33
+
34
+ elapsed = Benchmark.realtime do
35
+ unless File.exists? @options[:blendfile]
36
+ puts "Couldn't find '#{@options[:blendfile]}'"
37
+ exit 1
38
+ end
39
+
40
+ blender = YAML::load_file @options[:blendfile]
41
+
42
+ Dir.chdir(File.dirname(@options[:blendfile]))
43
+
44
+ blender.each do |output_name, sources|
45
+ output_new = false
46
+
47
+ # Checks the type flag and if the current file meets the type requirements continues
48
+ if output_name.match "." + @options[:file_type].to_s
49
+ file_type = output_name.match(/\.css/) ? "css" : "js"
50
+
51
+ # Checks if output file exists and checks the mtimes of the source files to the output file if new creates a new file
52
+ if File.exists? output_name
53
+ sources.each do |i|
54
+ if File.mtime(i) > File.mtime(output_name)
55
+ output_new = true
56
+ break
57
+ end
58
+ end
59
+
60
+ if output_new || @options[:force]
61
+ create_output(output_name, sources, file_type)
62
+ else
63
+ puts "Skipping: #{output_name}"
64
+ end
65
+ else
66
+ create_output(output_name, sources, file_type)
67
+ end
68
+ end
69
+ end
70
+ end
71
+
72
+ puts sprintf("%.5f", elapsed) + " seconds"
73
+ end
74
+
75
+ protected
76
+
77
+ def create_blendfile
78
+ if File.exists?(@options[:blendfile]) && !@options[:force]
79
+ puts "'#{@options[:blendfile]}' already exists"
80
+ exit 1
81
+ end
82
+
83
+ blend_files = Hash.new
84
+
85
+ Find.find(Dir.getwd) do |f|
86
+ f.gsub!(Dir.getwd.to_s+"/", "")
87
+ if File.extname(f) == ".css"
88
+ file = f.split(".css")
89
+ min_file = file[0] + "-min.css"
90
+ blend_files[f] = [min_file]
91
+ end
92
+
93
+ if File.extname(f) == ".js"
94
+ file = f.split(".js")
95
+ min_file = file[0] + "-min.js"
96
+ blend_files[f] = [min_file]
97
+ end
98
+
99
+ Find.prune if File.basename(f).index('.') == 0
100
+ end
101
+
102
+ File.open(@options[:blendfile], 'w') { |f| YAML.dump(blend_files, f) }
103
+
104
+ exit 0
105
+ end
106
+
107
+ # TODO Change to work with directory hashes (css/: [ colors.css, layout.css ])
108
+ def create_output(output_name, sources, type)
109
+ File.open(output_name, 'w') do |output_file|
110
+ output = ''
111
+
112
+ sources.each do |i|
113
+ output << IO.read(i)
114
+ end
115
+
116
+ # Compress
117
+ libdir = File.join(File.dirname(File.symlink?(__FILE__) ? File.readlink(__FILE__) : __FILE__), *%w[.. .. lib])
118
+
119
+ IO.popen("java -jar #{libdir}/yui/yuicompressor.jar #{@options[:yuiopts]} --type #{type}", mode="r+") do |io|
120
+ io.write output
121
+ io.close_write
122
+
123
+ output = io.read
124
+
125
+ if File.extname(output_name) == ".css"
126
+ output.gsub! ' and(', ' and (' # Workaround for YUI Compressor Bug #1938329
127
+ output.gsub! '/**/;}', '/**/}' # Workaround for YUI Compressor Bug #1961175
128
+
129
+ if @options[:data]
130
+ output = output.gsub(/url\(['"]?([^?']+)['"]+\)/im) do
131
+ uri = $1
132
+ mime_type = ''
133
+
134
+ # Make the URI absolute instead of relative. TODO Seems kinda hacky is there a better way?
135
+ uri.gsub! "../", ""
136
+
137
+ # Figure out the mime type.
138
+ mime_type = MIME::Types.type_for(uri)
139
+
140
+ url_contents = make_data_uri(IO.read(uri), mime_type[0])
141
+
142
+ %Q!url("#{url_contents}")!
143
+ end
144
+ end
145
+ end
146
+
147
+ output_file << output
148
+ end
149
+ end
150
+
151
+ puts output_name
152
+ end
153
+
154
+ def make_data_uri(content, content_type)
155
+ content = Base64.encode64(content)
156
+ uri = "data:#{content_type};base64,#{content}"
157
+ uri.gsub("\n", '')
158
+ end
159
+ end
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.1
4
+ version: 0.8.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Blake Elshire & Chris Griego
@@ -33,6 +33,7 @@ files:
33
33
  - README
34
34
  - MIT-LICENSE
35
35
  - bin/blend
36
+ - lib/front_end_architect/blender.rb
36
37
  - lib/yui/yuicompressor.jar
37
38
  - lib/yui/LICENSE
38
39
  has_rdoc: false