Skip to content

Instantly share code, notes, and snippets.

@alanshaw
Last active August 5, 2019 11:53
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save alanshaw/5a2d9465c5a05b201d949551bdb1fcc3 to your computer and use it in GitHub Desktop.
Save alanshaw/5a2d9465c5a05b201d949551bdb1fcc3 to your computer and use it in GitHub Desktop.
NYC to markdown list of names linked to github with counts for activities
{
"repos": [{
"login": "ipfs",
"repo": "aegir",
"after": "2019-05-22"
}, {
"login": "ipfs",
"repo": "js-ipfs",
"after": "2019-05-22"
}, {
"login": "multiformats",
"repo": "js-cid",
"after": "2019-05-22"
}, {
"login": "multiformats",
"repo": "js-cid-tool",
"after": "2019-05-22"
}, {
"login": "ipfs",
"repo": "js-datastore-core",
"after": "2019-05-22"
}, {
"login": "ipfs",
"repo": "js-datastore-pubsub",
"after": "2019-05-22"
}, {
"login": "ipfs",
"repo": "interface-datastore",
"after": "2019-05-22"
}, {
"login": "ipfs",
"repo": "interface-js-ipfs-core",
"after": "2019-05-22"
}, {
"login": "ipfs",
"repo": "js-ipfs-bitswap",
"after": "2019-05-22"
}, {
"login": "ipfs",
"repo": "js-ipfs-block",
"after": "2019-05-22"
}, {
"login": "ipfs",
"repo": "js-ipfs-block-service",
"after": "2019-05-22"
}, {
"login": "ipfs",
"repo": "js-ipfs-http-client",
"after": "2019-05-22"
}, {
"login": "ipfs",
"repo": "js-ipfs-http-response",
"after": "2019-05-22"
}, {
"login": "ipfs",
"repo": "js-ipfs-mfs",
"after": "2019-05-22"
}, {
"login": "ipfs",
"repo": "js-ipfs-multipart",
"after": "2019-05-22"
}, {
"login": "ipfs",
"repo": "js-ipfs-repo",
"after": "2019-05-22"
}, {
"login": "ipfs",
"repo": "js-ipfs-unixfs",
"after": "2019-05-22"
}, {
"login": "ipfs",
"repo": "js-ipfs-unixfs-engine",
"after": "2019-05-22"
}, {
"login": "ipfs",
"repo": "js-ipfs-unixfs-importer",
"after": "2019-05-22"
}, {
"login": "ipfs",
"repo": "js-ipfs-unixfs-exporter",
"after": "2019-05-22"
}, {
"login": "ipfs",
"repo": "js-ipfs-utils",
"after": "2019-05-22"
}, {
"login": "ipfs",
"repo": "js-ipfsd-ctl",
"after": "2019-05-22"
}, {
"login": "ipld",
"repo": "js-ipld",
"after": "2019-05-22"
}, {
"login": "ipld",
"repo": "js-ipld-bitcoin",
"after": "2019-05-22"
}, {
"login": "ipld",
"repo": "js-ipld-dag-cbor",
"after": "2019-05-22"
}, {
"login": "ipld",
"repo": "js-ipld-dag-pb",
"after": "2019-05-22"
}, {
"login": "ipld",
"repo": "js-ipld-ethereum",
"after": "2019-05-22"
}, {
"login": "ipld",
"repo": "js-ipld-git",
"after": "2019-05-22"
}, {
"login": "ipld",
"repo": "js-ipld-raw",
"after": "2019-05-22"
}, {
"login": "ipld",
"repo": "js-ipld-zcash",
"after": "2019-05-22"
}, {
"login": "ipfs",
"repo": "js-ipns",
"after": "2019-05-22"
}, {
"login": "ipfs",
"repo": "is-ipfs",
"after": "2019-05-22"
}, {
"login": "libp2p",
"repo": "js-libp2p",
"after": "2019-05-22"
}, {
"login": "libp2p",
"repo": "js-libp2p-bootstrap",
"after": "2019-05-22"
}, {
"login": "libp2p",
"repo": "js-libp2p-crypto",
"after": "2019-05-22"
}, {
"login": "libp2p",
"repo": "js-libp2p-delegated-content-routing",
"after": "2019-05-22"
}, {
"login": "libp2p",
"repo": "js-libp2p-delegated-peer-routing",
"after": "2019-05-22"
}, {
"login": "libp2p",
"repo": "js-libp2p-kad-dht",
"after": "2019-05-22"
}, {
"login": "libp2p",
"repo": "js-libp2p-keychain",
"after": "2019-05-22"
}, {
"login": "libp2p",
"repo": "js-libp2p-mdns",
"after": "2019-05-22"
}, {
"login": "libp2p",
"repo": "js-libp2p-mplex",
"after": "2019-05-22"
}, {
"login": "libp2p",
"repo": "js-libp2p-record",
"after": "2019-05-22"
}, {
"login": "libp2p",
"repo": "js-libp2p-secio",
"after": "2019-05-22"
}, {
"login": "libp2p",
"repo": "js-libp2p-tcp",
"after": "2019-05-22"
}, {
"login": "libp2p",
"repo": "js-libp2p-webrtc-star",
"after": "2019-05-22"
}, {
"login": "libp2p",
"repo": "js-libp2p-websocket-star",
"after": "2019-05-22"
}, {
"login": "libp2p",
"repo": "js-libp2p-websocket-star-multi",
"after": "2019-05-22"
}, {
"login": "libp2p",
"repo": "js-libp2p-websockets",
"after": "2019-05-22"
}, {
"login": "multiformats",
"repo": "js-mafmt",
"after": "2019-05-22"
}, {
"login": "multiformats",
"repo": "js-multiaddr",
"after": "2019-05-22"
}, {
"login": "multiformats",
"repo": "js-multibase",
"after": "2019-05-22"
}, {
"login": "multiformats",
"repo": "js-multicodec",
"after": "2019-05-22"
}, {
"login": "multiformats",
"repo": "js-multihash",
"after": "2019-05-22"
}, {
"login": "multiformats",
"repo": "js-multihashing-async",
"after": "2019-05-22"
}, {
"login": "libp2p",
"repo": "js-peer-book",
"after": "2019-05-22"
}, {
"login": "libp2p",
"repo": "js-peer-id",
"after": "2019-05-22"
}, {
"login": "libp2p",
"repo": "js-peer-info",
"after": "2019-05-22"
}, {
"login": "libp2p",
"repo": "pull-mplex",
"after": "2019-05-22"
}],
"orgs": []
}
# Run like:
# GITHUB_TOKEN=<your_github_personal_access_token> ./exec.sh
echo "🏗 Installing name-your-contributors module..."
echo "> npm i -g name-your-contributors"
npm i -g name-your-contributors
echo "❤️ Naming contributors..."
echo "> name-your-contributors --config config.json > combined-out.json"
name-your-contributors --config config.json > combined-out.json
echo "📝 Generating list..."
echo "> node nyc-to-list.js combined-out.json"
node nyc-to-list.js combined-out.json
/* outputs something like this:
* [Aakil Fernandes](https://github.com/aakilfernandes) (1 comment)
* [Alan Shaw](https://github.com/alanshaw) (35 PRs, 8 issues, 99 reviews, 165 comments)
* [Aleksey Bykhun](https://github.com/caffeinum) (1 issue, 1 comment)
* [Alex Knol](https://github.com/Elexy) (1 issue)
* [Alex North](https://github.com/anorth) (1 comment)
* [Alex Potsides](https://github.com/achingbrain) (32 PRs, 6 issues, 38 reviews, 79 comments)
* [André Cruz](https://github.com/satazor) (1 issue, 2 comments)
* [ANUDAVIS](https://github.com/ANUDAVIS) (1 comment)
* [Arkadiy Kukarkin](https://github.com/parkan) (1 issue, 4 comments)
* [AT1452](https://github.com/AT1452) (1 issue)
*/
const fs = require('fs')
const data = JSON.parse(fs.readFileSync(process.argv[2]))
const people = {}
data.repos.forEach(repo => {
Object.keys(repo.contributions).forEach(type => {
repo.contributions[type].forEach(person => {
if (people[person.login]) {
people[person.login].count += person.count
} else {
people[person.login] = person
}
people[person.login].counts = people[person.login].counts || {}
people[person.login].counts[type] = (people[person.login].counts[type] || 0) + person.count
})
})
})
function plural (word, count) {
if (count === 1) return word
return `${word}s`
}
function getContribsString (person) {
const counts = []
if (person.counts.prCreators) counts.push(`${person.counts.prCreators} ${plural('PR', person.counts.prCreators)}`)
if (person.counts.issueCreators) counts.push(`${person.counts.issueCreators} ${plural('issue', person.counts.issueCreators)}`)
if (person.counts.reviewers) counts.push(`${person.counts.reviewers} ${plural('review', person.counts.reviewers)}`)
let totalComments = (person.counts.prCommentators || 0) + (person.counts.issueCommentators || 0)
if (totalComments) counts.push(`${totalComments} ${plural('comment', totalComments)}`)
if (counts.length) return ` (${counts.join(', ')})`
return ''
}
function getTotalContribs (person) {
let total = 0
total += person.counts.prCreators || 0
total += person.counts.issueCreators || 0
total += person.counts.reviewers || 0
total += person.counts.prCommentators || 0
total += person.counts.issueCommentators || 0
return total
}
const peoples = Object.values(people)
.sort((a, b) => (a.name || a.login).toLowerCase().localeCompare((b.name || b.login).toLowerCase()))
.filter(p => p.name !== 'greenkeeper' && p.login !== 'greenkeeper')
.filter(p => p.name !== 'azure-pipelines' && p.login !== 'azure-pipelines')
.filter(p => p.name !== 'codecov' && p.login !== 'codecov')
const totalContribs = peoples.reduce((total, p) => total + getTotalContribs(p), 0)
console.log(`In alphabetical order, here are the ${peoples.length} humans that made ${totalContribs} contributions to this release:\n`)
peoples.forEach(p => {
console.log(`* [${p.name || p.login}](${p.url})${getContribsString(p)}`)
})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment