/** * @function avgTime * @description Returns the average time it takes to close an issue in hours or days. * @param {Array} data Array with paths leading to GitLab Issue .json files * @param {string} time 'hours' or 'days' * @returns {number} */ function avgTime(data, time) { if (time !== 'hours' && time !== 'days') { return new Error('avgTime(data, time): time should be "hours" or "days"'); } let avg; for (const file of data) { const issue = require(file.path); const openDate = new Date(issue.created_at); const closeDate = new Date(issue.closed_at); let diff; if (time === 'days') { diff = (closeDate - openDate) / (1000 * 60 * 60 * 24); } else if (time === 'hours') { diff = (closeDate - openDate) / (1000 * 60 * 60); } avg = (typeof avg === 'undefined') ? avg = diff : avg += diff; } return (avg / data.length).toFixed(2); } /** * @function freqUsers * @description Returns the top X issue creators. * @param {Array} data Array with paths leading to GitLab Issue .json files * @param {number} maxUsers Maximum amount of users to return, defaults to 3 * @returns {Object} */ function freqUsers(data, maxUsers) { if (typeof maxUsers === 'undefined') { maxUsers = 3; } const userCounts = {}; for (const file of data) { const issue = require(file.path); if (typeof userCounts[issue.author.username] === 'undefined') { userCounts[issue.author.username] = 1; } else { userCounts[issue.author.username]++; } } const sortedArray = Object.keys(userCounts).sort((a, b) => userCounts[b] - userCounts[a]); const sortedObject = {}; for (let i = 0; i < maxUsers; i++) { if (typeof sortedArray[i] === 'undefined') { break; } sortedObject[sortedArray[i]] = userCounts[sortedArray[i]]; } return sortedObject; } /** * @function labelsAlphabet * @description Returns all labels found in alphabetical order with their amount. * @param {Array} data Array with paths leading to GitLab Issue .json files * @param {boolean} checkNull Boolean whether or not to check if closed_at is null (for currently open issues) * @returns {Object} */ function labelsAlphabet(data, checkNull) { if (typeof checkNull === 'undefined') { checkNull = false; } const labels = {}; for (const file of data) { const issue = require(file.path); if (checkNull && issue.closed_at !== null) { continue; } for (const label of issue.labels) { if (typeof labels[label] === 'undefined') { labels[label] = 1; } else { labels[label]++; } } } const labelsOrdered = {}; Object.keys(labels).sort().forEach(label => { labelsOrdered[label] = labels[label]; }); return labelsOrdered; } /** * @function changedLines * @description Returns the number of added, deleted and total lines changed * @param {Array} data Array with paths leading to GitLab Commit .json files (with stats) * @returns {Object} Object with added/deleted/total lines changed */ function changedLines(data) { const stats = { added: 0, deleted: 0, total: 0 }; for (const file of data) { const commit = require(file.path); stats.added += commit.stats.additions; stats.deleted += commit.stats.deletions; stats.total += commit.stats.additions - commit.stats.deletions; } return stats; } /** * @function uniqueContributors * @description Returns the names of all contributors * @param {Array} data Array with paths leading to GitLab Commit .json files (with stats) * @returns {Array} Array with names of all contributors */ function uniqueContributors(data) { const contributors = []; for (const file of data) { const commit = require(file.path); if (!contributors.includes(commit.author_name)) { contributors.push(commit.author_name); } } return contributors; } exports.avgTime = avgTime; exports.freqUsers = freqUsers; exports.labelsAlphabet = labelsAlphabet; exports.changedLines = changedLines; exports.uniqueContributors = uniqueContributors;