mirror of
https://gitlab.com/gitlab-org/gitlab-foss.git
synced 2025-07-25 16:03:48 +00:00
67 lines
2.1 KiB
Ruby
67 lines
2.1 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
module ExpandVariables
|
|
VariableExpansionError = Class.new(StandardError)
|
|
|
|
VARIABLES_REGEXP = /\$([a-zA-Z_][a-zA-Z0-9_]*)|\${\g<1>}|%\g<1>%/
|
|
|
|
class << self
|
|
def expand(value, variables, expand_file_refs: true, fail_on_masked: false)
|
|
replace_with(value, variables) do |collection, last_match|
|
|
match_or_blank_value(
|
|
collection, last_match, expand_file_refs: expand_file_refs, fail_on_masked: fail_on_masked
|
|
)
|
|
end
|
|
end
|
|
|
|
def expand_existing(value, variables, expand_file_refs: true, fail_on_masked: false)
|
|
replace_with(value, variables) do |collection, last_match|
|
|
match_or_original_value(
|
|
collection, last_match, expand_file_refs: expand_file_refs, fail_on_masked: fail_on_masked
|
|
)
|
|
end
|
|
end
|
|
|
|
def possible_var_reference?(value)
|
|
return unless value
|
|
|
|
%w[$ %].any? { |symbol| value.include?(symbol) }
|
|
end
|
|
|
|
private
|
|
|
|
def replace_with(value, variables)
|
|
# We lazily fabricate the variables collection in case there is no variable in the value string.
|
|
# `collection` needs to be initialized to nil here
|
|
# so that it is memoized in the closure block for `gsub`.
|
|
collection = nil
|
|
|
|
value.gsub(VARIABLES_REGEXP) do
|
|
collection ||= Gitlab::Ci::Variables::Collection.fabricate(variables)
|
|
yield(collection, Regexp.last_match)
|
|
end
|
|
end
|
|
|
|
def match_or_blank_value(collection, last_match, expand_file_refs:, fail_on_masked:)
|
|
match = last_match[1] || last_match[2]
|
|
replacement = collection[match]
|
|
|
|
if replacement.nil?
|
|
nil
|
|
elsif fail_on_masked && replacement.masked?
|
|
raise VariableExpansionError, 'masked variables cannot be expanded'
|
|
elsif replacement.file?
|
|
expand_file_refs ? replacement.value : last_match
|
|
else
|
|
replacement.value
|
|
end
|
|
end
|
|
|
|
def match_or_original_value(collection, last_match, expand_file_refs:, fail_on_masked:)
|
|
match_or_blank_value(
|
|
collection, last_match, expand_file_refs: expand_file_refs, fail_on_masked: fail_on_masked
|
|
) || last_match[0]
|
|
end
|
|
end
|
|
end
|