mill 0.11 → 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/.gitignore +11 -1
- data/LICENSE +1 -1
- data/Rakefile +1 -2
- 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 +81 -81
- 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 +181 -251
- data/lib/mill.rb +28 -8
- data/mill.gemspec +22 -17
- data/test/content/a.md +3 -0
- data/test/content/b/ba.md +3 -0
- data/test/content/b/bb.md +3 -0
- data/test/content/b/index.md +3 -0
- data/test/content/c.md +4 -0
- data/test/content/d.md +4 -0
- data/test/content/index.md +3 -0
- data/test/main_test.rb +68 -0
- data/test/mill.yaml +8 -0
- metadata +189 -40
- data/TODO.txt +0 -61
- data/lib/mill/html_helpers.rb +0 -122
- 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 -207
- data/lib/mill/version.rb +0 -5
data/lib/mill/site.rb
CHANGED
|
@@ -2,360 +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_by_uri = {}
|
|
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)
|
|
76
|
+
# ;;warn "adding #{resource.class} as #{resource.path}"
|
|
82
77
|
resource.site = self
|
|
78
|
+
resource.load
|
|
83
79
|
@resources << resource
|
|
84
|
-
@resources_by_uri[resource.uri] = resource
|
|
85
|
-
# ;;warn "added #{resource} as #{resource.uri}"
|
|
86
|
-
end
|
|
87
|
-
|
|
88
|
-
def delete_resource(resource)
|
|
89
|
-
@resources.delete(resource)
|
|
90
|
-
@resources_by_uri.delete(resource.uri)
|
|
91
80
|
end
|
|
92
81
|
|
|
93
|
-
def find_resource(
|
|
94
|
-
|
|
95
|
-
resource = @resources_by_uri[uri]
|
|
96
|
-
if resource.nil? && @shorten_uris
|
|
97
|
-
uri.path = uri.path.sub(%r{\.html$}, '')
|
|
98
|
-
resource = @resources_by_uri[uri]
|
|
99
|
-
end
|
|
100
|
-
resource
|
|
101
|
-
end
|
|
102
|
-
|
|
103
|
-
def resource_for_file(path)
|
|
104
|
-
find_resource(
|
|
105
|
-
URI.parse(
|
|
106
|
-
'/' + URI.encode(
|
|
107
|
-
path.relative_to(@output_dir).to_s
|
|
108
|
-
)
|
|
109
|
-
)
|
|
110
|
-
)
|
|
82
|
+
def find_resource(path)
|
|
83
|
+
@resources[path]
|
|
111
84
|
end
|
|
112
85
|
|
|
113
|
-
def
|
|
114
|
-
|
|
86
|
+
def root_resource
|
|
87
|
+
@resources['/']
|
|
115
88
|
end
|
|
116
89
|
|
|
117
90
|
def tag_uri
|
|
118
91
|
'tag:%s:' % [
|
|
119
92
|
[
|
|
120
|
-
|
|
121
|
-
|
|
93
|
+
site_uri.host.downcase,
|
|
94
|
+
site_control_date
|
|
122
95
|
].join(','),
|
|
123
96
|
]
|
|
124
97
|
end
|
|
125
98
|
|
|
126
99
|
def feed_author_name
|
|
127
|
-
|
|
100
|
+
site_title
|
|
128
101
|
end
|
|
129
102
|
|
|
130
103
|
def feed_author_uri
|
|
131
|
-
|
|
104
|
+
site_uri
|
|
132
105
|
end
|
|
133
106
|
|
|
134
107
|
def feed_author_email
|
|
135
|
-
|
|
108
|
+
site_email
|
|
136
109
|
end
|
|
137
110
|
|
|
138
111
|
def feed_resources
|
|
139
|
-
|
|
112
|
+
primary_resources
|
|
140
113
|
end
|
|
141
114
|
|
|
142
|
-
def
|
|
143
|
-
|
|
115
|
+
def sitemap_resources
|
|
116
|
+
primary_resources
|
|
144
117
|
end
|
|
145
118
|
|
|
146
|
-
def
|
|
147
|
-
@resources.select
|
|
148
|
-
end
|
|
149
|
-
|
|
150
|
-
def redirect_resources
|
|
151
|
-
@resources.select { |r| r.kind_of?(Resource::Redirect) }
|
|
152
|
-
end
|
|
153
|
-
|
|
154
|
-
def make
|
|
155
|
-
build
|
|
156
|
-
save
|
|
157
|
-
end
|
|
158
|
-
|
|
159
|
-
def list
|
|
160
|
-
|
|
161
|
-
list_keys = {
|
|
162
|
-
class: proc { |v| v.to_s.sub(/::Resource::/, '::') },
|
|
163
|
-
input_file: proc { |v| v.relative_to(@input_dir) },
|
|
164
|
-
output_file: proc { |v| v.relative_to(@output_dir) },
|
|
165
|
-
public: proc { |v| v },
|
|
166
|
-
content: proc { |v| '%dKB' % (v.to_s.length / 1024.0).ceil },
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
build
|
|
170
|
-
list = @resources.map do |resource|
|
|
171
|
-
Hash[
|
|
172
|
-
list_keys.map do |k, p|
|
|
173
|
-
v = resource.send(k)
|
|
174
|
-
[
|
|
175
|
-
k,
|
|
176
|
-
v ? p.call(v).to_s : '-'
|
|
177
|
-
]
|
|
178
|
-
end
|
|
179
|
-
]
|
|
180
|
-
end
|
|
181
|
-
format = list_keys.keys.map do |key|
|
|
182
|
-
'%%-%ds' % list.map { |item| item[key].length }.max
|
|
183
|
-
end.join(' ')
|
|
184
|
-
puts format % list_keys.keys
|
|
185
|
-
list.each do |item|
|
|
186
|
-
puts format % item.values
|
|
187
|
-
end
|
|
119
|
+
def primary_resources
|
|
120
|
+
@resources.select(&:primary?).sort_by(&:date)
|
|
188
121
|
end
|
|
189
122
|
|
|
190
123
|
def build
|
|
191
|
-
import_resources
|
|
192
124
|
load_resources
|
|
125
|
+
convert_resources
|
|
193
126
|
build_resources
|
|
127
|
+
check
|
|
194
128
|
end
|
|
195
129
|
|
|
196
|
-
def
|
|
130
|
+
def load_resources
|
|
197
131
|
add_files
|
|
198
132
|
add_redirects
|
|
199
|
-
|
|
200
|
-
add_feed if
|
|
201
|
-
add_sitemap if
|
|
202
|
-
add_robots if
|
|
203
|
-
add_htpasswd if @htpasswd_file
|
|
204
|
-
end
|
|
205
|
-
|
|
206
|
-
def load_resources
|
|
207
|
-
on_each_resource do |resource|
|
|
208
|
-
# ;;warn "#{resource.uri}: loading"
|
|
209
|
-
resource.load
|
|
210
|
-
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?
|
|
211
137
|
end
|
|
212
138
|
|
|
213
139
|
def build_resources
|
|
214
|
-
|
|
215
|
-
# ;;warn "#{resource.
|
|
140
|
+
@resources.each do |resource|
|
|
141
|
+
# ;;warn "#{resource.path}: building"
|
|
216
142
|
resource.build
|
|
217
143
|
end
|
|
218
144
|
end
|
|
219
145
|
|
|
220
|
-
def
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
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
|
|
226
154
|
end
|
|
227
155
|
end
|
|
228
156
|
|
|
229
|
-
def
|
|
230
|
-
if
|
|
231
|
-
|
|
157
|
+
def save
|
|
158
|
+
if output_dir.exist?
|
|
159
|
+
output_dir.children.reject { |p| p.basename.to_s == '.git' }.each do |path|
|
|
232
160
|
path.rm_rf
|
|
233
161
|
end
|
|
162
|
+
else
|
|
163
|
+
output_dir.mkpath
|
|
234
164
|
end
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
build
|
|
239
|
-
checker = WebChecker.new(site_uri: @site_uri, site_dir: @output_dir)
|
|
240
|
-
end
|
|
241
|
-
|
|
242
|
-
def snapshot
|
|
243
|
-
@output_dir.chdir do
|
|
244
|
-
system('git',
|
|
245
|
-
'add',
|
|
246
|
-
'.')
|
|
247
|
-
system('git',
|
|
248
|
-
'commit',
|
|
249
|
-
'-a',
|
|
250
|
-
'-m',
|
|
251
|
-
'Update.')
|
|
165
|
+
@resources.each do |resource|
|
|
166
|
+
# ;;warn "#{resource.path}: saving"
|
|
167
|
+
resource.save
|
|
252
168
|
end
|
|
253
169
|
end
|
|
254
170
|
|
|
255
|
-
def
|
|
256
|
-
@
|
|
257
|
-
|
|
258
|
-
|
|
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
|
|
259
181
|
end
|
|
260
182
|
end
|
|
261
183
|
|
|
262
|
-
def
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
'--verbose',
|
|
267
|
-
'--archive',
|
|
268
|
-
'--exclude=.git',
|
|
269
|
-
'--delete-after',
|
|
270
|
-
@output_dir.to_s,
|
|
271
|
-
@site_rsync)
|
|
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(', ')})"
|
|
272
188
|
end
|
|
273
189
|
|
|
274
|
-
def
|
|
275
|
-
@
|
|
276
|
-
old_uri = resource.uri.dup
|
|
277
|
-
begin
|
|
278
|
-
yield(resource)
|
|
279
|
-
rescue Error => e
|
|
280
|
-
raise e, "#{resource.input_file || '-'} (#{old_uri}): #{e}"
|
|
281
|
-
end
|
|
282
|
-
if resource.uri != old_uri
|
|
283
|
-
# ;;warn "URI changed: #{old_uri} => #{resource.uri}"
|
|
284
|
-
@resources_by_uri.delete(old_uri)
|
|
285
|
-
@resources_by_uri[resource.uri] = resource
|
|
286
|
-
end
|
|
287
|
-
end
|
|
190
|
+
def resource_class_for_type(type)
|
|
191
|
+
@file_types[type]
|
|
288
192
|
end
|
|
289
193
|
|
|
290
194
|
private
|
|
291
195
|
|
|
292
|
-
def resource_class_for_file(file)
|
|
293
|
-
type = MIME::Types.of(file.to_s).first
|
|
294
|
-
if type && (klass = @file_types[type.content_type])
|
|
295
|
-
klass
|
|
296
|
-
else
|
|
297
|
-
raise Error, "Unknown file type: #{file.to_s.inspect} (#{MIME::Types.of(file.to_s).join(', ')})"
|
|
298
|
-
end
|
|
299
|
-
end
|
|
300
|
-
|
|
301
196
|
def add_files
|
|
302
|
-
raise Error, "Input
|
|
303
|
-
|
|
197
|
+
raise Error, "Input directory not found: #{input_dir}" unless input_dir.exist?
|
|
198
|
+
input_dir.find do |input_file|
|
|
304
199
|
if input_file.basename.to_s[0] == '.'
|
|
305
200
|
Find.prune
|
|
201
|
+
elsif input_file.basename.to_s == "Icon\r"
|
|
202
|
+
# skip macOS garbage file
|
|
306
203
|
elsif input_file.directory?
|
|
307
|
-
# skip
|
|
204
|
+
# skip directories
|
|
308
205
|
else (klass = resource_class_for_file(input_file))
|
|
309
|
-
resource = klass.new(
|
|
310
|
-
input_file: input_file,
|
|
311
|
-
output_file: @output_dir / input_file.relative_to(@input_dir))
|
|
206
|
+
resource = klass.new(input: input_file, path: '/' + input_file.relative_to(input_dir).to_s)
|
|
312
207
|
add_resource(resource)
|
|
313
208
|
end
|
|
314
209
|
end
|
|
315
210
|
end
|
|
316
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
|
+
|
|
317
231
|
def add_feed
|
|
318
|
-
@feed_resource = Resource::Feed.new(
|
|
319
|
-
output_file: @output_dir / 'feed.xml')
|
|
232
|
+
@feed_resource = Resource::Feed.new(path: '/feed.xml')
|
|
320
233
|
add_resource(@feed_resource)
|
|
321
234
|
end
|
|
322
235
|
|
|
323
236
|
def add_sitemap
|
|
324
|
-
@sitemap_resource = Resource::Sitemap.new(
|
|
325
|
-
output_file: @output_dir / 'sitemap.xml')
|
|
237
|
+
@sitemap_resource = Resource::Sitemap.new(path: '/sitemap.xml')
|
|
326
238
|
add_resource(@sitemap_resource)
|
|
327
239
|
end
|
|
328
240
|
|
|
329
241
|
def add_robots
|
|
330
|
-
@robots_resource = Resource::Robots.new(
|
|
331
|
-
output_file: @output_dir / 'robots.txt')
|
|
242
|
+
@robots_resource = Resource::Robots.new(path: '/robots.txt')
|
|
332
243
|
add_resource(@robots_resource)
|
|
333
244
|
end
|
|
334
245
|
|
|
335
246
|
def add_redirects
|
|
336
247
|
if @redirects
|
|
337
248
|
@redirects.each do |from, to|
|
|
338
|
-
|
|
339
|
-
resource = Resource::Redirect.new(
|
|
340
|
-
output_file: output_file,
|
|
341
|
-
redirect_uri: to)
|
|
249
|
+
resource = Resource::Redirect.new(path: Path.new(from).add_extension('.redirect').to_s, redirect_uri: to)
|
|
342
250
|
add_resource(resource)
|
|
343
251
|
end
|
|
344
252
|
end
|
|
345
253
|
end
|
|
346
254
|
|
|
347
|
-
def
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
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
|
|
352
272
|
end
|
|
353
273
|
|
|
354
|
-
def
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
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
|
|
359
289
|
end
|
|
360
290
|
|
|
361
291
|
end
|
data/lib/mill.rb
CHANGED
|
@@ -1,28 +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
9
|
require 'RedCloth'
|
|
9
|
-
require '
|
|
10
|
+
require 'run-command'
|
|
10
11
|
require 'sassc'
|
|
12
|
+
require 'set_params'
|
|
13
|
+
require 'simple-builder'
|
|
14
|
+
require 'simple-command-parser'
|
|
15
|
+
require 'simple-configurator'
|
|
16
|
+
require 'simple-printer'
|
|
11
17
|
require 'time'
|
|
12
|
-
require '
|
|
18
|
+
require 'tree'
|
|
13
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'
|
|
14
32
|
require 'mill/error'
|
|
15
|
-
require 'mill/html_helpers'
|
|
16
|
-
require 'mill/navigator'
|
|
17
33
|
require 'mill/resource'
|
|
34
|
+
require 'mill/resources'
|
|
18
35
|
require 'mill/resources/blob'
|
|
19
36
|
require 'mill/resources/feed'
|
|
20
|
-
require 'mill/resources/google_site_verification'
|
|
21
37
|
require 'mill/resources/image'
|
|
38
|
+
require 'mill/resources/markup'
|
|
39
|
+
require 'mill/resources/markdown'
|
|
40
|
+
require 'mill/resources/page'
|
|
22
41
|
require 'mill/resources/redirect'
|
|
23
42
|
require 'mill/resources/robots'
|
|
24
43
|
require 'mill/resources/sitemap'
|
|
25
44
|
require 'mill/resources/stylesheet'
|
|
26
|
-
require 'mill/resources/
|
|
45
|
+
require 'mill/resources/textile'
|
|
27
46
|
require 'mill/site'
|
|
28
|
-
|
|
47
|
+
|
|
48
|
+
Path.new(__FILE__).dirname.glob('mill/commands/*.rb').each { |p| require p }
|
data/mill.gemspec
CHANGED
|
@@ -1,10 +1,6 @@
|
|
|
1
|
-
#encoding: utf-8
|
|
2
|
-
|
|
3
|
-
require_relative 'lib/mill/version'
|
|
4
|
-
|
|
5
1
|
Gem::Specification.new do |s|
|
|
6
2
|
s.name = 'mill'
|
|
7
|
-
s.version =
|
|
3
|
+
s.version = '0.18'
|
|
8
4
|
s.summary = 'A simple but useful static site generator.'
|
|
9
5
|
s.author = 'John Labovitz'
|
|
10
6
|
s.email = 'johnl@johnlabovitz.com'
|
|
@@ -12,23 +8,32 @@ Gem::Specification.new do |s|
|
|
|
12
8
|
Mill provides a simple but useful static site generator.
|
|
13
9
|
}
|
|
14
10
|
s.license = 'MIT'
|
|
15
|
-
s.homepage = '
|
|
11
|
+
s.homepage = 'https://github.com/jslabovitz/mill'
|
|
16
12
|
s.files = `git ls-files`.split("\n")
|
|
17
13
|
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
|
18
14
|
s.executables = `git ls-files -- bin/*`.split("\n").map { |f| File.basename(f) }
|
|
19
15
|
s.require_path = 'lib'
|
|
20
16
|
|
|
21
|
-
s.add_dependency 'addressable', '~> 2.
|
|
22
|
-
s.add_dependency '
|
|
23
|
-
s.add_dependency '
|
|
24
|
-
s.add_dependency '
|
|
25
|
-
s.add_dependency '
|
|
26
|
-
s.add_dependency '
|
|
17
|
+
s.add_dependency 'addressable', '~> 2.8'
|
|
18
|
+
s.add_dependency 'hashstruct', '~> 1.6'
|
|
19
|
+
s.add_dependency 'http', '~> 5.3'
|
|
20
|
+
s.add_dependency 'image_size', '~> 3.4'
|
|
21
|
+
s.add_dependency 'kramdown', '~> 2.5'
|
|
22
|
+
s.add_dependency 'mime-types', '~> 3.7'
|
|
23
|
+
s.add_dependency 'nokogiri', '~> 1.18'
|
|
24
|
+
s.add_dependency 'path', '~> 2.1'
|
|
27
25
|
s.add_dependency 'RedCloth', '~> 4.3'
|
|
28
|
-
s.add_dependency 'rubypants', '~> 0.
|
|
29
|
-
s.add_dependency '
|
|
30
|
-
s.add_dependency '
|
|
26
|
+
s.add_dependency 'rubypants', '~> 0.7'
|
|
27
|
+
s.add_dependency 'rubytree', '~> 2.1'
|
|
28
|
+
s.add_dependency 'sassc', '~> 2.4'
|
|
29
|
+
s.add_dependency 'set_params', '~> 0.3'
|
|
30
|
+
s.add_dependency 'simple-builder', '~> 0.4'
|
|
31
|
+
s.add_dependency 'simple-command-parser', '~> 1.2'
|
|
32
|
+
s.add_dependency 'simple-configurator', '~> 0.2'
|
|
33
|
+
s.add_dependency 'simple-printer', '~> 0.4'
|
|
31
34
|
|
|
32
|
-
s.add_development_dependency '
|
|
33
|
-
s.add_development_dependency '
|
|
35
|
+
s.add_development_dependency 'minitest', '~> 5.26'
|
|
36
|
+
s.add_development_dependency 'minitest-power_assert', '~> 0.3'
|
|
37
|
+
s.add_development_dependency 'rake', '~> 13.3'
|
|
38
|
+
s.add_development_dependency 'simple-rake-tasks', '~> 0.1'
|
|
34
39
|
end
|
data/test/content/a.md
ADDED
data/test/content/c.md
ADDED