const config = require('./config.json') const df = require('date-format') const fs = require('fs') const Gitlab = require('gitlab/dist/es5').default const klaw = require('klaw-sync') const path = require('path') const api = new Gitlab({ token: config.token }) const months = [ 'January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December' ] const year = new Date().getFullYear().toString() const month = months[new Date().getMonth()] if (!fs.existsSync(path.join(__dirname, year))) fs.mkdirSync(path.join(__dirname, year)) if (!fs.existsSync(path.join(__dirname, year, month))) fs.mkdirSync(path.join(__dirname, year, month)) const openedPath = path.join(__dirname, year, month, 'Opened') const closedPath = path.join(__dirname, year, month, 'Closed') if (!fs.existsSync(openedPath)) fs.mkdirSync(openedPath) if (!fs.existsSync(closedPath)) fs.mkdirSync(closedPath) let args = '' for (const arg of process.argv) { args += arg + ' ' } if (!args.includes('--no-download')) download() else { createTable() createStatistics() } function download() { api.Projects .show('tildes/tildes') .then((project) => { api.Issues .all({ projectId: project.id }) .then((issues) => { for (const issue of issues) { if (new Date(issue.created_at).getMonth() === new Date().getMonth()) { fs.writeFileSync(path.join(openedPath, issue.iid.toString()) + '.json', JSON.stringify(issue, null, 2)) } if (new Date(issue.closed_at).getMonth() === new Date().getMonth()) { fs.writeFileSync(path.join(closedPath, issue.iid.toString()) + '.json', JSON.stringify(issue, null, 2)) } } }) .then(createTable) .then(createStatistics) }) } function createTable() { let opened = klaw(openedPath) let closed = klaw(closedPath) opened.sort(function(a,b) { const aFile = require(a.path) const bFile = require(b.path) return (aFile.iid > bFile.iid) ? 1 : ((bFile.iid > aFile.iid) ? -1 : 0) }) closed.sort(function(a,b) { const aFile = require(a.path) const bFile = require(b.path) return (aFile.iid > bFile.iid) ? 1 : ((bFile.iid > aFile.iid) ? -1 : 0) }) let table = '## Issue Table\n' table += '\n### Opened\n\n' table += '| Issue | Title | Author | Opened | Closed |\n' table += '| ----- | ----- | ------ | ------ | ------ |\n' for (const file of opened) { const issue = require(file.path) table += `| ${issue.iid} |` let title if (issue.title.length >= 50) { title = issue.title.substring(0, 47) + '...' } else { title = issue.title } table += ` ${title} |` table += ` ${issue.author.username} |` table += ` ${df.asString('yyyy/MM/dd hh:mm:ss', new Date(issue.created_at))} |` let closedAt if (issue.closed_at === null) { closedAt = '' } else { closedAt = df.asString('yyyy/MM/dd hh:mm:ss', new Date(issue.closed_at)) } table += ` ${closedAt} |\n` } table += '\n### Closed\n\n' table += '| Issue | Title | Author | Opened | Closed |\n' table += '| ----- | ----- | ------ | ------ | ------ |\n' for (const file of closed) { const issue = require(file.path) table += `| ${issue.iid} |` let title if (issue.title.length >= 50) { title = issue.title.substring(0, 47) + '...' } else { title = issue.title } table += ` ${title} |` table += ` ${issue.author.username} |` table += ` ${df.asString('yyyy/MM/dd hh:mm:ss', new Date(issue.created_at))} |` let closedAt if (issue.closed_at === null) { closedAt = '' } else { closedAt = df.asString('yyyy/MM/dd hh:mm:ss', new Date(issue.closed_at)) } table += ` ${closedAt} |\n` } if (!fs.existsSync(path.join(__dirname, year, month, 'post.md'))) fs.copyFileSync(path.join(__dirname, 'template.md'), path.join(__dirname, year, month, 'post.md')) fs.writeFileSync(path.join(__dirname, year, month, 'table.md'), table, {encoding: 'UTF-8'}) } function createStatistics() { let opened = klaw(openedPath) let closed = klaw(closedPath) let statistics = '## Statistics\n\n' statistics += `In the month of ${month} ` statistics += `${opened.length} issues were opened and ` statistics += `${closed.length} issues were closed.\n\n` const averageOpenPerDay = (opened.length / 30).toFixed(2) const averageClosePerDay = (closed.length / 30).toFixed(2) statistics += `An average of ${averageOpenPerDay} issues were opened ` statistics += `and ${averageClosePerDay} issues were closed each day.\n\n` let averageClosedDays let averageClosedHours for (const file of closed) { const issue = require(file.path) const openedAt = new Date(issue.created_at) const closedAt = new Date(issue.closed_at) const diffDays = (closedAt - openedAt) / (1000 * 60 * 60 * 24) const diffHours = (closedAt - openedAt) / (1000 * 60 * 60) averageClosedDays = (typeof averageClosedDays === 'undefined') ? averageClosedDays = diffDays : averageClosedDays += diffDays averageClosedHours = (typeof averageClosedHours === 'undefined') ? averageClosedHours = diffHours : averageClosedHours += diffHours } averageClosedDays = (averageClosedDays / closed.length).toFixed(2) averageClosedHours = (averageClosedHours / closed.length).toFixed(2) statistics += `The average time to close issues was ${averageClosedDays} days ` statistics += `or ${averageClosedHours} hours.\n\n` let _mostFrequent = {} for (const file of opened) { const issue = require(file.path) if (typeof _mostFrequent[issue.author.username] === 'undefined') _mostFrequent[issue.author.username] = 1 else _mostFrequent[issue.author.username]++ } let mostFrequent = Object.keys(_mostFrequent) mostFrequent.sort((a, b) => _mostFrequent[b] - _mostFrequent[a]) mostFrequent = mostFrequent.slice(0, 3) statistics += 'Most frequent issue creators:\n\n' for (const user of mostFrequent) { statistics += `* [${user}](https://gitlab.com/${user}) ` statistics += `with [${_mostFrequent[user]} issues created](https://gitlab.com/tildes/tildes/issues?state=all&author_username=${user}).\n` } let labels = {} for (const file of opened) { const issue = require(file.path) if (issue.closed_at !== null) continue for (const label of issue.labels) { if (typeof labels[label] === 'undefined') labels[label] = 1 else labels[label]++ } } let labelsOrdered = {} Object.keys(labels).sort().forEach(label => labelsOrdered[label] = labels[label]) statistics += '\nTotal amount of labels assigned to currently open issues:\n\n' for (const label in labelsOrdered) { statistics += `* [${label}](https://gitlab.com/tildes/tildes/issues?state=opened&label_name%5B%5D=${label.replace(' ', '+')}): ${labels[label]} times.\n` } labels = {} for (const file of closed) { const issue = require(file.path) for (const label of issue.labels) { if (typeof labels[label] === 'undefined') labels[label] = 1 else labels[label]++ } } labelsOrdered = {} Object.keys(labels).sort().forEach(label => labelsOrdered[label] = labels[label]) statistics += '\nTotal amount of labels assigned to closed issues:\n\n' for (const label in labelsOrdered) { statistics += `* [${label}](https://gitlab.com/tildes/tildes/issues?state=closed&label_name%5B%5D=${label.replace(' ', '+')}): ${labels[label]} times.\n` } fs.writeFileSync(path.join(__dirname, year, month, 'statistics.md'), statistics, {encoding: 'UTF-8'}) }