mirror of
https://gitlab.silvrtree.co.uk/martind2000/nci.git
synced 2025-01-11 05:55:07 +00:00
small projects collection api fixes + doc for it
This commit is contained in:
parent
7dd920ce28
commit
14a14d3785
2
app.js
2
app.js
@ -243,7 +243,7 @@ Steppy(
|
|||||||
app.projects.loadAll(this.slot());
|
app.projects.loadAll(this.slot());
|
||||||
},
|
},
|
||||||
function(err) {
|
function(err) {
|
||||||
logger.log('Loaded projects: ', app.projects.pluck('name'));
|
logger.log('Loaded projects: ', _(app.projects.getAll()).pluck('name'));
|
||||||
|
|
||||||
var host = app.config.http.host,
|
var host = app.config.http.host,
|
||||||
port = app.config.http.port;
|
port = app.config.http.port;
|
||||||
|
@ -88,7 +88,7 @@ exports.init = function(app, callback) {
|
|||||||
// related stat (last build date, avg build time, etc)
|
// related stat (last build date, avg build time, etc)
|
||||||
if (changes.completed) {
|
if (changes.completed) {
|
||||||
var projectsResource = app.dataio.resource('projects');
|
var projectsResource = app.dataio.resource('projects');
|
||||||
projectsResource.clientEmitSyncChange({name: build.project.name});
|
projectsResource.clientEmitSyncChange(build.project.name);
|
||||||
}
|
}
|
||||||
|
|
||||||
buildsResource.clientEmitSync('change', {
|
buildsResource.clientEmitSync('change', {
|
||||||
|
70
docs/developing-plugins/projects-collection.md
Normal file
70
docs/developing-plugins/projects-collection.md
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
- [ProjectsCollection()](#projectscollection)
|
||||||
|
- [ProjectsCollection.validateConfig():Function)](#projectscollectionvalidateconfigconfigobjectcallbackerrconfigfunction)
|
||||||
|
- [ProjectsCollection.load()]:Function)](#projectscollectionloadnamestringcallbackerrfunction)
|
||||||
|
- [ProjectsCollection.loadAll()]:Function)](#projectscollectionloadallcallbackerrfunction)
|
||||||
|
- [ProjectsCollection.unload()]:Function)](#projectscollectionunloadnamestringcallbackerrfunction)
|
||||||
|
- [ProjectsCollection.get()](#projectscollectiongetnamestring)
|
||||||
|
- [ProjectsCollection.getAll()](#projectscollectiongetall)
|
||||||
|
- [ProjectsCollection.filter()](#projectscollectionfilterpredicatefunction)
|
||||||
|
- [ProjectsCollection.getAvgBuildDuration():Function)](#projectscollectiongetavgbuilddurationnamestringcallbackerrdurationfunction)
|
||||||
|
- [ProjectsCollection.remove()]:Function)](#projectscollectionremovenamestringcallbackerrfunction)
|
||||||
|
- [ProjectsCollection.rename()]:Function)](#projectscollectionrenamenamestringcallbackerrfunction)
|
||||||
|
|
||||||
|
## ProjectsCollection()
|
||||||
|
|
||||||
|
Projects collection contains all currently loaded projects and provides
|
||||||
|
operations for manipulating with them.
|
||||||
|
All projects stored on disk in `baseDir` and loaded to memory so
|
||||||
|
they can be received (by `get`, `getAll` and other methods) in a sync way.
|
||||||
|
Note that id for the particular project is a `name` of that project.
|
||||||
|
|
||||||
|
## ProjectsCollection.validateConfig(config:Object, callback(err,config):Function)
|
||||||
|
|
||||||
|
Validate and return given config
|
||||||
|
|
||||||
|
## ProjectsCollection.load(name:String, [callback(err)]:Function)
|
||||||
|
|
||||||
|
Load project to collection.
|
||||||
|
`projectLoaded` event with loaded config as argument will be emitted after
|
||||||
|
load.
|
||||||
|
|
||||||
|
## ProjectsCollection.loadAll([callback(err)]:Function)
|
||||||
|
|
||||||
|
Load all projects (from `this.baseDir`).
|
||||||
|
Calls `load` for every project in a base dir.
|
||||||
|
|
||||||
|
## ProjectsCollection.unload(name:String, [callback(err)]:Function)
|
||||||
|
|
||||||
|
Unload project from collection
|
||||||
|
`projectUnloaded` event with unloaded config as argument will be emitted
|
||||||
|
after unload.
|
||||||
|
|
||||||
|
## ProjectsCollection.get(name:String)
|
||||||
|
|
||||||
|
Get project config by name.
|
||||||
|
Returns config object or undefined if project is not found.
|
||||||
|
|
||||||
|
## ProjectsCollection.getAll()
|
||||||
|
|
||||||
|
Get configs for all currently loaded projects.
|
||||||
|
Returns array of config objects.
|
||||||
|
|
||||||
|
## ProjectsCollection.filter(predicate:Function)
|
||||||
|
|
||||||
|
Get project configs which match to predicate.
|
||||||
|
Returns array of config objects or empty array if there is no matched
|
||||||
|
project.
|
||||||
|
|
||||||
|
## ProjectsCollection.getAvgBuildDuration(name:String, callback(err,duration):Function)
|
||||||
|
|
||||||
|
Calculates average build duration (in ms) for the given project
|
||||||
|
|
||||||
|
## ProjectsCollection.remove(name:String, [callback(err)]:Function)
|
||||||
|
|
||||||
|
Remove project by name.
|
||||||
|
Calls `unload`, removes project from disk and db.
|
||||||
|
|
||||||
|
## ProjectsCollection.rename(name:String, [callback(err)]:Function)
|
||||||
|
|
||||||
|
Rename project.
|
||||||
|
Renames project on disk and db, also changes name for loaded project.
|
142
lib/project.js
142
lib/project.js
@ -10,11 +10,12 @@ var Steppy = require('twostep').Steppy,
|
|||||||
EventEmitter = require('events').EventEmitter,
|
EventEmitter = require('events').EventEmitter,
|
||||||
inherits = require('util').inherits;
|
inherits = require('util').inherits;
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* Projects collection it's something similar to backbone collection.
|
* Projects collection contains all currently loaded projects and provides
|
||||||
* But contrasting to backbone there is no model of a single project, when you
|
* operations for manipulating with them.
|
||||||
* receive project from collection you just get a json.
|
* All projects stored on disk in `baseDir` and loaded to memory so
|
||||||
* General id for the particular project is a `name` of that project.
|
* they can be received (by `get`, `getAll` and other methods) in a sync way.
|
||||||
|
* Note that id for the particular project is a `name` of that project.
|
||||||
*/
|
*/
|
||||||
function ProjectsCollection(params) {
|
function ProjectsCollection(params) {
|
||||||
this.db = params.db;
|
this.db = params.db;
|
||||||
@ -28,7 +29,10 @@ exports.ProjectsCollection = ProjectsCollection;
|
|||||||
inherits(ProjectsCollection, EventEmitter);
|
inherits(ProjectsCollection, EventEmitter);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Validates and returns given `config` to the `callback`(err, config)
|
* Validate and return given config.
|
||||||
|
*
|
||||||
|
* @param {Object} config
|
||||||
|
* @param {Function} callback(err,config)
|
||||||
*/
|
*/
|
||||||
ProjectsCollection.prototype.validateConfig = function(config, callback) {
|
ProjectsCollection.prototype.validateConfig = function(config, callback) {
|
||||||
Steppy(
|
Steppy(
|
||||||
@ -78,7 +82,7 @@ ProjectsCollection.prototype.validateConfig = function(config, callback) {
|
|||||||
|
|
||||||
ProjectsCollection.prototype._getProjectPath = function(name) {
|
ProjectsCollection.prototype._getProjectPath = function(name) {
|
||||||
return path.join(this.baseDir, name);
|
return path.join(this.baseDir, name);
|
||||||
}
|
};
|
||||||
|
|
||||||
ProjectsCollection.prototype._loadConfig = function(dir, callback) {
|
ProjectsCollection.prototype._loadConfig = function(dir, callback) {
|
||||||
var self = this;
|
var self = this;
|
||||||
@ -102,7 +106,7 @@ ProjectsCollection.prototype._loadConfig = function(dir, callback) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// apply defaults to not yet validated config
|
// apply defaults
|
||||||
_(config.steps).each(function(step) {
|
_(config.steps).each(function(step) {
|
||||||
if (!step.type) step.type = 'shell';
|
if (!step.type) step.type = 'shell';
|
||||||
if (!step.name && step.cmd) step.name = utils.prune(step.cmd, 40);
|
if (!step.name && step.cmd) step.name = utils.prune(step.cmd, 40);
|
||||||
@ -115,14 +119,26 @@ ProjectsCollection.prototype._loadConfig = function(dir, callback) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Loads project to collection
|
* Load project to collection.
|
||||||
|
* `projectLoaded` event with loaded config as argument will be emitted after
|
||||||
|
* load.
|
||||||
|
*
|
||||||
|
* @param {String} name
|
||||||
|
* @param {Function} [callback(err)]
|
||||||
*/
|
*/
|
||||||
ProjectsCollection.prototype.load = function(name, callback) {
|
ProjectsCollection.prototype.load = function(name, callback) {
|
||||||
|
callback = callback || _.noop;
|
||||||
var self = this,
|
var self = this,
|
||||||
dir = self._getProjectPath(name);
|
dir = self._getProjectPath(name);
|
||||||
|
|
||||||
Steppy(
|
Steppy(
|
||||||
function() {
|
function() {
|
||||||
|
if (self.get(name)) {
|
||||||
|
throw new Error(
|
||||||
|
'Can`t load already loaded project "' + name + '"'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
self._loadConfig(dir, this.slot());
|
self._loadConfig(dir, this.slot());
|
||||||
},
|
},
|
||||||
function(err, config) {
|
function(err, config) {
|
||||||
@ -140,6 +156,38 @@ ProjectsCollection.prototype.load = function(name, callback) {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load all projects (from `this.baseDir`).
|
||||||
|
* Calls `load` for every project in a base dir.
|
||||||
|
*
|
||||||
|
* @param {Function} [callback(err)]
|
||||||
|
*/
|
||||||
|
ProjectsCollection.prototype.loadAll = function(callback) {
|
||||||
|
callback = callback || _.noop;
|
||||||
|
var self = this;
|
||||||
|
|
||||||
|
Steppy(
|
||||||
|
function() {
|
||||||
|
fs.readdir(self.baseDir, this.slot());
|
||||||
|
},
|
||||||
|
function(err, dirs) {
|
||||||
|
var loadGroup = this.makeGroup();
|
||||||
|
_(dirs).each(function(dir) {
|
||||||
|
self.load(dir, loadGroup.slot());
|
||||||
|
});
|
||||||
|
},
|
||||||
|
callback
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unload project from collection
|
||||||
|
* `projectUnloaded` event with unloaded config as argument will be emitted
|
||||||
|
* after unload.
|
||||||
|
*
|
||||||
|
* @param {String} name
|
||||||
|
* @param {Function} [callback(err)]
|
||||||
|
*/
|
||||||
ProjectsCollection.prototype.unload = function(name, callback) {
|
ProjectsCollection.prototype.unload = function(name, callback) {
|
||||||
callback = callback || _.noop;
|
callback = callback || _.noop;
|
||||||
var self = this;
|
var self = this;
|
||||||
@ -163,52 +211,40 @@ ProjectsCollection.prototype.unload = function(name, callback) {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get project config by name.
|
||||||
|
* Returns config object or undefined if project is not found.
|
||||||
|
*
|
||||||
|
* @param {String} name
|
||||||
|
*/
|
||||||
ProjectsCollection.prototype.get = function(name) {
|
ProjectsCollection.prototype.get = function(name) {
|
||||||
return _(this.configs).findWhere({name: name});
|
return _(this.configs).findWhere({name: name});
|
||||||
};
|
};
|
||||||
|
|
||||||
ProjectsCollection.prototype.getAll = function(name) {
|
/**
|
||||||
|
* Get configs for all currently loaded projects.
|
||||||
|
* Returns array of config objects.
|
||||||
|
*/
|
||||||
|
ProjectsCollection.prototype.getAll = function() {
|
||||||
return this.configs;
|
return this.configs;
|
||||||
};
|
};
|
||||||
|
|
||||||
ProjectsCollection.prototype.findWhere = function(params) {
|
/**
|
||||||
return _(this.configs).findWhere(params);
|
* Get project configs which match to predicate.
|
||||||
};
|
* Returns array of config objects or empty array if there is no matched
|
||||||
|
* project.
|
||||||
ProjectsCollection.prototype.where = function(params) {
|
*
|
||||||
return _(this.configs).where(params);
|
* @param {Function} predicate
|
||||||
};
|
*/
|
||||||
|
ProjectsCollection.prototype.filter = function(predicate) {
|
||||||
ProjectsCollection.prototype.filter = function(iterator) {
|
return _(this.configs).filter(predicate);
|
||||||
return _(this.configs).filter(iterator);
|
|
||||||
};
|
|
||||||
|
|
||||||
ProjectsCollection.prototype.pluck = function(attribute) {
|
|
||||||
return _(this.configs).pluck(attribute);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Loads all projects (from `this.baseDir`)
|
* Calculate average build duration (in ms) for the given project.
|
||||||
*/
|
*
|
||||||
ProjectsCollection.prototype.loadAll = function(callback) {
|
* @param {String} name
|
||||||
var self = this;
|
* @param {Function} callback(err,duration)
|
||||||
|
|
||||||
Steppy(
|
|
||||||
function() {
|
|
||||||
fs.readdir(self.baseDir, this.slot());
|
|
||||||
},
|
|
||||||
function(err, dirs) {
|
|
||||||
var loadGroup = this.makeGroup();
|
|
||||||
_(dirs).each(function(dir) {
|
|
||||||
self.load(dir, loadGroup.slot());
|
|
||||||
});
|
|
||||||
},
|
|
||||||
callback
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Calculates average build duration for the given project
|
|
||||||
*/
|
*/
|
||||||
ProjectsCollection.prototype.getAvgBuildDuration = function(name, callback) {
|
ProjectsCollection.prototype.getAvgBuildDuration = function(name, callback) {
|
||||||
var self = this;
|
var self = this;
|
||||||
@ -236,7 +272,15 @@ ProjectsCollection.prototype.getAvgBuildDuration = function(name, callback) {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove project by name.
|
||||||
|
* Calls `unload`, removes project from disk and db.
|
||||||
|
*
|
||||||
|
* @param {String} name
|
||||||
|
* @param {Function} [callback(err)]
|
||||||
|
*/
|
||||||
ProjectsCollection.prototype.remove = function(name, callback) {
|
ProjectsCollection.prototype.remove = function(name, callback) {
|
||||||
|
callback = callback || _.noop;
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
Steppy(
|
Steppy(
|
||||||
@ -269,7 +313,15 @@ ProjectsCollection.prototype.remove = function(name, callback) {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Rename project.
|
||||||
|
* Renames project on disk and db, also changes name for loaded project.
|
||||||
|
*
|
||||||
|
* @param {String} name
|
||||||
|
* @param {Function} [callback(err)]
|
||||||
|
*/
|
||||||
ProjectsCollection.prototype.rename = function(name, newName, callback) {
|
ProjectsCollection.prototype.rename = function(name, newName, callback) {
|
||||||
|
callback = callback || _.noop;
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
Steppy(
|
Steppy(
|
||||||
|
@ -10,6 +10,7 @@
|
|||||||
"test": "npm run makeTestRepos && mocha --bail --reporter=spec --timeout 10000",
|
"test": "npm run makeTestRepos && mocha --bail --reporter=spec --timeout 10000",
|
||||||
"dev": "gulp",
|
"dev": "gulp",
|
||||||
"sync": "npm install && npm prune && bower install && bower prune",
|
"sync": "npm install && npm prune && bower install && bower prune",
|
||||||
|
"docProjectsCollection": "dox --api --skipSingleStar < lib/project.js > docs/developing-plugins/projects-collection.md",
|
||||||
"buildJs": "r.js -o static/js/requirejs/buid.js",
|
"buildJs": "r.js -o static/js/requirejs/buid.js",
|
||||||
"buildClean": "rm static/index.html",
|
"buildClean": "rm static/index.html",
|
||||||
"buildHtml": "jade views/index.jade --obj '{\"env\": \"production\"}' -o static/",
|
"buildHtml": "jade views/index.jade --obj '{\"env\": \"production\"}' -o static/",
|
||||||
@ -56,6 +57,7 @@
|
|||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"bower": "1.4.1",
|
"bower": "1.4.1",
|
||||||
|
"dox": "0.8.0",
|
||||||
"expect.js": "0.3.1",
|
"expect.js": "0.3.1",
|
||||||
"gulp": "3.8.11",
|
"gulp": "3.8.11",
|
||||||
"gulp-less": "3.0.3",
|
"gulp-less": "3.0.3",
|
||||||
|
@ -31,11 +31,11 @@ module.exports = function(app) {
|
|||||||
res.send(filteredProjects);
|
res.send(filteredProjects);
|
||||||
});
|
});
|
||||||
|
|
||||||
var getProject = function(params, callback) {
|
var getProject = function(name, callback) {
|
||||||
var project;
|
var project;
|
||||||
Steppy(
|
Steppy(
|
||||||
function() {
|
function() {
|
||||||
project = app.projects.findWhere(params.condition);
|
project = app.projects.get(name);
|
||||||
|
|
||||||
app.projects.getAvgBuildDuration(project.name, this.slot());
|
app.projects.getAvgBuildDuration(project.name, this.slot());
|
||||||
|
|
||||||
@ -84,12 +84,12 @@ module.exports = function(app) {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
// resource custom method which finds project by condition
|
// resource custom method which finds project by name
|
||||||
// and emits event about it change to clients
|
// and emits event about it change to clients
|
||||||
resource.clientEmitSyncChange = function(condition) {
|
resource.clientEmitSyncChange = function(name) {
|
||||||
Steppy(
|
Steppy(
|
||||||
function() {
|
function() {
|
||||||
getProject({condition: condition}, this.slot());
|
getProject(name, this.slot());
|
||||||
},
|
},
|
||||||
function(err, project) {
|
function(err, project) {
|
||||||
resource.clientEmitSync('change', {project: project});
|
resource.clientEmitSync('change', {project: project});
|
||||||
@ -106,7 +106,7 @@ module.exports = function(app) {
|
|||||||
resource.use('read', function(req, res) {
|
resource.use('read', function(req, res) {
|
||||||
Steppy(
|
Steppy(
|
||||||
function() {
|
function() {
|
||||||
getProject({condition: req.data}, this.slot());
|
getProject(req.data.name, this.slot());
|
||||||
},
|
},
|
||||||
function(err, project) {
|
function(err, project) {
|
||||||
res.send(project);
|
res.send(project);
|
||||||
|
Loading…
Reference in New Issue
Block a user