gumdrop 0.7.5 → 0.8.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -5,18 +5,18 @@ require 'logger'
5
5
 
6
6
  module Gumdrop
7
7
 
8
- STATIC_ASSETS= %w(.jpg .jpe .jpeg .gif .ico .png)
8
+ STATIC_ASSETS= %w(.jpg .jpe .jpeg .gif .ico .png .swf)
9
9
 
10
10
  class Server < Sinatra::Base
11
- site_file= Gumdrop.fetch_site_file
12
- unless site_file.nil?
13
- site= Site.new site_file
11
+ site= Gumdrop.fetch_site
12
+
13
+ unless site.nil?
14
14
  site.rescan()
15
15
 
16
16
  set :port, site.config.server_port if site.config.server_port
17
17
 
18
18
  if site.config.proxy_enabled
19
- require 'gumdrop/proxy_handler'
19
+ require 'gumdrop/support/proxy_handler'
20
20
  get '/-proxy/*' do handle_proxy(params, env) end
21
21
  post '/-proxy/*' do handle_proxy(params, env) end
22
22
  put '/-proxy/*' do handle_proxy(params, env) end
data/lib/gumdrop/site.rb CHANGED
@@ -17,10 +17,14 @@ module Gumdrop
17
17
  }
18
18
 
19
19
  class Site
20
+
21
+ extend Support::Callbacks
20
22
 
21
23
  attr_reader :opts,
22
24
  :root_path,
23
25
  :src_path,
26
+ :out_path,
27
+ :data_path,
24
28
  :blacklist,
25
29
  :greylist,
26
30
  :redirects,
@@ -34,15 +38,15 @@ module Gumdrop
34
38
  :content_hash,
35
39
  :last_run
36
40
 
37
- extend Callbacks
38
-
39
41
  callbacks :on_start,
40
42
  :on_before_scan,
41
43
  :on_scan,
42
44
  :on_before_generate,
43
45
  :on_generate,
44
46
  :on_before_render,
45
- :on_render,
47
+ :on_render,
48
+ :on_before_render_item,
49
+ :on_render_item,
46
50
  :on_end
47
51
 
48
52
  def initialize(sitefile, opts={})
@@ -53,11 +57,15 @@ module Gumdrop
53
57
  reset_all()
54
58
  end
55
59
 
60
+ def opts=(opts={})
61
+ @opts= opts
62
+ end
63
+
56
64
  def contents(*args)
57
65
  opts= args.extract_options!
58
66
  pattern= args.first || nil
59
67
 
60
- if pattern.nil?
68
+ if pattern.nil? or pattern.empty?
61
69
  if opts[:as] == :hash
62
70
  @content_hash
63
71
  else
@@ -65,17 +73,19 @@ module Gumdrop
65
73
  end
66
74
 
67
75
  else
68
- nodes = opts[:as] == :hash ? {} : []
69
- @content_hash.keys.each do |path|
70
- if path_match path, pattern
71
- if opts[:as] == :hash
72
- nodes[path]= @content_hash[path]
76
+ if pattern.is_a? Array
77
+ nodes= opts[:as] == :hash ? {} : []
78
+ pattern.each do |subpattern|
79
+ if opts[:as]== :hash
80
+ nodes.merge! match_nodes(subpattern, opts)
73
81
  else
74
- nodes << @content_hash[path]
82
+ nodes << match_nodes(subpattern, opts)
75
83
  end
76
84
  end
85
+ opts[:as]== :hash ? nodes : nodes.flatten
86
+ else
87
+ match_nodes(pattern, opts)
77
88
  end
78
- nodes
79
89
  end
80
90
  end
81
91
 
@@ -89,23 +99,36 @@ module Gumdrop
89
99
  self
90
100
  end
91
101
 
92
- def build
102
+ def build(force_reset=false)
93
103
  on_start(self)
104
+ report "[#{ Time.new }]"
105
+ reset_all() if force_reset
94
106
  scan()
95
107
  render()
96
108
  @last_run= Time.now
97
109
  on_end(self)
110
+ report "[Done]"
98
111
  self
99
112
  end
113
+
114
+ def rebuild
115
+ build true
116
+ end
100
117
 
101
118
  def report(msg, level=:info)
102
119
  case level
103
120
  when :info
104
- @log.info msg
105
- when :warning
121
+ unless @opts[:quiet]
122
+ if @opts[:subdued]
123
+ print "."
124
+ else
125
+ @log.info msg
126
+ end
127
+ end
128
+ when :warning, :warn
106
129
  @log.warn msg
107
130
  else
108
- puts msg
131
+ print "!" if @opts[:subdued]
109
132
  @log.error msg
110
133
  end
111
134
  end
@@ -137,12 +160,13 @@ module Gumdrop
137
160
  @greylist = []
138
161
  @redirects = []
139
162
 
140
- @content_hash = Hash.new {|h,k| h[k]= nil }
163
+ @content_hash = Hash.new {|h,k| h[k]= nil }
141
164
  @layouts = Hash.new {|h,k| h[k]= nil }
142
165
  @partials = Hash.new {|h,k| h[k]= nil }
143
166
  @generators = Hash.new {|h,k| h[k]= nil }
144
167
 
145
168
  @config = Gumdrop::Config.new DEFAULT_OPTIONS
169
+ @config.env = @opts[:env] if @opts.has_key? :env
146
170
 
147
171
  clear_on_start()
148
172
  clear_on_before_scan()
@@ -151,6 +175,8 @@ module Gumdrop
151
175
  clear_on_generate()
152
176
  clear_on_before_render()
153
177
  clear_on_render()
178
+ clear_on_before_render_item()
179
+ clear_on_render_item()
154
180
  clear_on_end()
155
181
 
156
182
  load_sitefile()
@@ -164,20 +190,35 @@ module Gumdrop
164
190
  init_logging()
165
191
  end
166
192
 
193
+ def match_nodes(pattern, opts={})
194
+ nodes = opts[:as] == :hash ? {} : []
195
+ @content_hash.keys.each do |path|
196
+ if path_match path, pattern
197
+ if opts[:as] == :hash
198
+ nodes[path]= @content_hash[path]
199
+ else
200
+ nodes << @content_hash[path]
201
+ end
202
+ end
203
+ end
204
+ nodes
205
+ end
206
+
167
207
  def init_logging
168
208
  begin
169
209
  @log = Logger.new @config.log, 'daily'
170
210
  rescue
171
- target= if @opts[:quiet] or @opts[:quiet_given]
211
+ target= if @opts[:quiet]
172
212
  nil
173
213
  else
174
214
  STDOUT
175
215
  end
176
216
  @log = Logger.new target
177
- report "Using STDOUT for logging because of exception: #{ $! }" unless target.nil?
217
+ # report "Using STDOUT for logging because of exception: #{ $! }" unless target.nil?
178
218
  end
179
219
  @log.formatter = proc do |severity, datetime, progname, msg|
180
- "#{datetime}: #{msg}\n"
220
+ # "#{datetime}: #{msg}\n"
221
+ " #{msg}\n"
181
222
  end
182
223
  end
183
224
 
@@ -252,20 +293,35 @@ module Gumdrop
252
293
  unless opts[:dry_run]
253
294
  report "[Compiling to #{@out_path}]", :info
254
295
  on_before_render(self)
255
- @content_hash.keys.sort.each do |path|
256
- node= @content_hash[path]
257
- unless node.ignore?
258
- output_path= File.join(@out_path, node.to_s)
259
- FileUtils.mkdir_p File.dirname(output_path)
260
- node.renderTo render_context, output_path, content_filters
261
- else
262
- report " ignoring: #{node.to_s}", :info
263
- end
296
+ nodes= if opts[:assets]
297
+ contents(opts[:assets])
298
+ else
299
+ contents()
300
+ end
301
+ nodes.each do |node|
302
+ render_content(node, render_context, content_filters)
264
303
  end
265
304
  on_render(self)
266
305
  end
267
306
  end
268
307
 
308
+ def render_content(node, ctx, filters)
309
+ unless node.ignore?
310
+ output_path= File.join(@out_path, node.to_s)
311
+ FileUtils.mkdir_p File.dirname(output_path)
312
+ begin
313
+ on_before_render_item(self, node)
314
+ node.renderTo ctx, output_path, filters
315
+ on_render_item(self, node)
316
+ rescue => ex
317
+ report "[!>EXCEPTION<!]: #{ node.to_s }", :error
318
+ report [ex.to_s, ex.backtrace].flatten.join("\n"), :error
319
+ exit 1 unless @opts[:resume]
320
+ end
321
+ else
322
+ report " ignoring: #{ node.to_s }", :info
323
+ end
324
+ end
269
325
  end
270
326
 
271
327
  class Sitefile
@@ -305,6 +361,10 @@ module Gumdrop
305
361
  @site.config.instance_eval &block
306
362
  end
307
363
  end
364
+
365
+ def tasks(&block)
366
+ Gumdrop::CLI::Internal.class_eval &block
367
+ end
308
368
 
309
369
  # Callbacks
310
370
  def on_start(&block)
@@ -328,6 +388,12 @@ module Gumdrop
328
388
  def on_render(&block)
329
389
  @site.on_render &block
330
390
  end
391
+ def on_before_render_item(&block)
392
+ @site.on_before_render &block
393
+ end
394
+ def on_render_item(&block)
395
+ @site.on_render &block
396
+ end
331
397
  def on_end(&block)
332
398
  @site.on_end &block
333
399
  end
@@ -0,0 +1,60 @@
1
+ module Gumdrop
2
+ module Support
3
+ module BasePackager
4
+
5
+ def compress_output(content, opts)
6
+ case opts[:compress]
7
+
8
+ when true, :jsmin
9
+ require 'jsmin'
10
+ JSMin.minify content
11
+
12
+ when :yuic
13
+ require "yui/compressor"
14
+ compressor = YUI::JavaScriptCompressor.new(:munge => opts[:obfuscate])
15
+ compressor.compress(content)
16
+
17
+ when :uglify
18
+ require "uglifier"
19
+ Uglifier.compile( content, :mangle=>opts[:obfuscate])
20
+
21
+ when :packr
22
+ require 'packr'
23
+ Packr.pack(content, :shrink_vars => true, :base62 => false, :private=>false)
24
+
25
+ when false
26
+ content
27
+
28
+ else
29
+ # UNKNOWN Compressor type!
30
+ @site.report "Unknown javascript compressor type! (#{ opts[:compressor] })", :warning
31
+ content
32
+ end
33
+ end
34
+
35
+ def keep_src(name, content, opts)
36
+ if opts[:keep_src] or opts[:keep_source]
37
+ ext= File.extname name
38
+ page name.gsub(ext, "#{opts.fetch(:source_postfix, '-src')}#{ext}") do
39
+ content
40
+ end
41
+ end
42
+ end
43
+
44
+ def prune_src(name, opts)
45
+ if opts[:prune] and opts[:root]
46
+ sp = File.expand_path( @site.config.source_dir )
47
+ rp = File.expand_path(opts[:root])
48
+ relative_root = rp.gsub(sp, '')[1..-1]
49
+ rrlen= relative_root.length - 1
50
+ @site.content_hash.keys.each do |path|
51
+ if path[0..rrlen] == relative_root and name != path
52
+ @site.content_hash.delete path
53
+ end
54
+ end
55
+ end
56
+ end
57
+
58
+ end
59
+ end
60
+ end
@@ -1,4 +1,4 @@
1
- module Gumdrop
1
+ module Gumdrop::Support
2
2
  module Callbacks
3
3
 
4
4
  # For defining callbacks
@@ -0,0 +1,34 @@
1
+ # sprockets.rb
2
+ begin
3
+ require 'sprockets'
4
+ has_sprockets= true
5
+ rescue LoadError
6
+ has_sprockets= false
7
+ end
8
+
9
+ module Gumdrop::Support
10
+
11
+ module Sprockets # mixes in to generator
12
+ include BasePackager
13
+
14
+ def sprockets(name, opts)
15
+ if has_sprockets
16
+ env = Sprockets::Environment.new @site.root_path
17
+ env.append_path @site.src_path
18
+ opts[:paths].each do |path|
19
+ env.append_path(path)
20
+ end
21
+ content= env[ opts[:src] ].to_s
22
+ page name do
23
+ compress_output(content, opts)
24
+ end
25
+ keep_src(name, content, opts)
26
+ prune_src(name, opts)
27
+ else
28
+ throw "Sprockets can't be loaded. Please add it to your Gemfile."
29
+ end
30
+ end
31
+
32
+ end
33
+
34
+ end
@@ -0,0 +1,144 @@
1
+ # stitch.rb
2
+ begin
3
+ require 'stitch-rb'
4
+ has_stitch= true
5
+ rescue LoadError
6
+ has_stitch= false
7
+ end
8
+
9
+ module Gumdrop::Support
10
+
11
+ module Stitch # mixes in to generator
12
+ include BasePackager
13
+
14
+ def stitch(name, opts)
15
+ if has_stitch
16
+ content= Stitch::Package.new(opts).compile
17
+ page name do
18
+ compress_output(content, opts)
19
+ end
20
+ keep_src(name, content, opts)
21
+ prune_src(name, opts)
22
+ else
23
+ throw "Stitch can't be loaded. Please add it to your Gemfile."
24
+ end
25
+ end
26
+
27
+ end
28
+
29
+ end
30
+
31
+ if defined?(Stitch)
32
+
33
+ class Stitch::Source
34
+ # Patch for gumdrop style filenames
35
+ def name
36
+ name = path.relative_path_from(root)
37
+ name = name.dirname + name.basename(".*")
38
+ name.to_s.gsub(".js", '')
39
+ end
40
+ end
41
+
42
+
43
+ # Custom Compilers
44
+
45
+
46
+ class SerenadeCompiler < Stitch::Compiler
47
+
48
+ extensions :serenade
49
+
50
+ def compile(path)
51
+ content= File.read(path)
52
+ viewname= File.basename(path).gsub('.serenade', '').gsub('.html', '').gsub('.', '_')
53
+ %{
54
+ Serenade.view(#{ viewname.to_json }, #{content.to_json});
55
+ }
56
+ end
57
+
58
+ end
59
+
60
+ # Not so sure on this one...
61
+ class HoganCompiler < Stitch::Compiler
62
+ # List of supported extensions
63
+ extensions :mustache
64
+
65
+ # A compile method which takes a file path,
66
+ # and returns a compiled string
67
+ def compile(path)
68
+ content = File.read(path)
69
+ %{
70
+ var template = Hogan.compile(#{content.to_json});
71
+ module.exports = (function(data){ return template.render(data); });
72
+ }
73
+ end
74
+ end
75
+
76
+ module CssJsCode
77
+
78
+ def export_js_code(path)
79
+ content= File.read(path)
80
+ %{
81
+ var css = #{ transpile(content, File.extname(path)).to_json },
82
+ node = null;
83
+ module.exports= {
84
+ content: css,
85
+ add: function(to){
86
+ if(node != null) return;
87
+ if(to == null) to= document.getElementsByTagName('HEAD')[0] || document.body;
88
+ node= document.createElement('style');
89
+ node.innerHTML= css;
90
+ to.appendChild(node);
91
+ return this;
92
+ },
93
+ remove: function() {
94
+ if(node != null) {
95
+ node.parentNode.removeChild(node);
96
+ node = null;
97
+ }
98
+ return this;
99
+ }
100
+ };
101
+ }
102
+ end
103
+
104
+ def transpile(content, ext)
105
+ content
106
+ end
107
+
108
+ end
109
+
110
+ class CssCompiler < Stitch::Compiler
111
+ include CssJsCode
112
+
113
+ extensions :css
114
+
115
+ def compile(path)
116
+ export_js_code path
117
+ end
118
+
119
+ end
120
+
121
+
122
+ begin
123
+ require 'sass'
124
+
125
+ class SassCompiler < Stitch::Compiler
126
+ include CssJsCode
127
+
128
+ extensions :sass, :scss
129
+
130
+ def compile(path)
131
+ export_js_code path
132
+ end
133
+
134
+ def transpile(content, ext)
135
+ type = (ext == '.sass') ? :sass : :scss
136
+ Sass::Engine.new(content, :syntax=>type).render
137
+ end
138
+ end
139
+
140
+ rescue
141
+ # Sass Not available
142
+ end
143
+
144
+ end