diff options
Diffstat (limited to 'lib/release_highlights/validator/entry.rb')
-rw-r--r-- | lib/release_highlights/validator/entry.rb | 74 |
1 files changed, 74 insertions, 0 deletions
diff --git a/lib/release_highlights/validator/entry.rb b/lib/release_highlights/validator/entry.rb new file mode 100644 index 00000000000..0dbe0cdf882 --- /dev/null +++ b/lib/release_highlights/validator/entry.rb @@ -0,0 +1,74 @@ +# frozen_string_literal: true + +module ReleaseHighlights + class Validator::Entry + include ActiveModel::Validations + include ActiveModel::Validations::Callbacks + + PACKAGES = %w(Core Starter Premium Ultimate).freeze + + attr_reader :entry + + validates :title, :body, :stage, presence: true + validates :'self-managed', :'gitlab-com', inclusion: { in: [true, false], message: "must be a boolean" } + validates :url, :image_url, format: { with: URI::DEFAULT_PARSER.make_regexp, message: 'must be a URL' } + validates :release, numericality: true + validate :validate_published_at + validate :validate_packages + + after_validation :add_line_numbers_to_errors! + + def initialize(entry) + @entry = entry + end + + def validate_published_at + published_at = value_for('published_at') + + return if published_at.is_a?(Date) + + errors.add(:published_at, 'must be valid Date') + end + + def validate_packages + packages = value_for('packages') + + if !packages.is_a?(Array) || packages.empty? || packages.any? { |p| PACKAGES.exclude?(p) } + errors.add(:packages, "must be one of #{PACKAGES}") + end + end + + def read_attribute_for_validation(key) + value_for(key) + end + + private + + def add_line_numbers_to_errors! + errors.messages.each do |attribute, messages| + messages.map! { |m| "#{m} (line #{line_number_for(attribute)})" } + end + end + + def line_number_for(key) + node = find_node(key) + + (node&.start_line || @entry.start_line) + 1 + end + + def value_for(key) + node = find_node(key) + + return if node.nil? + + index = entry.children.find_index(node) + + next_node = entry.children[index + 1] + next_node&.to_ruby + end + + def find_node(key) + entry.children.find {|node| node.try(:value) == key.to_s } + end + end +end |