diff options
author | James Lopez <james@jameslopez.es> | 2016-12-02 17:09:29 +0100 |
---|---|---|
committer | James Lopez <james@jameslopez.es> | 2017-01-17 11:32:55 +0100 |
commit | b214be493d9f179d4a929ee32d94a336da7b38f1 (patch) | |
tree | f669ed4d895e4e97cb050e22e210fe90cb57ba0d /lib/gitlab | |
parent | daa4f3ded718f4144877b7f0402bd495151c28de (diff) | |
download | gitlab-ce-b214be493d9f179d4a929ee32d94a336da7b38f1.tar.gz |
big refactor based on MR feedback
Diffstat (limited to 'lib/gitlab')
21 files changed, 123 insertions, 117 deletions
diff --git a/lib/gitlab/cycle_analytics/base_event.rb b/lib/gitlab/cycle_analytics/base_event_fetcher.rb index 2ce9c34d8e8..0d851f81b1d 100644 --- a/lib/gitlab/cycle_analytics/base_event.rb +++ b/lib/gitlab/cycle_analytics/base_event_fetcher.rb @@ -1,15 +1,15 @@ module Gitlab module CycleAnalytics - class BaseEvent + class BaseEventFetcher include MetricsTables - include ClassNameUtil - attr_reader :start_time_attrs, :end_time_attrs, :projections, :query + attr_reader :projections, :query, :stage - def initialize(fetcher:, options:) + def initialize(fetcher:, options:, stage:) @fetcher = fetcher @project = fetcher.project @options = options + @stage = stage end def fetch @@ -26,10 +26,6 @@ module Gitlab @order || @start_time_attrs end - def stage - class_name_for('Event') - end - private def update_author! diff --git a/lib/gitlab/cycle_analytics/base_stage.rb b/lib/gitlab/cycle_analytics/base_stage.rb index 551318f536a..f3b8bb6e1d3 100644 --- a/lib/gitlab/cycle_analytics/base_stage.rb +++ b/lib/gitlab/cycle_analytics/base_stage.rb @@ -1,18 +1,23 @@ module Gitlab module CycleAnalytics class BaseStage - include ClassNameUtil + attr_accessor :start_time_attrs, :end_time_attrs def initialize(project:, options:) @project = project @options = options @fetcher = Gitlab::CycleAnalytics::MetricsFetcher.new(project: project, from: options[:from], - branch: options[:branch]) + branch: options[:branch], + stage: self) + end + + def event + @event ||= Gitlab::CycleAnalytics::Event[stage].new(fetcher: @fetcher, options: @options) end def events - Gitlab::CycleAnalytics::Event[stage].new(fetcher: @fetcher, options: @options).fetch + event.fetch end def median_data @@ -24,7 +29,7 @@ module Gitlab end def median - raise NotImplementedError.new("Expected #{self.name} to implement median") + @fetcher.median end private diff --git a/lib/gitlab/cycle_analytics/class_name_util.rb b/lib/gitlab/cycle_analytics/class_name_util.rb deleted file mode 100644 index aac8d888077..00000000000 --- a/lib/gitlab/cycle_analytics/class_name_util.rb +++ /dev/null @@ -1,13 +0,0 @@ -module Gitlab - module CycleAnalytics - module ClassNameUtil - def class_name_for(type) - class_name.split(type).first.to_sym - end - - def class_name - self.class.name.demodulize - end - end - end -end diff --git a/lib/gitlab/cycle_analytics/review_event.rb b/lib/gitlab/cycle_analytics/code_event_fetcher.rb index 3f9ffa9657b..5245b9ca8fc 100644 --- a/lib/gitlab/cycle_analytics/review_event.rb +++ b/lib/gitlab/cycle_analytics/code_event_fetcher.rb @@ -1,21 +1,22 @@ module Gitlab module CycleAnalytics - class ReviewEvent < BaseEvent + class CodeEventFetcher < BaseEventFetcher include MergeRequestAllowed def initialize(*args) - @start_time_attrs = mr_table[:created_at] - @end_time_attrs = mr_metrics_table[:merged_at] @projections = [mr_table[:title], mr_table[:iid], mr_table[:id], mr_table[:created_at], mr_table[:state], mr_table[:author_id]] + @order = mr_table[:created_at] super(*args) end + private + def serialize(event) AnalyticsMergeRequestSerializer.new(project: @project).represent(event).as_json end diff --git a/lib/gitlab/cycle_analytics/code_stage.rb b/lib/gitlab/cycle_analytics/code_stage.rb index 778ce7b5435..977d0d0210c 100644 --- a/lib/gitlab/cycle_analytics/code_stage.rb +++ b/lib/gitlab/cycle_analytics/code_stage.rb @@ -1,14 +1,19 @@ module Gitlab module CycleAnalytics class CodeStage < BaseStage - def description - "Time until first merge request" + def initialize(*args) + @start_time_attrs = issue_metrics_table[:first_mentioned_in_commit_at] + @end_time_attrs = mr_table[:created_at] + + super(*args) end - def median - @fetcher.median(:code, - Issue::Metrics.arel_table[:first_mentioned_in_commit_at], - MergeRequest.arel_table[:created_at]) + def stage + :code + end + + def description + "Time until first merge request" end end end diff --git a/lib/gitlab/cycle_analytics/event.rb b/lib/gitlab/cycle_analytics/event.rb index 62fac89a0d5..bb3a5722a0f 100644 --- a/lib/gitlab/cycle_analytics/event.rb +++ b/lib/gitlab/cycle_analytics/event.rb @@ -2,7 +2,7 @@ module Gitlab module CycleAnalytics module Event def self.[](stage_name) - const_get("::Gitlab::CycleAnalytics::#{stage_name.to_s.camelize}Event") + CycleAnalytics.const_get("#{stage_name.to_s.camelize}Event") end end end diff --git a/lib/gitlab/cycle_analytics/production_event.rb b/lib/gitlab/cycle_analytics/issue_event_fetcher.rb index c03cd4f4909..0d8da99455e 100644 --- a/lib/gitlab/cycle_analytics/production_event.rb +++ b/lib/gitlab/cycle_analytics/issue_event_fetcher.rb @@ -1,11 +1,9 @@ module Gitlab module CycleAnalytics - class ProductionEvent < BaseEvent + class IssueEventFetcher < BaseEventFetcher include IssueAllowed def initialize(*args) - @start_time_attrs = issue_table[:created_at] - @end_time_attrs = mr_metrics_table[:first_deployed_to_production_at] @projections = [issue_table[:title], issue_table[:iid], issue_table[:id], diff --git a/lib/gitlab/cycle_analytics/issue_stage.rb b/lib/gitlab/cycle_analytics/issue_stage.rb index c317872fb1d..14e72c7ea48 100644 --- a/lib/gitlab/cycle_analytics/issue_stage.rb +++ b/lib/gitlab/cycle_analytics/issue_stage.rb @@ -1,15 +1,20 @@ module Gitlab module CycleAnalytics class IssueStage < BaseStage - def description - "Time before an issue gets scheduled" + def initialize(*args) + @start_time_attrs = issue_table[:created_at] + @end_time_attrs = [issue_metrics_table[:first_associated_with_milestone_at], + issue_metrics_table[:first_added_to_board_at]] + + super(*args) end - def median - @fetcher.median(:issue, - Issue.arel_table[:created_at], - [Issue::Metrics.arel_table[:first_associated_with_milestone_at], - Issue::Metrics.arel_table[:first_added_to_board_at]]) + def stage + :issue + end + + def description + "Time before an issue gets scheduled" end end end diff --git a/lib/gitlab/cycle_analytics/metrics_fetcher.rb b/lib/gitlab/cycle_analytics/metrics_fetcher.rb index 0542fbfb38d..865abd0fa6c 100644 --- a/lib/gitlab/cycle_analytics/metrics_fetcher.rb +++ b/lib/gitlab/cycle_analytics/metrics_fetcher.rb @@ -9,14 +9,15 @@ module Gitlab DEPLOYMENT_METRIC_STAGES = %i[production staging] - def initialize(project:, from:, branch:) + def initialize(project:, from:, branch:, stage:) @project = project @from = from @branch = branch + @stage = stage end - def median(name, start_time_attrs, end_time_attrs) - cte_table = Arel::Table.new("cte_table_for_#{name}") + def median + cte_table = Arel::Table.new("cte_table_for_#{@stage.stage}") # Build a `SELECT` query. We find the first of the `end_time_attrs` that isn't `NULL` (call this end_time). # Next, we find the first of the start_time_attrs that isn't `NULL` (call this start_time). @@ -24,24 +25,26 @@ module Gitlab # cycle analytics stage. interval_query = Arel::Nodes::As.new( cte_table, - subtract_datetimes(base_query_for(name), start_time_attrs, end_time_attrs, name.to_s)) + subtract_datetimes(base_query_for(name), @stage.start_time_attrs, @stage.end_time_attrs, @stage.stage.to_s)) median_datetime(cte_table, interval_query, name) end - def events(stage_class) - ActiveRecord::Base.connection.exec_query(events_query(stage_class).to_sql) + def events + ActiveRecord::Base.connection.exec_query(events_query.to_sql) end private - def events_query(stage_class) - base_query = base_query_for(stage_class.stage) - diff_fn = subtract_datetimes_diff(base_query, stage_class.start_time_attrs, stage_class.end_time_attrs) + def events_query + base_query = base_query_for(@stage.stage) + event = @stage.event - stage_class.custom_query(base_query) + diff_fn = subtract_datetimes_diff(base_query, @stage.start_time_attrs, @stage.end_time_attrs) - base_query.project(extract_diff_epoch(diff_fn).as('total_time'), *stage_class.projections).order(stage_class.order.desc) + event_instance.custom_query(base_query) + + base_query.project(extract_diff_epoch(diff_fn).as('total_time'), *event.projections).order(event.order.desc) end # Join table with a row for every <issue,merge_request> pair (where the merge request diff --git a/lib/gitlab/cycle_analytics/plan_event.rb b/lib/gitlab/cycle_analytics/plan_event_fetcher.rb index 4b06143495b..3e23c5644d3 100644 --- a/lib/gitlab/cycle_analytics/plan_event.rb +++ b/lib/gitlab/cycle_analytics/plan_event_fetcher.rb @@ -1,10 +1,7 @@ module Gitlab module CycleAnalytics - class PlanEvent < BaseEvent + class PlanEventFetcher < BaseEventFetcher def initialize(*args) - @start_time_attrs = issue_metrics_table[:first_associated_with_milestone_at] - @end_time_attrs = [issue_metrics_table[:first_added_to_board_at], - issue_metrics_table[:first_mentioned_in_commit_at]] @projections = [mr_diff_table[:st_commits].as('commits'), issue_metrics_table[:first_mentioned_in_commit_at]] diff --git a/lib/gitlab/cycle_analytics/plan_stage.rb b/lib/gitlab/cycle_analytics/plan_stage.rb index 5e6dd30d9e3..de2d5aaeb23 100644 --- a/lib/gitlab/cycle_analytics/plan_stage.rb +++ b/lib/gitlab/cycle_analytics/plan_stage.rb @@ -1,15 +1,20 @@ module Gitlab module CycleAnalytics class PlanStage < BaseStage - def description - "Time before an issue starts implementation" + def initialize(*args) + @start_time_attrs = [issue_metrics_table[:first_associated_with_milestone_at], + issue_metrics_table[:first_added_to_board_at]] + @end_time_attrs = issue_metrics_table[:first_mentioned_in_commit_at] + + super(*args) end - def median - @fetcher.median(:plan, - [Issue::Metrics.arel_table[:first_associated_with_milestone_at], - Issue::Metrics.arel_table[:first_added_to_board_at]], - Issue::Metrics.arel_table[:first_mentioned_in_commit_at]) + def stage + :code + end + + def description + "Time before an issue starts implementation" end end end diff --git a/lib/gitlab/cycle_analytics/issue_event.rb b/lib/gitlab/cycle_analytics/production_event_fetcher.rb index 76e8decf36e..b7eff7d22f4 100644 --- a/lib/gitlab/cycle_analytics/issue_event.rb +++ b/lib/gitlab/cycle_analytics/production_event_fetcher.rb @@ -1,12 +1,9 @@ module Gitlab module CycleAnalytics - class IssueEvent < BaseEvent + class ProductionEventFetcher < BaseEventFetcher include IssueAllowed def initialize(*args) - @start_time_attrs = issue_table[:created_at] - @end_time_attrs = [issue_metrics_table[:first_associated_with_milestone_at], - issue_metrics_table[:first_added_to_board_at]] @projections = [issue_table[:title], issue_table[:iid], issue_table[:id], diff --git a/lib/gitlab/cycle_analytics/production_stage.rb b/lib/gitlab/cycle_analytics/production_stage.rb index acd2f7b2b3b..104c6d3fd30 100644 --- a/lib/gitlab/cycle_analytics/production_stage.rb +++ b/lib/gitlab/cycle_analytics/production_stage.rb @@ -1,14 +1,19 @@ module Gitlab module CycleAnalytics class ProductionStage < BaseStage - def description - "From issue creation until deploy to production" + def initialize(*args) + @start_time_attrs = issue_table[:created_at] + @end_time_attrs = mr_metrics_table[:first_deployed_to_production_at] + + super(*args) end - def median - @fetcher.median(:production, - Issue.arel_table[:created_at], - MergeRequest::Metrics.arel_table[:first_deployed_to_production_at]) + def stage + :production + end + + def description + "From issue creation until deploy to production" end end end diff --git a/lib/gitlab/cycle_analytics/code_event.rb b/lib/gitlab/cycle_analytics/review_event_fetcher.rb index 68251630e08..4df0bd06393 100644 --- a/lib/gitlab/cycle_analytics/code_event.rb +++ b/lib/gitlab/cycle_analytics/review_event_fetcher.rb @@ -1,24 +1,19 @@ module Gitlab module CycleAnalytics - class CodeEvent < BaseEvent + class ReviewEventFetcher < BaseEventFetcher include MergeRequestAllowed def initialize(*args) - @start_time_attrs = issue_metrics_table[:first_mentioned_in_commit_at] - @end_time_attrs = mr_table[:created_at] @projections = [mr_table[:title], mr_table[:iid], mr_table[:id], mr_table[:created_at], mr_table[:state], mr_table[:author_id]] - @order = mr_table[:created_at] super(*args) end - private - def serialize(event) AnalyticsMergeRequestSerializer.new(project: @project).represent(event).as_json end diff --git a/lib/gitlab/cycle_analytics/review_stage.rb b/lib/gitlab/cycle_analytics/review_stage.rb index c7b5e34e16a..c7bbd29693b 100644 --- a/lib/gitlab/cycle_analytics/review_stage.rb +++ b/lib/gitlab/cycle_analytics/review_stage.rb @@ -1,14 +1,19 @@ module Gitlab module CycleAnalytics class ReviewStage < BaseStage - def description - "Time between merge request creation and merge/close" + def initialize(*args) + @start_time_attrs = mr_table[:created_at] + @end_time_attrs = mr_metrics_table[:merged_at] + + super(*args) end - def median - @fetcher.median(:review, - MergeRequest.arel_table[:created_at], - MergeRequest::Metrics.arel_table[:merged_at]) + def stage + :review + end + + def description + "Time between merge request creation and merge/close" end end end diff --git a/lib/gitlab/cycle_analytics/stage.rb b/lib/gitlab/cycle_analytics/stage.rb index acf746db6cd..28e0455df59 100644 --- a/lib/gitlab/cycle_analytics/stage.rb +++ b/lib/gitlab/cycle_analytics/stage.rb @@ -2,7 +2,7 @@ module Gitlab module CycleAnalytics module Stage def self.[](stage_name) - const_get("::Gitlab::CycleAnalytics::#{stage_name.to_s.camelize}Stage") + CycleAnalytics.const_get("#{stage_name.to_s.camelize}Stage") end end end diff --git a/lib/gitlab/cycle_analytics/staging_event.rb b/lib/gitlab/cycle_analytics/staging_event_fetcher.rb index eae18b447f0..ea98e211ad6 100644 --- a/lib/gitlab/cycle_analytics/staging_event.rb +++ b/lib/gitlab/cycle_analytics/staging_event_fetcher.rb @@ -1,9 +1,7 @@ module Gitlab module CycleAnalytics - class StagingEvent < BaseEvent + class StagingEventFetcher < BaseEventFetcher def initialize(*args) - @start_time_attrs = mr_metrics_table[:merged_at] - @end_time_attrs = mr_metrics_table[:first_deployed_to_production_at] @projections = [build_table[:id]] @order = build_table[:created_at] diff --git a/lib/gitlab/cycle_analytics/staging_stage.rb b/lib/gitlab/cycle_analytics/staging_stage.rb index b715a9453c7..079b26760bb 100644 --- a/lib/gitlab/cycle_analytics/staging_stage.rb +++ b/lib/gitlab/cycle_analytics/staging_stage.rb @@ -1,14 +1,19 @@ module Gitlab module CycleAnalytics class StagingStage < BaseStage - def description - "From merge request merge until deploy to production" + def initialize(*args) + @start_time_attrs = mr_metrics_table[:merged_at] + @end_time_attrs = mr_metrics_table[:first_deployed_to_production_at] + + super(*args) end - def median - @fetcher.median(:staging, - MergeRequest::Metrics.arel_table[:merged_at], - MergeRequest::Metrics.arel_table[:first_deployed_to_production_at]) + def stage + :staging + end + + def description + "From merge request merge until deploy to production" end end end diff --git a/lib/gitlab/cycle_analytics/test_event.rb b/lib/gitlab/cycle_analytics/test_event.rb deleted file mode 100644 index d0736672adf..00000000000 --- a/lib/gitlab/cycle_analytics/test_event.rb +++ /dev/null @@ -1,12 +0,0 @@ -module Gitlab - module CycleAnalytics - class TestEvent < StagingEvent - def initialize(*args) - super(*args) - - @start_time_attrs = mr_metrics_table[:latest_build_started_at] - @end_time_attrs = mr_metrics_table[:latest_build_finished_at] - end - end - end -end diff --git a/lib/gitlab/cycle_analytics/test_event_fetcher.rb b/lib/gitlab/cycle_analytics/test_event_fetcher.rb new file mode 100644 index 00000000000..a2589c6601a --- /dev/null +++ b/lib/gitlab/cycle_analytics/test_event_fetcher.rb @@ -0,0 +1,6 @@ +module Gitlab + module CycleAnalytics + class TestEventFetcher < StagingEventFetcher + end + end +end diff --git a/lib/gitlab/cycle_analytics/test_stage.rb b/lib/gitlab/cycle_analytics/test_stage.rb index 58f72bb405e..a105e5f2b1f 100644 --- a/lib/gitlab/cycle_analytics/test_stage.rb +++ b/lib/gitlab/cycle_analytics/test_stage.rb @@ -1,14 +1,19 @@ module Gitlab module CycleAnalytics class TestStage < BaseStage - def description - "Total test time for all commits/merges" + def initialize(*args) + @start_time_attrs = mr_metrics_table[:latest_build_started_at] + @end_time_attrs = mr_metrics_table[:latest_build_finished_at] + + super(*args) end - def median - @fetcher.median(:test, - MergeRequest::Metrics.arel_table[:latest_build_started_at], - MergeRequest::Metrics.arel_table[:latest_build_finished_at]) + def stage + :test + end + + def description + "Total test time for all commits/merges" end end end |