blob: 52673d03e6960b4d31cc567de0bd8c34039a4c73 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
|
# frozen_string_literal: true
module Gitlab
module Ci
module Variables
class Collection
include Enumerable
attr_reader :errors
def initialize(variables = [], errors = nil)
@variables = []
@variables_by_key = Hash.new { |h, k| h[k] = [] }
@errors = errors
variables.each { |variable| self.append(variable) }
end
def append(resource)
item = Collection::Item.fabricate(resource)
@variables.append(item)
@variables_by_key[item[:key]] << item
self
end
def compact
Collection.new(select { |variable| !variable.value.nil? })
end
def concat(resources)
return self if resources.nil?
tap { resources.each { |variable| self.append(variable) } }
end
def each
@variables.each { |variable| yield variable }
end
def +(other)
self.class.new.tap do |collection|
self.each { |variable| collection.append(variable) }
other.each { |variable| collection.append(variable) }
end
end
def [](key)
all(key)&.last
end
def all(key)
vars = @variables_by_key[key]
vars unless vars.empty?
end
def size
@variables.size
end
def to_runner_variables
self.map(&:to_runner_variable)
end
def to_hash
self.to_runner_variables
.to_h { |env| [env.fetch(:key), env.fetch(:value)] }
.with_indifferent_access
end
def reject(&block)
Collection.new(@variables.reject(&block))
end
def expand_value(value, keep_undefined: false, expand_file_vars: true)
value.gsub(Item::VARIABLES_REGEXP) do
match = Regexp.last_match # it is either a valid variable definition or a ($$ / %%)
full_match = match[0]
variable_name = match[:key]
next full_match unless variable_name # it is a ($$ / %%), so we don't touch it
# now we know that it is a valid variable definition: $VARIABLE_NAME / %VARIABLE_NAME / ${VARIABLE_NAME}
# we are trying to find a variable with key VARIABLE_NAME
variable = self[variable_name]
if variable # VARIABLE_NAME is an existing variable
next variable.value unless variable.file?
expand_file_vars ? variable.value : full_match
elsif keep_undefined
full_match # we do not touch the variable definition
else
nil # we remove the variable definition
end
end
end
def sort_and_expand_all(keep_undefined: false, expand_file_vars: true)
sorted = Sort.new(self)
return self.class.new(self, sorted.errors) unless sorted.valid?
new_collection = self.class.new
sorted.tsort.each do |item|
unless item.depends_on
new_collection.append(item)
next
end
# expand variables as they are added
variable = item.to_runner_variable
variable[:value] = new_collection.expand_value(variable[:value], keep_undefined: keep_undefined,
expand_file_vars: expand_file_vars)
new_collection.append(variable)
end
new_collection
end
def to_s
"#{@variables_by_key.keys}, @errors='#{@errors}'"
end
protected
attr_reader :variables
end
end
end
end
|