1 | Configuration = require './configuration'
|
2 | _ = require('underscore')._
|
3 | _.str = require 'underscore.string'
|
4 | _.mixin _.str.exports()
|
5 |
|
6 | Github = Configuration.Github
|
7 | Async = require 'async'
|
8 | Moment = require 'moment'
|
9 |
|
10 | Utils = require './utils'
|
11 | GhHelpers = require './gh_helpers'
|
12 |
|
13 |
|
14 | pulls = (fallback, keyword, filter, extra) ->
|
15 |
|
16 |
|
17 |
|
18 | args = keyword + ' ' + filter + ' ' + extra
|
19 | match = GhHelpers.githubPRUrlMatching(args)
|
20 | if (match?)
|
21 | getInfoPulls match, (error, results) ->
|
22 | if (error?)
|
23 | Utils.fallback_printError(fallback, error)
|
24 | else
|
25 | Utils.fallback_printList fallback, results
|
26 |
|
27 | else
|
28 | getAllRepos keyword, filter, Github.Org, 1, [], (err, list) ->
|
29 | if (err?)
|
30 | Utils.fallback_printError(fallback, err)
|
31 | else
|
32 | Utils.fallback_printList fallback,
|
33 | list, _.partial(pickLastIfNeeded, keyword, filter)
|
34 |
|
35 | getInfoPulls = (list, callback) ->
|
36 | Async.map list, (match, cb) ->
|
37 | getInfoPull match.org, match.repo, match.number, cb
|
38 | , callback
|
39 |
|
40 | getInfoPull = (org, reponame, number, callback) ->
|
41 | Github.Api.pullRequests.get {
|
42 | user: org,
|
43 | repo: reponame,
|
44 | number: number
|
45 | }, (error, details) =>
|
46 | if (error?)
|
47 | callback(error)
|
48 | else
|
49 | Github.Api.statuses.get {
|
50 | user: org,
|
51 | repo: reponame,
|
52 | sha: details.head.sha
|
53 | }, (error, statuses) ->
|
54 | if (error?)
|
55 | callback(error)
|
56 | else
|
57 | callback null, {
|
58 | title: details.title,
|
59 | url: details.html_url,
|
60 | infos: reponame,
|
61 | comments: "(#{details.head.ref} -> #{details.base.ref}) - " +
|
62 | Moment(details.created_at).fromNow() + " - " +
|
63 | details.comments + " comments" +
|
64 | needAttention(details.mergeable, details.state),
|
65 | status: GhHelpers.buildStatus(statuses),
|
66 | avatar: details.user.gravatar_id,
|
67 | order: details.created_at
|
68 | }
|
69 | isRepoInFilters = (name) ->
|
70 | _.some Configuration.Github.Filters, (filter) ->
|
71 | _.str.include name, filter
|
72 |
|
73 | checkRecentDate = (createdAt, filter) ->
|
74 | period = if filter? then filter else 'weeks'
|
75 |
|
76 | thisUnit = Moment().subtract(period, 1)
|
77 | Moment(createdAt).isAfter(thisUnit)
|
78 |
|
79 | shouldBeDisplayed = (keyword, filter, title, createdAt) ->
|
80 | if (keyword is 'last' and filter? and _.isNaN(parseInt(filter)))
|
81 | keyword = 'with'
|
82 |
|
83 | if (keyword is 'recent' and createdAt?)
|
84 | checkRecentDate(createdAt, filter)
|
85 | else if (not filter?) then true
|
86 | else
|
87 | term = filter.toLowerCase()
|
88 | query = title.toLowerCase()
|
89 | if (keyword is 'without' and _.str.include(query, term)) then false
|
90 | else if (keyword is 'with' and not _.str.include(query, term)) then false
|
91 | else true
|
92 |
|
93 | pickLastIfNeeded = (keyword, filter, list) ->
|
94 | if (keyword is 'last')
|
95 | number = if (filter? and not _.isNaN(parseInt(filter)))
|
96 | parseInt(filter)
|
97 | else 1
|
98 |
|
99 | _.first(list, number)
|
100 | else list
|
101 |
|
102 | needAttention = (mergeable, state) ->
|
103 | warning = ""
|
104 | warning = if not mergeable then " - *NEED REBASE*" else warning
|
105 | warning = if state is 'closed' then " - *CLOSED*" else warning
|
106 | warning
|
107 |
|
108 | getAllRepos = (keyword, filter, org, page, acc, globalCb) ->
|
109 | Github.Api.repos.getFromOrg { org: org, page: page, per_page: 100 }, (error, repos) ->
|
110 | if (error? or _.isEmpty(repos))
|
111 | globalCb(error, acc)
|
112 | else
|
113 | Async.concat repos, (repo, callback) ->
|
114 | if (isRepoInFilters(repo.name))
|
115 | Github.Api.pullRequests.getAll { user: Github.Org, repo: repo.name }, (error, prs) ->
|
116 | if (error?)
|
117 | callback error, []
|
118 | else
|
119 | Async.reduce prs, [],
|
120 | Async.apply (memo, pr, cb) ->
|
121 | query = pr.title + repo.name + pr.user.login
|
122 | if (shouldBeDisplayed(keyword, filter, query, pr.created_at))
|
123 | getInfoPull Github.Org, repo.name, pr.number, (error, r) ->
|
124 | memo.push r
|
125 | cb error, memo
|
126 | else
|
127 | cb(error, memo)
|
128 | , (err, list) ->
|
129 | callback(err, list)
|
130 | else
|
131 | callback null, []
|
132 | , (err, result) ->
|
133 | if (err?)
|
134 | globalCb(err, null)
|
135 | else
|
136 | getAllRepos(keyword, filter, org, parseInt(page) + 1, acc.concat(result), globalCb)
|
137 |
|
138 | module.exports = {
|
139 | name: "Pull Requests"
|
140 | description: "[ -url[s]- |
|
141 | without -filter- | with -filter- |
|
142 | recent [-unit-] |
|
143 | last [-number- | -filter-]
|
144 | ] List all Pull Requests of the organisation",
|
145 | action: pulls,
|
146 | isRepoInFilters: isRepoInFilters,
|
147 | shouldBeDisplayed: shouldBeDisplayed,
|
148 | pickLastIfNeeded: pickLastIfNeeded
|
149 | }
|