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

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'lib/gitlab/ci/badge')
-rw-r--r--lib/gitlab/ci/badge/base.rb23
-rw-r--r--lib/gitlab/ci/badge/coverage/metadata.rb30
-rw-r--r--lib/gitlab/ci/badge/coverage/report.rb75
-rw-r--r--lib/gitlab/ci/badge/coverage/template.rb64
-rw-r--r--lib/gitlab/ci/badge/metadata.rb42
-rw-r--r--lib/gitlab/ci/badge/pipeline/metadata.rb29
-rw-r--r--lib/gitlab/ci/badge/pipeline/status.rb48
-rw-r--r--lib/gitlab/ci/badge/pipeline/template.rb61
-rw-r--r--lib/gitlab/ci/badge/template.rb54
9 files changed, 426 insertions, 0 deletions
diff --git a/lib/gitlab/ci/badge/base.rb b/lib/gitlab/ci/badge/base.rb
new file mode 100644
index 00000000000..c65f120753d
--- /dev/null
+++ b/lib/gitlab/ci/badge/base.rb
@@ -0,0 +1,23 @@
+# frozen_string_literal: true
+
+module Gitlab::Ci
+ module Badge
+ class Base
+ def entity
+ raise NotImplementedError
+ end
+
+ def status
+ raise NotImplementedError
+ end
+
+ def metadata
+ raise NotImplementedError
+ end
+
+ def template
+ raise NotImplementedError
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/ci/badge/coverage/metadata.rb b/lib/gitlab/ci/badge/coverage/metadata.rb
new file mode 100644
index 00000000000..7654b6d6fc5
--- /dev/null
+++ b/lib/gitlab/ci/badge/coverage/metadata.rb
@@ -0,0 +1,30 @@
+# frozen_string_literal: true
+
+module Gitlab::Ci
+ module Badge
+ module Coverage
+ ##
+ # Class that describes coverage badge metadata
+ #
+ class Metadata < Badge::Metadata
+ def initialize(badge)
+ @project = badge.project
+ @ref = badge.ref
+ @job = badge.job
+ end
+
+ def title
+ 'coverage report'
+ end
+
+ def image_url
+ coverage_project_badges_url(@project, @ref, format: :svg)
+ end
+
+ def link_url
+ project_commits_url(@project, @ref)
+ end
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/ci/badge/coverage/report.rb b/lib/gitlab/ci/badge/coverage/report.rb
new file mode 100644
index 00000000000..28863a0703b
--- /dev/null
+++ b/lib/gitlab/ci/badge/coverage/report.rb
@@ -0,0 +1,75 @@
+# frozen_string_literal: true
+
+module Gitlab::Ci
+ module Badge
+ module Coverage
+ ##
+ # Test coverage report badge
+ #
+ class Report < Badge::Base
+ attr_reader :project, :ref, :job, :customization
+
+ def initialize(project, ref, opts: { job: nil })
+ @project = project
+ @ref = ref
+ @job = opts[:job]
+ @customization = {
+ key_width: opts[:key_width].to_i,
+ key_text: opts[:key_text]
+ }
+ end
+
+ def entity
+ 'coverage'
+ end
+
+ def status
+ @coverage ||= raw_coverage
+ return unless @coverage
+
+ @coverage.to_f.round(2)
+ end
+
+ def metadata
+ @metadata ||= Coverage::Metadata.new(self)
+ end
+
+ def template
+ @template ||= Coverage::Template.new(self)
+ end
+
+ private
+
+ def successful_pipeline
+ @successful_pipeline ||= @project.ci_pipelines.latest_successful_for_ref(@ref)
+ end
+
+ def failed_pipeline
+ @failed_pipeline ||= @project.ci_pipelines.latest_failed_for_ref(@ref)
+ end
+
+ def running_pipeline
+ @running_pipeline ||= @project.ci_pipelines.latest_running_for_ref(@ref)
+ end
+
+ def raw_coverage
+ latest =
+ if @job.present?
+ builds = ::Ci::Build
+ .in_pipelines([successful_pipeline, running_pipeline, failed_pipeline])
+ .latest
+ .success
+ .for_ref(@ref)
+ .by_name(@job)
+
+ builds.max_by(&:created_at)
+ else
+ successful_pipeline
+ end
+
+ latest&.coverage
+ end
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/ci/badge/coverage/template.rb b/lib/gitlab/ci/badge/coverage/template.rb
new file mode 100644
index 00000000000..7589fa5ff8b
--- /dev/null
+++ b/lib/gitlab/ci/badge/coverage/template.rb
@@ -0,0 +1,64 @@
+# frozen_string_literal: true
+
+module Gitlab::Ci
+ module Badge
+ module Coverage
+ ##
+ # Class that represents a coverage badge template.
+ #
+ # Template object will be passed to badge.svg.erb template.
+ #
+ class Template < Badge::Template
+ STATUS_COLOR = {
+ good: '#4c1',
+ acceptable: '#a3c51c',
+ medium: '#dfb317',
+ low: '#e05d44',
+ unknown: '#9f9f9f'
+ }.freeze
+
+ def initialize(badge)
+ @entity = badge.entity
+ @status = badge.status
+ @key_text = badge.customization.dig(:key_text)
+ @key_width = badge.customization.dig(:key_width)
+ end
+
+ def key_text
+ if @key_text && @key_text.size <= MAX_KEY_TEXT_SIZE
+ @key_text
+ else
+ @entity.to_s
+ end
+ end
+
+ def value_text
+ @status ? ("%.2f%%" % @status) : 'unknown'
+ end
+
+ def key_width
+ if @key_width && @key_width.between?(1, MAX_KEY_WIDTH)
+ @key_width
+ else
+ 62
+ end
+ end
+
+ def value_width
+ @status ? 54 : 58
+ end
+
+ def value_color
+ case @status
+ when 95..100 then STATUS_COLOR[:good]
+ when 90..95 then STATUS_COLOR[:acceptable]
+ when 75..90 then STATUS_COLOR[:medium]
+ when 0..75 then STATUS_COLOR[:low]
+ else
+ STATUS_COLOR[:unknown]
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/ci/badge/metadata.rb b/lib/gitlab/ci/badge/metadata.rb
new file mode 100644
index 00000000000..eec9fedfaa9
--- /dev/null
+++ b/lib/gitlab/ci/badge/metadata.rb
@@ -0,0 +1,42 @@
+# frozen_string_literal: true
+
+module Gitlab::Ci
+ module Badge
+ ##
+ # Abstract class for badge metadata
+ #
+ class Metadata
+ include Gitlab::Routing
+ include ActionView::Helpers::AssetTagHelper
+ include ActionView::Helpers::UrlHelper
+
+ def initialize(badge)
+ @badge = badge
+ end
+
+ def to_html
+ link_to(image_tag(image_url, alt: title), link_url)
+ end
+
+ def to_markdown
+ "[![#{title}](#{image_url})](#{link_url})"
+ end
+
+ def to_asciidoc
+ "image:#{image_url}[link=\"#{link_url}\",title=\"#{title}\"]"
+ end
+
+ def title
+ raise NotImplementedError
+ end
+
+ def image_url
+ raise NotImplementedError
+ end
+
+ def link_url
+ raise NotImplementedError
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/ci/badge/pipeline/metadata.rb b/lib/gitlab/ci/badge/pipeline/metadata.rb
new file mode 100644
index 00000000000..2aa08476336
--- /dev/null
+++ b/lib/gitlab/ci/badge/pipeline/metadata.rb
@@ -0,0 +1,29 @@
+# frozen_string_literal: true
+
+module Gitlab::Ci
+ module Badge
+ module Pipeline
+ ##
+ # Class that describes pipeline badge metadata
+ #
+ class Metadata < Badge::Metadata
+ def initialize(badge)
+ @project = badge.project
+ @ref = badge.ref
+ end
+
+ def title
+ 'pipeline status'
+ end
+
+ def image_url
+ pipeline_project_badges_url(@project, @ref, format: :svg)
+ end
+
+ def link_url
+ project_commits_url(@project, id: @ref)
+ end
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/ci/badge/pipeline/status.rb b/lib/gitlab/ci/badge/pipeline/status.rb
new file mode 100644
index 00000000000..a2ee2642872
--- /dev/null
+++ b/lib/gitlab/ci/badge/pipeline/status.rb
@@ -0,0 +1,48 @@
+# frozen_string_literal: true
+
+module Gitlab::Ci
+ module Badge
+ module Pipeline
+ ##
+ # Pipeline status badge
+ #
+ class Status < Badge::Base
+ attr_reader :project, :ref, :customization
+
+ def initialize(project, ref, opts: {})
+ @project = project
+ @ref = ref
+ @ignore_skipped = Gitlab::Utils.to_boolean(opts[:ignore_skipped], default: false)
+ @customization = {
+ key_width: opts[:key_width].to_i,
+ key_text: opts[:key_text]
+ }
+
+ @sha = @project.commit(@ref).try(:sha)
+ end
+
+ def entity
+ 'pipeline'
+ end
+
+ # rubocop: disable CodeReuse/ActiveRecord
+ def status
+ pipelines = @project.ci_pipelines
+ .where(sha: @sha)
+
+ relation = @ignore_skipped ? pipelines.without_statuses([:skipped]) : pipelines
+ relation.latest_status(@ref) || 'unknown'
+ end
+ # rubocop: enable CodeReuse/ActiveRecord
+
+ def metadata
+ @metadata ||= Pipeline::Metadata.new(self)
+ end
+
+ def template
+ @template ||= Pipeline::Template.new(self)
+ end
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/ci/badge/pipeline/template.rb b/lib/gitlab/ci/badge/pipeline/template.rb
new file mode 100644
index 00000000000..8430b01fc9a
--- /dev/null
+++ b/lib/gitlab/ci/badge/pipeline/template.rb
@@ -0,0 +1,61 @@
+# frozen_string_literal: true
+
+module Gitlab::Ci
+ module Badge
+ module Pipeline
+ ##
+ # Class that represents a pipeline badge template.
+ #
+ # Template object will be passed to badge.svg.erb template.
+ #
+ class Template < Badge::Template
+ STATUS_RENAME = { 'success' => 'passed' }.freeze
+ STATUS_COLOR = {
+ success: '#4c1',
+ failed: '#e05d44',
+ running: '#dfb317',
+ pending: '#dfb317',
+ preparing: '#a7a7a7',
+ canceled: '#9f9f9f',
+ skipped: '#9f9f9f',
+ unknown: '#9f9f9f'
+ }.freeze
+
+ def initialize(badge)
+ @entity = badge.entity
+ @status = badge.status
+ @key_text = badge.customization.dig(:key_text)
+ @key_width = badge.customization.dig(:key_width)
+ end
+
+ def key_text
+ if @key_text && @key_text.size <= MAX_KEY_TEXT_SIZE
+ @key_text
+ else
+ @entity.to_s
+ end
+ end
+
+ def value_text
+ STATUS_RENAME[@status.to_s] || @status.to_s
+ end
+
+ def key_width
+ if @key_width && @key_width.between?(1, MAX_KEY_WIDTH)
+ @key_width
+ else
+ 62
+ end
+ end
+
+ def value_width
+ 54
+ end
+
+ def value_color
+ STATUS_COLOR[@status.to_sym] || STATUS_COLOR[:unknown]
+ end
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/ci/badge/template.rb b/lib/gitlab/ci/badge/template.rb
new file mode 100644
index 00000000000..0580dad72ba
--- /dev/null
+++ b/lib/gitlab/ci/badge/template.rb
@@ -0,0 +1,54 @@
+# frozen_string_literal: true
+
+module Gitlab::Ci
+ module Badge
+ ##
+ # Abstract template class for badges
+ #
+ class Template
+ MAX_KEY_TEXT_SIZE = 64
+ MAX_KEY_WIDTH = 512
+
+ def initialize(badge)
+ @entity = badge.entity
+ @status = badge.status
+ end
+
+ def key_text
+ raise NotImplementedError
+ end
+
+ def value_text
+ raise NotImplementedError
+ end
+
+ def key_width
+ raise NotImplementedError
+ end
+
+ def value_width
+ raise NotImplementedError
+ end
+
+ def value_color
+ raise NotImplementedError
+ end
+
+ def key_color
+ '#555'
+ end
+
+ def key_text_anchor
+ key_width / 2
+ end
+
+ def value_text_anchor
+ key_width + (value_width / 2)
+ end
+
+ def width
+ key_width + value_width
+ end
+ end
+ end
+end