gitlab-ce/lib/gitlab/ci/interpolation/inputs/base_input.rb

93 lines
2.4 KiB
Ruby

# frozen_string_literal: true
module Gitlab
module Ci
module Interpolation
class Inputs
##
# This is a common abstraction for all input types
class BaseInput
ArgumentNotValidError = Class.new(StandardError)
# Checks whether the class matches the type in the specification
def self.matches?(spec)
raise NotImplementedError
end
# Human readable type used in error messages
def self.type_name
raise NotImplementedError
end
# Checks whether the provided value is of the given type
def valid_value?(value)
raise NotImplementedError
end
attr_reader :errors, :name, :spec, :value
def initialize(name:, spec:, value:)
@name = name
@errors = []
# Treat minimal spec definition (nil) as a valid hash:
# spec:
# inputs:
# website:
@spec = spec || {} # specification from input definition
@value = value # actual value provided by the user
validate!
end
def to_hash
raise ArgumentNotValidError unless valid?
{ name => actual_value }
end
def valid?
@errors.none?
end
private
def validate!
return error('required value has not been provided') if required_input? && value.nil?
# validate default value
return error("default value is not a #{self.class.type_name}") if !required_input? && !valid_value?(default)
# validate provided value
error("provided value is not a #{self.class.type_name}") unless valid_value?(value)
end
def error(message)
@errors.push("`#{name}` input: #{message}")
end
def actual_value
# nil check is to support boolean values.
value.nil? ? default : value
end
# An input specification without a default value is required.
# For example:
# ```yaml
# spec:
# inputs:
# website:
# ```
def required_input?
!spec.key?(:default)
end
def default
spec[:default]
end
end
end
end
end
end