diff --git a/bin/ncu-contrib b/bin/ncu-contrib index 5b0d5e08..84981f85 100755 --- a/bin/ncu-contrib +++ b/bin/ncu-contrib @@ -2,8 +2,6 @@ 'use strict'; -const SEARCH_ISSUE = 'SearchIssue'; - const Request = require('../lib/request'); const auth = require('../lib/auth'); const { runPromise } = require('../lib/run'); @@ -53,18 +51,17 @@ async function main(argv) { const cli = new CLI(); const credentials = await auth(); const request = new Request(credentials); + const config = require('../lib/config').getMergedConfig(); + argv = Object.assign(argv, config); const analyzer = new ContributionAnalyzer(request, cli, argv); const [ command ] = argv._; switch (command) { case 'collaborators': - const collaborators = await analyzer.getCollaborators(); - await analyzer.getLatestContributionForIds( - collaborators.map(user => user.login)); + await analyzer.getLatestContributionForCollaborators(); break; case 'tsc': - const tsc = await analyzer.getTSC(); - await analyzer.getLatestContributionForIds(tsc.map(user => user.login)); + await analyzer.getLatestContributionForTSC(); break; case 'for': await analyzer.getLatestContributionForIds(argv.ids); diff --git a/lib/contribution-analyzer.js b/lib/contribution-analyzer.js index f3e1f75c..300ea3ee 100644 --- a/lib/contribution-analyzer.js +++ b/lib/contribution-analyzer.js @@ -4,10 +4,8 @@ const SEARCH_ISSUE = 'SearchIssue'; const SEARCH_COMMIT = 'SearchCommit'; const USER = 'User'; -const fs = require('fs'); -const path = require('path'); -const { writeJson, readJson, readFile } = require('./file'); const { getCollaborators } = require('./collaborators'); +const Cache = require('./cache'); const { isTheSamePerson } = require('./user'); class ContributionAnalyzer { @@ -15,13 +13,45 @@ class ContributionAnalyzer { this.request = request; this.cli = cli; this.argv = argv; - const cacheDir = path.resolve(__dirname, '..', '.ncu', - 'cache'); - const type = this.argv.type; - this.cache = { - temp: path.join(cacheDir, `${type}.json`), - result: path.join(cacheDir, `${type}-sorted.json`) - }; + } + + async getCommits(user) { + const { request, argv } = this; + const { owner, repo, branch } = argv; + + const userData = await request.gql(USER, { login: user }); + const authorId = userData.user.id; + const results = await request.gql(SEARCH_COMMIT, { + owner, repo, branch, authorId + }, [ 'repository', 'ref', 'target', 'history' ]); + return results + .sort((a, b) => { + return a.authoredDate > b.authoredDate ? -1 : 1; + }); + } + + async getParticipation(user) { + const { request } = this; + const results = await request.gql(SEARCH_ISSUE, { + queryString: `involves:${user} org:nodejs`, + mustBeAuthor: false + }); + if (results.search.nodes.length === 0) { + return [{ + url: 'N/A', + date: 'N/A', + isRelavent: false, + type: 'N/A' + }]; + } + + const res = results.search.nodes + .map(issue => this.participationByUser(issue, user)) + // .filter((res) => res.isRelavent) + .sort((a, b) => { + return a.date > b.date ? -1 : 1; + }); + return res; } participationByUser(issue, user) { @@ -67,45 +97,6 @@ class ContributionAnalyzer { return result; } - - async getParticipation(user) { - const { cli, request } = this; - const results = await request.gql(SEARCH_ISSUE, { - queryString: `involves:${user} org:nodejs`, - mustBeAuthor: false - }); - if (results.search.nodes.length === 0) { - return [{ - url: 'N/A', - date: 'N/A', - isRelavent: false, - type: 'N/A' - }]; - } - - const res = results.search.nodes - .map(issue => this.participationByUser(issue, user)) - // .filter((res) => res.isRelavent) - .sort((a, b) => { - return a.date > b.date ? -1 : 1; - }); - return res; - } - - async getCommits(user) { - const { cli, request, argv } = this; - const { owner, repo, branch } = argv; - - const userData = await request.gql(USER, { login: user }); - const authorId = userData.user.id; - const results = await request.gql(SEARCH_COMMIT, { - owner, repo, branch, authorId - }, [ 'repository', 'ref', 'target', 'history' ]); - return results - .sort((a, b) => { - return a.authoredDate > b.authoredDate ? -1 : 1; - }); - } async getContributionsForId(user) { const { argv } = this; @@ -126,31 +117,6 @@ class ContributionAnalyzer { }; } - async getCollaborators() { - const { cli, request, argv } = this; - const { owner, repo, readme } = argv; - cli.startSpinner('Getting collaborator contacts'); - let readmeText; - if (readme) { - cli.updateSpinner(`Reading collaborator contacts from ${readme}`); - readmeText = readFile(readme); - } else { - cli.updateSpinner( - `Getting collaborator contacts from README of ${owner}/${repo}`); - const url = `https://raw.githubusercontent.com/${owner}/${repo}/master/README.md`; - readmeText = await request.text(url); - } - const collaborators = getCollaborators(readmeText, cli, owner, repo); - const result = Array.from(collaborators.values()); - cli.stopSpinner(`Read ${result.length} collaborators`); - return result; - } - - async getTSC() { - const collaborators = await this.getCollaborators(); - return collaborators.filter((user) => user.isTSC()); - } - formatContribution(user, data) { if (this.argv.type === 'participation') { const type = @@ -190,33 +156,19 @@ class ContributionAnalyzer { return item.authoredDate; } } - async getResults(ids) { - const { cache, cli, argv, request } = this; - let latestContrib = cache ? readJson(cache.temp) : {}; + async getLatestContributionForIds(ids) { + const { cli } = this; const total = ids.length; let counter = 1; - + const latestContrib = {}; for (const user of ids) { cli.startSpinner(`Grabbing data for @${user}, ${counter++}/${total}..`); - let data = latestContrib[user]; - if (data) { - cli.updateSpinner(`Skip grabbing cached data for @${user}`); - } else { - data = await this.getLatestContributionForId(user); - latestContrib[user] = data; - if (cache && counter % 11 === 10) { - writeJson(cache.temp, latestContrib); - } - } - + const data = await this.getLatestContributionForId(user); + latestContrib[user] = data; cli.stopSpinner(this.formatContribution(user, data)); } - - if (cache) { - writeJson(cache.temp, latestContrib); - } - + const sorted = ids.sort((a, b) => { const aa = latestContrib[a]; const bb = latestContrib[b]; @@ -228,27 +180,31 @@ class ContributionAnalyzer { return sorted; } - async getLatestContributionForIds(ids) { - const { cache, cli, argv, request } = this; - let sorted; - - if (this.cache && fs.existsSync(this.cache.result)) { - sorted = readJson(this.cache.result); - const existingIds = new Set(sorted.map(item => item.user)); - if (ids.every(id => existingIds.has(id))) { - for (const data of sorted) { - cli.log(this.formatContribution(data.user, data)); - } - return; - } - } - - sorted = await this.getResults(ids); + async getLatestContributionForCollaborators() { + const { cli, argv, request } = this; + const collaborators = await getCollaborators(cli, request, argv); + const ids = [...collaborators.keys()]; + return this.getLatestContributionForIds(ids); + } - if (cache) { - writeJson(cache.result, sorted); - } + async getLatestContributionForTSC() { + const { cli, argv, request } = this; + const collaborators = await getCollaborators(cli, request, argv); + const tsc = [...collaborators.values()].filter((user) => user.isTSC()); + const ids = tsc.map(user => user.login); + return this.getLatestContributionForIds(ids); } } +const contribCache = new Cache(); +contribCache.wrap(ContributionAnalyzer, { + getCommits(user) { + return { key: `commits-${user}`, ext: '.json' }; + }, + getParticipation(user) { + return { key: `participation-${user}`, ext: '.json' }; + } +}); +contribCache.enable(); + module.exports = ContributionAnalyzer;