Skip to content

Instantly share code, notes, and snippets.

@vsetka
Last active November 20, 2017 14:09
Show Gist options
  • Save vsetka/15bdabe80cded9c9ce57e19d31a8b901 to your computer and use it in GitHub Desktop.
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/)
"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