2019-02-05 12:16:18 -05:00
|
|
|
# frozen_string_literal: true
|
|
|
|
|
2021-01-20 07:11:06 -05:00
|
|
|
module Tooling
|
2019-02-05 12:16:18 -05:00
|
|
|
module Danger
|
|
|
|
class Teammate
|
2021-01-07 04:10:22 -05:00
|
|
|
attr_reader :options, :username, :name, :role, :projects, :available, :hungry, :reduced_capacity, :tz_offset_hours
|
2020-05-14 11:08:14 -04:00
|
|
|
|
2020-06-17 14:09:08 -04:00
|
|
|
# The options data are produced by https://gitlab.com/gitlab-org/gitlab-roulette/-/blob/master/lib/team_member.rb
|
2019-02-05 12:16:18 -05:00
|
|
|
def initialize(options = {})
|
2020-07-22 17:09:50 -04:00
|
|
|
@options = options
|
2019-02-05 12:16:18 -05:00
|
|
|
@username = options['username']
|
2020-06-17 14:09:08 -04:00
|
|
|
@name = options['name']
|
|
|
|
@markdown_name = options['markdown_name']
|
2019-05-23 14:07:59 -04:00
|
|
|
@role = options['role']
|
2019-02-05 12:16:18 -05:00
|
|
|
@projects = options['projects']
|
2020-06-17 14:09:08 -04:00
|
|
|
@available = options['available']
|
2020-09-21 14:09:58 -04:00
|
|
|
@hungry = options['hungry']
|
2021-01-07 04:10:22 -05:00
|
|
|
@reduced_capacity = options['reduced_capacity']
|
2020-07-07 17:09:13 -04:00
|
|
|
@tz_offset_hours = options['tz_offset_hours']
|
2019-02-05 12:16:18 -05:00
|
|
|
end
|
|
|
|
|
2020-07-22 17:09:50 -04:00
|
|
|
def to_h
|
|
|
|
options
|
|
|
|
end
|
|
|
|
|
|
|
|
def ==(other)
|
|
|
|
return false unless other.respond_to?(:username)
|
|
|
|
|
|
|
|
other.username == username
|
|
|
|
end
|
|
|
|
|
2019-02-05 12:16:18 -05:00
|
|
|
def in_project?(name)
|
|
|
|
projects&.has_key?(name)
|
|
|
|
end
|
|
|
|
|
2021-01-22 10:09:08 -05:00
|
|
|
def any_capability?(project, category)
|
|
|
|
capabilities(project).any? { |capability| capability.end_with?(category.to_s) }
|
|
|
|
end
|
|
|
|
|
2019-05-23 14:07:59 -04:00
|
|
|
def reviewer?(project, category, labels)
|
2020-09-29 14:09:52 -04:00
|
|
|
has_capability?(project, category, :reviewer, labels)
|
2019-02-05 12:16:18 -05:00
|
|
|
end
|
|
|
|
|
2019-05-23 14:07:59 -04:00
|
|
|
def traintainer?(project, category, labels)
|
|
|
|
has_capability?(project, category, :trainee_maintainer, labels)
|
2019-02-05 12:16:18 -05:00
|
|
|
end
|
|
|
|
|
2019-05-23 14:07:59 -04:00
|
|
|
def maintainer?(project, category, labels)
|
|
|
|
has_capability?(project, category, :maintainer, labels)
|
2019-02-05 12:16:18 -05:00
|
|
|
end
|
|
|
|
|
2020-08-25 08:04:30 -04:00
|
|
|
def markdown_name(author: nil)
|
2020-07-07 17:09:13 -04:00
|
|
|
"#{@markdown_name} (#{utc_offset_text(author)})"
|
|
|
|
end
|
|
|
|
|
|
|
|
def local_hour
|
|
|
|
(Time.now.utc + tz_offset_hours * 3600).hour
|
|
|
|
end
|
|
|
|
|
|
|
|
protected
|
|
|
|
|
|
|
|
def floored_offset_hours
|
|
|
|
floored_offset = tz_offset_hours.floor(0)
|
|
|
|
|
|
|
|
floored_offset == tz_offset_hours ? floored_offset : tz_offset_hours
|
|
|
|
end
|
|
|
|
|
2019-10-16 17:07:22 -04:00
|
|
|
private
|
|
|
|
|
2020-07-07 17:09:13 -04:00
|
|
|
def utc_offset_text(author = nil)
|
|
|
|
offset_text =
|
|
|
|
if floored_offset_hours >= 0
|
|
|
|
"UTC+#{floored_offset_hours}"
|
|
|
|
else
|
|
|
|
"UTC#{floored_offset_hours}"
|
|
|
|
end
|
|
|
|
|
|
|
|
return offset_text unless author
|
|
|
|
|
|
|
|
"#{offset_text}, #{offset_diff_compared_to_author(author)}"
|
|
|
|
end
|
|
|
|
|
|
|
|
def offset_diff_compared_to_author(author)
|
|
|
|
diff = floored_offset_hours - author.floored_offset_hours
|
2020-08-05 11:09:59 -04:00
|
|
|
return "same timezone as `@#{author.username}`" if diff == 0
|
2020-07-07 17:09:13 -04:00
|
|
|
|
2020-08-03 17:09:40 -04:00
|
|
|
ahead_or_behind = diff < 0 ? 'behind' : 'ahead of'
|
2020-07-08 08:09:33 -04:00
|
|
|
pluralized_hours = pluralize(diff.abs, 'hour', 'hours')
|
2020-07-07 17:09:13 -04:00
|
|
|
|
2020-07-08 08:09:33 -04:00
|
|
|
"#{pluralized_hours} #{ahead_or_behind} `@#{author.username}`"
|
2020-07-07 17:09:13 -04:00
|
|
|
end
|
|
|
|
|
2019-05-23 14:07:59 -04:00
|
|
|
def has_capability?(project, category, kind, labels)
|
|
|
|
case category
|
|
|
|
when :test
|
2019-11-22 16:06:19 -05:00
|
|
|
area = role[/Software Engineer in Test(?:.*?, (\w+))/, 1]
|
2019-05-23 14:07:59 -04:00
|
|
|
|
2019-08-27 13:13:55 -04:00
|
|
|
area && labels.any?("devops::#{area.downcase}") if kind == :reviewer
|
2019-09-03 18:02:55 -04:00
|
|
|
when :engineering_productivity
|
2019-10-31 08:06:26 -04:00
|
|
|
return false unless role[/Engineering Productivity/]
|
|
|
|
return true if kind == :reviewer
|
2020-12-21 04:10:07 -05:00
|
|
|
return true if capabilities(project).include?("#{kind} engineering_productivity")
|
2019-10-31 08:06:26 -04:00
|
|
|
|
|
|
|
capabilities(project).include?("#{kind} backend")
|
2019-05-23 14:07:59 -04:00
|
|
|
else
|
|
|
|
capabilities(project).include?("#{kind} #{category}")
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2019-02-05 12:16:18 -05:00
|
|
|
def capabilities(project)
|
2019-03-06 11:00:27 -05:00
|
|
|
Array(projects.fetch(project, []))
|
2019-02-05 12:16:18 -05:00
|
|
|
end
|
2020-07-08 08:09:33 -04:00
|
|
|
|
|
|
|
def pluralize(count, singular, plural)
|
|
|
|
word = count == 1 || count.to_s =~ /^1(\.0+)?$/ ? singular : plural
|
|
|
|
|
|
|
|
"#{count || 0} #{word}"
|
|
|
|
end
|
2019-02-05 12:16:18 -05:00
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|