cc-os/plugins/os-adr/lib/adr/repository.rb

56 lines
1.4 KiB
Ruby

module Adr
# The docs/adr/ directory of one project. Scans files, derives the next ID
# from directory contents (never the index), reads and writes records.
class Repository
INDEX_FILENAME = "README.md"
Entry = Struct.new(:path, :record)
def initialize(root:)
@root = root
end
attr_reader :root
def dir = File.join(root, "docs", "adr")
def index_path = File.join(dir, INDEX_FILENAME)
def exists?
Dir.exist?(dir) && File.exist?(index_path)
end
def adr_paths
Dir.glob(File.join(dir, "[0-9][0-9][0-9][0-9]-*.md")).sort
end
# Only files in the os-adr format count as entries; legacy frontmatter-less
# files sharing docs/adr/ (pre-migration sources) are skipped, not errors.
def entries
adr_paths.filter_map do |path|
Entry.new(path, Record.parse(File.read(path)))
rescue Record::ParseError, Psych::SyntaxError
nil
end
end
def next_id
max = adr_paths.map { |path| File.basename(path)[0, 4].to_i }.max || 0
format("%04d", max + 1)
end
def find(id)
entries.find { |entry| entry.record.id == id }
end
def write(record)
path = File.join(dir, "#{record.id}-#{Adr.slugify(record.title)}.md")
File.write(path, record.to_markdown)
path
end
def write_entry(entry)
File.write(entry.path, entry.record.to_markdown)
end
end
end