Last active
November 20, 2017 14:09
-
-
Save vsetka/15bdabe80cded9c9ce57e19d31a8b901 to your computer and use it in GitHub Desktop.
Summarizes repo language stats for top 100 (by star count) user owned repos to get a "feel" for user language preference/experience. Replace GITHUB_USERNAME with a user you want to summarize and YOUR_GITHUB_API_TOKEN with the access token (https://help.github.com/articles/creating-a-personal-access-token-for-the-command-line/)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
"use strict"; | |
const https = require("https"); | |
const API_TOKEN = "YOUR_GITHUB_API_TOKEN"; | |
const GITHUB_USER = "GITHUB_USERNAME"; | |
const request = (options, postBody) => { | |
return new Promise((resolve, reject) => { | |
const req = https.request(options, res => { | |
let body = ""; | |
res.setEncoding("utf8"); | |
res.on("data", data => (body += data)); | |
res.on("end", () => resolve(JSON.parse(body))); | |
}); | |
req.on("error", reject); | |
req.write(JSON.stringify(postBody)); | |
req.end(); | |
}); | |
}; | |
const getQuery = (user, limit = 100) => ({ | |
query: `query ($limit: Int!, $user: String!) { | |
user(login: $user) { | |
contributedRepositories(first: $limit, orderBy: {field: STARGAZERS, direction: DESC}) { | |
edges { | |
node { | |
name | |
owner { | |
login | |
} | |
languages(first: $limit) { | |
totalSize | |
totalCount | |
edges { | |
size | |
node { | |
name | |
} | |
} | |
} | |
} | |
} | |
} | |
} | |
}`, | |
variables: `{ | |
"limit": ${limit}, | |
"user": "${user}" | |
}` | |
}); | |
const getUserPublicProjectStats = async user => { | |
const { | |
data: { user: { contributedRepositories: { edges: repos } } } | |
} = await request( | |
{ | |
hostname: "api.github.com", | |
port: 443, | |
protocol: "https:", | |
path: "/graphql", | |
method: "POST", | |
headers: { | |
Authorization: `bearer ${API_TOKEN}`, | |
"User-Agent": "github_api v0.1", | |
"Content-Type": "application/json", | |
"Content-Length": Buffer.byteLength(JSON.stringify(getQuery(user))), | |
"Cache-Control": "no-cache" | |
} | |
}, | |
getQuery(user) | |
); | |
let totalLanguageLines = {}; | |
const stats = repos | |
.filter(r => r.node.owner.login === user) | |
.map(({ node: { name, languages, languages: { edges } } }) => ({ | |
name, | |
languages: edges.reduce( | |
(mapped, { node: { name }, size }) => | |
Object.assign(mapped, { | |
[name]: { | |
size, | |
percent: `${Math.round(size / languages.totalSize * 10000) / | |
100}%` | |
} | |
}), | |
{} | |
) | |
})); | |
stats.forEach(({ languages }) => { | |
Object.keys(languages).forEach(name => { | |
totalLanguageLines[name] = totalLanguageLines[name] || 0; | |
totalLanguageLines[name] += languages[name].size; | |
}); | |
}); | |
let totalLanguageLinesSum = Object.keys(totalLanguageLines).reduce( | |
(total, lang) => totalLanguageLines[lang] + total, | |
0 | |
); | |
let totals = Object.keys(totalLanguageLines) | |
.sort((a, b) => totalLanguageLines[b] - totalLanguageLines[a]) | |
.map( | |
lang => | |
`${lang}: ${Math.round( | |
totalLanguageLines[lang] / totalLanguageLinesSum * 10000 | |
) / 100}%` | |
) | |
.join("\n"); | |
return { | |
stats, | |
totals | |
}; | |
}; | |
getUserPublicProjectStats(GITHUB_USER).then(({ stats, totals }) => { | |
console.log("Repo stats:\n"); | |
console.log(JSON.stringify(stats, null, 2)); | |
console.log("\n\nTotals:\n"); | |
console.log(totals); | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment