philiprehberger-changelog_parser
Parser for Keep a Changelog format with querying and write-back
Requirements
- Ruby >= 3.1
Installation
Add to your Gemfile:
gem "philiprehberger-changelog_parser"Or install directly:
gem install philiprehberger-changelog_parserUsage
require "philiprehberger/changelog_parser"
changelog = Philiprehberger::ChangelogParser.parse('CHANGELOG.md')
changelog.versions # => ['Unreleased', '0.2.0', '0.1.0']
changelog.latest # => VersionEntry for 0.2.0Querying Versions
entry = changelog.version('0.2.0')
entry.date # => '2026-03-20'
entry.categories['Added'] # => ['New feature A', 'New feature B']Adding Entries
changelog.add('Unreleased', 'Added', 'New search feature')
changelog.add('Unreleased', 'Fixed', 'Resolved login bug')Releasing a Version
changelog.release('0.3.0', date: '2026-03-22')
# Moves Unreleased entries to the new versionWriting Back
changelog.write('CHANGELOG.md')
# Or get the markdown string
markdown = changelog.to_markdownJSON Serialization
json = changelog.to_json
# => '{"title":"Changelog","versions":[{"version":"Unreleased","date":null,"categories":{}},...]}'Comparing Versions
require "philiprehberger/changelog_parser"
changelog = Philiprehberger::ChangelogParser.parse("CHANGELOG.md")
# Get all changes between two versions
changes = changelog.diff("0.1.0", "0.3.0")
changes["Added"] # => ["Feature B", "Feature C"]
# Get all changes since a version
recent = changelog.since("0.1.0")
recent["Fixed"] # => ["Bug fix B"]Searching Entries
results = changelog.search("authentication")
results.each do |match|
puts "#{match[:version]} [#{match[:category]}] #{match[:entry]}"
end
# Also accepts regex
changelog.search(/\bbug\b/i)Validation
warnings = changelog.validate
# => ["empty version: 0.2.0", "date out of order: 2026-03-01 before 2026-03-15"]Filtering by Category
added = changelog.filter(category: 'Added')
added.each do |match|
puts "#{match[:version]} (#{match[:date]}): #{match[:entry]}"
endRemoving Entries
changelog.remove('Unreleased', 'Added', 'Obsolete feature')JSON Round-Trip
json = changelog.to_json
restored = Philiprehberger::ChangelogParser.from_json(json)
restored.versions # => same as originalParsing Strings
changelog = Philiprehberger::ChangelogParser.parse(<<~MD)
# Changelog
## [Unreleased]
## [0.1.0] - 2026-03-15
### Added
- Initial release
MDAPI
ChangelogParser
| Method | Description |
|---|---|
.parse(path_or_string) |
Parse a changelog from a file path or string |
.from_json(json_string) |
Deserialize a changelog from a JSON string |
Changelog
| Method | Description |
|---|---|
#versions |
Return all version strings |
#version(v) |
Find a specific version entry |
#unreleased |
Return the Unreleased entry |
#latest |
Return the latest released version |
#add(version, category, entry) |
Add an entry to a version |
#remove(version, category, entry) |
Remove an entry from a version |
#release(version, date:) |
Create a release from Unreleased |
#write(path) |
Write changelog to a file |
#diff(from, to) |
Returns merged entries between two versions |
#since(version) |
Returns merged entries newer than a version |
#filter(category:) |
Return all entries from a specific category across versions |
#search(query) |
Search entries by keyword or regex |
#validate |
Check for common issues (duplicates, date order, empty versions) |
#to_json |
Serialize as JSON string |
#to_markdown |
Render as markdown string |
VersionEntry
| Method | Description |
|---|---|
#version |
The version string |
#date |
The release date |
#categories |
Hash of category to entries |
#empty? |
True if version has no entries |
Development
bundle install
bundle exec rspec
bundle exec rubocopSupport
If you find this project useful: