apps/strider/dist-lib/routes/projects.js
const async = require('async');
const common = require('../common');
const debug = require('debug')('strider:routes:projects');
const express = require('express');
const models = require('../models');
const pjson = require('../../package.json');
const router = express.Router();
const Project = models.Project;
const User = models.User;
router
.route('/')
.get(function (req, res) {
return renderProjects(false, req, res);
})
.post(function (req, res) {
const refresh = req.body.refresh !== 'false' && req.body.refresh !== '0';
return renderProjects(refresh, req, res);
});
module.exports = router;
function renderProjects(refresh, req, res) {
const tasks = [];
const repomap = {};
const configured = {};
const unconfigured = [];
const providers = common.userConfigs.provider;
const manual = {};
const manualProjects = {};
Object.keys(common.pluginConfigs.provider).forEach(function (key) {
const config = common.pluginConfigs.provider[key];
if (common.extensions.provider[key].hosted)
return;
manualProjects[key] = [];
manual[key] = {
provider: config,
projects: manualProjects[key],
};
});
Project.find({ creator: req.user._id })
.lean()
.exec(function (err, projects) {
if (err)
return res.send(500, 'Failed to get projects from the database');
// tree is { providerid: { accountid: { repoid: project._id, ...}, ...}, ...}
// to track which repos have been configured
const tree = {};
for (let i = 0; i < projects.length; i++) {
const provider = projects[i].provider;
if (!provider.account) {
if (!manual[provider.id]) {
manual[provider.id] = {
provider: common.pluginConfigs.provider[provider.id],
projects: [],
};
}
manual[provider.id].projects.push(projects[i]);
continue;
}
deepObj(tree, provider.id, provider.account)[provider.repo_id] = {
_id: projects[i]._id,
name: projects[i].name,
};
}
req.user.accounts.forEach(function (account) {
configured[account.provider] = true;
// Caching
const haveCache = Array.isArray(account.cache) && account.cache.length > 0;
if (!refresh && haveCache) {
groupRepos(account, repomap, tree, account.toJSON().cache);
return;
}
tasks.push(function (next) {
debug(`Now trying to list repos for the following provider for an account in the user model: ${account.provider}`);
if (!common.extensions.provider[account.provider]) {
next(new Error(`The plugin for ${account.provider} could not be found. Please install the plugin from Admin > Plugins`));
}
else {
common.extensions.provider[account.provider].listRepos(account.config, function (err, repos) {
if (err) {
if (haveCache) {
groupRepos(account, repomap, tree, account.toJSON().cache);
}
return next(err);
}
account.set('cache', repos);
groupRepos(account, repomap, tree, repos);
account.last_updated = new Date();
next();
});
}
});
});
for (const id in providers) {
if (configured[id] || !providers[id].setupLink)
continue;
unconfigured.push(providers[id]);
}
debug('Fetching projects...');
async.parallel(tasks, function (err) {
if (err) {
req.flash('account', `Failed to refresh repositories: ${err.message || err}`);
debug(err);
}
// cache the fetched repos
User.updateOne({ _id: req.user._id }, { $set: { accounts: req.user.toJSON().accounts } }, function (err, num) {
if (err)
debug('error saving repo cache');
if (!num)
debug("Didn't effect any users");
debug('Saved repo cache');
// user is already be available via the "currentUser" template variable
return res.format({
html: function () {
res.render('projects.html', {
unconfigured: unconfigured,
providers: providers,
manual: manual,
manualProjects: manualProjects,
repos: repomap,
flash: req.flash(),
project_types: availableProjectTypes(),
version: pjson.version,
});
},
json: function () {
res.send({
unconfigured: unconfigured,
providers: providers,
manual: manual,
manualProjects: manualProjects,
repos: repomap,
project_types: availableProjectTypes(),
});
},
});
});
});
});
}
function availableProjectTypes() {
const available = {};
for (const id in common.project_types) {
let good = true;
const plugins = common.project_types[id].plugins;
for (let i = 0; i < plugins.length; i++) {
if (!common.extensions.job[plugins[i]]) {
good = false;
break;
}
}
if (good) {
available[id] = common.project_types[id];
}
}
return available;
}
function groupRepos(account, repomap, tree, repos) {
const groups = deepObj(repomap, account.provider, account.id);
const projectmap = getDeep(tree, account.provider, account.id) || {};
for (let i = 0; i < repos.length; i++) {
if (!groups[repos[i].group]) {
groups[repos[i].group] = {
configured: 0,
repos: [],
};
}
repos[i].project = projectmap[repos[i].id];
groups[repos[i].group].repos.push(repos[i]);
if (repos[i].project) {
groups[repos[i].group].configured += 1;
}
}
}
function getDeep(obj) {
return [].slice.call(arguments, 1).reduce(function (obj, name) {
return obj && obj[name];
}, obj);
}
function deepObj(obj) {
const names = [].slice.call(arguments, 1);
return names.reduce(function (obj, name) {
return obj[name] || (obj[name] = {});
}, obj);
}
//# sourceMappingURL=projects.js.map