hubot-gitlab-agile
Version:
Hubot script to integrate with gitlab
191 lines (158 loc) • 6.36 kB
JavaScript
// Description:
// Create and mark tasks to do, done, etc.
// Commands:
// hubot gitlab search p <term>
// hubot gitlab search projects <term>
// hubot gitlab list projects
// hubot gitlab list p
// hubot gitlab list milestones <project_id>
// hubot gitlab list m <project_id>
// hubot gitlab list issues <project_id>
// hubot gitlab list i <project_id>
// hubot gitlab progress <project_id> <milestone_id>
// Dependencies:
// hubot-redis-brain node-gitlab
/*jslint node: true*/
module.exports = function(robot) {
"use strict";
var GITLAB_RECORD_LIMIT = process.env.GITLAB_RECORD_LIMIT || 20;
var GITLAB_EFFORT_REGEX = /\$effort:\s*(\d+)/i;
var GITLAB_URL = process.env.GITLAB_URL;
var GITLAB_TOKEN = process.env.GITLAB_TOKEN;
var gitlab = require('gitlab')({
url: GITLAB_URL,
token: GITLAB_TOKEN
});
var _ = require('underscore');
var fs = require('fs');
var path = require('path');
var projectListTemplate = loadTemplate('projects.html');
var issuesListTemplate = loadTemplate('issues.html');
var milestonesListTemplate = loadTemplate('milestones.html');
var burndownTemplate = loadTemplate('burndown.html');
robot.brain.on("loaded", function() {
});
function loadTemplate(templatePath) {
var templateContent = fs.readFileSync(path.join(__dirname, 'templates') + '/' + templatePath, 'utf8');
return _.template(templateContent);
}
function listProjects(res) {
var params = extractParams(res);
res.reply("Ok child, let me fetch some projects for you. Hang on just a sec.");
gitlab.projects.all(function(projects){
var reply = projectListTemplate({list: projects, limit: params.limit});
res.reply(reply);
});
}
function searchProjects(res) {
var params = extractParams(res);
res.reply("I'll check around for that project of yours...");
var searchTerm = res.match.slice(1).join(' ');
gitlab.projects.search(searchTerm, function(projects){
var reply = projectListTemplate({list: projects, limit: null});
res.reply(reply);
});
}
function extractParams(res) {
var params = {};
if (res.match.length > 0 && !isNaN(res.match[1])) {
params.project_id = parseInt(res.match[1]);
}
if (res.match.length > 0 && !isNaN(res.match[2])) {
params.milestone_id = parseInt(res.match[2]);
}
for (var i = 0; i < res.match.length; i++) {
var match = res.match[i];
if (match == 'all' || match == 'closed' || match == 'opened') {
params.modifier = match;
}
}
if (params.modifier == 'all') {
params.limit = 0;
}
else {
params.limit = GITLAB_RECORD_LIMIT;
}
return params;
}
function listMilestones(res) {
var params = extractParams(res);
res.reply("Ok, sure...you want to see the big picture? Fetching milestones...");
gitlab.projects.milestones.all(params.project_id, function(milestones){
var reply = milestonesListTemplate({project_id: params.project_id,
limit: params.limit,
list: milestones});
res.reply(reply);
});
}
function listIssues(res) {
var params = extractParams(res);
res.reply("Let me check the exu-tracker for some issues...hang on a while.");
gitlab.projects.issues.list(params.project_id, function(issues){
var reply = issuesListTemplate({
project_id: params.project_id,
limit: params.limit,
list: issues
});
res.reply(reply);
});
}
function mapEffort(issue) {
var effortMatch = GITLAB_EFFORT_REGEX.exec(issue.description);
if (!effortMatch) {
return 1;
}
if (effortMatch.length > 0) {
return parseInt(effortMatch[1]);
}
return 1;
}
function reduceEffort(effortA, effortB) {
return effortA + effortB;
}
function calculateProgress(res) {
var params = extractParams(res);
res.reply("Let me check your progress. I hope your team did better this time!");
gitlab.projects.issues.list(params.project_id, function(issues) {
var milestoneIssues = _.filter(issues, function(i) { return i.milestone && i.milestone.iid == params.milestone_id; });
var openIssues = _.filter(milestoneIssues, function(i) { return i.state != 'closed'; });
var closedIssues = _.filter(milestoneIssues, function(i) { return i.state == 'closed'; });
var totalEffort = _.reduce(_.map(milestoneIssues, mapEffort), reduceEffort);
var openEffort = _.reduce(_.map(openIssues, mapEffort), reduceEffort);
var closedEffort = _.reduce(_.map(closedIssues, mapEffort), reduceEffort);
var reply = burndownTemplate({project_id: params.project_id,
total: totalEffort,
open: openEffort,
closed: closedEffort
});
res.reply(reply);
});
}
robot.respond(/gitlab progress (\d+) (\d+)/i, function(res){
calculateProgress(res);
});
robot.respond(/gitlab search p (\w+(\s\w+)*)+/i, function(res){
searchProjects(res);
});
robot.respond(/gitlab search projects (\w+(\s\w+)*)+/i, function(res){
searchProjects(res);
});
robot.respond(/gitlab list p(\sall)*/i, function(res){
listProjects(res);
});
robot.respond(/gitlab list projects(\sall)*/i, function(res){
listProjects(res);
});
robot.respond(/gitlab list milestones (\d+)(\sall|\sopened|\sclosed)*/i, function(res){
listMilestones(res);
});
robot.respond(/gitlab list m (\d+)(\sall|\sopened\sclosed)*/i, function(res) {
listMilestones(res);
});
robot.respond(/gitlab list i (\d+)(\sall|\sopened|\sclosed)*/i, function(res){
listIssues(res);
});
robot.respond(/gitlab list issues (\d+)(\sall|\sopened|\sclosed)*/i, function(res){
listIssues(res);
});
};