gumdrop 0.7.5 → 0.8.0
Sign up to get free protection for your applications and to get access to all the features.
- data/ChangeLog.md +10 -0
- data/Gemfile.lock +35 -0
- data/bin/gumdrop +16 -7
- data/gumdrop.gemspec +2 -1
- data/lib/gumdrop.rb +38 -13
- data/lib/gumdrop/cli/external.rb +55 -0
- data/lib/gumdrop/cli/internal.rb +75 -0
- data/lib/gumdrop/content.rb +13 -7
- data/lib/gumdrop/generator.rb +16 -85
- data/lib/gumdrop/server.rb +5 -5
- data/lib/gumdrop/site.rb +94 -28
- data/lib/gumdrop/support/base_packager.rb +60 -0
- data/lib/gumdrop/{callbacks.rb → support/callbacks.rb} +1 -1
- data/lib/gumdrop/{hash_object.rb → support/hash_object.rb} +0 -0
- data/lib/gumdrop/{proxy_handler.rb → support/proxy_handler.rb} +0 -0
- data/lib/gumdrop/support/sprockets.rb +34 -0
- data/lib/gumdrop/support/stitch.rb +144 -0
- data/lib/gumdrop/version.rb +1 -1
- data/notes.md +347 -0
- data/templates/backbone/Gemfile +1 -1
- data/templates/backbone/Gumdrop +6 -1
- data/templates/blank/Gemfile +2 -2
- data/templates/blank/Gumdrop +25 -2
- data/templates/default/Gemfile +2 -2
- data/templates/default/Gumdrop +27 -1
- data/templates/default/Rakefile +15 -15
- metadata +30 -14
- data/lib/gumdrop/cli.rb +0 -167
- data/lib/gumdrop/sprockets_support.rb +0 -3
- data/lib/gumdrop/stitch_support.rb +0 -114
- data/templates/blank/Rakefile +0 -38
data/lib/gumdrop/server.rb
CHANGED
@@ -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
|
-
|
12
|
-
|
13
|
-
|
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
|
-
|
69
|
-
|
70
|
-
|
71
|
-
if opts[:as]
|
72
|
-
nodes
|
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 <<
|
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
|
-
@
|
105
|
-
|
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
|
-
|
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
|
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]
|
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
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
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
|
File without changes
|
File without changes
|
@@ -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
|