strider
Version:
Brilliant continuous deployment platform
224 lines • 7.93 kB
JavaScript
const _ = require('lodash');
const common = require('../common');
const debug = require('debug')('strider:utils');
const gravatar = require('gravatar');
module.exports = {
gravatar: gravatarDefault,
sanitizeProject: sanitizeProject,
sanitizeBranch: sanitizeBranch,
sanitizeUser: sanitizeUser,
timeFromId: timeFromId,
defaultSchema: defaultSchema,
validateAgainstSchema: validateAgainstSchema,
mergePlugins: mergePlugins,
mergeConfigs: mergeConfigs,
findBranch: findBranch,
};
function findBranch(branches, name) {
let foundBranch = false;
branches.some(function (branch) {
if (branch.name) {
const regEx = new RegExp(`^${branch.name.replace(/\*/g, '.*')}$`);
if (regEx.test(name)) {
foundBranch = branch;
return true;
}
}
});
return (function discreteBranchFn(name, branch, branches) {
//console.log('findBranch('+name+') wants to return '+branch.name);
if (branch.name !== name) {
//console.warn('Possibly returning unintended branch (expected '+name+' but got '+branch.name+'). attempting to locate discretely named branch '+name+' if it exists.');
const discreteBranch = _.find(branches, { name: name });
if (discreteBranch) {
branch = discreteBranch;
//console.info("Located discrete branch, instead returning "+branch.name)
}
else {
//console.warn("Unable to find discrete branch "+name+", still returning "+branch.name);
}
}
return branch;
})(name, foundBranch, branches);
}
// merge plugins from the DB with ones from strider.json. The latter overrides the former
function mergePlugins(branch, sjson) {
if (!branch)
return sjson;
if (!sjson)
return branch;
// if strict_plugins is not turned on, we merge each plugin config instead of overwriting.
const plugins = [];
const pluginMap = {};
for (let pluginIndex = 0; pluginIndex < sjson.length; pluginIndex++) {
plugins.push(sjson[pluginIndex]);
pluginMap[sjson[pluginIndex].id] = true;
}
for (let branchIndex = 0; branchIndex < branch.length; branchIndex++) {
if (!pluginMap[branch[branchIndex].id])
plugins.push(branch[branchIndex]);
}
return plugins;
}
function mergeConfigs(branch, striderJson) {
// Is this still a mongoose document?
if (typeof branch.toObject === 'function') {
branch = branch.toObject();
}
// Copy all properties of the branch configuration to a new object (inherited properties are ignored, there
// shouldn't be any anyway). Then override all values with what is defined in the strider.json.
// Note that this overrides all plugin configuration.
const config = _.assign({}, branch, striderJson);
// Get a list of all plugins and their default configuration schemas.
// We can find these in common.extensions, which contains separate objects for every type of extension that exists.
// In those objects we find keys which are the IDs of the plugin and the value is the configuration schema of that
// plugin.
// We recursively traverse this data structure and merge it into a single hash, while generating an instance of the
// default configuration, so we can access the configurations for each extension easily.
const allSchemas = _.keys(common.extensions).reduce((allSchemas, extensionType) => {
_.keys(common.extensions[extensionType]).reduce((allSchemas, pluginId) => {
if (extensionType === 'runner')
return allSchemas;
allSchemas[pluginId] = defaultSchema(common.extensions[extensionType][pluginId]);
return allSchemas;
}, allSchemas);
return allSchemas;
}, {});
// For every plugin, merge the default configuration into a new object and then assign the user configuration
// over it.
if (config.plugins && config.plugins.length) {
config.plugins.forEach((plugin) => {
if (!allSchemas[plugin.id])
return plugin.config;
plugin.config = _.assign({}, allSchemas[plugin.id], plugin.config);
});
}
// If the user requests to have plugin configurations merged (through the merge_plugins setting in the strider.json)
// merge the plugin configurations.
// Here, we do not need to care about the default configuration of a plugin, as the web UI will always have the
// full configuration schema populated.
if (!striderJson.merge_plugins)
return config;
debug('Merging plugin configurations');
config.plugins = mergePlugins(branch.plugins, striderJson.plugins);
return config;
}
function validateVal(val, schema) {
if (schema === String)
return `${val}`;
if (schema === Number) {
val = parseFloat(schema);
return isNaN(val) ? 0 : val;
}
if (schema === Boolean)
return !!val;
if (Array.isArray(schema)) {
const ret = [];
if (!Array.isArray(val))
return [];
for (let i = 0; i < val.length; i++) {
ret.push(validateVal(val[i], schema[0]));
}
return ret;
}
if (schema.type && !schema.type.type) {
val = validateVal(val, schema.type);
if (schema.enum && schema.enum.indexOf(val) === -1) {
return;
}
return val;
}
if ('object' !== typeof schema)
return;
if ('object' !== typeof val)
return {};
// if schema is {}, it's unchecked.
if (Object.keys(schema).length === 0)
return val;
return validateAgainstSchema(val, schema);
}
function defaultVal(val) {
if (val === String)
return '';
if (val === Number)
return 0;
if (val === Boolean)
return false;
if (!val)
return null;
if (Array.isArray(val))
return [];
if (val.type && !val.type.type) {
if (val.default)
return val.default;
if (val.enum)
return val.enum[0];
return defaultVal(val.type);
}
if ('object' === typeof val)
return defaultSchema(val);
return null;
}
function defaultSchema(schema) {
const data = {};
for (const key in schema) {
data[key] = defaultVal(schema[key]);
}
return data;
}
function validateAgainstSchema(obj, schema) {
const data = {};
for (const key in obj) {
if (!schema[key])
continue;
data[key] = validateVal(obj[key], schema[key]);
}
return data;
}
function timeFromId(id) {
return new Date(parseInt(id.toString().substring(0, 8), 16) * 1000);
}
function sanitizeBranch(branch) {
const plugins = [];
for (let i = 0; i < branch.plugins; i++) {
plugins.push({
id: branch.plugins[i].id,
enabled: branch.plugins[i].enabled,
});
}
return {
plugins: plugins,
public: branch.public,
active: branch.active,
deploy_on_green: branch.deploy_on_green,
deploy_on_pull_request: branch.deploy_on_pull_request,
runner: {
id: branch.runner && branch.runner.id,
},
};
}
function sanitizeUser(user) {
for (let i = 0; i < user.accounts.length; i++) {
delete user.accounts[i].cache;
}
return user;
}
function sanitizeProject(project) {
return {
_id: project._id,
name: project.name,
branches: project.branches.map(sanitizeBranch),
public: project.public,
display_url: project.display_url,
display_name: project.display_name,
provider: {
id: project.provider.id,
},
};
}
function gravatarDefault(email) {
return gravatar.url(email, {
d: 'identicon',
}, true);
}
//# sourceMappingURL=index.js.map