History

Store docs' metadata in meta.json files

To avoid relying on the filesystem for modified times.

Thibaut Courouble committed 8 years ago

Commit 0725a691 parent ed12d864 files · +48 −60Browse files

Unified · Split

4 files
  1. lib/docs/core/doc.rb +14 −0
  2. lib/docs/core/manifest.rb +3 −21
  3. test/lib/docs/core/doc_test.rb +21 −0
  4. test/lib/docs/core/manifest_test.rb +10 −39
lib/docs/core/doc.rb+14−0
@@ -2,6 +2,7 @@ module Docs · 1 unmodified line
22 class Doc
33 INDEX_FILENAME = 'index.json'
44 DB_FILENAME = 'db.json'
5+ META_FILENAME = 'meta.json'
56
67 class << self
78 include Instrumentable
@@ -73,6 +74,10 @@ module Docs · 65 unmodified lines
7374 File.join path, DB_FILENAME
7475 end
7576
77+ def meta_path
78+ File.join path, META_FILENAME
79+ end
80+
7681 def as_json
7782 json = { name: name, slug: slug, type: type }
7883 json[:links] = links if links.present?
@@ -107,6 +112,7 @@ module Docs · 28 unmodified lines
107112 if index.present?
108113 store_index(store, INDEX_FILENAME, index)
109114 store_index(store, DB_FILENAME, pages)
115+ store_meta(store)
110116 true
111117 else
112118 false
@@ -131,8 +137,16 @@ module Docs · 18 unmodified lines
131137 instrument "#{filename.remove('.json')}.doc", before: old_json, after: new_json
132138 store.write(filename, new_json)
133139 end
140+
141+ def store_meta(store)
142+ json = as_json
143+ json[:mtime] = Time.now.to_i
144+ json[:db_size] = store.size(DB_FILENAME)
145+ store.write(META_FILENAME, json.to_json)
146+ end
134147 end
135148
149+
136150 def initialize
137151 raise NotImplementedError, "#{self.class} is an abstract class and cannot be instantiated." if self.class.abstract
138152 end
lib/docs/core/manifest.rb+3−21
@@ -14,32 +14,14 @@ module Docs · 13 unmodified lines
1414 end
1515
1616 def as_json
17− indexed_docs.map do |doc|
18− json = doc.as_json
19− json[:mtime] = doc_mtime(doc)
20− json[:db_size] = doc_db_size(doc)
21− json
17+ @docs.each_with_object [] do |doc, result|
18+ next unless @store.exist?(doc.meta_path)
19+ result << JSON.parse(@store.read(doc.meta_path))
2220 end
2321 end
2422
2523 def to_json
2624 JSON.generate(as_json)
2725 end
28−
29− private
30−
31− def indexed_docs
32− @docs.select do |doc|
33− @store.exist?(doc.index_path) && @store.exist?(doc.db_path)
34− end
35− end
36−
37− def doc_mtime(doc)
38− [@store.mtime(doc.index_path).to_i, @store.mtime(doc.db_path).to_i].max
39− end
40−
41− def doc_db_size(doc)
42− @store.size(doc.db_path)
43− end
4426 end
4527 end
test/lib/docs/core/doc_test.rb+21−0
@@ -131,6 +131,13 @@ class DocsDocTest < MiniTest::Spec · 130 unmodified lines
131131 end
132132 end
133133
134+ describe ".meta_path" do
135+ it "returns .path + ::META_FILENAME" do
136+ stub(doc).path { 'path' }
137+ assert_equal File.join('path', Docs::Doc::META_FILENAME), doc.meta_path
138+ end
139+ end
140+
134141 describe ".new" do
135142 it "raises an error when .abstract is true" do
136143 doc.abstract = true
@@ -265,12 +272,14 @@ class DocsDocTest < MiniTest::Spec · 128 unmodified lines
265272 mock(store).write(page[:store_path], page[:output])
266273 mock(store).write('index.json', anything)
267274 mock(store).write('db.json', anything)
275+ mock(store).write('meta.json', anything)
268276 doc.store_pages(store)
269277 end
270278
271279 it "stores an index that contains all the pages' entries" do
272280 stub(store).write(page[:store_path], page[:output])
273281 stub(store).write('db.json', anything)
282+ stub(store).write('meta.json', anything)
274283 mock(store).write('index.json', anything) do |path, json|
275284 json = JSON.parse(json)
276285 assert_equal pages.length, json['entries'].length
@@ -282,6 +291,7 @@ class DocsDocTest < MiniTest::Spec · 5 unmodified lines
282291 it "stores a db that contains all the pages, indexed by path" do
283292 stub(store).write(page[:store_path], page[:output])
284293 stub(store).write('index.json', anything)
294+ stub(store).write('meta.json', anything)
285295 mock(store).write('db.json', anything) do |path, json|
286296 json = JSON.parse(json)
287297 assert_equal page[:output], json[page[:path]]
@@ -289,6 +299,17 @@ class DocsDocTest < MiniTest::Spec · 1 unmodified line
289299 doc.store_pages(store)
290300 end
291301
302+ it "stores a meta file that contains the doc's metadata" do
303+ stub(store).write(page[:store_path], page[:output])
304+ stub(store).write('index.json', anything)
305+ stub(store).write('db.json', anything)
306+ mock(store).write('meta.json', anything) do |path, json|
307+ json = JSON.parse(json)
308+ assert_equal %w(name slug type mtime db_size).sort, json.keys.sort
309+ end
310+ doc.store_pages(store)
311+ end
312+
292313 it "replaces the .path directory before storing the files" do
293314 stub(doc).path { 'path' }
294315 stub(store).write { assert false }
test/lib/docs/core/manifest_test.rb+10−39
@@ -41,17 +41,12 @@ class ManifestTest < MiniTest::Spec · 40 unmodified lines
4141 end
4242
4343 describe "#as_json" do
44− let :index_path do
45− 'index_path'
46− end
47−
48− let :db_path do
49− 'db_path'
44+ let :meta_path do
45+ 'meta_path'
5046 end
5147
5248 before do
53− stub(doc).index_path { index_path }
54− stub(doc).db_path { db_path }
49+ stub(doc).meta_path { meta_path }
5550 end
5651
5752 it "returns an array" do
@@ -59,46 +54,22 @@ class ManifestTest < MiniTest::Spec · 1 unmodified line
5954 assert_instance_of Array, manifest.as_json
6055 end
6156
62− context "when the doc has an index and a db" do
57+ context "when the doc has a meta file" do
6358 before do
64− stub(store).exist?(index_path) { true }
65− stub(store).exist?(db_path) { true }
59+ stub(store).exist?(meta_path) { true }
60+ stub(store).read(meta_path) { '{"name":"Test"}' }
6661 end
6762
68− it "includes the doc's JSON representation" do
63+ it "includes the doc's meta representation" do
6964 json = manifest.as_json
7065 assert_equal 1, json.length
71− assert_empty doc.as_json.keys - json.first.keys
72− end
73−
74− it "adds an :mtime attribute with the greatest of the index and db files' mtime" do
75− mtime_index = Time.now - 1
76− mtime_db = Time.now - 2
77− stub(store).mtime(index_path) { mtime_index }
78− stub(store).mtime(db_path) { mtime_db }
79− assert_equal mtime_index.to_i, manifest.as_json.first[:mtime]
80− mtime_index, mtime_db = mtime_db, mtime_index
81− assert_equal mtime_db.to_i, manifest.as_json.first[:mtime]
82− end
83−
84− it "adds a :db_size attribute" do
85− stub(store).size(db_path) { 42 }
86− assert_equal 42, manifest.as_json.first[:db_size]
87− end
88− end
89−
90− context "when the doc doesn't have an index" do
91− it "doesn't include the doc" do
92− stub(store).exist?(db_path) { true }
93− stub(store).exist?(index_path) { false }
94− assert_empty manifest.as_json
66+ assert_equal 'Test', json[0]['name']
9567 end
9668 end
9769
98− context "when the doc doesn't have a db" do
70+ context "when the doc doesn't have a meta file" do
9971 it "doesn't include the doc" do
100− stub(store).exist?(index_path) { true }
101− stub(store).exist?(db_path) { false }
72+ stub(store).exist?(meta_path) { false }
10273 assert_empty manifest.as_json
10374 end
10475 end