summaryrefslogtreecommitdiff
path: root/lib/gitlab/ci/config/entry/node.rb
diff options
context:
space:
mode:
Diffstat (limited to 'lib/gitlab/ci/config/entry/node.rb')
-rw-r--r--lib/gitlab/ci/config/entry/node.rb83
1 files changed, 83 insertions, 0 deletions
diff --git a/lib/gitlab/ci/config/entry/node.rb b/lib/gitlab/ci/config/entry/node.rb
new file mode 100644
index 00000000000..5eef2868cd6
--- /dev/null
+++ b/lib/gitlab/ci/config/entry/node.rb
@@ -0,0 +1,83 @@
+module Gitlab
+ module Ci
+ class Config
+ module Entry
+ ##
+ # Base abstract class for each configuration entry node.
+ #
+ class Node
+ class InvalidError < StandardError; end
+
+ attr_reader :config, :metadata
+ attr_accessor :key, :parent, :description
+
+ def initialize(config, **metadata)
+ @config = config
+ @metadata = metadata
+ @entries = {}
+
+ @validator = self.class.validator.new(self)
+ @validator.validate(:new)
+ end
+
+ def [](key)
+ @entries[key] || Entry::Undefined.new
+ end
+
+ def compose!(deps = nil)
+ return unless valid?
+
+ yield if block_given?
+ end
+
+ def leaf?
+ @entries.none?
+ end
+
+ def descendants
+ @entries.values
+ end
+
+ def ancestors
+ @parent ? @parent.ancestors + [@parent] : []
+ end
+
+ def valid?
+ errors.none?
+ end
+
+ def errors
+ @validator.messages + descendants.flat_map(&:errors)
+ end
+
+ def value
+ if leaf?
+ @config
+ else
+ meaningful = @entries.select do |_key, value|
+ value.specified? && value.relevant?
+ end
+
+ Hash[meaningful.map { |key, entry| [key, entry.value] }]
+ end
+ end
+
+ def specified?
+ true
+ end
+
+ def relevant?
+ true
+ end
+
+ def self.default
+ end
+
+ def self.validator
+ Validator
+ end
+ end
+ end
+ end
+ end
+end