diff options
author | Grzegorz Bizon <grzesiek.bizon@gmail.com> | 2017-09-14 12:59:41 +0200 |
---|---|---|
committer | Grzegorz Bizon <grzesiek.bizon@gmail.com> | 2017-09-18 13:57:14 +0200 |
commit | 241197c29aa8fe3cae9e5ded9947cfb2bee3574c (patch) | |
tree | 90a15cad60fcd756ee90d89ae5dbdfea3351352a /lib | |
parent | dd784b1518501032e01e521adbf6ecf98d54ba55 (diff) | |
download | gitlab-ce-241197c29aa8fe3cae9e5ded9947cfb2bee3574c.tar.gz |
Extract job refs policy specs into separate class
Diffstat (limited to 'lib')
-rw-r--r-- | lib/gitlab/ci/build/policy/refs.rb | 50 | ||||
-rw-r--r-- | lib/gitlab/ci/yaml_processor.rb | 75 |
2 files changed, 59 insertions, 66 deletions
diff --git a/lib/gitlab/ci/build/policy/refs.rb b/lib/gitlab/ci/build/policy/refs.rb new file mode 100644 index 00000000000..4f2bbd9eaac --- /dev/null +++ b/lib/gitlab/ci/build/policy/refs.rb @@ -0,0 +1,50 @@ +module Gitlab + module Ci + module Build + module Policy + class Refs < Policy::Specification + def initialize(refs) + @patterns = Array(refs) + end + + def satisfied_by?(pipeline, path:) + @patterns.any? do |pattern| + pattern, ref_path = pattern.split('@', 2) + + matches_path?(ref_path, path) && + matches_pattern?(pattern, pipeline) + end + end + + private + + def matches_path?(ref_path, expected_path) + return true unless ref_path + + expected_path == ref_path + end + + def matches_pattern?(pattern, pipeline) + return true if pipeline.tag? && pattern == 'tags' + return true if !pipeline.tag? && pattern == 'branches' + return true if source_to_pattern(pipeline.source) == pattern + + if pattern.first == "/" && pattern.last == "/" + Regexp.new(pattern[1...-1]) =~ pipeline.ref + else + pattern == pipeline.ref + end + end + + def source_to_pattern(source) + if %w[api external web].include?(source) + source + else + source&.pluralize + end + end + end + end + end + end +end diff --git a/lib/gitlab/ci/yaml_processor.rb b/lib/gitlab/ci/yaml_processor.rb index 44e616c01e5..d688683474c 100644 --- a/lib/gitlab/ci/yaml_processor.rb +++ b/lib/gitlab/ci/yaml_processor.rb @@ -21,10 +21,11 @@ module Gitlab raise ValidationError, e.message end + + # REFACTORING STUB, remove this method, used only in tests. + # def builds_for_stage_and_ref(stage, ref, tag = false, source = nil) - jobs_for_stage_and_ref(stage, ref, tag, source).map do |name, _| - build_attributes(name) - end + pipeline_stage_builds(stage, ::Ci::Pipeline.new(ref: ref, source: source, tag: tag)) end def builds @@ -84,32 +85,19 @@ module Gitlab private def pipeline_stage_builds(stage, pipeline) - builds = builds_for_stage_and_ref( - stage, pipeline.ref, pipeline.tag?, pipeline.source) - - builds.select do |build| - job = @jobs[build.fetch(:name).to_sym] + stage_jobs = @jobs.select do |_, job| + next unless job[:stage] == stage only_specs = Gitlab::Ci::Build::Policy .fabricate(job.fetch(:only, {})) except_specs = Gitlab::Ci::Build::Policy .fabricate(job.fetch(:except, {})) - only_specs.all? { |spec| spec.satisfied_by?(pipeline) } && - except_specs.none? { |spec| spec.satisfied_by?(pipeline) } - end - end - - def jobs_for_ref(ref, tag = false, source = nil) - @jobs.select do |_, job| - process?(job.dig(:only, :refs), job.dig(:except, :refs), ref, tag, source) + only_specs.all? { |spec| spec.satisfied_by?(pipeline, path: @path) } && + except_specs.none? { |spec| spec.satisfied_by?(pipeline, path: @path) } end - end - def jobs_for_stage_and_ref(stage, ref, tag = false, source = nil) - jobs_for_ref(ref, tag, source).select do |_, job| - job[:stage] == stage - end + stage_jobs.map { |_, job| build_attributes(job[:name]) } end def initial_parsing @@ -204,51 +192,6 @@ module Gitlab raise ValidationError, "#{name} job: on_stop job #{on_stop} needs to have action stop defined" end end - - def process?(only_params, except_params, ref, tag, source) - if only_params.present? - return false unless matching?(only_params, ref, tag, source) - end - - if except_params.present? - return false if matching?(except_params, ref, tag, source) - end - - true - end - - def matching?(patterns, ref, tag, source) - patterns.any? do |pattern| - pattern, path = pattern.split('@', 2) - matches_path?(path) && matches_pattern?(pattern, ref, tag, source) - end - end - - def matches_path?(path) - return true unless path - - path == self.path - end - - def matches_pattern?(pattern, ref, tag, source) - return true if tag && pattern == 'tags' - return true if !tag && pattern == 'branches' - return true if source_to_pattern(source) == pattern - - if pattern.first == "/" && pattern.last == "/" - Regexp.new(pattern[1...-1]) =~ ref - else - pattern == ref - end - end - - def source_to_pattern(source) - if %w[api external web].include?(source) - source - else - source&.pluralize - end - end end end end |