summaryrefslogtreecommitdiff
path: root/lib/gitlab
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2020-03-06 15:08:05 +0000
committerGitLab Bot <gitlab-bot@gitlab.com>2020-03-06 15:08:05 +0000
commitf78257cbddd711e18cbce93ad740a4aa0acac347 (patch)
tree7f018abe3ce1c0010879cc480f348a35e616fabb /lib/gitlab
parentf500600a43b531e2e7a5858b74bd35312b02c349 (diff)
downloadgitlab-ce-f78257cbddd711e18cbce93ad740a4aa0acac347.tar.gz
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'lib/gitlab')
-rw-r--r--lib/gitlab/ci/artifact_file_reader.rb71
-rw-r--r--lib/gitlab/ci/config.rb14
-rw-r--r--lib/gitlab/ci/config/entry/bridge.rb7
-rw-r--r--lib/gitlab/ci/config/entry/include.rb2
-rw-r--r--lib/gitlab/ci/config/entry/inherit.rb30
-rw-r--r--lib/gitlab/ci/config/entry/job.rb7
-rw-r--r--lib/gitlab/ci/config/entry/processable.rb30
-rw-r--r--lib/gitlab/ci/config/entry/root.rb13
-rw-r--r--lib/gitlab/ci/config/entry/workflow.rb1
-rw-r--r--lib/gitlab/ci/config/external/context.rb5
-rw-r--r--lib/gitlab/ci/config/external/file/artifact.rb93
-rw-r--r--lib/gitlab/ci/config/external/file/local.rb3
-rw-r--r--lib/gitlab/ci/config/external/file/project.rb3
-rw-r--r--lib/gitlab/ci/config/external/mapper.rb3
-rw-r--r--lib/gitlab/ci/pipeline/chain/base.rb2
-rw-r--r--lib/gitlab/ci/pipeline/chain/command.rb4
-rw-r--r--lib/gitlab/ci/pipeline/chain/config/process.rb3
-rw-r--r--lib/gitlab/ci/templates/Security/Container-Scanning.gitlab-ci.yml9
-rw-r--r--lib/gitlab/ci/templates/Security/Dependency-Scanning.gitlab-ci.yml2
-rw-r--r--lib/gitlab/ci/yaml_processor.rb9
-rw-r--r--lib/gitlab/config/entry/attributable.rb2
-rw-r--r--lib/gitlab/config/entry/configurable.rb15
22 files changed, 264 insertions, 64 deletions
diff --git a/lib/gitlab/ci/artifact_file_reader.rb b/lib/gitlab/ci/artifact_file_reader.rb
new file mode 100644
index 00000000000..c2d17cc176e
--- /dev/null
+++ b/lib/gitlab/ci/artifact_file_reader.rb
@@ -0,0 +1,71 @@
+# frozen_string_literal: true
+
+# This class takes in input a Ci::Build object and an artifact path to read.
+# It downloads and extracts the artifacts archive, then returns the content
+# of the artifact, if found.
+module Gitlab
+ module Ci
+ class ArtifactFileReader
+ Error = Class.new(StandardError)
+
+ MAX_ARCHIVE_SIZE = 5.megabytes
+
+ def initialize(job)
+ @job = job
+
+ raise ArgumentError, 'Job does not have artifacts' unless @job.artifacts?
+
+ validate!
+ end
+
+ def read(path)
+ return unless job.artifacts_metadata
+
+ metadata_entry = job.artifacts_metadata_entry(path)
+
+ if metadata_entry.total_size > MAX_ARCHIVE_SIZE
+ raise Error, "Artifacts archive for job `#{job.name}` is too large: max #{max_archive_size_in_mb}"
+ end
+
+ read_zip_file!(path)
+ end
+
+ private
+
+ attr_reader :job
+
+ def validate!
+ if job.job_artifacts_archive.size > MAX_ARCHIVE_SIZE
+ raise Error, "Artifacts archive for job `#{job.name}` is too large: max #{max_archive_size_in_mb}"
+ end
+
+ unless job.artifacts_metadata?
+ raise Error, "Job `#{job.name}` has missing artifacts metadata and cannot be extracted!"
+ end
+ end
+
+ def read_zip_file!(file_path)
+ job.artifacts_file.use_file do |archive_path|
+ Zip::File.open(archive_path) do |zip_file|
+ entry = zip_file.find_entry(file_path)
+ unless entry
+ raise Error, "Path `#{file_path}` does not exist inside the `#{job.name}` artifacts archive!"
+ end
+
+ if entry.name_is_directory?
+ raise Error, "Path `#{file_path}` was expected to be a file but it was a directory!"
+ end
+
+ zip_file.get_input_stream(entry) do |is|
+ is.read
+ end
+ end
+ end
+ end
+
+ def max_archive_size_in_mb
+ ActiveSupport::NumberHelper.number_to_human_size(MAX_ARCHIVE_SIZE)
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/ci/config.rb b/lib/gitlab/ci/config.rb
index 38ab3475d01..e069f734e32 100644
--- a/lib/gitlab/ci/config.rb
+++ b/lib/gitlab/ci/config.rb
@@ -18,12 +18,9 @@ module Gitlab
attr_reader :root
- def initialize(config, project: nil, sha: nil, user: nil)
- @context = build_context(project: project, sha: sha, user: user)
-
- if Feature.enabled?(:ci_limit_yaml_expansion, project, default_enabled: true)
- @context.set_deadline(TIMEOUT_SECONDS)
- end
+ def initialize(config, project: nil, sha: nil, user: nil, parent_pipeline: nil)
+ @context = build_context(project: project, sha: sha, user: user, parent_pipeline: parent_pipeline)
+ @context.set_deadline(TIMEOUT_SECONDS)
@config = expand_config(config)
@@ -87,11 +84,12 @@ module Gitlab
initial_config
end
- def build_context(project:, sha:, user:)
+ def build_context(project:, sha:, user:, parent_pipeline:)
Config::External::Context.new(
project: project,
sha: sha || project&.repository&.root_ref_sha,
- user: user)
+ user: user,
+ parent_pipeline: parent_pipeline)
end
def track_and_raise_for_dev_exception(error)
diff --git a/lib/gitlab/ci/config/entry/bridge.rb b/lib/gitlab/ci/config/entry/bridge.rb
index 6fdaa373170..f4362d3b0ce 100644
--- a/lib/gitlab/ci/config/entry/bridge.rb
+++ b/lib/gitlab/ci/config/entry/bridge.rb
@@ -11,7 +11,7 @@ module Gitlab
class Bridge < ::Gitlab::Config::Entry::Node
include ::Gitlab::Ci::Config::Entry::Processable
- ALLOWED_KEYS = %i[trigger allow_failure when variables needs].freeze
+ ALLOWED_KEYS = %i[trigger allow_failure when needs].freeze
validations do
validates :config, allowed_keys: ALLOWED_KEYS + PROCESSABLE_ALLOWED_KEYS
@@ -45,10 +45,6 @@ module Gitlab
inherit: false,
metadata: { allowed_needs: %i[job bridge] }
- entry :variables, ::Gitlab::Ci::Config::Entry::Variables,
- description: 'Environment variables available for this job.',
- inherit: false
-
attributes :when, :allow_failure
def self.matching?(name, config)
@@ -67,7 +63,6 @@ module Gitlab
needs: (needs_value if needs_defined?),
ignore: !!allow_failure,
when: self.when,
- variables: (variables_value if variables_defined?),
scheduling_type: needs_defined? && !bridge_needs ? :dag : :stage
).compact
end
diff --git a/lib/gitlab/ci/config/entry/include.rb b/lib/gitlab/ci/config/entry/include.rb
index f2f3dd84eda..cd09d83b728 100644
--- a/lib/gitlab/ci/config/entry/include.rb
+++ b/lib/gitlab/ci/config/entry/include.rb
@@ -10,7 +10,7 @@ module Gitlab
class Include < ::Gitlab::Config::Entry::Node
include ::Gitlab::Config::Entry::Validatable
- ALLOWED_KEYS = %i[local file remote template].freeze
+ ALLOWED_KEYS = %i[local file remote template artifact job].freeze
validations do
validates :config, hash_or_string: true
diff --git a/lib/gitlab/ci/config/entry/inherit.rb b/lib/gitlab/ci/config/entry/inherit.rb
new file mode 100644
index 00000000000..540f1e62c6c
--- /dev/null
+++ b/lib/gitlab/ci/config/entry/inherit.rb
@@ -0,0 +1,30 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module Ci
+ class Config
+ module Entry
+ ##
+ # This class represents a inherit entry
+ #
+ class Inherit < ::Gitlab::Config::Entry::Node
+ include ::Gitlab::Config::Entry::Configurable
+
+ ALLOWED_KEYS = %i[default variables].freeze
+
+ validations do
+ validates :config, allowed_keys: ALLOWED_KEYS
+ end
+
+ entry :default, ::Gitlab::Config::Entry::Boolean,
+ description: 'Indicates whether to inherit `default:`.',
+ default: true
+
+ entry :variables, ::Gitlab::Config::Entry::Boolean,
+ description: 'Indicates whether to inherit `variables:`.',
+ default: true
+ end
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/ci/config/entry/job.rb b/lib/gitlab/ci/config/entry/job.rb
index 8db21b116eb..1ea59491378 100644
--- a/lib/gitlab/ci/config/entry/job.rb
+++ b/lib/gitlab/ci/config/entry/job.rb
@@ -13,7 +13,7 @@ module Gitlab
ALLOWED_WHEN = %w[on_success on_failure always manual delayed].freeze
ALLOWED_KEYS = %i[tags script type image services
allow_failure type when start_in artifacts cache
- dependencies before_script needs after_script variables
+ dependencies before_script needs after_script
environment coverage retry parallel interruptible timeout
resource_group release].freeze
@@ -112,10 +112,6 @@ module Gitlab
metadata: { allowed_needs: %i[job cross_dependency] },
inherit: false
- entry :variables, Entry::Variables,
- description: 'Environment variables available for this job.',
- inherit: false
-
entry :environment, Entry::Environment,
description: 'Environment configuration for this job.',
inherit: false
@@ -174,7 +170,6 @@ module Gitlab
when: self.when,
start_in: self.start_in,
dependencies: dependencies,
- variables: variables_defined? ? variables_value : {},
environment: environment_defined? ? environment_value : nil,
environment_name: environment_defined? ? environment_value[:name] : nil,
coverage: coverage_defined? ? coverage_value : nil,
diff --git a/lib/gitlab/ci/config/entry/processable.rb b/lib/gitlab/ci/config/entry/processable.rb
index bfa2905ed77..b4da48957b0 100644
--- a/lib/gitlab/ci/config/entry/processable.rb
+++ b/lib/gitlab/ci/config/entry/processable.rb
@@ -14,7 +14,7 @@ module Gitlab
include ::Gitlab::Config::Entry::Attributable
include ::Gitlab::Config::Entry::Inheritable
- PROCESSABLE_ALLOWED_KEYS = %i[extends stage only except rules].freeze
+ PROCESSABLE_ALLOWED_KEYS = %i[extends stage only except rules variables inherit].freeze
included do
validations do
@@ -54,12 +54,21 @@ module Gitlab
allowed_when: %w[on_success on_failure always never manual delayed].freeze
}
+ entry :variables, ::Gitlab::Ci::Config::Entry::Variables,
+ description: 'Environment variables available for this job.',
+ inherit: false
+
+ entry :inherit, ::Gitlab::Ci::Config::Entry::Inherit,
+ description: 'Indicates whether to inherit defaults or not.',
+ inherit: false,
+ default: {}
+
attributes :extends, :rules
end
def compose!(deps = nil)
super do
- has_workflow_rules = deps&.workflow&.has_rules?
+ has_workflow_rules = deps&.workflow_entry&.has_rules?
# If workflow:rules: or rules: are used
# they are considered not compatible
@@ -73,6 +82,9 @@ module Gitlab
@entries.delete(:except) unless except_defined? # rubocop:disable Gitlab/ModuleWithInstanceVariables
end
+ # inherit root variables
+ @root_variables_value = deps&.variables_value # rubocop:disable Gitlab/ModuleWithInstanceVariables
+
yield if block_given?
end
end
@@ -82,7 +94,10 @@ module Gitlab
end
def overwrite_entry(deps, key, current_entry)
- deps.default[key] unless current_entry.specified?
+ return unless inherit_entry&.default_value
+ return unless deps.default_entry
+
+ deps.default_entry[key] unless current_entry.specified?
end
def value
@@ -90,9 +105,18 @@ module Gitlab
stage: stage_value,
extends: extends,
rules: rules_value,
+ variables: root_and_job_variables_value,
only: only_value,
except: except_value }.compact
end
+
+ def root_and_job_variables_value
+ if inherit_entry&.variables_value
+ @root_variables_value.to_h.merge(variables_value.to_h) # rubocop:disable Gitlab/ModuleWithInstanceVariables
+ else
+ variables_value.to_h
+ end
+ end
end
end
end
diff --git a/lib/gitlab/ci/config/entry/root.rb b/lib/gitlab/ci/config/entry/root.rb
index caa0725c4bd..19d6a470941 100644
--- a/lib/gitlab/ci/config/entry/root.rb
+++ b/lib/gitlab/ci/config/entry/root.rb
@@ -65,7 +65,8 @@ module Gitlab
reserved: true
entry :workflow, Entry::Workflow,
- description: 'List of evaluable rules to determine Pipeline status'
+ description: 'List of evaluable rules to determine Pipeline status',
+ default: {}
dynamic_helpers :jobs
@@ -73,7 +74,7 @@ module Gitlab
:image_value,
:services_value,
:after_script_value,
- :cache_value, to: :default
+ :cache_value, to: :default_entry
attr_reader :jobs_config
@@ -102,14 +103,6 @@ module Gitlab
end
end
- def default
- self[:default]
- end
-
- def workflow
- self[:workflow] if workflow_defined?
- end
-
private
# rubocop: disable CodeReuse/ActiveRecord
diff --git a/lib/gitlab/ci/config/entry/workflow.rb b/lib/gitlab/ci/config/entry/workflow.rb
index 1d9007c9b9b..5bc992a38a0 100644
--- a/lib/gitlab/ci/config/entry/workflow.rb
+++ b/lib/gitlab/ci/config/entry/workflow.rb
@@ -12,7 +12,6 @@ module Gitlab
validations do
validates :config, type: Hash
validates :config, allowed_keys: ALLOWED_KEYS
- validates :config, presence: true
end
entry :rules, Entry::Rules,
diff --git a/lib/gitlab/ci/config/external/context.rb b/lib/gitlab/ci/config/external/context.rb
index bb4439cd069..814dcc66362 100644
--- a/lib/gitlab/ci/config/external/context.rb
+++ b/lib/gitlab/ci/config/external/context.rb
@@ -7,13 +7,14 @@ module Gitlab
class Context
TimeoutError = Class.new(StandardError)
- attr_reader :project, :sha, :user
+ attr_reader :project, :sha, :user, :parent_pipeline
attr_reader :expandset, :execution_deadline
- def initialize(project: nil, sha: nil, user: nil)
+ def initialize(project: nil, sha: nil, user: nil, parent_pipeline: nil)
@project = project
@sha = sha
@user = user
+ @parent_pipeline = parent_pipeline
@expandset = Set.new
@execution_deadline = 0
diff --git a/lib/gitlab/ci/config/external/file/artifact.rb b/lib/gitlab/ci/config/external/file/artifact.rb
new file mode 100644
index 00000000000..fcfdda21c08
--- /dev/null
+++ b/lib/gitlab/ci/config/external/file/artifact.rb
@@ -0,0 +1,93 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module Ci
+ class Config
+ module External
+ module File
+ class Artifact < Base
+ extend ::Gitlab::Utils::Override
+ include Gitlab::Utils::StrongMemoize
+
+ attr_reader :job_name
+
+ def initialize(params, context)
+ @location = params[:artifact]
+ @job_name = params[:job]
+
+ super
+ end
+
+ def content
+ strong_memoize(:content) do
+ next unless artifact_job
+
+ Gitlab::Ci::ArtifactFileReader.new(artifact_job).read(location)
+ rescue Gitlab::Ci::ArtifactFileReader::Error => error
+ errors.push(error.message)
+ end
+ end
+
+ def matching?
+ super &&
+ Feature.enabled?(:ci_dynamic_child_pipeline, project)
+ end
+
+ private
+
+ def project
+ context&.parent_pipeline&.project
+ end
+
+ def validate_content!
+ return unless ensure_preconditions_satisfied!
+
+ errors.push("File `#{location}` is empty!") unless content.present?
+ end
+
+ def ensure_preconditions_satisfied!
+ unless creating_child_pipeline?
+ errors.push('Including configs from artifacts is only allowed when triggering child pipelines')
+ return false
+ end
+
+ unless job_name.present?
+ errors.push("Job must be provided when including configs from artifacts")
+ return false
+ end
+
+ unless artifact_job.present?
+ errors.push("Job `#{job_name}` not found in parent pipeline or does not have artifacts!")
+ return false
+ end
+
+ true
+ end
+
+ def artifact_job
+ strong_memoize(:artifact_job) do
+ next unless creating_child_pipeline?
+
+ context.parent_pipeline.find_job_with_archive_artifacts(job_name)
+ end
+ end
+
+ def creating_child_pipeline?
+ context.parent_pipeline.present?
+ end
+
+ override :expand_context_attrs
+ def expand_context_attrs
+ {
+ project: context.project,
+ sha: context.sha,
+ user: context.user,
+ parent_pipeline: context.parent_pipeline
+ }
+ end
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/ci/config/external/file/local.rb b/lib/gitlab/ci/config/external/file/local.rb
index 8cb1575a3e1..e74f5b33de7 100644
--- a/lib/gitlab/ci/config/external/file/local.rb
+++ b/lib/gitlab/ci/config/external/file/local.rb
@@ -40,7 +40,8 @@ module Gitlab
{
project: context.project,
sha: context.sha,
- user: context.user
+ user: context.user,
+ parent_pipeline: context.parent_pipeline
}
end
end
diff --git a/lib/gitlab/ci/config/external/file/project.rb b/lib/gitlab/ci/config/external/file/project.rb
index c7b49b495fa..be479741784 100644
--- a/lib/gitlab/ci/config/external/file/project.rb
+++ b/lib/gitlab/ci/config/external/file/project.rb
@@ -71,7 +71,8 @@ module Gitlab
{
project: project,
sha: sha,
- user: context.user
+ user: context.user,
+ parent_pipeline: context.parent_pipeline
}
end
end
diff --git a/lib/gitlab/ci/config/external/mapper.rb b/lib/gitlab/ci/config/external/mapper.rb
index 0143d7784fa..97ae6c4ceba 100644
--- a/lib/gitlab/ci/config/external/mapper.rb
+++ b/lib/gitlab/ci/config/external/mapper.rb
@@ -13,7 +13,8 @@ module Gitlab
External::File::Remote,
External::File::Template,
External::File::Local,
- External::File::Project
+ External::File::Project,
+ External::File::Artifact
].freeze
Error = Class.new(StandardError)
diff --git a/lib/gitlab/ci/pipeline/chain/base.rb b/lib/gitlab/ci/pipeline/chain/base.rb
index aabdf7ce47d..9b494f3a7ec 100644
--- a/lib/gitlab/ci/pipeline/chain/base.rb
+++ b/lib/gitlab/ci/pipeline/chain/base.rb
@@ -7,7 +7,7 @@ module Gitlab
class Base
attr_reader :pipeline, :command, :config
- delegate :project, :current_user, to: :command
+ delegate :project, :current_user, :parent_pipeline, to: :command
def initialize(pipeline, command)
@pipeline = pipeline
diff --git a/lib/gitlab/ci/pipeline/chain/command.rb b/lib/gitlab/ci/pipeline/chain/command.rb
index 6a16e6df23d..fa46114615c 100644
--- a/lib/gitlab/ci/pipeline/chain/command.rb
+++ b/lib/gitlab/ci/pipeline/chain/command.rb
@@ -72,6 +72,10 @@ module Gitlab
project.repository.ambiguous_ref?(origin_ref)
end
end
+
+ def parent_pipeline
+ bridge&.parent_pipeline
+ end
end
end
end
diff --git a/lib/gitlab/ci/pipeline/chain/config/process.rb b/lib/gitlab/ci/pipeline/chain/config/process.rb
index 09d1b0edc93..1e47be21b93 100644
--- a/lib/gitlab/ci/pipeline/chain/config/process.rb
+++ b/lib/gitlab/ci/pipeline/chain/config/process.rb
@@ -15,7 +15,8 @@ module Gitlab
@command.config_content, {
project: project,
sha: @pipeline.sha,
- user: current_user
+ user: current_user,
+ parent_pipeline: parent_pipeline
}
)
rescue Gitlab::Ci::YamlProcessor::ValidationError => ex
diff --git a/lib/gitlab/ci/templates/Security/Container-Scanning.gitlab-ci.yml b/lib/gitlab/ci/templates/Security/Container-Scanning.gitlab-ci.yml
index f708e95c2cf..6efb6b4e273 100644
--- a/lib/gitlab/ci/templates/Security/Container-Scanning.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/Security/Container-Scanning.gitlab-ci.yml
@@ -5,9 +5,7 @@ variables:
container_scanning:
stage: test
- image:
- name: registry.gitlab.com/gitlab-org/security-products/analyzers/klar:$CS_MAJOR_VERSION
- entrypoint: []
+ image: registry.gitlab.com/gitlab-org/security-products/analyzers/klar:$CS_MAJOR_VERSION
variables:
# By default, use the latest clair vulnerabilities database, however, allow it to be overridden here with a specific image
# to enable container scanning to run offline, or to provide a consistent list of vulnerabilities for integration testing purposes
@@ -22,10 +20,7 @@ container_scanning:
- name: $CLAIR_DB_IMAGE
alias: clair-vulnerabilities-db
script:
- # the kubernetes executor currently ignores the Docker image entrypoint value, so the start.sh script must
- # be explicitly executed here in order for this to work with both the kubernetes and docker executors
- # see this issue for more details https://gitlab.com/gitlab-org/gitlab-runner/issues/4125
- - /container-scanner/start.sh
+ - /analyzer run
artifacts:
reports:
container_scanning: gl-container-scanning-report.json
diff --git a/lib/gitlab/ci/templates/Security/Dependency-Scanning.gitlab-ci.yml b/lib/gitlab/ci/templates/Security/Dependency-Scanning.gitlab-ci.yml
index 5ff6413898f..4a9fa3091be 100644
--- a/lib/gitlab/ci/templates/Security/Dependency-Scanning.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/Security/Dependency-Scanning.gitlab-ci.yml
@@ -59,6 +59,8 @@ dependency_scanning:
BUNDLER_AUDIT_UPDATE_DISABLED \
BUNDLER_AUDIT_ADVISORY_DB_URL \
BUNDLER_AUDIT_ADVISORY_DB_REF_NAME \
+ RETIREJS_JS_ADVISORY_DB \
+ RETIREJS_NODE_ADVISORY_DB \
) \
--volume "$PWD:/code" \
--volume /var/run/docker.sock:/var/run/docker.sock \
diff --git a/lib/gitlab/ci/yaml_processor.rb b/lib/gitlab/ci/yaml_processor.rb
index ae3ff4a51e2..764047dae6d 100644
--- a/lib/gitlab/ci/yaml_processor.rb
+++ b/lib/gitlab/ci/yaml_processor.rb
@@ -57,7 +57,7 @@ module Gitlab
when: job[:when] || 'on_success',
environment: job[:environment_name],
coverage_regex: job[:coverage],
- yaml_variables: transform_to_yaml_variables(job_variables(name)),
+ yaml_variables: transform_to_yaml_variables(job[:variables]),
needs_attributes: job.dig(:needs, :job),
interruptible: job[:interruptible],
only: job[:only],
@@ -146,13 +146,6 @@ module Gitlab
end
end
- def job_variables(name)
- job_variables = @jobs.dig(name.to_sym, :variables)
-
- @variables.to_h
- .merge(job_variables.to_h)
- end
-
def transform_to_yaml_variables(variables)
variables.to_h.map do |key, value|
{ key: key.to_s, value: value, public: true }
diff --git a/lib/gitlab/config/entry/attributable.rb b/lib/gitlab/config/entry/attributable.rb
index 4deb233d10e..d266d5218de 100644
--- a/lib/gitlab/config/entry/attributable.rb
+++ b/lib/gitlab/config/entry/attributable.rb
@@ -10,7 +10,7 @@ module Gitlab
def attributes(*attributes)
attributes.flatten.each do |attribute|
if method_defined?(attribute)
- raise ArgumentError, "Method already defined: #{attribute}"
+ raise ArgumentError, "Method '#{attribute}' already defined in '#{name}'"
end
define_method(attribute) do
diff --git a/lib/gitlab/config/entry/configurable.rb b/lib/gitlab/config/entry/configurable.rb
index 3fd562c2904..571e7a5127e 100644
--- a/lib/gitlab/config/entry/configurable.rb
+++ b/lib/gitlab/config/entry/configurable.rb
@@ -76,7 +76,7 @@ module Gitlab
# rubocop: disable CodeReuse/ActiveRecord
def entry(key, entry, description: nil, default: nil, inherit: nil, reserved: nil, metadata: {})
entry_name = key.to_sym
- raise ArgumentError, "Entry #{key} already defined" if @nodes.to_h[entry_name]
+ raise ArgumentError, "Entry '#{key}' already defined in '#{name}'" if @nodes.to_h[entry_name]
factory = ::Gitlab::Config::Entry::Factory.new(entry)
.with(description: description)
@@ -98,8 +98,8 @@ module Gitlab
def helpers(*nodes, dynamic: false)
nodes.each do |symbol|
- if method_defined?("#{symbol}_defined?") || method_defined?("#{symbol}_value")
- raise ArgumentError, "Method #{symbol}_defined? or #{symbol}_value already defined"
+ if method_defined?("#{symbol}_defined?") || method_defined?("#{symbol}_entry") || method_defined?("#{symbol}_value")
+ raise ArgumentError, "Method '#{symbol}_defined?', '#{symbol}_entry' or '#{symbol}_value' already defined in '#{name}'"
end
unless @nodes.to_h[symbol]
@@ -110,10 +110,13 @@ module Gitlab
entries[symbol]&.specified?
end
- define_method("#{symbol}_value") do
- return unless entries[symbol] && entries[symbol].valid?
+ define_method("#{symbol}_entry") do
+ entries[symbol]
+ end
- entries[symbol].value
+ define_method("#{symbol}_value") do
+ entry = entries[symbol]
+ entry.value if entry&.valid?
end
end
end