diff options
author | De Wet Blomerus <dewet@blomerus.org> | 2016-08-25 04:55:32 +0200 |
---|---|---|
committer | De Wet Blomerus <dewet@blomerus.org> | 2016-08-25 04:55:32 +0200 |
commit | 23bed91b3fb21a92b836011677cc75c884188f10 (patch) | |
tree | 537b13118dcaff623375ee78a1484242361d415a /app/models/concerns/has_status.rb | |
parent | 6fb46b604e4feebcbaa92d3d44d7616be709c0e5 (diff) | |
download | gitlab-ce-23bed91b3fb21a92b836011677cc75c884188f10.tar.gz |
rename Statuseable to HasStatus
Diffstat (limited to 'app/models/concerns/has_status.rb')
-rw-r--r-- | app/models/concerns/has_status.rb | 93 |
1 files changed, 93 insertions, 0 deletions
diff --git a/app/models/concerns/has_status.rb b/app/models/concerns/has_status.rb new file mode 100644 index 00000000000..f7b8352405c --- /dev/null +++ b/app/models/concerns/has_status.rb @@ -0,0 +1,93 @@ +module HasStatus + extend ActiveSupport::Concern + + AVAILABLE_STATUSES = %w[created pending running success failed canceled skipped] + STARTED_STATUSES = %w[running success failed skipped] + ACTIVE_STATUSES = %w[pending running] + COMPLETED_STATUSES = %w[success failed canceled] + + class_methods do + def status_sql + scope = all.relevant + builds = scope.select('count(*)').to_sql + success = scope.success.select('count(*)').to_sql + ignored = scope.ignored.select('count(*)').to_sql if scope.respond_to?(:ignored) + ignored ||= '0' + pending = scope.pending.select('count(*)').to_sql + running = scope.running.select('count(*)').to_sql + canceled = scope.canceled.select('count(*)').to_sql + skipped = scope.skipped.select('count(*)').to_sql + + deduce_status = "(CASE + WHEN (#{builds})=0 THEN NULL + WHEN (#{builds})=(#{skipped}) THEN 'skipped' + WHEN (#{builds})=(#{success})+(#{ignored})+(#{skipped}) THEN 'success' + WHEN (#{builds})=(#{pending})+(#{skipped}) THEN 'pending' + WHEN (#{builds})=(#{canceled})+(#{success})+(#{ignored})+(#{skipped}) THEN 'canceled' + WHEN (#{running})+(#{pending})>0 THEN 'running' + ELSE 'failed' + END)" + + deduce_status + end + + def status + all.pluck(self.status_sql).first + end + + def started_at + all.minimum(:started_at) + end + + def finished_at + all.maximum(:finished_at) + end + end + + included do + validates :status, inclusion: { in: AVAILABLE_STATUSES } + + state_machine :status, initial: :created do + state :created, value: 'created' + state :pending, value: 'pending' + state :running, value: 'running' + state :failed, value: 'failed' + state :success, value: 'success' + state :canceled, value: 'canceled' + state :skipped, value: 'skipped' + end + + scope :created, -> { where(status: 'created') } + scope :relevant, -> { where.not(status: 'created') } + scope :running, -> { where(status: 'running') } + scope :pending, -> { where(status: 'pending') } + scope :success, -> { where(status: 'success') } + scope :failed, -> { where(status: 'failed') } + scope :canceled, -> { where(status: 'canceled') } + scope :skipped, -> { where(status: 'skipped') } + scope :running_or_pending, -> { where(status: [:running, :pending]) } + scope :finished, -> { where(status: [:success, :failed, :canceled]) } + end + + def started? + STARTED_STATUSES.include?(status) && started_at + end + + def active? + ACTIVE_STATUSES.include?(status) + end + + def complete? + COMPLETED_STATUSES.include?(status) + end + + private + + def calculate_duration + if started_at && finished_at + finished_at - started_at + elsif started_at + Time.now - started_at + end + end +end |