event refactor and errors

This commit is contained in:
Peter Cottle 2012-09-10 12:55:49 -07:00
parent 4f30ad73a8
commit 3d1890bb3b
3 changed files with 111 additions and 36 deletions

23
src/errors.js Normal file
View file

@ -0,0 +1,23 @@
function CommandProcessError(msg) {
this.msg = msg;
}
CommandProcessError.prototype = _.copy(Error.prototype);
CommandProcessError.prototype.toString = function() {
return 'Command Process Error: ' + this.msg;
};
function CommandResult(msg) {
this.msg = msg;
}
CommandResult.prototype = _.copy(Error.prototype);
CommandResult.prototype.toString = function() {
return 'Command Result: ' + this.msg;
};
CommandResult.prototype.toResult = function() {
return this.msg.replace('\n', '</br>');
};

View file

@ -14,15 +14,17 @@ function GitEngine() {
this.id_gen = 0; this.id_gen = 0;
this.branches = []; this.branches = [];
this._init(); events.on('gitCommandReady', _.bind(this.dispatch, this));
this.init();
} }
GitEngine.prototype._init = function() { GitEngine.prototype.init = function() {
// make an initial commit and a master branch // make an initial commit and a master branch
this.rootCommit = new Commit({rootCommit: true}); this.rootCommit = new Commit({rootCommit: true});
this.refs[this.rootCommit.get('id')] = this.rootCommit; this.refs[this.rootCommit.get('id')] = this.rootCommit;
var master = this._makeBranch('master', this.rootCommit); var master = this.makeBranch('master', this.rootCommit);
this.HEAD = new Ref({ this.HEAD = new Ref({
id: 'HEAD', id: 'HEAD',
target: master target: master
@ -40,7 +42,7 @@ GitEngine.prototype.getDetachedHead = function() {
return targetType !== 'branch'; return targetType !== 'branch';
}; };
GitEngine.prototype._validateBranchName = function(name) { GitEngine.prototype.validateBranchName = function(name) {
name = name.replace(/\s/g, ''); name = name.replace(/\s/g, '');
if (!/^[a-zA-Z0-9]+$/.test(name)) { if (!/^[a-zA-Z0-9]+$/.test(name)) {
throw new Error('woah bad branch name!! This is not ok: ' + name); throw new Error('woah bad branch name!! This is not ok: ' + name);
@ -51,8 +53,8 @@ GitEngine.prototype._validateBranchName = function(name) {
return name; return name;
}; };
GitEngine.prototype._makeBranch = function(id, target) { GitEngine.prototype.makeBranch = function(id, target) {
id = this._validateBranchName(id); id = this.validateBranchName(id);
if (this.refs[id]) { if (this.refs[id]) {
throw new Error('that branch id already exists!'); throw new Error('that branch id already exists!');
} }
@ -84,7 +86,7 @@ GitEngine.prototype.printBranches = function() {
}); });
}; };
GitEngine.prototype._makeCommit = function(parent) { GitEngine.prototype.makeCommit = function(parent) {
var commit = new Commit({ var commit = new Commit({
parents: [parent] parents: [parent]
}); });
@ -102,18 +104,18 @@ GitEngine.prototype.commit = function() {
targetCommit = targetBranch.get('target'); targetCommit = targetBranch.get('target');
} }
var newCommit = this._makeCommit(targetCommit); var newCommit = this.makeCommit(targetCommit);
targetBranch.set('target', newCommit); targetBranch.set('target', newCommit);
}; };
GitEngine.prototype._resolveId = function(idOrTarget) { GitEngine.prototype.resolveId = function(idOrTarget) {
if (typeof idOrTarget !== 'string') { if (typeof idOrTarget !== 'string') {
return idOrTarget; return idOrTarget;
} }
return this._resolveStringRef(idOrTarget); return this.resolveStringRef(idOrTarget);
}; };
GitEngine.prototype._resolveStringRef = function(ref) { GitEngine.prototype.resolveStringRef = function(ref) {
if (this.refs[ref]) { if (this.refs[ref]) {
return this.refs[ref]; return this.refs[ref];
} }
@ -146,13 +148,13 @@ GitEngine.prototype._resolveStringRef = function(ref) {
if (!this.refs[startRef]) { if (!this.refs[startRef]) {
throw new Error('the ref ' + startRef +' does not exist.'); throw new Error('the ref ' + startRef +' does not exist.');
} }
var commit = this._getCommitFromRef(startRef); var commit = this.getCommitFromRef(startRef);
return this._numBackFrom(commit, numBack); return this.numBackFrom(commit, numBack);
}; };
GitEngine.prototype._getCommitFromRef = function(ref) { GitEngine.prototype.getCommitFromRef = function(ref) {
var start = this._resolveId(ref); var start = this.resolveId(ref);
// works for both HEAD and just a single layer. aka branch // works for both HEAD and just a single layer. aka branch
while (start.get('type') !== 'commit') { while (start.get('type') !== 'commit') {
start = start.get('target'); start = start.get('target');
@ -160,7 +162,7 @@ GitEngine.prototype._getCommitFromRef = function(ref) {
return start; return start;
}; };
GitEngine.prototype._numBackFrom = function(commit, numBack) { GitEngine.prototype.numBackFrom = function(commit, numBack) {
// going back '3' from a given ref is not trivial, for you might have // going back '3' from a given ref is not trivial, for you might have
// a bunch of merge commits and such. like this situation: // a bunch of merge commits and such. like this situation:
// //
@ -204,7 +206,7 @@ GitEngine.prototype._numBackFrom = function(commit, numBack) {
}; };
GitEngine.prototype.checkout = function(idOrTarget) { GitEngine.prototype.checkout = function(idOrTarget) {
var target = this._resolveId(idOrTarget); var target = this.resolveId(idOrTarget);
if (target.get('id') === 'HEAD') { if (target.get('id') === 'HEAD') {
// meaningless command but i used to do this back in the day // meaningless command but i used to do this back in the day
return; return;
@ -223,17 +225,17 @@ GitEngine.prototype.branch = function(name, ref, options) {
options = options || {}; options = options || {};
if (options['-d'] || options['-D']) { if (options['-d'] || options['-D']) {
this._deleteBranch(name); this.deleteBranch(name);
return; return;
} }
var target = this._getCommitFromRef(ref); var target = this.getCommitFromRef(ref);
this._makeBranch(name, target); this.makeBranch(name, target);
}; };
GitEngine.prototype._deleteBranch = function(name) { GitEngine.prototype.deleteBranch = function(name) {
// trying to delete, lets check our refs // trying to delete, lets check our refs
var target = this._resolveId(name); var target = this.resolveId(name);
if (target.get('type') !== 'branch') { if (target.get('type') !== 'branch') {
throw new Error("You can't delete things that arent branches with branch command"); throw new Error("You can't delete things that arent branches with branch command");
} }
@ -250,7 +252,7 @@ GitEngine.prototype._deleteBranch = function(name) {
}; };
GitEngine.prototype.dispatch = function(commandObj) { GitEngine.prototype.dispatch = function(commandObj) {
// TODO: parse arguments // TODO: parse arguments as well
this[commandObj.method](); this[commandObj.method]();
}; };

View file

@ -28,24 +28,36 @@ var CommandLineView = Backbone.View.extend({
this.submit(); this.submit();
}, },
processError: function(err) {
// in this demo, every command that's not a git command will
// throw an exception. Some of these errors might be just to
// short-circuit the normal programatic flow, so we handle them
// here
if (err instanceof CommandProcessError) {
events.trigger('commandProcessError', err);
} else if (err instanceof CommandResult) {
events.trigger('commandResultPrint', err);
} else {
throw err;
}
},
submit: function() { submit: function() {
var value = this.$('#commandTextField').val(); var value = this.$('#commandTextField').val();
this.$('#commandTextField').val(''); this.$('#commandTextField').val('');
events.trigger('commandConsumed', value);
if (!value.length) {
// return early, just want a blank line
}
console.log('the value');
console.log(value);
try { try {
var command = new Command(value); var command = new Command(value);
console.log(command); console.log(command);
// immediately execute for now TODO // immediately execute for now, will change later
gitEngine.dispatch(command); events.trigger('gitCommandReady', command);
} catch (e) { } catch (err) {
alert('Error with that command: ' + String(e)); if (err instanceof CommandProcessError) {
events.trigger('commandProcessError', err);
} else if (err instanceof CommandResultError) {
} else {
throw err;
}
} }
} }
}); });
@ -56,12 +68,26 @@ var CommandLineHistoryView = Backbone.View.extend({
this.addCommand, this this.addCommand, this
)); ));
events.on('commandProcessError', _.bind(
this.commandError, this
));
events.on('commandResultPrint', _.bind(
this.commandResultPrint, this
));
this.commandTemplate = ' \ this.commandTemplate = ' \
<p class="commandLine <%= name %>"> \ <p class="commandLine <%= class %>"> \
<span class="arrows">&gt; &gt; &gt;</span> \ <span class="arrows">&gt; &gt; &gt;</span> \
<%= command %> \ <%= command %> \
</p> \ </p> \
'; ';
this.resultTemplate = ' \
<p class="commandResult <%= class %>"> \
<%= result %>
</p>
';
}, },
addCommand: function(commandText) { addCommand: function(commandText) {
@ -74,5 +100,29 @@ var CommandLineHistoryView = Backbone.View.extend({
} }
) )
); );
},
commandError: function(err) {
this.$('#commandDisplay').append(
_.template(
this.resultTemplate,
{
class: 'errorResult',
result: err.toResult()
}
)
);
},
commandResultPrint: function(err) {
this.$('#commandDisplay').append(
_.template(
this.resultTemplate,
{
class; 'commandResult',
result: err.toResult()
}
)
);
} }
}); });