mirror of
https://github.com/freeCodeCamp/devdocs
synced 2024-11-16 19:48:10 +01:00
Store docs' metadata in meta.json files
To avoid relying on the filesystem for modified times.
This commit is contained in:
parent
ed12d86e56
commit
0725a69af5
4 changed files with 48 additions and 60 deletions
|
@ -2,6 +2,7 @@ module Docs
|
|||
class Doc
|
||||
INDEX_FILENAME = 'index.json'
|
||||
DB_FILENAME = 'db.json'
|
||||
META_FILENAME = 'meta.json'
|
||||
|
||||
class << self
|
||||
include Instrumentable
|
||||
|
@ -73,6 +74,10 @@ module Docs
|
|||
File.join path, DB_FILENAME
|
||||
end
|
||||
|
||||
def meta_path
|
||||
File.join path, META_FILENAME
|
||||
end
|
||||
|
||||
def as_json
|
||||
json = { name: name, slug: slug, type: type }
|
||||
json[:links] = links if links.present?
|
||||
|
@ -107,6 +112,7 @@ module Docs
|
|||
if index.present?
|
||||
store_index(store, INDEX_FILENAME, index)
|
||||
store_index(store, DB_FILENAME, pages)
|
||||
store_meta(store)
|
||||
true
|
||||
else
|
||||
false
|
||||
|
@ -131,8 +137,16 @@ module Docs
|
|||
instrument "#{filename.remove('.json')}.doc", before: old_json, after: new_json
|
||||
store.write(filename, new_json)
|
||||
end
|
||||
|
||||
def store_meta(store)
|
||||
json = as_json
|
||||
json[:mtime] = Time.now.to_i
|
||||
json[:db_size] = store.size(DB_FILENAME)
|
||||
store.write(META_FILENAME, json.to_json)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
def initialize
|
||||
raise NotImplementedError, "#{self.class} is an abstract class and cannot be instantiated." if self.class.abstract
|
||||
end
|
||||
|
|
|
@ -14,32 +14,14 @@ module Docs
|
|||
end
|
||||
|
||||
def as_json
|
||||
indexed_docs.map do |doc|
|
||||
json = doc.as_json
|
||||
json[:mtime] = doc_mtime(doc)
|
||||
json[:db_size] = doc_db_size(doc)
|
||||
json
|
||||
@docs.each_with_object [] do |doc, result|
|
||||
next unless @store.exist?(doc.meta_path)
|
||||
result << JSON.parse(@store.read(doc.meta_path))
|
||||
end
|
||||
end
|
||||
|
||||
def to_json
|
||||
JSON.generate(as_json)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def indexed_docs
|
||||
@docs.select do |doc|
|
||||
@store.exist?(doc.index_path) && @store.exist?(doc.db_path)
|
||||
end
|
||||
end
|
||||
|
||||
def doc_mtime(doc)
|
||||
[@store.mtime(doc.index_path).to_i, @store.mtime(doc.db_path).to_i].max
|
||||
end
|
||||
|
||||
def doc_db_size(doc)
|
||||
@store.size(doc.db_path)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -131,6 +131,13 @@ class DocsDocTest < MiniTest::Spec
|
|||
end
|
||||
end
|
||||
|
||||
describe ".meta_path" do
|
||||
it "returns .path + ::META_FILENAME" do
|
||||
stub(doc).path { 'path' }
|
||||
assert_equal File.join('path', Docs::Doc::META_FILENAME), doc.meta_path
|
||||
end
|
||||
end
|
||||
|
||||
describe ".new" do
|
||||
it "raises an error when .abstract is true" do
|
||||
doc.abstract = true
|
||||
|
@ -265,12 +272,14 @@ class DocsDocTest < MiniTest::Spec
|
|||
mock(store).write(page[:store_path], page[:output])
|
||||
mock(store).write('index.json', anything)
|
||||
mock(store).write('db.json', anything)
|
||||
mock(store).write('meta.json', anything)
|
||||
doc.store_pages(store)
|
||||
end
|
||||
|
||||
it "stores an index that contains all the pages' entries" do
|
||||
stub(store).write(page[:store_path], page[:output])
|
||||
stub(store).write('db.json', anything)
|
||||
stub(store).write('meta.json', anything)
|
||||
mock(store).write('index.json', anything) do |path, json|
|
||||
json = JSON.parse(json)
|
||||
assert_equal pages.length, json['entries'].length
|
||||
|
@ -282,6 +291,7 @@ class DocsDocTest < MiniTest::Spec
|
|||
it "stores a db that contains all the pages, indexed by path" do
|
||||
stub(store).write(page[:store_path], page[:output])
|
||||
stub(store).write('index.json', anything)
|
||||
stub(store).write('meta.json', anything)
|
||||
mock(store).write('db.json', anything) do |path, json|
|
||||
json = JSON.parse(json)
|
||||
assert_equal page[:output], json[page[:path]]
|
||||
|
@ -289,6 +299,17 @@ class DocsDocTest < MiniTest::Spec
|
|||
doc.store_pages(store)
|
||||
end
|
||||
|
||||
it "stores a meta file that contains the doc's metadata" do
|
||||
stub(store).write(page[:store_path], page[:output])
|
||||
stub(store).write('index.json', anything)
|
||||
stub(store).write('db.json', anything)
|
||||
mock(store).write('meta.json', anything) do |path, json|
|
||||
json = JSON.parse(json)
|
||||
assert_equal %w(name slug type mtime db_size).sort, json.keys.sort
|
||||
end
|
||||
doc.store_pages(store)
|
||||
end
|
||||
|
||||
it "replaces the .path directory before storing the files" do
|
||||
stub(doc).path { 'path' }
|
||||
stub(store).write { assert false }
|
||||
|
|
|
@ -41,17 +41,12 @@ class ManifestTest < MiniTest::Spec
|
|||
end
|
||||
|
||||
describe "#as_json" do
|
||||
let :index_path do
|
||||
'index_path'
|
||||
end
|
||||
|
||||
let :db_path do
|
||||
'db_path'
|
||||
let :meta_path do
|
||||
'meta_path'
|
||||
end
|
||||
|
||||
before do
|
||||
stub(doc).index_path { index_path }
|
||||
stub(doc).db_path { db_path }
|
||||
stub(doc).meta_path { meta_path }
|
||||
end
|
||||
|
||||
it "returns an array" do
|
||||
|
@ -59,46 +54,22 @@ class ManifestTest < MiniTest::Spec
|
|||
assert_instance_of Array, manifest.as_json
|
||||
end
|
||||
|
||||
context "when the doc has an index and a db" do
|
||||
context "when the doc has a meta file" do
|
||||
before do
|
||||
stub(store).exist?(index_path) { true }
|
||||
stub(store).exist?(db_path) { true }
|
||||
stub(store).exist?(meta_path) { true }
|
||||
stub(store).read(meta_path) { '{"name":"Test"}' }
|
||||
end
|
||||
|
||||
it "includes the doc's JSON representation" do
|
||||
it "includes the doc's meta representation" do
|
||||
json = manifest.as_json
|
||||
assert_equal 1, json.length
|
||||
assert_empty doc.as_json.keys - json.first.keys
|
||||
end
|
||||
|
||||
it "adds an :mtime attribute with the greatest of the index and db files' mtime" do
|
||||
mtime_index = Time.now - 1
|
||||
mtime_db = Time.now - 2
|
||||
stub(store).mtime(index_path) { mtime_index }
|
||||
stub(store).mtime(db_path) { mtime_db }
|
||||
assert_equal mtime_index.to_i, manifest.as_json.first[:mtime]
|
||||
mtime_index, mtime_db = mtime_db, mtime_index
|
||||
assert_equal mtime_db.to_i, manifest.as_json.first[:mtime]
|
||||
end
|
||||
|
||||
it "adds a :db_size attribute" do
|
||||
stub(store).size(db_path) { 42 }
|
||||
assert_equal 42, manifest.as_json.first[:db_size]
|
||||
assert_equal 'Test', json[0]['name']
|
||||
end
|
||||
end
|
||||
|
||||
context "when the doc doesn't have an index" do
|
||||
context "when the doc doesn't have a meta file" do
|
||||
it "doesn't include the doc" do
|
||||
stub(store).exist?(db_path) { true }
|
||||
stub(store).exist?(index_path) { false }
|
||||
assert_empty manifest.as_json
|
||||
end
|
||||
end
|
||||
|
||||
context "when the doc doesn't have a db" do
|
||||
it "doesn't include the doc" do
|
||||
stub(store).exist?(index_path) { true }
|
||||
stub(store).exist?(db_path) { false }
|
||||
stub(store).exist?(meta_path) { false }
|
||||
assert_empty manifest.as_json
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in a new issue