Class: GemHadar::ChangelogGenerator

Inherits:
Object
  • Object
show all
Includes:
PromptTemplate, Utils
Defined in:
lib/gem_hadar/changelog_generator.rb

Overview

A class that generates changelog entries by analyzing Git history and AI processing

The ChangelogGenerator class provides functionality to create structured changelog entries based on Git commit history. It can generate individual changelog entries for specific version ranges or create complete changelogs including all version entries. The class integrates with AI models to produce human-readable changelog content by processing Git logs through configured prompts and models.

Examples:

Generating a changelog entry for a version range

generator = GemHadar::ChangelogGenerator.new
entry = generator.generate('v1.0.0', 'v1.2.0')

Generating a complete changelog

generator = GemHadar::ChangelogGenerator.new
generator.generate_full(STDOUT)

Adding changelog entries to an existing file

GemHadar::ChangelogGenerator.add_to_file('CHANGELOG.md')

Instance Method Summary collapse

Methods included from PromptTemplate

#default_changelog_prompt, #default_changelog_system_prompt, #default_git_release_prompt, #default_git_release_system_prompt, #default_version_bump_prompt, #default_version_bump_system_prompt

Methods included from Utils

#ask?, #xdg_config, #xdg_config_dir, #xdg_config_filename, #xdg_config_home

Constructor Details

#initialize(gem_hadar) ⇒ ChangelogGenerator

Returns a new instance of ChangelogGenerator.



29
30
31
# File 'lib/gem_hadar/changelog_generator.rb', line 29

def initialize(gem_hadar)
  @gem_hadar = gem_hadar
end

Instance Method Details

#add_to_file(filename) ⇒ Object

The add_to_file method appends new changelog entries to an existing changelog file

This method identifies the highest version already present in the changelog file, retrieves all subsequent version tags from the Git repository, and generates changelog entries for each consecutive pair of versions. It then inserts these entries into the file after the existing content, maintaining the chronological order of changes.

Parameters:

  • filename (String)

    the path to the changelog file to which entries will be added



153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
# File 'lib/gem_hadar/changelog_generator.rb', line 153

def add_to_file(filename)
  highest_version = find_highest_version(filename)

  if highest_version
    versions = read_versions
    versions = versions.drop_while { |t| t < highest_version }
  else
    raise ArgumentError, "Could not find highest version in #{filename.inspect}"
  end

  return if versions.size < 2

  changelog = generate_changelog(versions)
  return if changelog.empty?
  inject_into_filename(filename, changelog)
end

#generate(from, to = 'HEAD') ⇒ String

The generate method creates a changelog entry by analyzing Git history and AI processing.

This method retrieves the Git log for a specified range of commits, processes the log through an AI model using configured prompts, and formats the result into a markdown changelog entry with a date header.

Parameters:

  • from (String)

    the starting version or commit reference for the Git log range

  • to (String) (defaults to: 'HEAD')

    the ending version or commit reference for the Git log range, defaults to ‘HEAD’

Returns:

  • (String)

    a formatted markdown changelog entry including date and AI-generated content

  • (String)

    a minimal changelog entry with just date and version when no changes are found



49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
# File 'lib/gem_hadar/changelog_generator.rb', line 49

def generate(from, to = 'HEAD')
  from = GemHadar::VersionSpec[from]
  to   = GemHadar::VersionSpec[to]

  range = "#{from.tag}..#{to.tag}"

  log = `git log #{range}`
  $?.success? or raise "Failed to get git log for range #{range}"

  date = `git log -n1 --pretty='format:%cd' --date=short #{to.tag.inspect}`.chomp

  if log.strip.empty?
    return "\n## #{date} #{to.without_prefix.to_s}\n"
  end

  system          = xdg_config('gem_hadar', 'changelog_system_prompt.txt', default_changelog_system_prompt)
  prompt_template = xdg_config('gem_hadar', 'changelog_prompt.txt', default_changelog_prompt)
  prompt = prompt_template % { log_diff: log }

  response = ollama_generate(system:, prompt:)

  changes = response.gsub(/\t/, '  ')

  return "\n## #{date} #{to.tag}\n\n#{changes}\n"
end

#generate_full(output) ⇒ String

The generate_full method creates a complete changelog by processing all version tags in the repository and generating entries for each consecutive pair of versions

This method retrieves all semantic version tags from the Git repository, sorts them, and generates changelog entries for each pair of consecutive versions. It also adds an initial entry for the first version with a “Start” marker

Parameters:

  • output (IO)

    the output stream to which the complete changelog will be written

Returns:

  • (String)

    a complete changelog including all version entries and a header

Raises:

  • (RuntimeError)

    if no version tags are found in the repository



124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
# File 'lib/gem_hadar/changelog_generator.rb', line 124

def generate_full(output)
  versions = read_versions

  unless versions.any?
    raise "No version tags found in repository"
  end

  first_version = versions.first
  date          = `git log -n1 --pretty='format:%cd' --date=short #{first_version.tag.to_s}`.chomp
  changelog     = ["\n## #{date} #{first_version.tag.to_s}\n\n* Start\n"]

  changelog = generate_changelog(versions, changelog:)

  changelog << "# Changes\n"

  output << changelog.join("")
end

#generate_range(output, from, to) ⇒ Object

The generate_range method creates a changelog for a specific version range by processing Git log differences and AI-generated content

This method retrieves version tags within a specified range, filters them based on the provided version boundaries, generates changelog entries for each version in the range, and writes the complete changelog to the provided output stream

Parameters:

  • output (IO)

    the output stream to which the changelog will be written

  • from (String)

    the starting version or commit reference for the range

  • to (String)

    the ending version or commit reference for the range, defaults to ‘HEAD’



89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
# File 'lib/gem_hadar/changelog_generator.rb', line 89

def generate_range(output, from, to)
  from = GemHadar::VersionSpec[from]
  to   = GemHadar::VersionSpec[to]

  versions = read_versions

  unless versions.any?
    raise "No version tags found in repository"
  end

  versions = versions.select do |v|
    v >= from && v <= to
  end

  changelog = generate_changelog(versions)

  output << changelog.join("")
end