// TODO: add comments, I'm lazy :sleeping: const bsync = require('browser-sync'), GitLab = require('gitlab/dist/es5').default, df = require('date-format'), fs = require('fs'), klaw = require('klaw-sync'), path = require('path') const gulp = require('gulp'), pug = require('gulp-pug'), sass = require('gulp-sass'), stylelint = require('gulp-stylelint') const { avgTime, freqUsers, labelsAlphabet } = require('./statistics') const output = path.join(__dirname, 'public') gulp.task('download', () => { const year = new Date().getFullYear().toString() const month = months[new Date().getMonth()] const openedPath = path.join(__dirname, 'data', year, month, 'Opened') const closedPath = path.join(__dirname, 'data', year, month, 'Closed') checkPaths() const config = require('./config.json') const api = new GitLab({ token: config.token }) 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(() => { console.log('Finished downloading, creating table and statistics.') }) .then(createTable) .then(createStatistics) }) }) gulp.task('no-download', () => { createTable() createStatistics() }) gulp.task('build', ['lint:sass'], () => { gulp .src('src/*.pug') .pipe(pug()) .pipe(gulp.dest(output)) gulp .src('src/posts/*.pug') .pipe(pug()) .pipe(gulp.dest(output + '/posts')) gulp .src('src/sass/*.sass') .pipe(sass({ outputStyle: 'compressed' })) .pipe(gulp.dest(output + '/css')) gulp .src('src/favicons/**') .pipe(gulp.dest(output)) }) gulp.task('watch', () => { bsync.init({ server: output }) gulp.watch('src/**', ['build']).on('change', bsync.reload) }) gulp.task('lint:sass', () => { gulp .src('src/**/*.sass') .pipe(stylelint({ reporters: [{formatter: 'string', console: true}] })) }) const months = [ 'January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December' ] function createTable() { const year = new Date().getFullYear().toString() const month = months[new Date().getMonth()] const openedPath = path.join(__dirname, 'data', year, month, 'Opened') const closedPath = path.join(__dirname, 'data', year, month, 'Closed') checkPaths() 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 = 'article(id="issue-table")\n' table += ' h2 Issue Table\n' table += ' h3(id="opened") Opened\n' table += ' table\n' table += ' thead\n' table += ' tr\n' table += ' td Issue\n' table += ' td Title\n' table += ' td Author\n' table += ' td Opened\n' table += ' td Closed\n' table += ' tbody\n' for (const file of opened) { const issue = require(file.path) table += ' tr\n' table += ` td: a(href="${issue.web_url}") ${issue.iid}\n` let title if (issue.title.length >= 50) { title = issue.title.substring(0, 47) + '...' } else { title = issue.title } table += ` td ${title}\n` table += ` td: a(href="${issue.author.web_url}") ${issue.author.username}\n` table += ` td ${df.asString('yyyy/MM/dd hh:mm:ss', new Date(issue.created_at))}\n` let closedAt if (issue.closed_at === null) { closedAt = '' } else { closedAt = df.asString('yyyy/MM/dd hh:mm:ss', new Date(issue.closed_at)) } table += ` td ${closedAt}\n` } table += '\n h3(id="closed") Closed\n' table += ' table\n' table += ' thead\n' table += ' tr\n' table += ' td Issue\n' table += ' td Title\n' table += ' td Author\n' table += ' td Opened\n' table += ' td Closed\n' table += ' tbody\n' for (const file of closed) { const issue = require(file.path) table += ' tr\n' table += ` td: a(href="${issue.web_url}") ${issue.iid}\n` let title if (issue.title.length >= 50) { title = issue.title.substring(0, 47) + '...' } else { title = issue.title } table += ` td ${title}\n` table += ` td: a(href="${issue.author.web_url}") ${issue.author.username}\n` table += ` td ${df.asString('yyyy/MM/dd hh:mm:ss', new Date(issue.created_at))}\n` let closedAt if (issue.closed_at === null) { closedAt = '' } else { closedAt = df.asString('yyyy/MM/dd hh:mm:ss', new Date(issue.closed_at)) } table += ` td ${closedAt}\n` } table = table.replace('<', '') table = table.replace('>', '') fs.writeFileSync(path.join(__dirname, 'data', year, month, 'table.pug'), table, {encoding: 'UTF-8'}) } function createStatistics() { const year = new Date().getFullYear().toString() const month = months[new Date().getMonth()] const openedPath = path.join(__dirname, 'data', year, month, 'Opened') const closedPath = path.join(__dirname, 'data', year, month, 'Closed') checkPaths() let opened = klaw(openedPath) let closed = klaw(closedPath) let statistics = 'article(id="statistics")\n' statistics += ' h2 Statistics\n' statistics += ` p In the month of ${month} ` statistics += `${opened.length} issues were opened and ` statistics += `${closed.length} issues were closed.\n` statistics += ` p An average of ${(opened.length / 30).toFixed(2)} issues were opened ` statistics += `and ${(closed.length / 30).toFixed(2)} issues were closed each day.\n` statistics += ` p The average time to close issues was ${avgTime(closed, 'days')} days ` statistics += `or ${avgTime(closed, 'hours')} hours.\n` const topUsers = freqUsers(opened, 3) statistics += ' p Top 3 issue creators:\n' statistics += ' ol\n' for (const user in topUsers) { statistics += ' li\n' statistics += ` a(href="https://gitlab.com/${user}") ${user}\n` statistics += ' |\n' statistics += ' | with\n' statistics += ' |\n' statistics += ` a(href="https://gitlab.com/tildes/tildes/issues?state=all&author_username=${user}") ${topUsers[user]} issues created\n` statistics += ' | .\n' } let labels = labelsAlphabet(opened, true) statistics += ' p Amount of labels assigned to currently open issues:\n' statistics += ' ul\n' for (const label in labels) { statistics += ' li\n' statistics += ` a(href="https://gitlab.com/tildes/tildes/issues?state=opened&label_name%5B%5D=${label.replace(' ', '+')}") ${label}\n` statistics += ' | :\n' statistics += ` | ${labels[label]} ` if (labels[label] === 1) statistics += 'time.\n' else statistics += 'times.\n' } labels = labelsAlphabet(closed, false) statistics += ' p Amount of labels assigned to closed issues:\n' statistics += ' ul\n' for (const label in labels) { statistics += ' li\n' statistics += ` a(href="https://gitlab.com/tildes/tildes/issues?state=closed&label_name%5B%5D=${label.replace(' ', '+')}") ${label}\n` statistics += ' | :\n' statistics += ` | ${labels[label]} ` if (labels[label] === 1) statistics += 'time.\n' else statistics += 'times.\n' } fs.writeFileSync(path.join(__dirname, 'data', year, month, 'statistics.pug'), statistics, {encoding: 'UTF-8'}) } // Checking if all the directories exist and creating them if not // There's probably a better way to do this, like "mkdir -p " // TODO: rework checkPaths() function checkPaths() { const year = new Date().getFullYear().toString() const month = months[new Date().getMonth()] const openedPath = path.join(__dirname, 'data', year, month, 'Opened') const closedPath = path.join(__dirname, 'data', year, month, 'Closed') if (!fs.existsSync(path.join(__dirname, 'data'))) fs.mkdirSync(path.join(__dirname, 'data')) if (!fs.existsSync(path.join(__dirname, 'data', year))) fs.mkdirSync(path.join(__dirname, 'data', year)) if (!fs.existsSync(path.join(__dirname, 'data', year, month))) fs.mkdirSync(path.join(__dirname, 'data', year, month)) if (!fs.existsSync(openedPath)) fs.mkdirSync(openedPath) if (!fs.existsSync(closedPath)) fs.mkdirSync(closedPath) }