Welcome to mirror list, hosted at ThFree Co, Russian Federation.

generator.rb « changelog « gitlab « lib - gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: a80ca0728f98595b48949653f4d2b570b9a0960f (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})/.freeze

      # 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