mill 0.11 → 0.16

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 552fff29a5bcd1a558ba23332357186141369ddb3077452a0b0d8a7514df257a
4
- data.tar.gz: 96b5ce3171c004bcf807b3d8b6185bd83b3c8d120f5e896cf046ba8dca70a38f
3
+ metadata.gz: 5accfe1e5067386b3de4898faceb6ea201c6bc30097da779c38ef343e0aad18c
4
+ data.tar.gz: 5861a090880607573153929c75f0475fb258467676b2a4084514e8b368028bb6
5
5
  SHA512:
6
- metadata.gz: a8fb52dc75caeee17ba0fe74d1182b4a64c9dd6edaca7891360019e70facb3cac35cfdf46ad6a6c81708ef65fce775969b12d404c5d577ca922989a2b0155c01
7
- data.tar.gz: 12423dfe0681de5e5aacf90cb97167b44193e332ed7f8a62b1b4cbbb7426fe4d4ce3f5cde9784c414683cfb9b1096357bffd74bccb1dcaf1a2b4457bcd07ee5a
6
+ metadata.gz: 1c1e0a63042509e67a028e2e50b2f61fa92560ee16bb77370ca1ca82d1f75ebbd7054b9ba8b2408aff32e83a44c3e5f9cc2600316e5dd22c8a47ef7d26cee932
7
+ data.tar.gz: 7dc21c2b4181768be5150d1e51ef6ea9b16aba0a33c8536dd9609e72b458913e2fa79ee460d9c50c204dc6a0da733587bd4807005a16ca2acc4e5806b33d168d
data/.gitignore CHANGED
@@ -1 +1,11 @@
1
- *.gem
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+
11
+ /test/output
data/Gemfile ADDED
@@ -0,0 +1,6 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
4
+
5
+ gem 'path', github: 'eregon/path'
6
+ gem 'rubytree', github: 'evolve75/RubyTree'
data/Rakefile CHANGED
@@ -1,2 +1,9 @@
1
- require 'rubygems/tasks'
2
- Gem::Tasks.new
1
+ require 'bundler/gem_tasks'
2
+ Bundler.require
3
+ require 'rake/testtask'
4
+
5
+ Rake::TestTask.new do |t|
6
+ t.test_files = FileList['test/*test.rb']
7
+ end
8
+
9
+ task :default => :test
data/TODO.txt CHANGED
@@ -1,6 +1,10 @@
1
+ - remove textile/pre processors from Resource::Text
2
+ - streamline to allow domain-specific subclassing if needed
3
+
1
4
  - initialize site by setting ivars directly, not by passing params to super's initialize()
2
5
 
3
6
  - create alternate sites (beta, final, etc.) by subclassing site, and changing @output or @location
7
+ - allow CLI option to specify site
4
8
 
5
9
  - rework resource URI usage
6
10
  - 'uri' attribute should be canonical
@@ -41,8 +45,6 @@
41
45
  - sidebars
42
46
  - strings (existing String extensions)
43
47
 
44
- - create bin/mill tool to replace Rake
45
-
46
48
  - split Resource#date into Resource#published & Resource#updated
47
49
  + add <published> element to feed
48
50
  + #published should be stated date (e.g., from header)
@@ -56,6 +58,4 @@
56
58
 
57
59
  - save compressed versions of files
58
60
  - write compressed versions along with non-compressed
59
- - serve compressed versions if asked by client
60
-
61
- - add MailChimp signup form generator to HTMLHelpers
61
+ - serve compressed versions if asked by client
data/bin/mill CHANGED
@@ -20,8 +20,8 @@ begin
20
20
  $site.snapshot
21
21
  when 'upload'
22
22
  $site.upload
23
- when 'output-dir'
24
- puts $site.output_dir
23
+ when 'show'
24
+ puts $site.send(ARGV.shift)
25
25
  else
26
26
  raise "Unknown command: #{command.inspect}"
27
27
  end
@@ -5,10 +5,12 @@ require 'mime/types'
5
5
  require 'nokogiri'
6
6
  require 'path'
7
7
  require 'pp'
8
+ # require 'pry' rescue nil
8
9
  require 'RedCloth'
9
10
  require 'rubypants'
10
11
  require 'sassc'
11
12
  require 'time'
13
+ require 'tree'
12
14
  require 'web-checker'
13
15
 
14
16
  require 'mill/error'
@@ -104,13 +104,19 @@ module HTMLHelpers
104
104
  nil => RubyPants,
105
105
  smart_quotes: RubyPants,
106
106
  markdown: Kramdown::Document,
107
- textile: RedCloth,
107
+ textile: [RedCloth, :no_span_caps],
108
108
  pre: PreText,
109
109
  }
110
110
 
111
111
  def to_html(options={})
112
- converter = Converters[options[:mode]] or raise "Unknown to_html mode: #{options[:mode].inspect}"
113
- html = Nokogiri::HTML::DocumentFragment.parse(converter.new(self).to_html)
112
+ converter_class = Converters[options[:mode]] or raise "Unknown to_html mode: #{options[:mode].inspect}"
113
+ if converter_class.kind_of?(Array)
114
+ converter_class, *converter_options = *converter_class
115
+ converter = converter_class.new(self, converter_options)
116
+ else
117
+ converter = converter_class.new(self)
118
+ end
119
+ html = Nokogiri::HTML::DocumentFragment.parse(converter.to_html)
114
120
  if !options[:multiline] && (p_elem = html.at_xpath('p'))
115
121
  html = p_elem.children.to_html
116
122
  end
@@ -6,10 +6,12 @@ module Mill
6
6
 
7
7
  attr_accessor :input_file
8
8
  attr_accessor :output_file
9
+ attr_accessor :path
9
10
  attr_accessor :date
10
11
  attr_accessor :public
11
12
  attr_accessor :content
12
13
  attr_accessor :site
14
+ attr_accessor :node
13
15
 
14
16
  def initialize(input_file: nil,
15
17
  output_file: nil,
@@ -23,7 +25,10 @@ module Mill
23
25
  else
24
26
  @date = DateTime.now
25
27
  end
26
- @output_file = Path.new(output_file) if output_file
28
+ if output_file
29
+ @output_file = Path.new(output_file)
30
+ @path = '/' + @output_file.relative_to(site.output_dir).to_s
31
+ end
27
32
  self.date = date if date
28
33
  self.public = public
29
34
  @content = content
@@ -57,39 +62,47 @@ module Mill
57
62
  end
58
63
 
59
64
  def public?
60
- @public
65
+ @public == true
66
+ end
67
+
68
+ def text?
69
+ kind_of?(Resource::Text) && public?
70
+ end
71
+
72
+ def redirect?
73
+ kind_of?(Resource::Redirect)
61
74
  end
62
75
 
63
76
  def inspect
64
- "<%p> input_file: %p, output_file: %p, date: %s, public: %p, content: <%p>" % [
77
+ "<%p> input_file: %p, output_file: %p, path: %s, date: %s, public: %p, content: <%p>, parent: %p, siblings: %p, children: %p" % [
65
78
  self.class,
66
79
  @input_file ? @input_file.relative_to(@site.input_dir).to_s : nil,
67
80
  @output_file ? @output_file.relative_to(@site.output_dir).to_s : nil,
81
+ @path,
68
82
  @date.to_s,
69
83
  @public,
70
- @content && @content.class,
84
+ @content&.class,
85
+ parent&.path,
86
+ siblings.map(&:path),
87
+ children.map(&:path),
71
88
  ]
72
89
  end
73
90
 
74
- def find_sibling_resources(klass=nil)
75
- # parent_uri = parent_uri
76
- @site.resources.select do |resource|
77
- resource != self &&
78
- (klass.nil? || resource.kind_of?(klass)) &&
79
- resource.parent_uri == parent_uri
80
- end
91
+ def parent
92
+ @node.parent&.content
81
93
  end
82
94
 
83
- def uri
84
- raise Error, "#{@input_file}: No output file defined for #{self.class}" unless @output_file
85
- path = '/' + @output_file.relative_to(@site.output_dir).to_s
86
- path.sub!(%r{/index\.html$}, '/')
87
- path.sub!(%r{\.html$}, '') if @site.shorten_uris
88
- Addressable::URI.encode(path, Addressable::URI)
95
+ def siblings
96
+ @node.siblings.map(&:content).compact
89
97
  end
90
98
 
91
- def parent_uri
92
- uri + '.'
99
+ def children
100
+ @node.children.map(&:content).compact
101
+ end
102
+
103
+ def uri
104
+ raise Error, "#{@input_file}: No path defined for #{self.class}" unless @path
105
+ Addressable::URI.encode(@path, Addressable::URI)
93
106
  end
94
107
 
95
108
  def absolute_uri
@@ -119,14 +132,14 @@ module Mill
119
132
  def save
120
133
  @output_file.dirname.mkpath
121
134
  if (content = final_content)
122
- # ;;warn "#{uri}: writing #{@input_file} to #{@output_file}"
135
+ # ;;warn "#{path}: writing #{@input_file} to #{@output_file}"
123
136
  @output_file.write(content.to_s)
124
137
  @output_file.utime(@date.to_time, @date.to_time)
125
138
  elsif @input_file
126
- # ;;warn "#{uri}: copying #{@input_file} to #{@output_file}"
139
+ # ;;warn "#{path}: copying #{@input_file} to #{@output_file}"
127
140
  @input_file.copy(@output_file)
128
141
  else
129
- raise Error, "Can't build resource without content or input file: #{uri}"
142
+ raise Error, "Can't build resource without content or input file: #{path}"
130
143
  end
131
144
  end
132
145
 
@@ -1,3 +1,4 @@
1
+
1
2
  module Mill
2
3
 
3
4
  class Resource
@@ -15,19 +16,29 @@ module Mill
15
16
  attr_accessor :title
16
17
  attr_accessor :summary
17
18
  attr_accessor :author
19
+ attr_accessor :type
18
20
 
19
- def initialize(title: nil, summary: nil, author: nil, public: true, **args)
21
+ def initialize(title: nil, summary: nil, author: nil, public: true, output_file: nil, **args)
20
22
  @title = title
21
23
  @summary = summary
22
24
  @author = author
23
- super(public: public, **args)
25
+ @type = nil
26
+ super(
27
+ public: public,
28
+ output_file: output_file&.replace_extension('.html'),
29
+ **args)
30
+ if @path
31
+ @path.sub!(%r{\.html$}, '') if @site&.shorten_uris
32
+ @path.sub!(%r{(.*)index$}, '\1')
33
+ end
24
34
  end
25
35
 
26
36
  def inspect
27
- super + ", title: %p, summary: %p, author: %p" % [
37
+ super + ", title: %p, summary: %p, author: %p, type: %p" % [
28
38
  @title,
29
39
  @summary,
30
40
  @author,
41
+ @type,
31
42
  ]
32
43
  end
33
44
 
@@ -35,7 +46,7 @@ module Mill
35
46
  super
36
47
  if @input_file
37
48
  @content = @input_file.read
38
- mode = case @input_file.extname.downcase
49
+ @type = case @input_file.extname.downcase
39
50
  when '.md', '.mdown', '.markdown'
40
51
  :markdown
41
52
  when '.textile'
@@ -47,10 +58,10 @@ module Mill
47
58
  else
48
59
  raise "Unknown text type: #{@input_file}"
49
60
  end
50
- if mode != :html
61
+ if @type != :html
51
62
  parse_text_header
52
- @content = (@content || '').to_html(mode: mode, multiline: true)
53
- @output_file = @output_file.replace_extension('.html')
63
+ @content = (@content || '').to_html(mode: @type, multiline: true)
64
+ @type = :html
54
65
  end
55
66
  begin
56
67
  @content = parse_html(@content)
@@ -66,7 +77,7 @@ module Mill
66
77
  if (title_elem = @content.at_xpath('/html/head/title'))
67
78
  @title = title_elem.text
68
79
  else
69
- @title = uri.to_s
80
+ @title = @path
70
81
  end
71
82
  end
72
83
  @content.xpath('/html/head/meta[@name]').each do |meta|
@@ -78,7 +89,7 @@ module Mill
78
89
  if @content.split(/\n/, 2).first =~ /^\w+:\s+/
79
90
  header, @content = @content.split(/\n\n/, 2)
80
91
  header.split(/\n/).map do |line|
81
- key, value = line.strip.split(/:\s+/, 2)
92
+ key, value = line.strip.split(/:\s*/, 2)
82
93
  key = key.gsub('-', '_').downcase.to_sym
83
94
  send("#{key}=", value)
84
95
  end
@@ -86,7 +97,7 @@ module Mill
86
97
  end
87
98
 
88
99
  def final_content
89
- html_document(@site.html_version) do |doc|
100
+ html_document(@site&.html_version || :html5) do |doc|
90
101
  doc.html(lang: 'en') do |html|
91
102
  html.parent << head
92
103
  html.parent << body
@@ -168,7 +179,7 @@ module Mill
168
179
  self_uri.scheme = 'http'
169
180
  link_uri.scheme = 'http'
170
181
  attribute.value = self_uri.route_to(link_uri)
171
- # ;;warn "[#{uri}] shortened link #{elem.name}/@#{attribute.name}: #{link_uri} => #{attribute.value}"
182
+ # ;;warn "[#{path}] shortened link #{elem.name}/@#{attribute.name}: #{link_uri} => #{attribute.value}"
172
183
  end
173
184
  end
174
185
  end
@@ -195,7 +206,7 @@ module Mill
195
206
  body_elem.children
196
207
  end
197
208
  else
198
- warn "Warning: Resource #{uri} (#{self.class}) has no content"
209
+ warn "Warning: Resource #{path} (#{self.class}) has no content"
199
210
  nil
200
211
  end
201
212
  end
@@ -64,8 +64,8 @@ module Mill
64
64
  @google_site_verification = google_site_verification
65
65
  @redirects = redirects
66
66
 
67
- @resources = []
68
- @resources_by_uri = {}
67
+ @resources = {}
68
+ @resources_tree = Tree::TreeNode.new('')
69
69
  build_file_types
70
70
  end
71
71
 
@@ -79,35 +79,20 @@ module Mill
79
79
  end
80
80
 
81
81
  def add_resource(resource)
82
- resource.site = self
83
- @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
- end
92
-
93
- def find_resource(uri)
94
- uri = Addressable::URI.parse(uri.to_s) unless uri.kind_of?(Addressable::URI)
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]
82
+ raise "Must assign resource to site" unless resource.site
83
+ @resources[resource.path] = resource
84
+ node = @resources_tree
85
+ resource.path.split('/').reject(&:empty?).each do |component|
86
+ node = node[component] || (node << Tree::TreeNode.new(component))
99
87
  end
100
- resource
88
+ resource.node = node
89
+ node.content = resource
90
+ # ;;warn "added #{resource} as #{resource.path}"
101
91
  end
102
92
 
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
- )
93
+ def find_resource(path)
94
+ path = path.path if path.kind_of?(Addressable::URI)
95
+ @resources[path] || @resources[path + '/']
111
96
  end
112
97
 
113
98
  def home_resource
@@ -135,20 +120,30 @@ module Mill
135
120
  @site_email
136
121
  end
137
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
131
+ end
132
+
138
133
  def feed_resources
139
134
  public_resources.sort_by(&:date)
140
135
  end
141
136
 
142
137
  def public_resources
143
- @resources.select(&:public)
138
+ select_resources(&:public?)
144
139
  end
145
140
 
146
- def private_resources
147
- @resources.select { |r| r.kind_of?(Resource::Text) && !r.public }
141
+ def redirect_resources
142
+ select_resources(&:redirect?)
148
143
  end
149
144
 
150
- def redirect_resources
151
- @resources.select { |r| r.kind_of?(Resource::Redirect) }
145
+ def text_resources
146
+ select_resources(&:text?)
152
147
  end
153
148
 
154
149
  def make
@@ -156,35 +151,67 @@ module Mill
156
151
  save
157
152
  end
158
153
 
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
- }
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
+ }
168
180
 
181
+ def list
169
182
  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
- ]
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
178
196
  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
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
187
213
  end
214
+ puts
188
215
  end
189
216
 
190
217
  def build
@@ -205,14 +232,14 @@ module Mill
205
232
 
206
233
  def load_resources
207
234
  on_each_resource do |resource|
208
- # ;;warn "#{resource.uri}: loading"
235
+ # ;;warn "#{resource.path}: loading"
209
236
  resource.load
210
237
  end
211
238
  end
212
239
 
213
240
  def build_resources
214
241
  on_each_resource do |resource|
215
- # ;;warn "#{resource.uri}: building"
242
+ # ;;warn "#{resource.path}: building"
216
243
  resource.build
217
244
  end
218
245
  end
@@ -221,7 +248,7 @@ module Mill
221
248
  clean
222
249
  @output_dir.mkpath
223
250
  on_each_resource do |resource|
224
- # ;;warn "#{resource.uri}: saving"
251
+ # ;;warn "#{resource.path}: saving"
225
252
  resource.save
226
253
  end
227
254
  end
@@ -241,6 +268,8 @@ module Mill
241
268
 
242
269
  def snapshot
243
270
  @output_dir.chdir do
271
+ system('git',
272
+ 'init') unless Path.new('.git').exist?
244
273
  system('git',
245
274
  'add',
246
275
  '.')
@@ -265,6 +294,7 @@ module Mill
265
294
  '--progress',
266
295
  '--verbose',
267
296
  '--archive',
297
+ # '--append-verify',
268
298
  '--exclude=.git',
269
299
  '--delete-after',
270
300
  @output_dir.to_s,
@@ -272,17 +302,11 @@ module Mill
272
302
  end
273
303
 
274
304
  def on_each_resource(&block)
275
- @resources.each do |resource|
276
- old_uri = resource.uri.dup
305
+ @resources.values.each do |resource|
277
306
  begin
278
307
  yield(resource)
279
308
  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
309
+ raise e, "#{resource.input_file || '-'} (#{resource.path}): #{e}"
286
310
  end
287
311
  end
288
312
  end
@@ -299,7 +323,7 @@ module Mill
299
323
  end
300
324
 
301
325
  def add_files
302
- raise Error, "Input path not found: #{@input_dir}" unless @input_dir.exist?
326
+ raise Error, "Input directory not found: #{@input_dir}" unless @input_dir.exist?
303
327
  @input_dir.find do |input_file|
304
328
  if input_file.basename.to_s[0] == '.'
305
329
  Find.prune
@@ -308,7 +332,8 @@ module Mill
308
332
  else (klass = resource_class_for_file(input_file))
309
333
  resource = klass.new(
310
334
  input_file: input_file,
311
- output_file: @output_dir / input_file.relative_to(@input_dir))
335
+ output_file: @output_dir / input_file.relative_to(@input_dir),
336
+ site: self)
312
337
  add_resource(resource)
313
338
  end
314
339
  end
@@ -316,19 +341,22 @@ module Mill
316
341
 
317
342
  def add_feed
318
343
  @feed_resource = Resource::Feed.new(
319
- output_file: @output_dir / 'feed.xml')
344
+ output_file: @output_dir / 'feed.xml',
345
+ site: self)
320
346
  add_resource(@feed_resource)
321
347
  end
322
348
 
323
349
  def add_sitemap
324
350
  @sitemap_resource = Resource::Sitemap.new(
325
- output_file: @output_dir / 'sitemap.xml')
351
+ output_file: @output_dir / 'sitemap.xml',
352
+ site: self)
326
353
  add_resource(@sitemap_resource)
327
354
  end
328
355
 
329
356
  def add_robots
330
357
  @robots_resource = Resource::Robots.new(
331
- output_file: @output_dir / 'robots.txt')
358
+ output_file: @output_dir / 'robots.txt',
359
+ site: self)
332
360
  add_resource(@robots_resource)
333
361
  end
334
362
 
@@ -338,7 +366,8 @@ module Mill
338
366
  output_file = @output_dir / Path.new(from).relative_to('/')
339
367
  resource = Resource::Redirect.new(
340
368
  output_file: output_file,
341
- redirect_uri: to)
369
+ redirect_uri: to,
370
+ site: self)
342
371
  add_resource(resource)
343
372
  end
344
373
  end
@@ -347,14 +376,16 @@ module Mill
347
376
  def add_google_site_verification
348
377
  resource = Resource::GoogleSiteVerification.new(
349
378
  output_file: (@output_dir / @google_site_verification).add_extension('.html'),
350
- key: @google_site_verification)
379
+ key: @google_site_verification,
380
+ site: self)
351
381
  add_resource(resource)
352
382
  end
353
383
 
354
384
  def add_htpasswd
355
385
  resource = Resource.new(
356
386
  input_file: @htpasswd_file,
357
- output_file: @output_dir / '.htpasswd')
387
+ output_file: @output_dir / '.htpasswd',
388
+ site: self)
358
389
  add_resource(resource)
359
390
  end
360
391
 
@@ -1,5 +1,5 @@
1
1
  module Mill
2
2
 
3
- VERSION = '0.11'
3
+ VERSION = '0.16'
4
4
 
5
5
  end
@@ -18,17 +18,22 @@ Gem::Specification.new do |s|
18
18
  s.executables = `git ls-files -- bin/*`.split("\n").map { |f| File.basename(f) }
19
19
  s.require_path = 'lib'
20
20
 
21
- s.add_dependency 'addressable', '~> 2.5'
22
- s.add_dependency 'image_size', '~> 1.5'
23
- s.add_dependency 'kramdown', '~> 1.16'
24
- s.add_dependency 'mime-types', '~> 3.1'
25
- s.add_dependency 'nokogiri', '~> 1.8'
21
+ s.add_dependency 'addressable', '~> 2.7'
22
+ s.add_dependency 'image_size', '~> 2.1'
23
+ s.add_dependency 'kramdown', '~> 2.3'
24
+ s.add_dependency 'mime-types', '~> 3.3'
25
+ s.add_dependency 'nokogiri', '~> 1.10'
26
26
  s.add_dependency 'path', '~> 2.0'
27
27
  s.add_dependency 'RedCloth', '~> 4.3'
28
- s.add_dependency 'rubypants', '~> 0.6'
29
- s.add_dependency 'sassc', '~> 2.0'
30
- s.add_dependency 'web-checker', '~> 0'
28
+ s.add_dependency 'rubypants', '~> 0.7'
29
+ s.add_dependency 'rubytree', '~> 1.0'
30
+ s.add_dependency 'sassc', '~> 2.4'
31
+ s.add_dependency 'web-checker', '~> 0.4'
31
32
 
32
- s.add_development_dependency 'rake', '~> 0'
33
- s.add_development_dependency 'rubygems-tasks', '~> 0.0'
33
+ s.add_development_dependency 'bundler', '~> 2.2'
34
+ s.add_development_dependency 'minitest', '~> 5.14'
35
+ s.add_development_dependency 'minitest-power_assert', '~> 0.3'
36
+ s.add_development_dependency 'pry', '~> 0.13'
37
+ s.add_development_dependency 'rake', '~> 13.0'
38
+ s.add_development_dependency 'rubygems-tasks', '~> 0.2'
34
39
  end
@@ -0,0 +1,3 @@
1
+ Title: a
2
+
3
+ This is a.
@@ -0,0 +1,3 @@
1
+ Title: ba
2
+
3
+ This is ba.
@@ -0,0 +1,3 @@
1
+ Title: bb
2
+
3
+ This is bb.
@@ -0,0 +1,3 @@
1
+ Title: b index
2
+
3
+ This is index of b.
@@ -0,0 +1,3 @@
1
+ Title: index
2
+
3
+ This is index.
@@ -0,0 +1,56 @@
1
+ $VERBOSE = false
2
+
3
+ require 'minitest/autorun'
4
+ require 'minitest/power_assert'
5
+
6
+ $LOAD_PATH.unshift File.expand_path('../lib', __FILE__)
7
+ require 'mill'
8
+
9
+ module Mill
10
+
11
+ class Test < Minitest::Test
12
+
13
+ def setup
14
+ @site = Site.new(
15
+ input_dir: 'test/content',
16
+ output_dir: 'test/output',
17
+ site_title: 'Test',
18
+ site_uri: 'http://test.test',
19
+ html_version: :html5,
20
+ )
21
+ @site.make
22
+ # ;;@site.print_tree
23
+ # ;;@site.list
24
+ # ;;binding.pry
25
+ @root = @site.find_resource('/') or raise
26
+ @a = @site.find_resource('/a') or raise
27
+ @b = @site.find_resource('/b') or raise
28
+ @ba = @site.find_resource('/b/ba') or raise
29
+ @bb = @site.find_resource('/b/bb') or raise
30
+ end
31
+
32
+ def test_has_index
33
+ assert { @root }
34
+ end
35
+
36
+ def test_children
37
+ assert { @root.children == [@a, @b] }
38
+ assert { @a.children.empty? }
39
+ end
40
+
41
+ def test_parent
42
+ assert { @a.parent == @root }
43
+ assert { @b.parent == @root }
44
+ assert { @ba.parent == @b }
45
+ assert { @bb.parent == @b }
46
+ end
47
+
48
+ def test_siblings
49
+ assert { @root.siblings.empty? }
50
+ assert { @a.siblings == [@b] }
51
+ assert { @ba.siblings == [@bb] }
52
+ end
53
+
54
+ end
55
+
56
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mill
3
3
  version: !ruby/object:Gem::Version
4
- version: '0.11'
4
+ version: '0.16'
5
5
  platform: ruby
6
6
  authors:
7
7
  - John Labovitz
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-09-28 00:00:00.000000000 Z
11
+ date: 2020-12-31 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: addressable
@@ -16,70 +16,70 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '2.5'
19
+ version: '2.7'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: '2.5'
26
+ version: '2.7'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: image_size
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: '1.5'
33
+ version: '2.1'
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: '1.5'
40
+ version: '2.1'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: kramdown
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
45
  - - "~>"
46
46
  - !ruby/object:Gem::Version
47
- version: '1.16'
47
+ version: '2.3'
48
48
  type: :runtime
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
- version: '1.16'
54
+ version: '2.3'
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: mime-types
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
59
  - - "~>"
60
60
  - !ruby/object:Gem::Version
61
- version: '3.1'
61
+ version: '3.3'
62
62
  type: :runtime
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
66
  - - "~>"
67
67
  - !ruby/object:Gem::Version
68
- version: '3.1'
68
+ version: '3.3'
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: nokogiri
71
71
  requirement: !ruby/object:Gem::Requirement
72
72
  requirements:
73
73
  - - "~>"
74
74
  - !ruby/object:Gem::Version
75
- version: '1.8'
75
+ version: '1.10'
76
76
  type: :runtime
77
77
  prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
80
  - - "~>"
81
81
  - !ruby/object:Gem::Version
82
- version: '1.8'
82
+ version: '1.10'
83
83
  - !ruby/object:Gem::Dependency
84
84
  name: path
85
85
  requirement: !ruby/object:Gem::Requirement
@@ -114,70 +114,140 @@ dependencies:
114
114
  requirements:
115
115
  - - "~>"
116
116
  - !ruby/object:Gem::Version
117
- version: '0.6'
117
+ version: '0.7'
118
118
  type: :runtime
119
119
  prerelease: false
120
120
  version_requirements: !ruby/object:Gem::Requirement
121
121
  requirements:
122
122
  - - "~>"
123
123
  - !ruby/object:Gem::Version
124
- version: '0.6'
124
+ version: '0.7'
125
+ - !ruby/object:Gem::Dependency
126
+ name: rubytree
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - "~>"
130
+ - !ruby/object:Gem::Version
131
+ version: '1.0'
132
+ type: :runtime
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - "~>"
137
+ - !ruby/object:Gem::Version
138
+ version: '1.0'
125
139
  - !ruby/object:Gem::Dependency
126
140
  name: sassc
127
141
  requirement: !ruby/object:Gem::Requirement
128
142
  requirements:
129
143
  - - "~>"
130
144
  - !ruby/object:Gem::Version
131
- version: '2.0'
145
+ version: '2.4'
132
146
  type: :runtime
133
147
  prerelease: false
134
148
  version_requirements: !ruby/object:Gem::Requirement
135
149
  requirements:
136
150
  - - "~>"
137
151
  - !ruby/object:Gem::Version
138
- version: '2.0'
152
+ version: '2.4'
139
153
  - !ruby/object:Gem::Dependency
140
154
  name: web-checker
141
155
  requirement: !ruby/object:Gem::Requirement
142
156
  requirements:
143
157
  - - "~>"
144
158
  - !ruby/object:Gem::Version
145
- version: '0'
159
+ version: '0.4'
146
160
  type: :runtime
147
161
  prerelease: false
148
162
  version_requirements: !ruby/object:Gem::Requirement
149
163
  requirements:
150
164
  - - "~>"
151
165
  - !ruby/object:Gem::Version
152
- version: '0'
166
+ version: '0.4'
167
+ - !ruby/object:Gem::Dependency
168
+ name: bundler
169
+ requirement: !ruby/object:Gem::Requirement
170
+ requirements:
171
+ - - "~>"
172
+ - !ruby/object:Gem::Version
173
+ version: '2.2'
174
+ type: :development
175
+ prerelease: false
176
+ version_requirements: !ruby/object:Gem::Requirement
177
+ requirements:
178
+ - - "~>"
179
+ - !ruby/object:Gem::Version
180
+ version: '2.2'
181
+ - !ruby/object:Gem::Dependency
182
+ name: minitest
183
+ requirement: !ruby/object:Gem::Requirement
184
+ requirements:
185
+ - - "~>"
186
+ - !ruby/object:Gem::Version
187
+ version: '5.14'
188
+ type: :development
189
+ prerelease: false
190
+ version_requirements: !ruby/object:Gem::Requirement
191
+ requirements:
192
+ - - "~>"
193
+ - !ruby/object:Gem::Version
194
+ version: '5.14'
195
+ - !ruby/object:Gem::Dependency
196
+ name: minitest-power_assert
197
+ requirement: !ruby/object:Gem::Requirement
198
+ requirements:
199
+ - - "~>"
200
+ - !ruby/object:Gem::Version
201
+ version: '0.3'
202
+ type: :development
203
+ prerelease: false
204
+ version_requirements: !ruby/object:Gem::Requirement
205
+ requirements:
206
+ - - "~>"
207
+ - !ruby/object:Gem::Version
208
+ version: '0.3'
209
+ - !ruby/object:Gem::Dependency
210
+ name: pry
211
+ requirement: !ruby/object:Gem::Requirement
212
+ requirements:
213
+ - - "~>"
214
+ - !ruby/object:Gem::Version
215
+ version: '0.13'
216
+ type: :development
217
+ prerelease: false
218
+ version_requirements: !ruby/object:Gem::Requirement
219
+ requirements:
220
+ - - "~>"
221
+ - !ruby/object:Gem::Version
222
+ version: '0.13'
153
223
  - !ruby/object:Gem::Dependency
154
224
  name: rake
155
225
  requirement: !ruby/object:Gem::Requirement
156
226
  requirements:
157
227
  - - "~>"
158
228
  - !ruby/object:Gem::Version
159
- version: '0'
229
+ version: '13.0'
160
230
  type: :development
161
231
  prerelease: false
162
232
  version_requirements: !ruby/object:Gem::Requirement
163
233
  requirements:
164
234
  - - "~>"
165
235
  - !ruby/object:Gem::Version
166
- version: '0'
236
+ version: '13.0'
167
237
  - !ruby/object:Gem::Dependency
168
238
  name: rubygems-tasks
169
239
  requirement: !ruby/object:Gem::Requirement
170
240
  requirements:
171
241
  - - "~>"
172
242
  - !ruby/object:Gem::Version
173
- version: '0.0'
243
+ version: '0.2'
174
244
  type: :development
175
245
  prerelease: false
176
246
  version_requirements: !ruby/object:Gem::Requirement
177
247
  requirements:
178
248
  - - "~>"
179
249
  - !ruby/object:Gem::Version
180
- version: '0.0'
250
+ version: '0.2'
181
251
  description: "\n Mill provides a simple but useful static site generator.\n "
182
252
  email: johnl@johnlabovitz.com
183
253
  executables:
@@ -186,6 +256,7 @@ extensions: []
186
256
  extra_rdoc_files: []
187
257
  files:
188
258
  - ".gitignore"
259
+ - Gemfile
189
260
  - LICENSE
190
261
  - README.md
191
262
  - Rakefile
@@ -209,11 +280,17 @@ files:
209
280
  - lib/mill/site.rb
210
281
  - lib/mill/version.rb
211
282
  - mill.gemspec
283
+ - test/content/a.md
284
+ - test/content/b/ba.md
285
+ - test/content/b/bb.md
286
+ - test/content/b/index.md
287
+ - test/content/index.md
288
+ - test/test.rb
212
289
  homepage: http://github.com/jslabovitz/mill
213
290
  licenses:
214
291
  - MIT
215
292
  metadata: {}
216
- post_install_message:
293
+ post_install_message:
217
294
  rdoc_options: []
218
295
  require_paths:
219
296
  - lib
@@ -228,9 +305,14 @@ required_rubygems_version: !ruby/object:Gem::Requirement
228
305
  - !ruby/object:Gem::Version
229
306
  version: '0'
230
307
  requirements: []
231
- rubyforge_project:
232
- rubygems_version: 2.7.7
233
- signing_key:
308
+ rubygems_version: 3.2.3
309
+ signing_key:
234
310
  specification_version: 4
235
311
  summary: A simple but useful static site generator.
236
- test_files: []
312
+ test_files:
313
+ - test/content/a.md
314
+ - test/content/b/ba.md
315
+ - test/content/b/bb.md
316
+ - test/content/b/index.md
317
+ - test/content/index.md
318
+ - test/test.rb