Skip to content

Instantly share code, notes, and snippets.

@jamesarosen
Created December 13, 2016 21:45
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jamesarosen/4ef8a26f10727a85a7cc497143bd35fb to your computer and use it in GitHub Desktop.
Save jamesarosen/4ef8a26f10727a85a7cc497143bd35fb to your computer and use it in GitHub Desktop.
List Top N closed/merged pull requests for a GitHub repository, ordered by number of days open
const RSVP = require('rsvp');
const moment = require('moment');
const GITHUB_API_TOKEN = process.env.GITHUB_API_TOKEN;
const GITHUB_USER = process.env.GITHUB_USER;
const GITHUB_REPO = process.env.GITHUB_REPO;
const TOP_N = 30;
fetchAllPRs();
function fetchAllPRs() {
const GH = require('github');
const gh = new GH({ version: '3.0.0', protocol: 'https' });
gh.authenticate({ type: 'oauth', token: GITHUB_API_TOKEN });
fetchPRsStartingAtPage(0, gh)
.then(sortPRs)
.then(function(prs) { return prs.slice(0, TOP_N); })
.then(printPRs);
}
function fetchPRsStartingAtPage(page, gh) {
console.log(`fetching page ${page} of PRs`);
return new RSVP.Promise(function(resolve, reject) {
const query = {
user: GITHUB_USER,
repo: GITHUB_REPO,
state: 'closed',
direction: 'desc',
per_page: 100,
page
};
gh.pullRequests.getAll(query, function(err, thisPage) {
if (err || thisPage.length === 0) { return resolve([]); }
fetchPRsStartingAtPage(page + 1, gh)
.then(function(nextPage) {
resolve(nextPage.concat(thisPage));
});
});
});
}
function sortPRs(prs) {
return prs.sort(function(a, b) {
return daysOpen(b) - daysOpen(a);
});
}
function printPRs(prs) {
console.log(`Number ${trimPad('Title', 50)} Closed Days Open Merged?`);
console.log(new Array(91).join('='));
prs.forEach(function(pr) {
const number = trimPad(pr.number, 6);
const title = trimPad(pr.title, 50);
const closed = formatDate(pr.merged_at || pr.closed_at);
const days = trimPad(daysOpen(pr).toFixed(1), 9);
const merged = pr.merged_at ? 'Y' : '';
console.log(`${number} ${title} ${closed} ${days} ${merged}`);
});
}
function trimPad(string, length) {
string = '' + string;
if (string.length < length) {
return string + (new Array(length + 1 - string.length)).join(' ');
}
if (string.length === length) {
return string;
}
return string.slice(0, length - 3) + '...';
}
function formatDate(date) {
if (date == null) { return ' -- '; }
return moment(date).format('YYYY-MM-DD');
}
function daysOpen(pr) {
const closed = pr.merged_at || pr.closed_at;
const opened = pr.created_at;
if (closed == null || opened == null) return 0;
return (moment(closed) - moment(opened)) / (1000 * 60 * 60 * 24);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment