blob: 0e546c5eb6010326f0714320d182226a8829e346 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
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
57
58
59
|
# frozen_string_literal: true
module Gitlab
module Changelog
# Parsing and generating of Markdown changelogs.
class Generator
# The regex used to parse a release header.
RELEASE_REGEX =
/^##\s+(?<version>#{Gitlab::Regex.unbounded_semver_regex})/
# The `input` argument must be a `String` containing the existing
# changelog Markdown. If no changelog exists, this should be an empty
# `String`.
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
# 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`.
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
end
end
end
|