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

release_highlight.rb « models « app - gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 5a6f708f6890d980bffd3c7bf3cc3a00444ec51f (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
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
# frozen_string_literal: true

class ReleaseHighlight
  CACHE_DURATION = 1.hour

  FREE_PACKAGE = 'Free'
  PREMIUM_PACKAGE = 'Premium'
  ULTIMATE_PACKAGE = 'Ultimate'

  def self.paginated(page: 1)
    result = self.paginated_query(page: page)
    result = self.paginated_query(page: result.next_page) while next_page?(result)
    result
  end

  def self.paginated_query(page:)
    key = self.cache_key("items:page-#{page}")

    Rails.cache.fetch(key, expires_in: CACHE_DURATION) do
      items = self.load_items(page: page)

      next if items.nil?

      QueryResult.new(items: items, next_page: next_page(current_page: page))
    end
  end

  def self.load_items(page:)
    index = page - 1
    file_path = file_paths[index]

    return if file_path.nil?

    file = File.read(file_path)
    items = YAML.safe_load(file, permitted_classes: [Date])

    items&.map! do |item|
      next unless include_item?(item)

      begin
        item.tap { |i| i['description'] = Banzai.render(i['description'], { project: nil }) }
      rescue StandardError => e
        Gitlab::ErrorTracking.track_exception(e, file_path: file_path)

        next
      end
    end

    items&.compact
  rescue Psych::Exception => e
    Gitlab::ErrorTracking.track_exception(e, file_path: file_path)

    []
  end

  def self.whats_new_path
    Rails.root.join('data/whats_new/*.yml')
  end

  def self.file_paths
    @file_paths ||= self.relative_file_paths.map { |path| path.prepend(Rails.root.to_s) }
  end

  def self.relative_file_paths
    Rails.cache.fetch(self.cache_key('file_paths'), expires_in: CACHE_DURATION) do
      Dir.glob(whats_new_path).sort.reverse.map { |path| path.delete_prefix(Rails.root.to_s) }
    end
  end

  def self.cache_key(key)
    variant = Gitlab::CurrentSettings.current_application_settings.whats_new_variant
    ['release_highlight', variant, key, Gitlab.revision].join(':')
  end

  def self.next_page(current_page: 1)
    next_page = current_page + 1
    next_index = next_page - 1

    next_page if self.file_paths[next_index]
  end

  def self.most_recent_item_count
    key = self.cache_key('recent_item_count')

    Gitlab::ProcessMemoryCache.cache_backend.fetch(key, expires_in: CACHE_DURATION) do
      self.paginated&.items&.count
    end
  end

  def self.most_recent_version_digest
    key = self.cache_key('most_recent_version_digest')

    Gitlab::ProcessMemoryCache.cache_backend.fetch(key, expires_in: CACHE_DURATION) do
      version = self.paginated&.items&.first&.[]('release')&.to_s

      next if version.nil?

      Digest::SHA256.hexdigest(version)
    end
  end

  QueryResult = Struct.new(:items, :next_page, keyword_init: true) do
    include Enumerable

    delegate :each, to: :items
  end

  def self.current_package
    return FREE_PACKAGE unless defined?(License)

    case License.current&.plan&.downcase
    when License::PREMIUM_PLAN
      PREMIUM_PACKAGE
    when License::ULTIMATE_PLAN
      ULTIMATE_PACKAGE
    else
      FREE_PACKAGE
    end
  end

  def self.include_item?(item)
    platform = Gitlab.com? ? 'gitlab-com' : 'self-managed'

    return false unless item[platform]

    return true unless Gitlab::CurrentSettings.current_application_settings.whats_new_variant_current_tier?

    item['available_in']&.include?(current_package)
  end

  def self.next_page?(result)
    return false unless result

    # if all items for the current page doesn't belong to the current tier
    # or failed to parse current YAML, loading next page
    result.items == [] && result.next_page.present?
  end
end

ReleaseHighlight.prepend_mod