1# frozen_string_literal: true 2 3module Gitlab 4 module Ci 5 module Charts 6 class Chart 7 attr_reader :from, :to, :labels, :total, :success, :project, :pipeline_times 8 9 def initialize(project) 10 @labels = [] 11 @total = [] 12 @success = [] 13 @pipeline_times = [] 14 @project = project 15 16 collect 17 end 18 19 private 20 21 attr_reader :interval 22 23 # rubocop: disable CodeReuse/ActiveRecord 24 def collect 25 query = project.all_pipelines 26 .where(::Ci::Pipeline.arel_table['created_at'].gteq(@from)) 27 .where(::Ci::Pipeline.arel_table['created_at'].lteq(@to)) 28 29 totals_count = grouped_count(query) 30 success_count = grouped_count(query.success) 31 32 current = @from 33 while current <= @to 34 label = current.strftime(@format) 35 @labels << label 36 @total << (totals_count[label] || 0) 37 @success << (success_count[label] || 0) 38 39 current += interval_step 40 end 41 end 42 # rubocop: enable CodeReuse/ActiveRecord 43 44 # rubocop: disable CodeReuse/ActiveRecord 45 def grouped_count(query) 46 query 47 .group("date_trunc('#{interval}', #{::Ci::Pipeline.table_name}.created_at)") 48 .count(:created_at) 49 .transform_keys { |date| date.strftime(@format) } 50 end 51 # rubocop: enable CodeReuse/ActiveRecord 52 53 def interval_step 54 @interval_step ||= 1.public_send(interval) # rubocop: disable GitlabSecurity/PublicSend 55 end 56 end 57 58 class YearChart < Chart 59 def initialize(*) 60 @to = Date.today.end_of_month.end_of_day 61 @from = (@to - 1.year).beginning_of_month.beginning_of_day 62 @interval = :month 63 @format = '%B %Y' 64 65 super 66 end 67 end 68 69 class MonthChart < Chart 70 def initialize(*) 71 @to = Date.today.end_of_day 72 @from = (@to - 1.month).beginning_of_day 73 @interval = :day 74 @format = '%d %B' 75 76 super 77 end 78 end 79 80 class WeekChart < Chart 81 def initialize(*) 82 @to = Date.today.end_of_day 83 @from = (@to - 1.week).beginning_of_day 84 @interval = :day 85 @format = '%d %B' 86 87 super 88 end 89 end 90 91 class PipelineTime < Chart 92 def collect 93 commits = project.all_pipelines.last(30) 94 95 commits.each do |commit| 96 @labels << commit.short_sha 97 duration = commit.duration || 0 98 @pipeline_times << (duration / 60) 99 end 100 end 101 end 102 end 103 end 104end 105