Class: Gitlab::Changelog::Generator

Inherits:
Object
  • Object
show all
Defined in:
lib/gitlab/changelog/generator.rb

Overview

Parsing and generating of Markdown changelogs.

Constant Summary collapse

RELEASE_REGEX =

The regex used to parse a release header.

/^##\s+(?<version>#{Gitlab::Regex.unbounded_semver_regex})/.freeze

Instance Method Summary collapse

Constructor Details

#initialize(input = '') ⇒ Generator

The `input` argument must be a `String` containing the existing changelog Markdown. If no changelog exists, this should be an empty `String`.


14
15
16
17
18
19
20
21
22
23
24
25
# File 'lib/gitlab/changelog/generator.rb', line 14

def initialize(input = '')
  @lines = input.lines
  @locations = {}

  @lines.each_with_index do |line, index|
    matches = line.match(RELEASE_REGEX)

    next if !matches || !matches[:version]

    @locations[matches[:version]] = index
  end
end

Instance Method Details

#add(release) ⇒ Object

Generates the Markdown for the given release and returns the new changelog Markdown content.

The `release` argument must be an instance of `Gitlab::Changelog::Release`.


32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
# File 'lib/gitlab/changelog/generator.rb', line 32

def add(release)
  versions = [release.version, *@locations.keys]

  VersionSorter.rsort!(versions)

  new_index = versions.index(release.version)
  new_lines = @lines.dup
  markdown = release.to_markdown

  if (insert_after = versions[new_index + 1])
    line_index = @locations[insert_after]

    new_lines.insert(line_index, markdown)
  else
    # When adding to the end of the changelog, the previous section only
    # has a single newline, resulting in the release section title
    # following it immediately. When this is the case, we insert an extra
    # empty line to keep the changelog readable in its raw form.
    new_lines.push("\n") if versions.length > 1
    new_lines.push(markdown.rstrip)
    new_lines.push("\n")
  end

  new_lines.join
end