mirror of
https://gitlab.silvrtree.co.uk/martind2000/nci.git
synced 2025-01-10 21:55:08 +00:00
222 lines
5.8 KiB
JavaScript
222 lines
5.8 KiB
JavaScript
'use strict';
|
|
|
|
var Steppy = require('twostep').Steppy,
|
|
_ = require('underscore'),
|
|
EventEmitter = require('events').EventEmitter,
|
|
inherits = require('util').inherits;
|
|
|
|
/**
|
|
* Facade entity which accumulates operations with currently running and
|
|
* db saved builds.
|
|
*/
|
|
function BuildsCollection(params) {
|
|
this.db = params.db;
|
|
this.distributor = params.distributor;
|
|
|
|
this._proxyDistributorEvent('buildUpdate', 'buildUpdated');
|
|
this._proxyDistributorEvent('buildCancel', 'buildCanceled');
|
|
this._proxyDistributorEvent('buildLogLines', 'buildLogLines');
|
|
}
|
|
|
|
exports.BuildsCollection = BuildsCollection;
|
|
|
|
inherits(BuildsCollection, EventEmitter);
|
|
|
|
BuildsCollection.prototype._proxyDistributorEvent = function(source, dest) {
|
|
var self = this;
|
|
|
|
self.distributor.on(source, function() {
|
|
self.emit.apply(self, [dest].concat(_(arguments).toArray()));
|
|
});
|
|
};
|
|
|
|
/**
|
|
* Create build by running given project.
|
|
* - `params.projectName` - project to build
|
|
* - `params.withScmChangesOnly` - if true then build will be started only if
|
|
* there is scm changes for project
|
|
* - `params.queueQueued` - if true then currently queued project can be queued
|
|
* again
|
|
* - `params.initiator` - contains information about initiator of the build,
|
|
* must contain `type` property e.g. when one build triggers another:
|
|
* initiator: {type: 'build', id: 123, number: 10, project: {name: 'project1'}
|
|
*
|
|
* @param {Object} params
|
|
* @param {Function} [callback(err)]
|
|
*/
|
|
BuildsCollection.prototype.create = function(params, callback) {
|
|
this.distributor.run(params, callback);
|
|
};
|
|
|
|
/**
|
|
* Cancel build by id.
|
|
* Note that only queued build can be canceled currently.
|
|
*
|
|
* @param {Number} id
|
|
* @param {Function} [callback(err)]
|
|
*/
|
|
BuildsCollection.prototype.cancel = function(id, callback) {
|
|
this.distributor.cancel(id, callback);
|
|
};
|
|
|
|
/**
|
|
* Get build by id.
|
|
*
|
|
* @param {Number} id
|
|
* @param {Function} callback(err,build)
|
|
*/
|
|
BuildsCollection.prototype.get = function(id, callback) {
|
|
this.db.builds.find({start: {id: id}}, function(err, builds) {
|
|
callback(err, builds && builds[0]);
|
|
});
|
|
};
|
|
|
|
/**
|
|
* Get log lines for the given build.
|
|
* - `params.buildId` - target build
|
|
* - `params.from` - if set then lines from that number will be returned
|
|
* - `params.to` - if set then lines to that number will be returned
|
|
*
|
|
* @param {Object} params
|
|
* @param {Function} callback(err,logLinesData)
|
|
*/
|
|
BuildsCollection.prototype.getLogLines = function(params, callback) {
|
|
var self = this;
|
|
|
|
Steppy(
|
|
function() {
|
|
var findParams = {
|
|
start: {buildId: params.buildId},
|
|
end: {buildId: params.buildId}
|
|
};
|
|
if (params.from) findParams.start.number = params.from;
|
|
if (params.to) findParams.end.number = params.to;
|
|
|
|
var count = params.from && params.to ? params.to - params.from + 1: 0;
|
|
|
|
self.db.logLines.find(findParams, this.slot());
|
|
|
|
this.pass(count);
|
|
},
|
|
function(err, logLines, count) {
|
|
this.pass({
|
|
lines: logLines,
|
|
isLast: count ? logLines.length < count : true
|
|
});
|
|
},
|
|
callback
|
|
);
|
|
};
|
|
|
|
BuildsCollection.prototype.getLogLinesTail = function(params, callback) {
|
|
var self = this;
|
|
|
|
Steppy(
|
|
function() {
|
|
var findParams = {
|
|
reverse: true,
|
|
start: {buildId: params.buildId},
|
|
limit: params.limit
|
|
};
|
|
|
|
self.db.logLines.find(findParams, this.slot());
|
|
},
|
|
function(err, logLines) {
|
|
var lines = logLines.reverse(),
|
|
total = logLines.length ? logLines[logLines.length - 1].number : 0;
|
|
|
|
this.pass({lines: lines, total: total});
|
|
},
|
|
callback
|
|
);
|
|
};
|
|
|
|
/**
|
|
* Calculate average build duration for the given builds.
|
|
*
|
|
* @param {Object[]} builds
|
|
*/
|
|
BuildsCollection.prototype.getAvgBuildDuration = function(builds) {
|
|
var durationsSum = _(builds).reduce(function(sum, build) {
|
|
return sum + (build.endDate - build.startDate);
|
|
}, 0);
|
|
return Math.round(durationsSum / builds.length);
|
|
};
|
|
|
|
/**
|
|
* Get builds sorted by date in descending order.
|
|
* - `params.projectName` - optional project filter
|
|
* - `params.status` - optional status filter, can be used only when
|
|
* `params.projectName` is set. When used builds in the result will contain
|
|
* only following fields: id, number, startDate, endDate
|
|
* - `params.limit` - maximum builds count to get
|
|
*
|
|
* @param {Object} params
|
|
* @param {Function} callback(err,builds)
|
|
*/
|
|
BuildsCollection.prototype.getRecent = function(params, callback) {
|
|
var self = this;
|
|
|
|
Steppy(
|
|
function() {
|
|
var findParams = {start: {}, limit: params.limit};
|
|
|
|
// such condition for match one of projections:
|
|
// projectName, descCreateDate
|
|
// projectName, status, descCreateDate
|
|
// or just descCreateDate projection if project name is not set
|
|
if (params.projectName) {
|
|
findParams.start.projectName = params.projectName;
|
|
if (params.status) findParams.start.status = params.status;
|
|
}
|
|
|
|
findParams.start.descCreateDate = '';
|
|
|
|
self.db.builds.find(findParams, this.slot());
|
|
},
|
|
callback
|
|
);
|
|
};
|
|
|
|
/**
|
|
* Get info about current done builds streak.
|
|
* - `params.projectName` - optional project filter
|
|
*
|
|
* @param {Object} params
|
|
* @param {Function} callback(err,doneStreak)
|
|
*/
|
|
BuildsCollection.prototype.getDoneStreak = function(params, callback) {
|
|
var self = this;
|
|
|
|
Steppy(
|
|
function() {
|
|
var start = {};
|
|
|
|
if (params.projectName) start.projectName = params.projectName;
|
|
|
|
start.descCreateDate = '';
|
|
|
|
// tricky but effective streak counting inside filter goes below
|
|
var doneBuildsStreakCallback = _(this.slot()).once(),
|
|
doneBuildsStreak = {buildsCount: 0};
|
|
|
|
self.db.builds.find({
|
|
start: start,
|
|
filter: function(build) {
|
|
// error exits streak
|
|
if (build.status === 'error') {
|
|
doneBuildsStreakCallback(null, doneBuildsStreak);
|
|
return true;
|
|
}
|
|
if (build.status === 'done') {
|
|
doneBuildsStreak.buildsCount++;
|
|
}
|
|
},
|
|
limit: 1
|
|
}, function(err) {
|
|
doneBuildsStreakCallback(err, doneBuildsStreak);
|
|
});
|
|
},
|
|
callback
|
|
);
|
|
}; |