diff options
Diffstat (limited to 'lib/gitlab/ci/config/external/mapper.rb')
-rw-r--r-- | lib/gitlab/ci/config/external/mapper.rb | 52 |
1 files changed, 45 insertions, 7 deletions
diff --git a/lib/gitlab/ci/config/external/mapper.rb b/lib/gitlab/ci/config/external/mapper.rb index def3563e505..74bd927da39 100644 --- a/lib/gitlab/ci/config/external/mapper.rb +++ b/lib/gitlab/ci/config/external/mapper.rb @@ -5,25 +5,63 @@ module Gitlab class Config module External class Mapper - def initialize(values, project, sha) - @locations = Array(values.fetch(:include, [])) + include Gitlab::Utils::StrongMemoize + + FILE_CLASSES = [ + External::File::Remote, + External::File::Template, + External::File::Local + ].freeze + + AmbigiousSpecificationError = Class.new(StandardError) + + def initialize(values, project:, sha:) + @locations = Array.wrap(values.fetch(:include, [])) @project = project @sha = sha end def process - locations.map { |location| build_external_file(location) } + locations + .compact + .map(&method(:normalize_location)) + .map(&method(:select_first_matching)) end private - attr_reader :locations, :project, :sha + attr_reader :locations, :project, :sha, :user + + # convert location if String to canonical form + def normalize_location(location) + if location.is_a?(String) + normalize_location_string(location) + else + location.deep_symbolize_keys + end + end - def build_external_file(location) + def normalize_location_string(location) if ::Gitlab::UrlSanitizer.valid?(location) - External::File::Remote.new(location) + { remote: location } else - External::File::Local.new(location, project: project, sha: sha) + { local: location } + end + end + + def select_first_matching(location) + matching = FILE_CLASSES.map do |file_class| + file_class.new(location, context) + end.select(&:matching?) + + raise AmbigiousSpecificationError, "Include `#{location.to_json}` needs to match exactly one accessor!" unless matching.one? + + matching.first + end + + def context + strong_memoize(:context) do + External::File::Base::Context.new(project, sha) end end end |