mirror of
https://gitlab.silvrtree.co.uk/martind2000/nci.git
synced 2025-02-11 02:39:17 +00:00
add base scm class, mercurial class with tests
This commit is contained in:
parent
a51adc69d4
commit
dc00488eea
72
lib/scm/base.js
Normal file
72
lib/scm/base.js
Normal file
@ -0,0 +1,72 @@
|
||||
'use strict';
|
||||
|
||||
var spawn = require('child_process').spawn,
|
||||
EventEmitter = require('events').EventEmitter,
|
||||
inherits = require('util').inherits;
|
||||
|
||||
function BaseScm(config) {
|
||||
var self = this;
|
||||
self.config = config;
|
||||
['src'].forEach(function(key) {
|
||||
if (key in self.config === false) throw new Error(key + ' is not set');
|
||||
self[key] = self.config[key];
|
||||
});
|
||||
self.cwd = config.cwd;
|
||||
}
|
||||
|
||||
module.exports = BaseScm;
|
||||
|
||||
inherits(BaseScm, EventEmitter);
|
||||
|
||||
BaseScm.prototype._exec = function(command, args, callback) {
|
||||
var self = this,
|
||||
stdout = '';
|
||||
var cmd = spawn(command, args, {cwd: this.cwd});
|
||||
cmd.stdout.on('data', function(data) {
|
||||
if (self.isEmit) self.emit('stdout', data);
|
||||
stdout += data;
|
||||
});
|
||||
cmd.stderr.on('data', function(data) {
|
||||
callback(new Error('Scm outputs to stderr: ' + data));
|
||||
cmd.kill();
|
||||
});
|
||||
cmd.on('exit', function(code) {
|
||||
var err = null;
|
||||
if (code !== 0) err = new Error(
|
||||
'Scm command exits with non-zero code: ' + code
|
||||
)
|
||||
callback(err, stdout);
|
||||
});
|
||||
return cmd;
|
||||
};
|
||||
|
||||
/**
|
||||
* Clone repository to the `dst` update to `rev` and set `this.cwd` to `dst`
|
||||
*/
|
||||
BaseScm.prototype.clone = function(dst, rev, callback) {
|
||||
};
|
||||
|
||||
/**
|
||||
* Pull changes from remote repository without update
|
||||
*/
|
||||
BaseScm.prototype.pull = function(rev, callback) {
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns string id of current revision
|
||||
*/
|
||||
BaseScm.prototype.getId = function(callback) {
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns array of changes between revisions
|
||||
*/
|
||||
BaseScm.prototype.getChanges = function(rev1, rev2, callback) {
|
||||
};
|
||||
|
||||
/**
|
||||
* Updates to revision
|
||||
*/
|
||||
BaseScm.prototype.update = function(rev, callback) {
|
||||
};
|
||||
|
8
lib/scm/index.js
Normal file
8
lib/scm/index.js
Normal file
@ -0,0 +1,8 @@
|
||||
'use strict';
|
||||
|
||||
var path = require('path');
|
||||
|
||||
exports.createScm = function(config) {
|
||||
var Constructor = require(path.join(__dirname, config.type));
|
||||
return new Constructor(config);
|
||||
};
|
53
lib/scm/mercurial.js
Normal file
53
lib/scm/mercurial.js
Normal file
@ -0,0 +1,53 @@
|
||||
'use strict';
|
||||
|
||||
var BaseScm = require('./base'),
|
||||
inherits = require('util').inherits;
|
||||
|
||||
function MercurialScm(config) {
|
||||
BaseScm.call(this, config);
|
||||
}
|
||||
|
||||
module.exports = MercurialScm;
|
||||
|
||||
inherits(MercurialScm, BaseScm);
|
||||
|
||||
MercurialScm.prototype.defaultRev = 'default';
|
||||
|
||||
MercurialScm.prototype.clone = function(dst, rev, callback) {
|
||||
var self = this;
|
||||
this._exec('hg', ['clone', '--rev', rev, this.src, dst], function(err) {
|
||||
self.cwd = dst;
|
||||
callback(err);
|
||||
});
|
||||
};
|
||||
|
||||
MercurialScm.prototype.pull = function(rev, callback) {
|
||||
this._exec('hg', ['pull', '--rev', rev], callback);
|
||||
};
|
||||
|
||||
MercurialScm.prototype.getId = function(callback) {
|
||||
this._exec('hg', ['id', '--id'], function(err, stdout) {
|
||||
callback(err, !err && stdout.replace('\n', ''));
|
||||
});
|
||||
};
|
||||
|
||||
MercurialScm.prototype.getChanges = function(rev1, rev2, callback) {
|
||||
this._exec('hg', [
|
||||
'log', '--rev', rev2 + ':' + rev1,
|
||||
'--template', '{node|short};;;{author};;;{date|date};;;{desc}\n'
|
||||
], function(err, stdout) {
|
||||
callback(err, !err && stdout.split('\n').slice(0, -2).map(function(str) {
|
||||
var parts = str.split(';;;');
|
||||
return {
|
||||
id: parts[0],
|
||||
author: parts[1],
|
||||
date: new Date(parts[2]).getTime(),
|
||||
comment: parts[3]
|
||||
};
|
||||
}));
|
||||
});
|
||||
};
|
||||
|
||||
MercurialScm.prototype.update = function(rev, callback) {
|
||||
this._exec('hg', ['up', rev], callback);
|
||||
};
|
35
package.json
Normal file
35
package.json
Normal file
@ -0,0 +1,35 @@
|
||||
{
|
||||
"name": "nci",
|
||||
"version": "0.1.0-alpha",
|
||||
"description": "Continuous integration server written in node.js",
|
||||
"bin": {
|
||||
"nci": "bin/nci"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "mocha --bail --reporter=spec test"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git://github.com/okv/nci.git"
|
||||
},
|
||||
"keywords": [
|
||||
"continuous",
|
||||
"integration",
|
||||
"server",
|
||||
"ci",
|
||||
"build"
|
||||
],
|
||||
"author": "Oleg Korobenko <oleg.korobenko@gmail.com>",
|
||||
"license": "MIT",
|
||||
"bugs": {
|
||||
"url": "https://github.com/okv/nci/issues"
|
||||
},
|
||||
"homepage": "https://github.com/okv/nci",
|
||||
"dependencies": {
|
||||
"twostep": "0.4.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"expect.js": "0.3.1",
|
||||
"mocha": "1.18.2"
|
||||
}
|
||||
}
|
BIN
test/repos/.hg/00changelog.i
Normal file
BIN
test/repos/.hg/00changelog.i
Normal file
Binary file not shown.
1
test/repos/.hg/branch
Normal file
1
test/repos/.hg/branch
Normal file
@ -0,0 +1 @@
|
||||
default
|
2
test/repos/.hg/cache/branchheads-served
vendored
Normal file
2
test/repos/.hg/cache/branchheads-served
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
98e3a18d8193d36caf143e9b57f5123bfd5878c9 1
|
||||
98e3a18d8193d36caf143e9b57f5123bfd5878c9 default
|
2
test/repos/.hg/cache/tags
vendored
Normal file
2
test/repos/.hg/cache/tags
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
1 98e3a18d8193d36caf143e9b57f5123bfd5878c9
|
||||
|
BIN
test/repos/.hg/dirstate
Normal file
BIN
test/repos/.hg/dirstate
Normal file
Binary file not shown.
4
test/repos/.hg/requires
Normal file
4
test/repos/.hg/requires
Normal file
@ -0,0 +1,4 @@
|
||||
dotencode
|
||||
fncache
|
||||
revlogv1
|
||||
store
|
BIN
test/repos/.hg/store/00changelog.i
Normal file
BIN
test/repos/.hg/store/00changelog.i
Normal file
Binary file not shown.
BIN
test/repos/.hg/store/00manifest.i
Normal file
BIN
test/repos/.hg/store/00manifest.i
Normal file
Binary file not shown.
BIN
test/repos/.hg/store/data/rev0.txt.i
Normal file
BIN
test/repos/.hg/store/data/rev0.txt.i
Normal file
Binary file not shown.
BIN
test/repos/.hg/store/data/rev1.txt.i
Normal file
BIN
test/repos/.hg/store/data/rev1.txt.i
Normal file
Binary file not shown.
2
test/repos/.hg/store/fncache
Normal file
2
test/repos/.hg/store/fncache
Normal file
@ -0,0 +1,2 @@
|
||||
data/rev0.txt.i
|
||||
data/rev1.txt.i
|
0
test/repos/.hg/store/phaseroots
Normal file
0
test/repos/.hg/store/phaseroots
Normal file
BIN
test/repos/.hg/store/undo
Normal file
BIN
test/repos/.hg/store/undo
Normal file
Binary file not shown.
0
test/repos/.hg/store/undo.phaseroots
Normal file
0
test/repos/.hg/store/undo.phaseroots
Normal file
0
test/repos/.hg/undo.bookmarks
Normal file
0
test/repos/.hg/undo.bookmarks
Normal file
1
test/repos/.hg/undo.branch
Normal file
1
test/repos/.hg/undo.branch
Normal file
@ -0,0 +1 @@
|
||||
default
|
3
test/repos/.hg/undo.desc
Normal file
3
test/repos/.hg/undo.desc
Normal file
@ -0,0 +1,3 @@
|
||||
0
|
||||
pull
|
||||
file:///mnt/data/home/oleg/work/repository/git-hub/nci/test/repos/mercurial
|
0
test/repos/.hg/undo.dirstate
Normal file
0
test/repos/.hg/undo.dirstate
Normal file
BIN
test/repos/mercurial/.hg/00changelog.i
Normal file
BIN
test/repos/mercurial/.hg/00changelog.i
Normal file
Binary file not shown.
2
test/repos/mercurial/.hg/cache/branchheads-served
vendored
Normal file
2
test/repos/mercurial/.hg/cache/branchheads-served
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
9d7d08445f4ce095c22a98a902a391973cf07f37 2
|
||||
9d7d08445f4ce095c22a98a902a391973cf07f37 default
|
2
test/repos/mercurial/.hg/cache/tags
vendored
Normal file
2
test/repos/mercurial/.hg/cache/tags
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
2 9d7d08445f4ce095c22a98a902a391973cf07f37
|
||||
|
BIN
test/repos/mercurial/.hg/dirstate
Normal file
BIN
test/repos/mercurial/.hg/dirstate
Normal file
Binary file not shown.
1
test/repos/mercurial/.hg/last-message.txt
Normal file
1
test/repos/mercurial/.hg/last-message.txt
Normal file
@ -0,0 +1 @@
|
||||
third revision
|
4
test/repos/mercurial/.hg/requires
Normal file
4
test/repos/mercurial/.hg/requires
Normal file
@ -0,0 +1,4 @@
|
||||
dotencode
|
||||
fncache
|
||||
revlogv1
|
||||
store
|
BIN
test/repos/mercurial/.hg/store/00changelog.i
Normal file
BIN
test/repos/mercurial/.hg/store/00changelog.i
Normal file
Binary file not shown.
BIN
test/repos/mercurial/.hg/store/00manifest.i
Normal file
BIN
test/repos/mercurial/.hg/store/00manifest.i
Normal file
Binary file not shown.
BIN
test/repos/mercurial/.hg/store/data/rev0.txt.i
Normal file
BIN
test/repos/mercurial/.hg/store/data/rev0.txt.i
Normal file
Binary file not shown.
BIN
test/repos/mercurial/.hg/store/data/rev1.txt.i
Normal file
BIN
test/repos/mercurial/.hg/store/data/rev1.txt.i
Normal file
Binary file not shown.
BIN
test/repos/mercurial/.hg/store/data/rev2.txt.i
Normal file
BIN
test/repos/mercurial/.hg/store/data/rev2.txt.i
Normal file
Binary file not shown.
3
test/repos/mercurial/.hg/store/fncache
Normal file
3
test/repos/mercurial/.hg/store/fncache
Normal file
@ -0,0 +1,3 @@
|
||||
data/rev0.txt.i
|
||||
data/rev1.txt.i
|
||||
data/rev2.txt.i
|
1
test/repos/mercurial/.hg/store/phaseroots
Normal file
1
test/repos/mercurial/.hg/store/phaseroots
Normal file
@ -0,0 +1 @@
|
||||
1 da2762e71e87935198a25b0fceab0a364ad2e6d7
|
BIN
test/repos/mercurial/.hg/store/undo
Normal file
BIN
test/repos/mercurial/.hg/store/undo
Normal file
Binary file not shown.
1
test/repos/mercurial/.hg/store/undo.phaseroots
Normal file
1
test/repos/mercurial/.hg/store/undo.phaseroots
Normal file
@ -0,0 +1 @@
|
||||
1 da2762e71e87935198a25b0fceab0a364ad2e6d7
|
0
test/repos/mercurial/.hg/undo.bookmarks
Normal file
0
test/repos/mercurial/.hg/undo.bookmarks
Normal file
1
test/repos/mercurial/.hg/undo.branch
Normal file
1
test/repos/mercurial/.hg/undo.branch
Normal file
@ -0,0 +1 @@
|
||||
default
|
2
test/repos/mercurial/.hg/undo.desc
Normal file
2
test/repos/mercurial/.hg/undo.desc
Normal file
@ -0,0 +1,2 @@
|
||||
2
|
||||
commit
|
BIN
test/repos/mercurial/.hg/undo.dirstate
Normal file
BIN
test/repos/mercurial/.hg/undo.dirstate
Normal file
Binary file not shown.
0
test/repos/mercurial/rev0.txt
Normal file
0
test/repos/mercurial/rev0.txt
Normal file
0
test/repos/mercurial/rev1.txt
Normal file
0
test/repos/mercurial/rev1.txt
Normal file
0
test/repos/mercurial/rev2.txt
Normal file
0
test/repos/mercurial/rev2.txt
Normal file
0
test/repos/rev0.txt
Normal file
0
test/repos/rev0.txt
Normal file
0
test/repos/rev1.txt
Normal file
0
test/repos/rev1.txt
Normal file
116
test/scm.js
Normal file
116
test/scm.js
Normal file
@ -0,0 +1,116 @@
|
||||
'use strict';
|
||||
|
||||
var expect = require('expect.js'),
|
||||
path = require('path'),
|
||||
fs = require('fs'),
|
||||
createScm = require('../lib/scm').createScm;
|
||||
|
||||
|
||||
['mercurial'].forEach(function(type) {
|
||||
describe(type, function() {
|
||||
var data = getTestData(type),
|
||||
repositoryName = 'test-repository',
|
||||
repositoryPath = path.join(path.join(__dirname, 'repos'), repositoryName);
|
||||
|
||||
it('remove test repository dir if it exists', function(done) {
|
||||
if (fs.exists(repositoryPath, function(isExists) {
|
||||
if (isExists) {
|
||||
scm._exec('rm', ['-R', repositoryPath], done);
|
||||
} else {
|
||||
done();
|
||||
}
|
||||
}));
|
||||
});
|
||||
|
||||
var scm = createScm({
|
||||
type: type,
|
||||
src: path.join(__dirname, 'repos', type)
|
||||
});
|
||||
|
||||
var currentRev = data.rev0.id;
|
||||
it('clone rev0 to dst without errors', function(done) {
|
||||
scm.clone(repositoryPath, data.rev0.id, done);
|
||||
});
|
||||
|
||||
it('expect scm.cwd equals to dst', function() {
|
||||
expect(scm.cwd).equal(repositoryPath);
|
||||
});
|
||||
|
||||
it('expect current id equals to rev0', function(done) {
|
||||
scm.getId(function(err, id) {
|
||||
if (err) return done(err);
|
||||
expect(id).equal(data.rev0.id);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('expect none changes from rev0 to default revision', function(done) {
|
||||
scm.getChanges(data.rev0.id, scm.defaultRev, function(err, changes) {
|
||||
if (err) return done(err);
|
||||
expect(changes).ok();
|
||||
expect(changes).length(0);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('pull to default revision without errors', function(done) {
|
||||
scm.pull(scm.defaultRev, done);
|
||||
});
|
||||
|
||||
it('now (after pull) expect rev1 and rev2 as new changes (in reverse ' +
|
||||
'order) from rev0 to default revision', function(done) {
|
||||
scm.getChanges(data.rev0.id, scm.defaultRev, function(err, changes) {
|
||||
if (err) return done(err);
|
||||
expect(changes).ok();
|
||||
expect(changes).length(2);
|
||||
expect(changes).eql([data.rev2, data.rev1]);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('update to default revision (should update to rev2) without error',
|
||||
function(done) {
|
||||
scm.update(scm.defaultRev, done);
|
||||
});
|
||||
|
||||
it('expect current revision equals to rev2', function(done) {
|
||||
scm.getId(function(err, id) {
|
||||
if (err) return done(err);
|
||||
expect(id).equal(data.rev2.id);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('remove test repository dir', function(done) {
|
||||
scm._exec('rm', ['-R', repositoryPath], done);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
function getTestData(type) {
|
||||
if (type === 'mercurial') return getMercurialData();
|
||||
}
|
||||
|
||||
function getMercurialData() {
|
||||
return {
|
||||
rev0: {
|
||||
id: 'da2762e71e87',
|
||||
author: 'kotbegemot',
|
||||
date: new Date('Fri May 09 22:36:41 2014 +0400').getTime(),
|
||||
comment: 'zero revision'
|
||||
},
|
||||
rev1: {
|
||||
id: '98e3a18d8193',
|
||||
author: 'kotbegemot',
|
||||
date: new Date('Fri May 09 22:37:19 2014 +0400').getTime(),
|
||||
comment: 'first revision'
|
||||
},
|
||||
rev2: {
|
||||
id: '9d7d08445f4c',
|
||||
author: 'kotbegemot',
|
||||
date: new Date('Sat May 10 03:18:20 2014 +0400').getTime(),
|
||||
comment: 'third revision'
|
||||
}
|
||||
};
|
||||
}
|
Loading…
Reference in New Issue
Block a user