changelog

package module
v0.2.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 4, 2026 License: MIT Imports: 12 Imported by: 1

README

changelog

A Go library for parsing changelog files into structured entries. Automatic detection supports Keep a Changelog, markdown headers, setext/underline headings, and common single-line version headers.

Port of the Ruby changelog-parser gem.

Installation

go get github.com/git-pkgs/changelog

Usage

Parse a string
p := changelog.Parse(content)

for _, v := range p.Versions() {
    entry, _ := p.Entry(v)
    fmt.Printf("%s (%v): %s\n", v, entry.Date, entry.Content)
}
Parse a file
p, err := changelog.ParseFile("CHANGELOG.md")
Find and parse a changelog in a directory
p, err := changelog.FindAndParse(".")

Searches for common changelog filenames (CHANGELOG.md, NEWS, CHANGES, HISTORY, etc.) and parses the first match.

Specify format explicitly
p := changelog.ParseWithFormat(content, changelog.FormatKeepAChangelog)
p := changelog.ParseWithFormat(content, changelog.FormatMarkdown)
p := changelog.ParseWithFormat(content, changelog.FormatUnderline)
Custom regex pattern
pattern := regexp.MustCompile(`^Version ([\d.]+) released (\d{4}-\d{2}-\d{2})`)
p := changelog.ParseWithPattern(content, pattern)

The first capture group is the version string. An optional second capture group is parsed as a date (YYYY-MM-DD).

Get versions in a range
for _, v := range p.VersionsBetween("1.0.0", "2.0.0") {
    entry, _ := p.Entry(v)
    fmt.Printf("%s: %s\n", v, entry.Content)
}

VersionsBetween returns valid versions greater than the first bound and less than or equal to the second, newest first. An empty bound leaves that side open.

Get content between versions
content, ok := p.Between("1.0.0", "2.0.0")
Fetch and parse from a repository URL
p, err := changelog.FetchAndParse(ctx, "https://github.com/owner/repo", "CHANGELOG.md")

Constructs a raw content URL (GitHub and GitLab are supported), fetches the file, and parses it.

You can also build the raw URL yourself:

url, err := changelog.RawContentURL("https://github.com/owner/repo", "CHANGELOG.md")
// "https://raw.githubusercontent.com/owner/repo/HEAD/CHANGELOG.md"
Find line number for a version
line := p.LineForVersion("1.0.0") // 0-based, -1 if not found

Supported formats

Keep a Changelog (## [1.0.0] - 2024-01-15):

## [Unreleased]

## [1.1.0] - 2024-03-15
### Added
- New feature

## [1.0.0] - 2024-01-15
- Initial release

Markdown headers (## 1.0.0 (2024-01-15) or ### v1.0.0):

## 2.0.0 (2024-03-01)
- Breaking changes

## 1.5.0
- New features

Setext/underline (version with === or --- underline):

3.0.0
=====
Major release.

2.1.0
-----
Minor release.

License

MIT

Documentation

Overview

Package changelog parses changelog files into structured entries.

It supports Keep a Changelog (## [version] - date), markdown headers (## version or ### version), setext/underline style (version\n=====), and common single-line version headers. Format detection is automatic by default.

Basic usage:

p := changelog.Parse(content)
for _, v := range p.Versions() {
    entry, _ := p.Entry(v)
    fmt.Printf("%s: %s\n", v, entry.Content)
}

Parse a file:

p, err := changelog.ParseFile("CHANGELOG.md")

Find and parse a changelog in a directory:

p, err := changelog.FindAndParse(".")

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func FindChangelog

func FindChangelog(directory string) (string, error)

FindChangelog locates a changelog file in the given directory. Returns the path to the changelog file, or empty string if not found.

func RawContentURL added in v0.1.1

func RawContentURL(repoURL, filename string) (string, error)

RawContentURL constructs a URL that serves the raw content of a file in a repository. Supports GitHub and GitLab. The repoURL should be the repository's web URL (e.g. "https://github.com/owner/repo"). Trailing ".git" suffixes and slashes are stripped automatically.

Types

type Entry

type Entry struct {
	Date    *time.Time
	Content string
}

Entry holds the parsed data for a single changelog version.

type Format

type Format int

Format represents a changelog file format.

const (
	FormatAuto           Format = iota // Auto-detect format
	FormatKeepAChangelog               // ## [version] - date
	FormatMarkdown                     // ## version (date)
	FormatUnderline                    // version\n=====
)

type Parser

type Parser struct {
	// contains filtered or unexported fields
}

Parser holds the parsed changelog data and provides access methods.

func FetchAndParse added in v0.1.1

func FetchAndParse(ctx context.Context, repoURL, filename string) (*Parser, error)

FetchAndParse fetches a changelog from a repository and parses it. It constructs the raw content URL from the repository URL and changelog filename, fetches the content over HTTP, and returns a Parser.

func FindAndParse

func FindAndParse(directory string) (*Parser, error)

FindAndParse locates a changelog file in the directory and parses it.

func Parse

func Parse(content string) *Parser

Parse creates a parser with automatic format detection.

func ParseFile

func ParseFile(path string) (*Parser, error)

ParseFile reads and parses a changelog file.

func ParseWithFormat

func ParseWithFormat(content string, format Format) *Parser

ParseWithFormat creates a parser using the specified format.

func ParseWithPattern

func ParseWithPattern(content string, pattern *regexp.Regexp) *Parser

ParseWithPattern creates a parser using a custom regex pattern. The pattern must have at least one capture group for the version string. An optional second capture group captures the date (YYYY-MM-DD). The (?m) flag is automatically added if not already present, so that ^ and $ match line boundaries.

func (*Parser) Between

func (p *Parser) Between(oldVersion, newVersion string) (string, bool)

Between returns the content between two version headers. Either version can be empty to indicate the start or end of the changelog. Non-empty bounds must match versions extracted with the selected format. A leading "v" or "V" prefix is ignored when matching bounds. Returns the content and true if found, or empty string and false if not.

func (*Parser) Entries

func (p *Parser) Entries() map[string]Entry

Entries returns all entries as a map. Note that Go maps do not preserve insertion order; use Versions() + Entry() if order matters.

func (*Parser) Entry

func (p *Parser) Entry(version string) (Entry, bool)

Entry returns the entry for a specific version.

func (*Parser) LineForVersion

func (p *Parser) LineForVersion(version string) int

LineForVersion returns the 0-based line number for an extracted version header, or -1 if not found. Strips a leading "v" prefix for matching.

func (*Parser) Versions

func (p *Parser) Versions() []string

Versions returns the version strings in the order they appear in the changelog.

func (*Parser) VersionsBetween added in v0.2.0

func (p *Parser) VersionsBetween(from, to string) []string

VersionsBetween returns valid version strings greater than from and less than or equal to to, newest first. An empty bound leaves that side open.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL