Commit 5f502c3a authored by Grzegorz Bizon's avatar Grzegorz Bizon

Move external CI config class into proper namespace

parent 7acc6340
...@@ -15,7 +15,7 @@ module Gitlab ...@@ -15,7 +15,7 @@ module Gitlab
@global.compose! @global.compose!
rescue Loader::FormatError, Extendable::ExtensionError => e rescue Loader::FormatError, Extendable::ExtensionError => e
raise Config::ConfigError, e.message raise Config::ConfigError, e.message
rescue ::Gitlab::Ci::External::Processor::FileError => e rescue External::Processor::FileError => e
raise ::Gitlab::Ci::YamlProcessor::ValidationError, e.message raise ::Gitlab::Ci::YamlProcessor::ValidationError, e.message
end end
...@@ -81,7 +81,7 @@ module Gitlab ...@@ -81,7 +81,7 @@ module Gitlab
def process_external_files(config, project, opts) def process_external_files(config, project, opts)
sha = opts.fetch(:sha) { project.repository.root_ref_sha } sha = opts.fetch(:sha) { project.repository.root_ref_sha }
::Gitlab::Ci::External::Processor.new(config, project, sha).perform Config::External::Processor.new(config, project, sha).perform
end end
end end
end end
......
...@@ -2,25 +2,27 @@ ...@@ -2,25 +2,27 @@
module Gitlab module Gitlab
module Ci module Ci
module External class Config
module File module External
class Base module File
YAML_WHITELIST_EXTENSION = /(yml|yaml)$/i.freeze class Base
YAML_WHITELIST_EXTENSION = /(yml|yaml)$/i.freeze
def initialize(location, opts = {}) def initialize(location, opts = {})
@location = location @location = location
end end
def valid? def valid?
location.match(YAML_WHITELIST_EXTENSION) && content location.match(YAML_WHITELIST_EXTENSION) && content
end end
def content def content
raise NotImplementedError, 'content must be implemented and return a string or nil' raise NotImplementedError, 'content must be implemented and return a string or nil'
end end
def error_message def error_message
raise NotImplementedError, 'error_message must be implemented and return a string' raise NotImplementedError, 'error_message must be implemented and return a string'
end
end end
end end
end end
......
...@@ -2,30 +2,32 @@ ...@@ -2,30 +2,32 @@
module Gitlab module Gitlab
module Ci module Ci
module External class Config
module File module External
class Local < Base module File
attr_reader :location, :project, :sha class Local < Base
attr_reader :location, :project, :sha
def initialize(location, opts = {}) def initialize(location, opts = {})
super super
@project = opts.fetch(:project) @project = opts.fetch(:project)
@sha = opts.fetch(:sha) @sha = opts.fetch(:sha)
end end
def content def content
@content ||= fetch_local_content @content ||= fetch_local_content
end end
def error_message def error_message
"Local file '#{location}' is not valid." "Local file '#{location}' is not valid."
end end
private private
def fetch_local_content def fetch_local_content
project.repository.blob_data_at(sha, location) project.repository.blob_data_at(sha, location)
end
end end
end end
end end
......
...@@ -2,26 +2,28 @@ ...@@ -2,26 +2,28 @@
module Gitlab module Gitlab
module Ci module Ci
module External class Config
module File module External
class Remote < Base module File
include Gitlab::Utils::StrongMemoize class Remote < Base
attr_reader :location include Gitlab::Utils::StrongMemoize
attr_reader :location
def content def content
return @content if defined?(@content) return @content if defined?(@content)
@content = strong_memoize(:content) do @content = strong_memoize(:content) do
begin begin
Gitlab::HTTP.get(location) Gitlab::HTTP.get(location)
rescue Gitlab::HTTP::Error, Timeout::Error, SocketError, Gitlab::HTTP::BlockedUrlError rescue Gitlab::HTTP::Error, Timeout::Error, SocketError, Gitlab::HTTP::BlockedUrlError
nil nil
end
end end
end end
end
def error_message def error_message
"Remote file '#{location}' is not valid." "Remote file '#{location}' is not valid."
end
end end
end end
end end
......
...@@ -2,28 +2,29 @@ ...@@ -2,28 +2,29 @@
module Gitlab module Gitlab
module Ci module Ci
module External class Config
class Mapper module External
def initialize(values, project, sha) class Mapper
@locations = Array(values.fetch(:include, [])) def initialize(values, project, sha)
@project = project @locations = Array(values.fetch(:include, []))
@sha = sha @project = project
end @sha = sha
end
def process def process
locations.map { |location| build_external_file(location) } locations.map { |location| build_external_file(location) }
end end
private private
attr_reader :locations, :project, :sha attr_reader :locations, :project, :sha
def build_external_file(location) def build_external_file(location)
if ::Gitlab::UrlSanitizer.valid?(location) if ::Gitlab::UrlSanitizer.valid?(location)
Gitlab::Ci::External::File::Remote.new(location) External::File::Remote.new(location)
else else
options = { project: project, sha: sha } External::File::Local.new(location, project: project, sha: sha)
Gitlab::Ci::External::File::Local.new(location, options) end
end end
end end
end end
......
...@@ -2,49 +2,51 @@ ...@@ -2,49 +2,51 @@
module Gitlab module Gitlab
module Ci module Ci
module External class Config
class Processor module External
FileError = Class.new(StandardError) class Processor
FileError = Class.new(StandardError)
def initialize(values, project, sha)
@values = values def initialize(values, project, sha)
@external_files = Gitlab::Ci::External::Mapper.new(values, project, sha).process @values = values
@content = {} @external_files = External::Mapper.new(values, project, sha).process
end @content = {}
end
def perform def perform
return values if external_files.empty? return values if external_files.empty?
external_files.each do |external_file| external_files.each do |external_file|
validate_external_file(external_file) validate_external_file(external_file)
@content.deep_merge!(content_of(external_file)) @content.deep_merge!(content_of(external_file))
end end
append_inline_content append_inline_content
remove_include_keyword remove_include_keyword
end end
private private
attr_reader :values, :external_files, :content attr_reader :values, :external_files, :content
def validate_external_file(external_file) def validate_external_file(external_file)
unless external_file.valid? unless external_file.valid?
raise FileError, external_file.error_message raise FileError, external_file.error_message
end
end end
end
def content_of(external_file) def content_of(external_file)
Gitlab::Ci::Config::Loader.new(external_file.content).load! Config::Loader.new(external_file.content).load!
end end
def append_inline_content def append_inline_content
@content.deep_merge!(@values) @content.deep_merge!(@values)
end end
def remove_include_keyword def remove_include_keyword
content.delete(:include) content.delete(:include)
content content
end
end end
end end
end end
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
require 'spec_helper' require 'spec_helper'
describe Gitlab::Ci::External::File::Local do describe Gitlab::Ci::Config::External::File::Local do
let(:project) { create(:project, :repository) } let(:project) { create(:project, :repository) }
let(:local_file) { described_class.new(location, { project: project, sha: '12345' }) } let(:local_file) { described_class.new(location, { project: project, sha: '12345' }) }
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
require 'spec_helper' require 'spec_helper'
describe Gitlab::Ci::External::File::Remote do describe Gitlab::Ci::Config::External::File::Remote do
let(:remote_file) { described_class.new(location) } let(:remote_file) { described_class.new(location) }
let(:location) { 'https://gitlab.com/gitlab-org/gitlab-ce/blob/1234/.gitlab-ci-1.yml' } let(:location) { 'https://gitlab.com/gitlab-org/gitlab-ce/blob/1234/.gitlab-ci-1.yml' }
let(:remote_file_content) do let(:remote_file_content) do
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
require 'spec_helper' require 'spec_helper'
describe Gitlab::Ci::External::Mapper do describe Gitlab::Ci::Config::External::Mapper do
let(:project) { create(:project, :repository) } let(:project) { create(:project, :repository) }
let(:file_content) do let(:file_content) do
<<~HEREDOC <<~HEREDOC
...@@ -27,7 +27,8 @@ describe Gitlab::Ci::External::Mapper do ...@@ -27,7 +27,8 @@ describe Gitlab::Ci::External::Mapper do
end end
it 'returns File instances' do it 'returns File instances' do
expect(subject.first).to be_an_instance_of(Gitlab::Ci::External::File::Local) expect(subject.first)
.to be_an_instance_of(Gitlab::Ci::Config::External::File::Local)
end end
end end
...@@ -49,7 +50,8 @@ describe Gitlab::Ci::External::Mapper do ...@@ -49,7 +50,8 @@ describe Gitlab::Ci::External::Mapper do
end end
it 'returns File instances' do it 'returns File instances' do
expect(subject.first).to be_an_instance_of(Gitlab::Ci::External::File::Remote) expect(subject.first)
.to be_an_instance_of(Gitlab::Ci::Config::External::File::Remote)
end end
end end
end end
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
require 'spec_helper' require 'spec_helper'
describe Gitlab::Ci::External::Processor do describe Gitlab::Ci::Config::External::Processor do
let(:project) { create(:project, :repository) } let(:project) { create(:project, :repository) }
let(:processor) { described_class.new(values, project, '12345') } let(:processor) { described_class.new(values, project, '12345') }
...@@ -92,7 +92,8 @@ describe Gitlab::Ci::External::Processor do ...@@ -92,7 +92,8 @@ describe Gitlab::Ci::External::Processor do
end end
before do before do
allow_any_instance_of(Gitlab::Ci::External::File::Local).to receive(:fetch_local_content).and_return(local_file_content) allow_any_instance_of(Gitlab::Ci::Config::External::File::Local)
.to receive(:fetch_local_content).and_return(local_file_content)
end end
it 'should append the file to the values' do it 'should append the file to the values' do
...@@ -131,7 +132,10 @@ describe Gitlab::Ci::External::Processor do ...@@ -131,7 +132,10 @@ describe Gitlab::Ci::External::Processor do
before do before do
local_file_content = File.read(Rails.root.join('spec/fixtures/gitlab/ci/external_files/.gitlab-ci-template-1.yml')) local_file_content = File.read(Rails.root.join('spec/fixtures/gitlab/ci/external_files/.gitlab-ci-template-1.yml'))
allow_any_instance_of(Gitlab::Ci::External::File::Local).to receive(:fetch_local_content).and_return(local_file_content)
allow_any_instance_of(Gitlab::Ci::Config::External::File::Local)
.to receive(:fetch_local_content).and_return(local_file_content)
WebMock.stub_request(:get, remote_file).to_return(body: remote_file_content) WebMock.stub_request(:get, remote_file).to_return(body: remote_file_content)
end end
...@@ -150,7 +154,8 @@ describe Gitlab::Ci::External::Processor do ...@@ -150,7 +154,8 @@ describe Gitlab::Ci::External::Processor do
let(:local_file_content) { 'invalid content file ////' } let(:local_file_content) { 'invalid content file ////' }
before do before do
allow_any_instance_of(Gitlab::Ci::External::File::Local).to receive(:fetch_local_content).and_return(local_file_content) allow_any_instance_of(Gitlab::Ci::Config::External::File::Local)
.to receive(:fetch_local_content).and_return(local_file_content)
end end
it 'should raise an error' do it 'should raise an error' do
......
require 'fast_spec_helper' require 'spec_helper'
require_dependency 'active_model'
describe Gitlab::Ci::Config do describe Gitlab::Ci::Config do
let(:config) do let(:config) do
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment