class Keepachangelog::YamlParser

Parser for YAML content

The YAML files describing the Changelog are expected to be in a folder structure where each version is its own folder and each Merge Request or Pull Request is in its own YAML-file.

   changelog
   ├── 0.1.0
   │   └── 1-first-merge-request.yaml
   ├── 0.2.0
   │   └── 3-another-cool-mr.yaml
   ├── 0.3.0
   │   ├── 8-fixing-some-stuff.yaml
   │   └── 9-add-new-feature.yaml
   └── unreleased
       └── 11-minor-patch.yaml

Each YAML file is expected to be in the following format:

---
title: The ability to perform Foo while Bar is active
merge_request: 11
issue: 42
author: "@chbr"
type: New

Public Class Methods

load(path = nil) click to toggle source

Parse a folder with YAML files

# File lib/keepachangelog/parser/yaml.rb, line 42
def self.load(path = nil)
  path ||= 'changelog'
  p = new
  p.load(path)
  p
end
parse(content, version = 'unreleased') click to toggle source

Parse raw yaml content of a single file

# File lib/keepachangelog/parser/yaml.rb, line 37
def self.parse(content, version = 'unreleased')
  new.parse(content, version)
end

Public Instance Methods

load(path = nil) click to toggle source

Parse a folder with YAML files

# File lib/keepachangelog/parser/yaml.rb, line 58
def load(path = nil)
  path ||= 'changelog'
  read_meta("#{path}/meta.yaml")
  Dir.glob("#{path}/*").each { |f| parse_version(f) }
end
parse(content, version) click to toggle source

Parse raw yaml content of a single file

# File lib/keepachangelog/parser/yaml.rb, line 50
def parse(content, version)
  initialize_version version
  yaml = YAML.safe_load content
  return {} unless yaml
  add_change yaml, version
end

Private Instance Methods

add_change(yaml, version) click to toggle source
# File lib/keepachangelog/parser/yaml.rb, line 77
def add_change(yaml, version)
  changes = parsed_content['versions'][version]['changes']
  changes[yaml['type']] = (changes[yaml['type']] || []) +
                          [generate_line(yaml)]
  parsed_content
end
generate_line(yaml) click to toggle source
# File lib/keepachangelog/parser/yaml.rb, line 97
def generate_line(yaml)
  line = yaml['title']
  line += '.' unless line =~ /\p{Punct}$/
  line += " (!#{yaml['merge_request']})" if yaml['merge_request']
  line += " (##{yaml['issue']})" if yaml['issue']
  line += " (#{yaml['author']})" if yaml['author']
  line
end
initialize_version(version) click to toggle source
# File lib/keepachangelog/parser/yaml.rb, line 106
def initialize_version(version)
  return if parsed_content['versions'][version]
  parsed_content['versions'][version] = {
    'changes' => {},
    'date' => version_date(version)
  }
end
parse_file(filename, version) click to toggle source
# File lib/keepachangelog/parser/yaml.rb, line 93
def parse_file(filename, version)
  parse File.open(filename, &:read), version
end
parse_version(folder) click to toggle source
# File lib/keepachangelog/parser/yaml.rb, line 84
def parse_version(folder)
  version = File.basename(folder)
  return if version == 'meta.yaml'
  initialize_version version
  files = Dir.glob("#{folder}/**/*.yaml") +
          Dir.glob("#{folder}/**/*.yml")
  files.sort.each { |f| parse_file(f, version) }
end
read_meta(path) click to toggle source
# File lib/keepachangelog/parser/yaml.rb, line 66
def read_meta(path)
  return unless File.exist?(path)
  content = File.open(path, &:read)
  yaml = YAML.safe_load content
  return unless yaml
  parsed_content['title'] = yaml['title']
  parsed_content['url'] = yaml['url']
  parsed_content['intro'] = yaml['intro']
  parsed_content['section_order'] = yaml['section_order']
end
version_date(version) click to toggle source
# File lib/keepachangelog/parser/yaml.rb, line 114
def version_date(version)
  date = `git log -1 --format=%aI #{version} 2>/dev/null`.strip
  Time.parse(date).strftime('%Y-%m-%d')
rescue StandardError
  Gem::Version.correct?(version) ? Time.now.strftime('%Y-%m-%d') : nil
end