From b7ee04d4564deaf30cf3c8ead34701ac6d746c05 Mon Sep 17 00:00:00 2001 From: Markus Doits Date: Thu, 18 Oct 2018 18:48:44 +0200 Subject: refactor validations to a Entry::Retry class --- lib/gitlab/ci/config/entry/job.rb | 68 ++------------------------------ lib/gitlab/ci/config/entry/retry.rb | 64 ++++++++++++++++++++++++++++++ lib/gitlab/ci/config/entry/validators.rb | 10 +++++ 3 files changed, 78 insertions(+), 64 deletions(-) create mode 100644 lib/gitlab/ci/config/entry/retry.rb (limited to 'lib') diff --git a/lib/gitlab/ci/config/entry/job.rb b/lib/gitlab/ci/config/entry/job.rb index 5a91d5574f0..5ff03d803dc 100644 --- a/lib/gitlab/ci/config/entry/job.rb +++ b/lib/gitlab/ci/config/entry/job.rb @@ -16,8 +16,6 @@ module Gitlab dependencies before_script after_script variables environment coverage retry parallel extends].freeze - ALLOWED_KEYS_RETRY = %i[max when].freeze - validations do validates :config, allowed_keys: ALLOWED_KEYS validates :config, presence: true @@ -25,14 +23,12 @@ module Gitlab validates :name, presence: true validates :name, type: Symbol - validates :retry, hash_or_integer: true, allowed_keys: ALLOWED_KEYS_RETRY, allow_nil: true - validate :validate_retry, if: :validate_retry? - with_options allow_nil: true do validates :tags, array_of_strings: true validates :allow_failure, boolean: true validates :parallel, numericality: { only_integer: true, greater_than_or_equal_to: 2 } + validates :retry, hash_or_integer: true validates :when, inclusion: { in: %w[on_success on_failure always manual delayed], @@ -43,65 +39,6 @@ module Gitlab validates :extends, type: String end - def validate_retry? - config&.is_a?(Hash) && - config[:retry].present? && - (config[:retry].is_a?(Integer) || config[:retry].is_a?(Hash)) - end - - def validate_retry - if config[:retry].is_a?(Integer) - validate_retry_max(config[:retry]) - else - validate_retry_max(config[:retry][:max]) - validate_retry_when(config[:retry][:when]) - end - end - - def validate_retry_max(retry_max) - case retry_max - when Integer - validate_retry_max_integer(retry_max) - else - errors[:base] << "retry max #{::I18n.t('errors.messages.not_an_integer')}" - end - end - - def validate_retry_max_integer(retry_max) - errors[:base] << "retry max #{::I18n.t('errors.messages.less_than_or_equal_to', count: 2)}" if retry_max > 2 - errors[:base] << "retry max #{::I18n.t('errors.messages.greater_than_or_equal_to', count: 0)}" if retry_max < 0 - end - - def validate_retry_when(retry_when) - return if retry_when.blank? - - case retry_when - when String - validate_retry_when_string(retry_when) - when Array - validate_retry_when_array(retry_when) - else - errors[:base] << 'retry when should be an array of strings or a string' - end - end - - def possible_retry_when_values - @possible_retry_when_values ||= Gitlab::Ci::Status::Build::Failed.reasons.keys.map(&:to_s) + ['always'] - end - - def validate_retry_when_string(retry_when) - unless possible_retry_when_values.include?(retry_when) - errors[:base] << 'retry when is unknown' - end - end - - def validate_retry_when_array(retry_when) - unknown_whens = retry_when - possible_retry_when_values - unless unknown_whens.empty? - errors[:base] << "retry when contains unknown values: #{unknown_whens.join(', ')}" - end - end - validates :start_in, duration: { limit: '1 day' }, if: :delayed? validates :start_in, absence: true, unless: :delayed? end @@ -148,6 +85,9 @@ module Gitlab entry :coverage, Entry::Coverage, description: 'Coverage configuration for this job.' + entry :retry, Entry::Retry, + description: 'Retry configuration for this job.' + helpers :before_script, :script, :stage, :type, :after_script, :cache, :image, :services, :only, :except, :variables, :artifacts, :commands, :environment, :coverage, :retry, diff --git a/lib/gitlab/ci/config/entry/retry.rb b/lib/gitlab/ci/config/entry/retry.rb new file mode 100644 index 00000000000..140201447d1 --- /dev/null +++ b/lib/gitlab/ci/config/entry/retry.rb @@ -0,0 +1,64 @@ +module Gitlab + module Ci + class Config + module Entry + ## + # Entry that represents a retry config for a job. + # + class Retry < Simplifiable + strategy :SimpleRetry, if: -> (config) { config.is_a?(Integer) } + strategy :FullRetry, if: -> (config) { config.is_a?(Hash) } + + class SimpleRetry < Entry::Node + include Entry::Validatable + + validations do + validates :config, numericality: { only_integer: true, + greater_than_or_equal_to: 0, + less_than_or_equal_to: 2 } + end + end + + class FullRetry < Entry::Node + include Entry::Validatable + include Entry::Attributable + + ALLOWED_KEYS = %i[max when].freeze + attributes :max, :when + + validations do + validates :config, allowed_keys: ALLOWED_KEYS + + with_options allow_nil: true do + validates :max, numericality: { only_integer: true, + greater_than_or_equal_to: 0, + less_than_or_equal_to: 2 } + + validates :when, array_of_strings_or_string: true + validates :when, + allowed_array_values: { in: FullRetry.possible_retry_when_values }, + if: -> (config) { config.when.is_a?(Array) } + validates :when, + inclusion: { in: FullRetry.possible_retry_when_values }, + if: -> (config) { config.when.is_a?(String) } + end + end + + def self.possible_retry_when_values + @possible_retry_when_values ||= Gitlab::Ci::Status::Build::Failed.reasons.keys.map(&:to_s) + ['always'] + end + end + + class UnknownStrategy < Entry::Node + def errors + ["#{location} has to be either an integer or a hash"] + end + end + + def self.default + end + end + end + end + end +end diff --git a/lib/gitlab/ci/config/entry/validators.rb b/lib/gitlab/ci/config/entry/validators.rb index af902eb0ee8..a1d552fb2e5 100644 --- a/lib/gitlab/ci/config/entry/validators.rb +++ b/lib/gitlab/ci/config/entry/validators.rb @@ -24,6 +24,16 @@ module Gitlab end end + class AllowedArrayValuesValidator < ActiveModel::EachValidator + def validate_each(record, attribute, value) + unkown_values = value - options[:in] + unless unkown_values.empty? + record.errors.add(attribute, "contains unknown values: " + + unkown_values.join(', ')) + end + end + end + class ArrayOfStringsValidator < ActiveModel::EachValidator include LegacyValidationHelpers -- cgit v1.2.1