mill 0.16 → 0.18
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.
- checksums.yaml +4 -4
- data/LICENSE +1 -1
- data/Rakefile +1 -9
- data/TODO.md +4 -0
- data/bin/mill +1 -27
- data/lib/mill/command.rb +13 -0
- data/lib/mill/commands/build.rb +17 -0
- data/lib/mill/commands/check.rb +16 -0
- data/lib/mill/commands/diff.rb +18 -0
- data/lib/mill/commands/list.rb +20 -0
- data/lib/mill/commands/snapshot.rb +20 -0
- data/lib/mill/commands/tree.rb +17 -0
- data/lib/mill/commands/types.rb +18 -0
- data/lib/mill/commands/upload.rb +24 -0
- data/lib/mill/config.rb +27 -0
- data/lib/mill/resource.rb +74 -87
- data/lib/mill/resources/blob.rb +4 -0
- data/lib/mill/resources/feed.rb +5 -13
- data/lib/mill/resources/image.rb +10 -18
- data/lib/mill/resources/markdown.rb +20 -0
- data/lib/mill/resources/markup.rb +62 -0
- data/lib/mill/resources/page.rb +140 -0
- data/lib/mill/resources/redirect.rb +17 -16
- data/lib/mill/resources/robots.rb +3 -4
- data/lib/mill/resources/sitemap.rb +3 -5
- data/lib/mill/resources/stylesheet.rb +4 -4
- data/lib/mill/resources/textile.rb +27 -0
- data/lib/mill/resources.rb +89 -0
- data/lib/mill/site.rb +182 -283
- data/lib/mill.rb +27 -9
- data/mill.gemspec +19 -19
- data/test/content/c.md +4 -0
- data/test/content/d.md +4 -0
- data/test/main_test.rb +68 -0
- data/test/mill.yaml +8 -0
- metadata +118 -51
- data/Gemfile +0 -6
- data/TODO.txt +0 -61
- data/lib/mill/html_helpers.rb +0 -128
- data/lib/mill/navigator.rb +0 -61
- data/lib/mill/resources/dir.rb +0 -31
- data/lib/mill/resources/google_site_verification.rb +0 -30
- data/lib/mill/resources/text.rb +0 -218
- data/lib/mill/version.rb +0 -5
- data/test/test.rb +0 -56
data/lib/mill/site.rb
CHANGED
@@ -2,391 +2,290 @@ module Mill
|
|
2
2
|
|
3
3
|
class Site
|
4
4
|
|
5
|
-
attr_accessor :
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
@resource_classes = resource_classes
|
63
|
-
@navigator = navigator
|
64
|
-
@google_site_verification = google_site_verification
|
65
|
-
@redirects = redirects
|
66
|
-
|
67
|
-
@resources = {}
|
68
|
-
@resources_tree = Tree::TreeNode.new('')
|
69
|
-
build_file_types
|
70
|
-
end
|
71
|
-
|
72
|
-
def build_file_types
|
5
|
+
attr_accessor :config
|
6
|
+
attr_reader :feed_resource
|
7
|
+
attr_reader :sitemap_resource
|
8
|
+
attr_reader :robots_resource
|
9
|
+
attr_reader :redirects
|
10
|
+
attr_reader :resources
|
11
|
+
attr_reader :file_types
|
12
|
+
|
13
|
+
def self.load(dir=nil)
|
14
|
+
config = BaseConfig.make(dir: dir)
|
15
|
+
config = config.load_yaml(config.dir / ConfigFileName)
|
16
|
+
site_file = config.dir / config.code_dir / 'site.rb'
|
17
|
+
klass = load_site_class(site_file)
|
18
|
+
klass.new(config)
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.load_site_class(site_file)
|
22
|
+
Kernel.load(site_file.expand_path.to_s) if site_file.exist?
|
23
|
+
site_classes = subclasses
|
24
|
+
if site_classes.length == 0
|
25
|
+
self
|
26
|
+
elsif site_classes.length > 1
|
27
|
+
raise Error, "More than one #{self.class} class defined"
|
28
|
+
else
|
29
|
+
site_classes.first
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def initialize(config)
|
34
|
+
@config = config
|
35
|
+
@redirects = {}
|
36
|
+
@resources = Resources.new
|
37
|
+
make_file_types
|
38
|
+
end
|
39
|
+
|
40
|
+
def inspect
|
41
|
+
"<#{self.class}>"
|
42
|
+
end
|
43
|
+
|
44
|
+
def input_dir = @config.dir / @config.input_dir
|
45
|
+
def output_dir = @config.dir / @config.output_dir
|
46
|
+
def site_uri = @config.site_uri
|
47
|
+
def site_rsync = @config.site_rsync
|
48
|
+
def site_title = @config.site_title
|
49
|
+
def site_email = @config.site_email
|
50
|
+
def site_postal = @config.site_postal
|
51
|
+
def site_phone = @config.site_phone
|
52
|
+
def site_instagram = @config.site_instagram
|
53
|
+
def site_control_date = @config.site_control_date
|
54
|
+
def html_version = @config.html_version
|
55
|
+
def make_error? = @config.make_error
|
56
|
+
def make_feed? = @config.make_feed
|
57
|
+
def make_sitemap? = @config.make_sitemap
|
58
|
+
def make_robots? = @config.make_robots
|
59
|
+
def allow_robots? = @config.allow_robots
|
60
|
+
|
61
|
+
def make_file_types
|
73
62
|
@file_types = {}
|
74
|
-
(
|
63
|
+
get_file_types(Resource)
|
64
|
+
end
|
65
|
+
|
66
|
+
def get_file_types(klass)
|
67
|
+
klass.subclasses.each do |resource_class|
|
75
68
|
resource_class.const_get(:FileTypes).each do |type|
|
76
69
|
@file_types[type] = resource_class
|
77
70
|
end
|
71
|
+
get_file_types(resource_class)
|
78
72
|
end
|
79
73
|
end
|
80
74
|
|
81
75
|
def add_resource(resource)
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
node = node[component] || (node << Tree::TreeNode.new(component))
|
87
|
-
end
|
88
|
-
resource.node = node
|
89
|
-
node.content = resource
|
90
|
-
# ;;warn "added #{resource} as #{resource.path}"
|
76
|
+
# ;;warn "adding #{resource.class} as #{resource.path}"
|
77
|
+
resource.site = self
|
78
|
+
resource.load
|
79
|
+
@resources << resource
|
91
80
|
end
|
92
81
|
|
93
82
|
def find_resource(path)
|
94
|
-
path
|
95
|
-
@resources[path] || @resources[path + '/']
|
83
|
+
@resources[path]
|
96
84
|
end
|
97
85
|
|
98
|
-
def
|
99
|
-
|
86
|
+
def root_resource
|
87
|
+
@resources['/']
|
100
88
|
end
|
101
89
|
|
102
90
|
def tag_uri
|
103
91
|
'tag:%s:' % [
|
104
92
|
[
|
105
|
-
|
106
|
-
|
93
|
+
site_uri.host.downcase,
|
94
|
+
site_control_date
|
107
95
|
].join(','),
|
108
96
|
]
|
109
97
|
end
|
110
98
|
|
111
99
|
def feed_author_name
|
112
|
-
|
100
|
+
site_title
|
113
101
|
end
|
114
102
|
|
115
103
|
def feed_author_uri
|
116
|
-
|
104
|
+
site_uri
|
117
105
|
end
|
118
106
|
|
119
107
|
def feed_author_email
|
120
|
-
|
121
|
-
end
|
122
|
-
|
123
|
-
def select_resources(selector=nil, &block)
|
124
|
-
if block_given?
|
125
|
-
@resources.values.select(&block)
|
126
|
-
elsif selector.kind_of?(Class)
|
127
|
-
@resources.values.select { |r| r.kind_of?(selector) }
|
128
|
-
else
|
129
|
-
@resources.values.select(selector)
|
130
|
-
end
|
108
|
+
site_email
|
131
109
|
end
|
132
110
|
|
133
111
|
def feed_resources
|
134
|
-
|
112
|
+
primary_resources
|
135
113
|
end
|
136
114
|
|
137
|
-
def
|
138
|
-
|
115
|
+
def sitemap_resources
|
116
|
+
primary_resources
|
139
117
|
end
|
140
118
|
|
141
|
-
def
|
142
|
-
|
143
|
-
end
|
144
|
-
|
145
|
-
def text_resources
|
146
|
-
select_resources(&:text?)
|
147
|
-
end
|
148
|
-
|
149
|
-
def make
|
150
|
-
build
|
151
|
-
save
|
152
|
-
end
|
153
|
-
|
154
|
-
def print_tree(node=nil, level=0)
|
155
|
-
node ||= @resources_tree
|
156
|
-
if node.is_root?
|
157
|
-
print '*'
|
158
|
-
else
|
159
|
-
print "\t" * level
|
160
|
-
end
|
161
|
-
print " #{node.name.inspect}"
|
162
|
-
print " <#{node.content&.path}>"
|
163
|
-
print " (#{node.children.length} children)" if node.has_children?
|
164
|
-
puts
|
165
|
-
node.children { |child| print_tree(child, level + 1) }
|
166
|
-
end
|
167
|
-
|
168
|
-
ListKeys = {
|
169
|
-
path: :to_s,
|
170
|
-
input_file: :to_s,
|
171
|
-
output_file: :to_s,
|
172
|
-
date: :to_s,
|
173
|
-
public: :to_s,
|
174
|
-
class: :to_s,
|
175
|
-
content: proc { |r| r.content ? ('%s (%dKB)' % [r.content.class, (r.content.to_s.length / 1024.0).ceil]) : nil },
|
176
|
-
parent: proc { |r| r.parent&.path },
|
177
|
-
siblings: proc { |r| r.siblings.map(&:path) },
|
178
|
-
children: proc { |r| r.children.map(&:path) },
|
179
|
-
}
|
180
|
-
|
181
|
-
def list
|
182
|
-
build
|
183
|
-
width = ListKeys.keys.map(&:length).max
|
184
|
-
select_resources.each do |resource|
|
185
|
-
ListKeys.each do |key, converter|
|
186
|
-
value = resource.send(key)
|
187
|
-
value = case converter
|
188
|
-
when nil
|
189
|
-
value
|
190
|
-
when Symbol
|
191
|
-
value.send(converter)
|
192
|
-
when Proc
|
193
|
-
converter.call(resource)
|
194
|
-
else
|
195
|
-
raise
|
196
|
-
end
|
197
|
-
print '%*s: ' % [width, key]
|
198
|
-
case value
|
199
|
-
when Array
|
200
|
-
if value.empty?
|
201
|
-
puts '-'
|
202
|
-
else
|
203
|
-
value.each_with_index do |v, i|
|
204
|
-
print '%*s ' % [width, ''] if i > 0
|
205
|
-
puts (v.nil? ? '-' : v)
|
206
|
-
end
|
207
|
-
end
|
208
|
-
else
|
209
|
-
puts (value.nil? ? '-' : value)
|
210
|
-
end
|
211
|
-
end
|
212
|
-
puts
|
213
|
-
end
|
214
|
-
puts
|
119
|
+
def primary_resources
|
120
|
+
@resources.select(&:primary?).sort_by(&:date)
|
215
121
|
end
|
216
122
|
|
217
123
|
def build
|
218
|
-
import_resources
|
219
124
|
load_resources
|
125
|
+
convert_resources
|
220
126
|
build_resources
|
127
|
+
check
|
221
128
|
end
|
222
129
|
|
223
|
-
def
|
130
|
+
def load_resources
|
224
131
|
add_files
|
225
132
|
add_redirects
|
226
|
-
|
227
|
-
add_feed if
|
228
|
-
add_sitemap if
|
229
|
-
add_robots if
|
230
|
-
add_htpasswd if @htpasswd_file
|
231
|
-
end
|
232
|
-
|
233
|
-
def load_resources
|
234
|
-
on_each_resource do |resource|
|
235
|
-
# ;;warn "#{resource.path}: loading"
|
236
|
-
resource.load
|
237
|
-
end
|
133
|
+
add_error if make_error?
|
134
|
+
add_feed if make_feed?
|
135
|
+
add_sitemap if make_sitemap?
|
136
|
+
add_robots if make_robots?
|
238
137
|
end
|
239
138
|
|
240
139
|
def build_resources
|
241
|
-
|
140
|
+
@resources.each do |resource|
|
242
141
|
# ;;warn "#{resource.path}: building"
|
243
142
|
resource.build
|
244
143
|
end
|
245
144
|
end
|
246
145
|
|
247
|
-
def
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
146
|
+
def convert_resources
|
147
|
+
@resources.select { |r| r.respond_to?(:convert) }.each do |resource|
|
148
|
+
new_resource = resource.convert
|
149
|
+
@resources.delete(resource)
|
150
|
+
if new_resource
|
151
|
+
new_resource.load
|
152
|
+
add_resource(new_resource)
|
153
|
+
end
|
253
154
|
end
|
254
155
|
end
|
255
156
|
|
256
|
-
def
|
257
|
-
if
|
258
|
-
|
157
|
+
def save
|
158
|
+
if output_dir.exist?
|
159
|
+
output_dir.children.reject { |p| p.basename.to_s == '.git' }.each do |path|
|
259
160
|
path.rm_rf
|
260
161
|
end
|
162
|
+
else
|
163
|
+
output_dir.mkpath
|
164
|
+
end
|
165
|
+
@resources.each do |resource|
|
166
|
+
# ;;warn "#{resource.path}: saving"
|
167
|
+
resource.save
|
261
168
|
end
|
262
169
|
end
|
263
170
|
|
264
|
-
def check
|
265
|
-
build
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
'add',
|
275
|
-
'.')
|
276
|
-
system('git',
|
277
|
-
'commit',
|
278
|
-
'-a',
|
279
|
-
'-m',
|
280
|
-
'Update.')
|
171
|
+
def check(external: false)
|
172
|
+
build if @resources.empty?
|
173
|
+
@resources.of_class(Resource::Page).each do |resource|
|
174
|
+
resource.links.each do |link|
|
175
|
+
begin
|
176
|
+
check_uri(link, external: external)
|
177
|
+
rescue Error => e
|
178
|
+
warn "#{resource.path}: #{e}"
|
179
|
+
end
|
180
|
+
end
|
281
181
|
end
|
282
182
|
end
|
283
183
|
|
284
|
-
def
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
end
|
184
|
+
def resource_class_for_file(file)
|
185
|
+
types = MIME::Types.type_for(file.to_s)
|
186
|
+
content_type = types.last&.content_type or raise Error, "Can't determine content type: #{file.to_s.inspect}"
|
187
|
+
resource_class_for_type(content_type) or raise Error, "Unknown file type: #{file.to_s.inspect} (#{types.join(', ')})"
|
289
188
|
end
|
290
189
|
|
291
|
-
def
|
292
|
-
|
293
|
-
system('rsync',
|
294
|
-
'--progress',
|
295
|
-
'--verbose',
|
296
|
-
'--archive',
|
297
|
-
# '--append-verify',
|
298
|
-
'--exclude=.git',
|
299
|
-
'--delete-after',
|
300
|
-
@output_dir.to_s,
|
301
|
-
@site_rsync)
|
302
|
-
end
|
303
|
-
|
304
|
-
def on_each_resource(&block)
|
305
|
-
@resources.values.each do |resource|
|
306
|
-
begin
|
307
|
-
yield(resource)
|
308
|
-
rescue Error => e
|
309
|
-
raise e, "#{resource.input_file || '-'} (#{resource.path}): #{e}"
|
310
|
-
end
|
311
|
-
end
|
190
|
+
def resource_class_for_type(type)
|
191
|
+
@file_types[type]
|
312
192
|
end
|
313
193
|
|
314
194
|
private
|
315
195
|
|
316
|
-
def resource_class_for_file(file)
|
317
|
-
type = MIME::Types.of(file.to_s).first
|
318
|
-
if type && (klass = @file_types[type.content_type])
|
319
|
-
klass
|
320
|
-
else
|
321
|
-
raise Error, "Unknown file type: #{file.to_s.inspect} (#{MIME::Types.of(file.to_s).join(', ')})"
|
322
|
-
end
|
323
|
-
end
|
324
|
-
|
325
196
|
def add_files
|
326
|
-
raise Error, "Input directory not found: #{
|
327
|
-
|
197
|
+
raise Error, "Input directory not found: #{input_dir}" unless input_dir.exist?
|
198
|
+
input_dir.find do |input_file|
|
328
199
|
if input_file.basename.to_s[0] == '.'
|
329
200
|
Find.prune
|
201
|
+
elsif input_file.basename.to_s == "Icon\r"
|
202
|
+
# skip macOS garbage file
|
330
203
|
elsif input_file.directory?
|
331
|
-
# skip
|
204
|
+
# skip directories
|
332
205
|
else (klass = resource_class_for_file(input_file))
|
333
|
-
resource = klass.new(
|
334
|
-
input_file: input_file,
|
335
|
-
output_file: @output_dir / input_file.relative_to(@input_dir),
|
336
|
-
site: self)
|
206
|
+
resource = klass.new(input: input_file, path: '/' + input_file.relative_to(input_dir).to_s)
|
337
207
|
add_resource(resource)
|
338
208
|
end
|
339
209
|
end
|
340
210
|
end
|
341
211
|
|
212
|
+
def add_error
|
213
|
+
input = Simple::Builder.parse_html_document(
|
214
|
+
Kramdown::Document.new(
|
215
|
+
%Q{
|
216
|
+
Something went wrong.
|
217
|
+
The page you were looking for doesn’t exist or couldn’t be displayed.
|
218
|
+
Please try another option.
|
219
|
+
}.gsub(/\s+/, ' ').strip
|
220
|
+
).to_html
|
221
|
+
)
|
222
|
+
klass = resource_class_for_type('text/html')
|
223
|
+
@error_resource = klass.new(
|
224
|
+
path: '/error.html',
|
225
|
+
title: 'Error',
|
226
|
+
primary: false,
|
227
|
+
input: input)
|
228
|
+
add_resource(@error_resource)
|
229
|
+
end
|
230
|
+
|
342
231
|
def add_feed
|
343
|
-
@feed_resource = Resource::Feed.new(
|
344
|
-
output_file: @output_dir / 'feed.xml',
|
345
|
-
site: self)
|
232
|
+
@feed_resource = Resource::Feed.new(path: '/feed.xml')
|
346
233
|
add_resource(@feed_resource)
|
347
234
|
end
|
348
235
|
|
349
236
|
def add_sitemap
|
350
|
-
@sitemap_resource = Resource::Sitemap.new(
|
351
|
-
output_file: @output_dir / 'sitemap.xml',
|
352
|
-
site: self)
|
237
|
+
@sitemap_resource = Resource::Sitemap.new(path: '/sitemap.xml')
|
353
238
|
add_resource(@sitemap_resource)
|
354
239
|
end
|
355
240
|
|
356
241
|
def add_robots
|
357
|
-
@robots_resource = Resource::Robots.new(
|
358
|
-
output_file: @output_dir / 'robots.txt',
|
359
|
-
site: self)
|
242
|
+
@robots_resource = Resource::Robots.new(path: '/robots.txt')
|
360
243
|
add_resource(@robots_resource)
|
361
244
|
end
|
362
245
|
|
363
246
|
def add_redirects
|
364
247
|
if @redirects
|
365
248
|
@redirects.each do |from, to|
|
366
|
-
|
367
|
-
resource = Resource::Redirect.new(
|
368
|
-
output_file: output_file,
|
369
|
-
redirect_uri: to,
|
370
|
-
site: self)
|
249
|
+
resource = Resource::Redirect.new(path: Path.new(from).add_extension('.redirect').to_s, redirect_uri: to)
|
371
250
|
add_resource(resource)
|
372
251
|
end
|
373
252
|
end
|
374
253
|
end
|
375
254
|
|
376
|
-
def
|
377
|
-
|
378
|
-
|
379
|
-
|
380
|
-
|
381
|
-
|
255
|
+
def check_uri(uri, external: false)
|
256
|
+
if uri.relative?
|
257
|
+
unless find_resource(uri.path)
|
258
|
+
raise Error, "NOT FOUND: #{uri}"
|
259
|
+
end
|
260
|
+
elsif external
|
261
|
+
if uri.scheme.start_with?('http')
|
262
|
+
# warn "checking external URI: #{uri}"
|
263
|
+
begin
|
264
|
+
check_external_uri(uri)
|
265
|
+
rescue => e
|
266
|
+
raise Error, "external URI: #{uri}: #{e}"
|
267
|
+
end
|
268
|
+
else
|
269
|
+
warn "Don't know how to check URI: #{uri}"
|
270
|
+
end
|
271
|
+
end
|
382
272
|
end
|
383
273
|
|
384
|
-
def
|
385
|
-
|
386
|
-
|
387
|
-
|
388
|
-
|
389
|
-
|
274
|
+
def check_external_uri(uri)
|
275
|
+
response = HTTP.timeout(3).get(uri)
|
276
|
+
case response.code
|
277
|
+
when 200...300
|
278
|
+
# ignore
|
279
|
+
when 300...400
|
280
|
+
redirect_uri = Addressable::URI.parse(response.headers['Location'])
|
281
|
+
check_external_uri(uri + redirect_uri)
|
282
|
+
when 404
|
283
|
+
raise Error, "URI not found: #{uri}"
|
284
|
+
when 999
|
285
|
+
# ignore bogus LinkedIn status
|
286
|
+
else
|
287
|
+
raise Error, "Bad status from #{uri}: #{response.inspect}"
|
288
|
+
end
|
390
289
|
end
|
391
290
|
|
392
291
|
end
|
data/lib/mill.rb
CHANGED
@@ -1,30 +1,48 @@
|
|
1
1
|
require 'addressable'
|
2
|
+
require 'hashstruct'
|
3
|
+
require 'http'
|
2
4
|
require 'image_size'
|
3
5
|
require 'kramdown'
|
4
6
|
require 'mime/types'
|
5
7
|
require 'nokogiri'
|
6
8
|
require 'path'
|
7
|
-
require 'pp'
|
8
|
-
# require 'pry' rescue nil
|
9
9
|
require 'RedCloth'
|
10
|
-
require '
|
10
|
+
require 'run-command'
|
11
11
|
require 'sassc'
|
12
|
+
require 'set_params'
|
13
|
+
require 'simple-builder'
|
14
|
+
require 'simple-command-parser'
|
15
|
+
require 'simple-configurator'
|
16
|
+
require 'simple-printer'
|
12
17
|
require 'time'
|
13
18
|
require 'tree'
|
14
|
-
require 'web-checker'
|
15
19
|
|
20
|
+
class Class
|
21
|
+
|
22
|
+
def self.subclasses
|
23
|
+
constants
|
24
|
+
.map { |c| const_get(c) }
|
25
|
+
.select { |c| c.kind_of?(Class) }
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
|
30
|
+
require 'mill/command'
|
31
|
+
require 'mill/config'
|
16
32
|
require 'mill/error'
|
17
|
-
require 'mill/html_helpers'
|
18
|
-
require 'mill/navigator'
|
19
33
|
require 'mill/resource'
|
34
|
+
require 'mill/resources'
|
20
35
|
require 'mill/resources/blob'
|
21
36
|
require 'mill/resources/feed'
|
22
|
-
require 'mill/resources/google_site_verification'
|
23
37
|
require 'mill/resources/image'
|
38
|
+
require 'mill/resources/markup'
|
39
|
+
require 'mill/resources/markdown'
|
40
|
+
require 'mill/resources/page'
|
24
41
|
require 'mill/resources/redirect'
|
25
42
|
require 'mill/resources/robots'
|
26
43
|
require 'mill/resources/sitemap'
|
27
44
|
require 'mill/resources/stylesheet'
|
28
|
-
require 'mill/resources/
|
45
|
+
require 'mill/resources/textile'
|
29
46
|
require 'mill/site'
|
30
|
-
|
47
|
+
|
48
|
+
Path.new(__FILE__).dirname.glob('mill/commands/*.rb').each { |p| require p }
|