require 'parallel' module FireWatch class ReportBuilder ISSUE_REGEX = /.?#(\d+)/ attr_reader :github_client, :harvest_client, :github_repos, :harvest_clients, :harvest_projects, :harvest_users, :time_entries def initialize(github_client:, harvest_client:) @github_client = github_client @harvest_client = harvest_client @github_repos, @harvest_clients, @harvest_projects, @harvest_users = Parallel.map([ @github_client.repos.list(org: 'wildland').sort_by{|r| r.name}, @harvest_client.clients.all, @harvest_client.projects.all, @harvest_client.users.all ]) {|j| j} end def issue_pull_request_report(selected_github_repo:, selected_github_milestones:, selected_harvest_projects:) @time_entries = Parallel.map( selected_harvest_projects.select{|p| !p.starts_on.nil?}.map do |project| @harvest_client.reports.time_by_project( project, Time.parse(project.starts_on), project.ends_on.nil? ? Time.now : Time.parse(project.ends_on) ) end ){|j| j} @time_entries.flatten! github_report = [] selected_github_milestones.each do |selected_milestone| issues, pull_request_issues = @github_client.issues.list(user: 'wildland', repo: selected_github_repo.name, milestone: selected_milestone.number, state: 'all').partition{|i| i.pull_request == nil} pull_requests = pull_request_issues.map do |i| @github_client.pull_requests.get(user: 'wildland', repo: selected_github_repo.name, number: i.number).body end issues.each do |issue| github_report << report_line( issue: issue, pull_request: nil, selected_github_repo: selected_github_repo, selected_github_milestone: selected_milestone ) end pull_requests.each do |pr| github_report << report_line( issue: pr, pull_request: pr, selected_github_repo: selected_github_repo, selected_github_milestone: selected_milestone ) end end return github_report, @time_entries.map do |e| { time_entry: e, harvest_user: @harvest_users.find{|u| u.id == e.user_id} } end # TODO format time_entries that are missing end def report_line(issue:, pull_request:, selected_github_repo:, selected_github_milestone:) github_report_line = { github_repo: selected_github_repo, github_milestone: selected_github_milestone, github_estimated_size_label: !issue.labels.nil? && !issue.labels.find{|l| l.name.include?"size:"}.nil? ? issue.labels.find{|l| l.name.include?"size:"} : nil, issue: issue, pull_request: pull_request, harvest_time_entries: [] } relevant_time_entries, @time_entries = @time_entries.partition do |entry| entry.notes.nil? ? false : entry.notes.scan(ISSUE_REGEX).flatten.any?{|m| m.eql? github_report_line[:issue].number.to_s } end if !relevant_time_entries.empty? relevant_time_entries.chunk{|i| i.user_id }.each do |user_id, user_time_entries| user = harvest_users.find{|u| u.id == user_id} github_report_line[:harvest_time_entries] << { harvest_user: user, time_entries: user_time_entries, harvest_projects: @harvest_projects.select{|p| user_time_entries.map(&:project_id).uniq.include? p.id} } end @time_entries.concat relevant_time_entries.select { |entry| entry.notes.nil? ? false : entry.notes.scan(ISSUE_REGEX).flatten.count > 1 } end return github_report_line end end end