Skip to content

Instantly share code, notes, and snippets.

@crucialfelix
Last active November 11, 2016 17:48
Show Gist options
  • Select an option

  • Save crucialfelix/c37441a2381efbfe97fbcc8ca286f061 to your computer and use it in GitHub Desktop.

Select an option

Save crucialfelix/c37441a2381efbfe97fbcc8ca286f061 to your computer and use it in GitHub Desktop.
Changelog generator used for SuperCollider 3.8
/**
* Prints contributors list sorted by number of issues and pull requests.
* Closed issues and successfully merged pull-requests only.
*/
var fs = require('fs');
var _ = require('lodash');
var ib = [];
var pb = [];
var milestone = '3.8';
for (var i = 0; i < 10; i++) {
var jsonPath = `./github-data/pulls-closed-${i}.json`;
if (fs.existsSync(jsonPath)) {
var d = require(jsonPath);
pb.push(d);
}
var jsonPath2 = `./github-data/issues-closed-${i}.json`;
if (fs.existsSync(jsonPath2)) {
var d = require(jsonPath2);
ib.push(d);
}
}
// console.log(pb);
var pulls = _.flatten([].concat(pb));
var issues = _.flatten([].concat(ib));
var pullsMap = {};
_.each(pulls, (p) => {
pullsMap[p.number] = p;
});
function shouldIncludePull(pull) {
// has been merged
return pull.merged_at && shouldIncludeIssue(pull);
}
function shouldIncludeIssue(issue) {
// console.log({state: issue.state, milestone: issue.milestone && issue.milestone.title});
var status = (issue.state === 'closed' && issue.milestone && issue.milestone.title === milestone);
if (!status) {
return false;
}
// labels includes 'invalid' or 'wontfix'
// if number is in pulls and there is no merged at
var pull = pullsMap[issue.number];
if (pull) {
// was never merged
if (!pull.merged_at) {
return false;
}
}
return true;
}
function mapIssueData(pull) {
// console.log(pull.user);
return {
user: {
name: pull.user.login,
url: pull.user.html_url
}
};
}
var issuesData = issues.filter(shouldIncludeIssue).map(mapIssueData);
var users = {};
_.each(issuesData, (pull) => {
if (users[pull.user.name]) {
users[pull.user.name].count += 1;
} else {
pull.user.count = 1;
users[pull.user.name] = pull.user;
}
});
var contributors = _.reverse(_.sortBy(_.values(users), 'count'));
// rendering
console.log(`# Contributors ${milestone}`);
console.log();
function printUser(user) {
// console.log(`- []${user.
// name}](${user.url})`);
console.log(`- ${user.name}`);
}
_.each(contributors, printUser);
#
# Fetch issues and pull-requests for this milestone from the github REST API
#
mkdir -p github-data
# Download all labels
curl "https://api.github.com/repos/supercollider/supercollider/labels?per_page=100" -o github-data/labels.json
# Download all issues
# Get the milestone id (not the name) from:
# https://github.com/supercollider/supercollider/milestones
curl "https://api.github.com/repos/supercollider/supercollider/issues?per_page=100&page=[1-5]&state=closed&milestone=7" -o "github-data/issues-closed-#1.json"
# Download all pull-requests
curl "https://api.github.com/repos/supercollider/supercollider/pulls?per_page=100&page=[1-2]&state=closed&milestone=7" -o "github-data/pulls-closed-#1.json"
{
"name": "supercollider",
"version": "1.0.0",
"description": "[![Build Status](https://travis-ci.org/supercollider/supercollider.svg?branch=master)](https://travis-ci.org/supercollider/supercollider)",
"main": "changelog.js",
"directories": {
"example": "examples"
},
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"repository": {
"type": "git",
"url": "git+https://github.com/supercollider/supercollider.git"
},
"author": "",
"license": "ISC",
"bugs": {
"url": "https://github.com/supercollider/supercollider/issues"
},
"homepage": "https://github.com/supercollider/supercollider#readme",
"devDependencies": {
"lodash": "^4.16.2"
}
}
var fs = require('fs');
var _ = require('lodash');
var ib = [];
var pb = [];
var milestone = '3.8';
// Issues and pull-requests are collated by the first matching label.
// Additional labels could be displayed
var labels = [
'API change',
'comp: scsynth',
'comp: server plugins',
'comp: supernova',
'comp: sclang',
'comp: class library',
'comp: help',
'comp: HID',
'comp: JITlib',
'comp: Qt GUI',
'comp: SCDoc',
'comp: build',
'debian packaging',
'env: Psycollider',
'env: Qt IDE',
'env: SC.app',
'env: sced',
'env: scel',
'env: scvim',
'git repository',
'os: Linux',
'os: Mac OS X',
'os: Windows',
'os: iOS',
'qt5',
'quarks',
'architecture: arm',
'bug',
'enhancement',
'performance',
'crash'
];
// These labels are never shown.
var hideLabels = [
'Work In Progress - don\'t merge me yet',
'cannot reproduce',
'changes-requested',
'duplicate',
'gitreports',
'has-conflicts',
'in progress',
'known issue',
'limited to old version',
'low hanging fruit',
'needs documentation',
'needs refactoring',
'needs unit test',
'invalid',
'not a big issue',
'organizational',
'question',
'retest',
'severe',
'fix proposed',
'todo-document-this',
'waiting for information',
'waiting for testing',
'waiting-for-consensus',
'wontfix',
'worksforme'
];
for (var i = 0; i < 10; i++) {
var jsonPath = `./github-data/pulls-closed-${i}.json`;
if (fs.existsSync(jsonPath)) {
var d = require(jsonPath);
pb.push(d);
}
var jsonPath2 = `./github-data/issues-closed-${i}.json`;
if (fs.existsSync(jsonPath2)) {
var d = require(jsonPath2);
ib.push(d);
}
}
// console.log(pb);
var pulls = _.flatten([].concat(pb));
var issues = _.flatten([].concat(ib));
var pullsMap = {};
_.each(pulls, (p) => {
pullsMap[p.number] = p;
});
function shouldIncludePull(pull) {
// has been merged
return pull.merged_at && shouldIncludeIssue(pull);
}
function shouldIncludeIssue(issue) {
// console.log({state: issue.state, milestone: issue.milestone && issue.milestone.title});
var status = (issue.state === 'closed' && issue.milestone && issue.milestone.title === milestone);
if (!status) {
return false;
}
// labels includes 'invalid' or 'wontfix'
// if number is in pulls and there is no merged at
//
var pull = pullsMap[issue.number];
if (pull) {
// was never merged
if (!pull.merged_at) {
return false;
}
}
return true;
}
function mapIssueData(pull) {
return {
id: pull.number,
pr: pullsMap[pull.number] ? true : false,
url: pull.html_url,
title: pull.title,
// body: pull.body,
user: {
name: pull.user.login,
url: pull.user.html_url
},
labels: pull.labels && pull.labels.map(l => l.name)
};
}
function category(pull) {
if (pull.labels) {
return _.find(labels, (l) => _.find(pull.labels, (ll) => ll === l));
}
}
var issuesData = issues.filter(shouldIncludeIssue).map(mapIssueData);
// console.log(issues.length, issuesData.length);
// group by label
var categories = {};
function pushToCat(cat, pull) {
if (!categories[cat]) {
categories[cat] = [];
}
categories[cat].push(pull);
}
var misc = 'Miscellaneous';
// _.each(pullsData, (pull) => {
// var cat = category(pull) || misc;
// pushToCat(cat, pull);
// });
_.each(issuesData, (pull) => {
var cat = category(pull) || misc;
pushToCat(cat, pull);
});
// rendering
console.log(`# CHANGELOG ${milestone}`);
console.log();
function formatIssue(issue) {
return [
`- ${issue.title}`,
` [\#${issue.id}](${issue.url}) by [${issue.user.name}](${issue.user.url})`
].join('\n');
// { id: 2239,
// pr: true,
// url: 'https://github.com/supercollider/supercollider/pull/2239',
// title: 'Increase the default number of audio buses from 128 to 1024',
// user: { name: 'vivid-synth', url: 'https://github.com/vivid-synth' },
// labels: [ 'API change', 'comp: class library', 'comp: scsynth' ] }
}
var allLabels = [].concat(labels, [misc]);
_.each(allLabels, (label) => {
var ps = categories[label];
if (ps) {
console.log();
console.log('## ', label);
console.log();
_.each(ps, (issue) => console.log(formatIssue(issue)));
}
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment