|
7 | 7 | const htmlparser = require('htmlparser'); |
8 | 8 | const moment = require('moment'); |
9 | 9 |
|
10 | | - const fetchContribs = async (user, since, until, ora, console) => { |
| 10 | + const fetchContribs = async (user, since, until, ora, console, alsoIssues) => { |
11 | 11 | ora = ora || (() => { |
12 | 12 | return { |
13 | 13 | start() { return this; }, |
|
21 | 21 | }; |
22 | 22 |
|
23 | 23 | const joinDate = await getFirstDayAtGithub(user, ora); |
24 | | - const result = await getContribs(user, joinDate, since, until, ora, console); |
| 24 | + const result = await getContribs(user, joinDate, since, until, ora, console, alsoIssues); |
25 | 25 | return result; |
26 | 26 | }; |
27 | 27 |
|
|
82 | 82 | return result; |
83 | 83 | }; |
84 | 84 |
|
85 | | - const getContribs = async (user, joinDate, since, until, ora, console) => { |
| 85 | + const getContribs = async (user, joinDate, since, until, ora, console, alsoIssues) => { |
86 | 86 | const commitsHtmlToRepos = html => { |
87 | 87 | const repos = new Set(); |
88 | 88 |
|
|
116 | 116 | return repos; |
117 | 117 | }; |
118 | 118 |
|
119 | | - const prsHtmlToRepos = html => { |
| 119 | + const issuesHtmlToRepos = html => { |
120 | 120 | const repos = new Set(); |
121 | 121 |
|
122 | 122 | const handler = new htmlparser.DefaultHandler((error, dom) => {}); |
|
149 | 149 | return repos; |
150 | 150 | }; |
151 | 151 |
|
| 152 | + const hotIssuesHtmlToRepos = html => { |
| 153 | + const repos = new Set(); |
| 154 | + |
| 155 | + const regex = /<a.*href="\/(.*)\/(.*)\/issues\//g; |
| 156 | + let linkToIssue; |
| 157 | + while ((linkToIssue = regex.exec(html))) { |
| 158 | + const owner = linkToIssue[1]; |
| 159 | + const name = linkToIssue[2]; |
| 160 | + repos.add(`${owner}/${name}`); |
| 161 | + } |
| 162 | + |
| 163 | + return repos; |
| 164 | + }; |
| 165 | + |
| 166 | + const progressMsg = (isDone, alsoIssues, numOfQueriedDays, numOfDaysToQuery) => { |
| 167 | + let result = (isDone && 'Fetched') || 'Fetching'; |
| 168 | + result += ' all commits'; |
| 169 | + result += (alsoIssues && ', PRs and issues') || ' and PRs'; |
| 170 | + |
| 171 | + if (isDone) { |
| 172 | + result += '.'; |
| 173 | + } else if (numOfQueriedDays && numOfDaysToQuery) { |
| 174 | + result += ` [${numOfQueriedDays}/${numOfDaysToQuery}]`; |
| 175 | + } else { |
| 176 | + result += '...'; |
| 177 | + } |
| 178 | + |
| 179 | + if (!alsoIssues) { |
| 180 | + result += ' Consider using --issues to fetch issues as well.'; |
| 181 | + } |
| 182 | + return result; |
| 183 | + }; |
| 184 | + |
152 | 185 | let oldestDate = joinDate; |
153 | 186 | if (since) { |
154 | 187 | oldestDate = new Date(Math.max(oldestDate, stringToDate(since))); |
|
175 | 208 | `https://github.com/users/${user}/created_commits?from=${currDateStr}&to=${currDateStr}` |
176 | 209 | ); |
177 | 210 | const userCommitsHtml = await userCommits.text(); |
| 211 | + const commitsRepos = commitsHtmlToRepos(userCommitsHtml); |
| 212 | + |
178 | 213 | const userPRs = await fetchRetry( |
179 | 214 | `https://github.com/users/${user}/created_pull_requests?from=${currDateStr}&to=${currDateStr}`, |
180 | 215 | ); |
181 | 216 | const userPRsHtml = await userPRs.text(); |
182 | | - const commitsRepos = commitsHtmlToRepos(userCommitsHtml); |
183 | | - const prsRepos = prsHtmlToRepos(userPRsHtml); |
| 217 | + const prsRepos = issuesHtmlToRepos(userPRsHtml); |
| 218 | + |
| 219 | + let issuesRepos = []; |
| 220 | + let hotIssuesRepos = []; |
| 221 | + if (alsoIssues) { |
| 222 | + const userIssues = await fetchRetry( |
| 223 | + `https://github.com/users/${user}/created_issues?from=${currDateStr}&to=${currDateStr}`, |
| 224 | + ); |
| 225 | + const userIssuesHtml = await userIssues.text(); |
| 226 | + issuesRepos = issuesHtmlToRepos(userIssuesHtml); |
| 227 | + |
| 228 | + const userHotIssues = await fetchRetry( |
| 229 | + `https://github.com/${user}?from=${currDateStr}`, |
| 230 | + ); |
| 231 | + const userHotIssuesHtml = await userHotIssues.text(); |
| 232 | + hotIssuesRepos = hotIssuesHtmlToRepos(userHotIssuesHtml); |
| 233 | + } |
| 234 | + |
184 | 235 | progressSpinner.stop(); // temporary stop for logging |
185 | 236 | for (const repo of commitsRepos) { |
186 | | - console.log(`${currDateStr}: (commits) ${repo}`); |
| 237 | + console.log(`${currDateStr}: (commits) ${repo}`); |
187 | 238 | result.add(repo); |
188 | 239 | } |
189 | 240 | for (const repo of prsRepos) { |
190 | | - console.log(`${currDateStr}: (PRs) ${repo}`); |
| 241 | + console.log(`${currDateStr}: (PRs) ${repo}`); |
| 242 | + result.add(repo); |
| 243 | + } |
| 244 | + for (const repo of issuesRepos) { |
| 245 | + console.log(`${currDateStr}: (issues) ${repo}`); |
191 | 246 | result.add(repo); |
192 | 247 | } |
193 | | - progressSpinner.start(`Fetching all commits and PRs [${++numOfQueriedDays}/${numOfDaysToQuery}]`); |
| 248 | + for (const repo of hotIssuesRepos) { |
| 249 | + console.log(`${currDateStr}: (hot issues) ${repo}`); |
| 250 | + result.add(repo); |
| 251 | + } |
| 252 | + progressSpinner.start( |
| 253 | + progressMsg(false, alsoIssues, ++numOfQueriedDays, numOfDaysToQuery) |
| 254 | + ); |
194 | 255 | })(); |
195 | 256 | }; |
196 | 257 | })(); |
|
205 | 266 | ora(warning).warn(); |
206 | 267 |
|
207 | 268 | const result = new Set(); |
208 | | - const progressSpinner = ora('Fetching all commits and PRs...').start(); |
| 269 | + const progressSpinner = ora(progressMsg(false, alsoIssues)).start(); |
209 | 270 | await new PromisePool(getContribsOnOneDay, 5).start(); |
210 | | - progressSpinner.succeed('Fetched all commits and PRs.'); |
| 271 | + progressSpinner.succeed(progressMsg(true, alsoIssues)); |
211 | 272 | return result; |
212 | 273 | }; |
213 | 274 |
|
|
0 commit comments