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

release.rb « changelog « gitlab « lib - gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: f782197cc8e2958ced271f5c11fe8a41c1d2131d (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
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
# frozen_string_literal: true

module Gitlab
  module Changelog
    # A release to add to a changelog.
    class Release
      attr_reader :version

      def initialize(version:, date:, config:)
        @version = version
        @date = date
        @config = config
        @entries = Hash.new { |h, k| h[k] = [] }

        # This ensures that entries are presented in the same order as the
        # categories Hash in the user's configuration.
        @config.categories.values.each do |category|
          @entries[category] = []
        end
      end

      def add_entry(
        title:,
        commit:,
        category:,
        author: nil,
        merge_request: nil
      )
        # When changing these fields, keep in mind that this needs to be
        # backwards compatible. For example, you can't just remove a field as
        # this will break the changelog generation process for existing users.
        entry = {
          'title' => title,
          'commit' => {
            'reference' => commit.to_reference(full: true),
            'trailers' => commit.trailers
          }
        }

        if author
          entry['author'] = {
            'reference' => author.to_reference(full: true),
            'contributor' => @config.contributor?(author)
          }
          entry['author']['credit'] = entry['author']['contributor'] || @config.always_credit_author?(author)
        end

        if merge_request
          entry['merge_request'] = {
            'reference' => merge_request.to_reference(full: true)
          }
        end

        @entries[@config.category(category)] << entry
      end

      def to_markdown
        state = TemplateParser::EvalState.new
        data = { 'categories' => entries_for_template }

        # While not critical, we would like release sections to be separated by
        # an empty line in the changelog; ensuring it's readable even in its
        # raw form.
        #
        # Since it can be a bit tricky to get this right in a template, we
        # enforce an empty line separator ourselves.
        markdown =
          begin
            @config.template.evaluate(state, data).strip
          rescue TemplateParser::Error => e
            raise Error, e.message
          end

        # The release header can't be changed using the Liquid template, as we
        # need this to be in a known format. Without this restriction, we won't
        # know where to insert a new release section in an existing changelog.
        "## #{@version} (#{release_date})\n\n#{markdown}\n\n"
      end

      def header_start_pattern
        /^##\s*#{Regexp.escape(@version)}/
      end

      private

      def release_date
        @config.format_date(@date)
      end

      def entries_for_template
        rows = []

        @entries.each do |category, entries|
          next if entries.empty?

          rows << {
            'title' => category,
            'count' => entries.length,
            'single_change' => entries.length == 1,
            'entries' => entries
          }
        end

        rows
      end
    end
  end
end