Welcome to mirror list, hosted at ThFree Co, Russian Federation.

base.rb « tags « yaml « config « ci « gitlab « lib - gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 13416a4afb6c223e57e0a5becd431e1f267f9226 (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
# frozen_string_literal: true

module Gitlab
  module Ci
    class Config
      module Yaml
        module Tags
          class Base
            CircularReferenceError = Class.new(Tags::TagError)
            NotValidError = Class.new(Tags::TagError)

            extend ::Gitlab::Utils::Override

            attr_accessor :resolved_status, :resolved_value, :data

            def self.tag
              raise NotImplementedError
            end

            # Only one of the `seq`, `scalar`, `map` fields is available.
            def init_with(coder)
              @data = {
                tag: coder.tag,       # This is the custom YAML tag, like !reference or !flatten
                style: coder.style,
                seq: coder.seq,       # This holds Array data
                scalar: coder.scalar, # This holds data of basic types, like String.
                map: coder.map        # This holds Hash data.
              }
            end

            def valid?
              raise NotImplementedError
            end

            def resolve(resolver)
              raise NotValidError, validation_error_message unless valid?
              raise CircularReferenceError, circular_error_message if resolving?
              return resolved_value if resolved?

              self.resolved_status = :in_progress
              self.resolved_value = _resolve(resolver)
              self.resolved_status = :done
              resolved_value
            end

            private

            def _resolve(resolver)
              raise NotImplementedError
            end

            def resolved?
              resolved_status == :done
            end

            def resolving?
              resolved_status == :in_progress
            end

            def circular_error_message
              "#{data[:tag]} #{data[:seq].inspect} is part of a circular chain"
            end

            def validation_error_message
              "#{data[:tag]} #{(data[:scalar].presence || data[:map].presence || data[:seq]).inspect} is not valid"
            end
          end
        end
      end
    end
  end
end